// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <stdlib.h> #include <limits> #include "base/logging.h" #include "mojo/edk/system/ports/event.h" namespace mojo { namespace edk { namespace ports { // static bool Message::Parse(const void* bytes, size_t num_bytes, size_t* num_header_bytes, size_t* num_payload_bytes, size_t* num_ports_bytes) { if (num_bytes < sizeof(EventHeader)) return false; const EventHeader* header = static_cast<const EventHeader*>(bytes); switch (header->type) { case EventType::kUser: // See below. break; case EventType::kPortAccepted: *num_header_bytes = sizeof(EventHeader); break; case EventType::kObserveProxy: *num_header_bytes = sizeof(EventHeader) + sizeof(ObserveProxyEventData); break; case EventType::kObserveProxyAck: *num_header_bytes = sizeof(EventHeader) + sizeof(ObserveProxyAckEventData); break; case EventType::kObserveClosure: *num_header_bytes = sizeof(EventHeader) + sizeof(ObserveClosureEventData); break; case EventType::kMergePort: *num_header_bytes = sizeof(EventHeader) + sizeof(MergePortEventData); break; default: return false; } if (header->type == EventType::kUser) { if (num_bytes < sizeof(EventHeader) + sizeof(UserEventData)) return false; const UserEventData* event_data = reinterpret_cast<const UserEventData*>( reinterpret_cast<const char*>(header + 1)); if (event_data->num_ports > std::numeric_limits<uint16_t>::max()) return false; *num_header_bytes = sizeof(EventHeader) + sizeof(UserEventData) + event_data->num_ports * sizeof(PortDescriptor); *num_ports_bytes = event_data->num_ports * sizeof(PortName); if (num_bytes < *num_header_bytes + *num_ports_bytes) return false; *num_payload_bytes = num_bytes - *num_header_bytes - *num_ports_bytes; } else { if (*num_header_bytes != num_bytes) return false; *num_payload_bytes = 0; *num_ports_bytes = 0; } return true; } Message::Message(size_t num_payload_bytes, size_t num_ports) : Message(sizeof(EventHeader) + sizeof(UserEventData) + num_ports * sizeof(PortDescriptor), num_payload_bytes, num_ports * sizeof(PortName)) { num_ports_ = num_ports; } Message::Message(size_t num_header_bytes, size_t num_payload_bytes, size_t num_ports_bytes) : start_(nullptr), num_header_bytes_(num_header_bytes), num_ports_bytes_(num_ports_bytes), num_payload_bytes_(num_payload_bytes) { } void Message::InitializeUserMessageHeader(void* start) { start_ = static_cast<char*>(start); memset(start_, 0, num_header_bytes_); GetMutableEventHeader(this)->type = EventType::kUser; GetMutableEventData<UserEventData>(this)->num_ports = static_cast<uint32_t>(num_ports_); } } // namespace ports } // namespace edk } // namespace mojo