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_MESSAGE_FOR_TRANSIT_H_ 6 #define MOJO_EDK_SYSTEM_MESSAGE_FOR_TRANSIT_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 12 #include "base/macros.h" 13 #include "base/memory/ptr_util.h" 14 #include "mojo/edk/system/dispatcher.h" 15 #include "mojo/edk/system/ports_message.h" 16 #include "mojo/edk/system/system_impl_export.h" 17 18 namespace mojo { 19 namespace edk { 20 21 // MessageForTransit holds onto a PortsMessage which may be sent via 22 // |MojoWriteMessage()| or which may have been received on a pipe endpoint. 23 // Instances of this class are exposed to Mojo system API consumers via the 24 // opaque pointers used with |MojoCreateMessage()|, |MojoDestroyMessage()|, 25 // |MojoWriteMessageNew()|, and |MojoReadMessageNew()|. 26 class MOJO_SYSTEM_IMPL_EXPORT MessageForTransit { 27 public: 28 #pragma pack(push, 1) 29 // Header attached to every message. 30 struct MessageHeader { 31 // The number of serialized dispatchers included in this header. 32 uint32_t num_dispatchers; 33 34 // Total size of the header, including serialized dispatcher data. 35 uint32_t header_size; 36 }; 37 38 // Header for each dispatcher in a message, immediately following the message 39 // header. 40 struct DispatcherHeader { 41 // The type of the dispatcher, correpsonding to the Dispatcher::Type enum. 42 int32_t type; 43 44 // The size of the serialized dispatcher, not including this header. 45 uint32_t num_bytes; 46 47 // The number of ports needed to deserialize this dispatcher. 48 uint32_t num_ports; 49 50 // The number of platform handles needed to deserialize this dispatcher. 51 uint32_t num_platform_handles; 52 }; 53 #pragma pack(pop) 54 55 ~MessageForTransit(); 56 57 // A static constructor for building outbound messages. 58 static MojoResult Create( 59 std::unique_ptr<MessageForTransit>* message, 60 uint32_t num_bytes, 61 const Dispatcher::DispatcherInTransit* dispatchers, 62 uint32_t num_dispatchers); 63 64 // A static constructor for wrapping inbound messages. WrapPortsMessage(std::unique_ptr<PortsMessage> message)65 static std::unique_ptr<MessageForTransit> WrapPortsMessage( 66 std::unique_ptr<PortsMessage> message) { 67 return base::WrapUnique(new MessageForTransit(std::move(message))); 68 } 69 bytes()70 const void* bytes() const { 71 DCHECK(message_); 72 return static_cast<const void*>( 73 static_cast<const char*>(message_->payload_bytes()) + 74 header()->header_size); 75 } 76 mutable_bytes()77 void* mutable_bytes() { 78 DCHECK(message_); 79 return static_cast<void*>( 80 static_cast<char*>(message_->mutable_payload_bytes()) + 81 header()->header_size); 82 } 83 num_bytes()84 size_t num_bytes() const { 85 size_t header_size = header()->header_size; 86 DCHECK_GE(message_->num_payload_bytes(), header_size); 87 return message_->num_payload_bytes() - header_size; 88 } 89 num_handles()90 size_t num_handles() const { return header()->num_dispatchers; } 91 ports_message()92 const PortsMessage& ports_message() const { return *message_; } 93 TakePortsMessage()94 std::unique_ptr<PortsMessage> TakePortsMessage() { 95 return std::move(message_); 96 } 97 98 private: 99 explicit MessageForTransit(std::unique_ptr<PortsMessage> message); 100 header()101 const MessageForTransit::MessageHeader* header() const { 102 DCHECK(message_); 103 return static_cast<const MessageForTransit::MessageHeader*>( 104 message_->payload_bytes()); 105 } 106 107 std::unique_ptr<PortsMessage> message_; 108 109 DISALLOW_COPY_AND_ASSIGN(MessageForTransit); 110 }; 111 112 } // namespace edk 113 } // namespace mojo 114 115 #endif // MOJO_EDK_SYSTEM_MESSAGE_FOR_TRANSIT_H_ 116