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 #ifndef MOJO_EDK_SYSTEM_PORTS_MESSAGE_H_ 6 #define MOJO_EDK_SYSTEM_PORTS_MESSAGE_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 12 #include "mojo/edk/system/ports/name.h" 13 14 namespace mojo { 15 namespace edk { 16 namespace ports { 17 18 // A message consists of a header (array of bytes), payload (array of bytes) 19 // and an array of ports. The header is used by the Node implementation. 20 // 21 // This class is designed to be subclassed, and the subclass is responsible for 22 // providing the underlying storage. The header size will be aligned, and it 23 // should be followed in memory by the array of ports and finally the payload. 24 // 25 // NOTE: This class does not manage the lifetime of the ports it references. 26 class Message { 27 public: ~Message()28 virtual ~Message() {} 29 30 // Inspect the message at |bytes| and return the size of each section. Returns 31 // |false| if the message is malformed and |true| otherwise. 32 static bool Parse(const void* bytes, 33 size_t num_bytes, 34 size_t* num_header_bytes, 35 size_t* num_payload_bytes, 36 size_t* num_ports_bytes); 37 mutable_header_bytes()38 void* mutable_header_bytes() { return start_; } header_bytes()39 const void* header_bytes() const { return start_; } num_header_bytes()40 size_t num_header_bytes() const { return num_header_bytes_; } 41 mutable_payload_bytes()42 void* mutable_payload_bytes() { 43 return start_ + num_header_bytes_ + num_ports_bytes_; 44 } payload_bytes()45 const void* payload_bytes() const { 46 return const_cast<Message*>(this)->mutable_payload_bytes(); 47 } num_payload_bytes()48 size_t num_payload_bytes() const { return num_payload_bytes_; } 49 mutable_ports()50 PortName* mutable_ports() { 51 return reinterpret_cast<PortName*>(start_ + num_header_bytes_); 52 } ports()53 const PortName* ports() const { 54 return const_cast<Message*>(this)->mutable_ports(); 55 } num_ports_bytes()56 size_t num_ports_bytes() const { return num_ports_bytes_; } num_ports()57 size_t num_ports() const { return num_ports_bytes_ / sizeof(PortName); } 58 59 protected: 60 // Constructs a new Message base for a user message. 61 // 62 // Note: You MUST call InitializeUserMessageHeader() before this Message is 63 // ready for transmission. 64 Message(size_t num_payload_bytes, size_t num_ports); 65 66 // Constructs a new Message base for an internal message. Do NOT call 67 // InitializeUserMessageHeader() when using this constructor. 68 Message(size_t num_header_bytes, 69 size_t num_payload_bytes, 70 size_t num_ports_bytes); 71 72 Message(const Message& other) = delete; 73 void operator=(const Message& other) = delete; 74 75 // Initializes the header in a newly allocated message buffer to carry a 76 // user message. 77 void InitializeUserMessageHeader(void* start); 78 79 // Note: storage is [header][ports][payload]. 80 char* start_ = nullptr; 81 size_t num_ports_ = 0; 82 size_t num_header_bytes_ = 0; 83 size_t num_ports_bytes_ = 0; 84 size_t num_payload_bytes_ = 0; 85 }; 86 87 using ScopedMessage = std::unique_ptr<Message>; 88 89 } // namespace ports 90 } // namespace edk 91 } // namespace mojo 92 93 #endif // MOJO_EDK_SYSTEM_PORTS_MESSAGE_H_ 94