• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stdlib.h>
6 
7 #include <limits>
8 
9 #include "base/logging.h"
10 #include "mojo/edk/system/ports/event.h"
11 
12 namespace mojo {
13 namespace edk {
14 namespace ports {
15 
16 // static
Parse(const void * bytes,size_t num_bytes,size_t * num_header_bytes,size_t * num_payload_bytes,size_t * num_ports_bytes)17 bool Message::Parse(const void* bytes,
18                     size_t num_bytes,
19                     size_t* num_header_bytes,
20                     size_t* num_payload_bytes,
21                     size_t* num_ports_bytes) {
22   if (num_bytes < sizeof(EventHeader))
23     return false;
24   const EventHeader* header = static_cast<const EventHeader*>(bytes);
25   switch (header->type) {
26     case EventType::kUser:
27       // See below.
28       break;
29     case EventType::kPortAccepted:
30       *num_header_bytes = sizeof(EventHeader);
31       break;
32     case EventType::kObserveProxy:
33       *num_header_bytes = sizeof(EventHeader) + sizeof(ObserveProxyEventData);
34       break;
35     case EventType::kObserveProxyAck:
36       *num_header_bytes =
37           sizeof(EventHeader) + sizeof(ObserveProxyAckEventData);
38       break;
39     case EventType::kObserveClosure:
40       *num_header_bytes = sizeof(EventHeader) + sizeof(ObserveClosureEventData);
41       break;
42     case EventType::kMergePort:
43       *num_header_bytes = sizeof(EventHeader) + sizeof(MergePortEventData);
44       break;
45     default:
46       return false;
47   }
48 
49   if (header->type == EventType::kUser) {
50     if (num_bytes < sizeof(EventHeader) + sizeof(UserEventData))
51       return false;
52     const UserEventData* event_data =
53         reinterpret_cast<const UserEventData*>(
54             reinterpret_cast<const char*>(header + 1));
55     if (event_data->num_ports > std::numeric_limits<uint16_t>::max())
56       return false;
57     *num_header_bytes = sizeof(EventHeader) +
58                         sizeof(UserEventData) +
59                         event_data->num_ports * sizeof(PortDescriptor);
60     *num_ports_bytes = event_data->num_ports * sizeof(PortName);
61     if (num_bytes < *num_header_bytes + *num_ports_bytes)
62       return false;
63     *num_payload_bytes = num_bytes - *num_header_bytes - *num_ports_bytes;
64   } else {
65     if (*num_header_bytes != num_bytes)
66       return false;
67     *num_payload_bytes = 0;
68     *num_ports_bytes = 0;
69   }
70 
71   return true;
72 }
73 
Message(size_t num_payload_bytes,size_t num_ports)74 Message::Message(size_t num_payload_bytes, size_t num_ports)
75     : Message(sizeof(EventHeader) + sizeof(UserEventData) +
76                   num_ports * sizeof(PortDescriptor),
77               num_payload_bytes, num_ports * sizeof(PortName)) {
78   num_ports_ = num_ports;
79 }
80 
Message(size_t num_header_bytes,size_t num_payload_bytes,size_t num_ports_bytes)81 Message::Message(size_t num_header_bytes,
82                  size_t num_payload_bytes,
83                  size_t num_ports_bytes)
84     : start_(nullptr),
85       num_header_bytes_(num_header_bytes),
86       num_ports_bytes_(num_ports_bytes),
87       num_payload_bytes_(num_payload_bytes) {
88 }
89 
InitializeUserMessageHeader(void * start)90 void Message::InitializeUserMessageHeader(void* start) {
91   start_ = static_cast<char*>(start);
92   memset(start_, 0, num_header_bytes_);
93   GetMutableEventHeader(this)->type = EventType::kUser;
94   GetMutableEventData<UserEventData>(this)->num_ports =
95       static_cast<uint32_t>(num_ports_);
96 }
97 
98 }  // namespace ports
99 }  // namespace edk
100 }  // namespace mojo
101