• 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 #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