| // 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. |
| |
| #ifndef MOJO_EDK_SYSTEM_MESSAGE_FOR_TRANSIT_H_ |
| #define MOJO_EDK_SYSTEM_MESSAGE_FOR_TRANSIT_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "mojo/edk/system/dispatcher.h" |
| #include "mojo/edk/system/ports_message.h" |
| #include "mojo/edk/system/system_impl_export.h" |
| |
| namespace mojo { |
| namespace edk { |
| |
| // MessageForTransit holds onto a PortsMessage which may be sent via |
| // |MojoWriteMessage()| or which may have been received on a pipe endpoint. |
| // Instances of this class are exposed to Mojo system API consumers via the |
| // opaque pointers used with |MojoCreateMessage()|, |MojoDestroyMessage()|, |
| // |MojoWriteMessageNew()|, and |MojoReadMessageNew()|. |
| class MOJO_SYSTEM_IMPL_EXPORT MessageForTransit { |
| public: |
| #pragma pack(push, 1) |
| // Header attached to every message. |
| struct MessageHeader { |
| // The number of serialized dispatchers included in this header. |
| uint32_t num_dispatchers; |
| |
| // Total size of the header, including serialized dispatcher data. |
| uint32_t header_size; |
| }; |
| |
| // Header for each dispatcher in a message, immediately following the message |
| // header. |
| struct DispatcherHeader { |
| // The type of the dispatcher, correpsonding to the Dispatcher::Type enum. |
| int32_t type; |
| |
| // The size of the serialized dispatcher, not including this header. |
| uint32_t num_bytes; |
| |
| // The number of ports needed to deserialize this dispatcher. |
| uint32_t num_ports; |
| |
| // The number of platform handles needed to deserialize this dispatcher. |
| uint32_t num_platform_handles; |
| }; |
| #pragma pack(pop) |
| |
| ~MessageForTransit(); |
| |
| // A static constructor for building outbound messages. |
| static MojoResult Create( |
| std::unique_ptr<MessageForTransit>* message, |
| uint32_t num_bytes, |
| const Dispatcher::DispatcherInTransit* dispatchers, |
| uint32_t num_dispatchers); |
| |
| // A static constructor for wrapping inbound messages. |
| static std::unique_ptr<MessageForTransit> WrapPortsMessage( |
| std::unique_ptr<PortsMessage> message) { |
| return base::WrapUnique(new MessageForTransit(std::move(message))); |
| } |
| |
| const void* bytes() const { |
| DCHECK(message_); |
| return static_cast<const void*>( |
| static_cast<const char*>(message_->payload_bytes()) + |
| header()->header_size); |
| } |
| |
| void* mutable_bytes() { |
| DCHECK(message_); |
| return static_cast<void*>( |
| static_cast<char*>(message_->mutable_payload_bytes()) + |
| header()->header_size); |
| } |
| |
| size_t num_bytes() const { |
| size_t header_size = header()->header_size; |
| DCHECK_GE(message_->num_payload_bytes(), header_size); |
| return message_->num_payload_bytes() - header_size; |
| } |
| |
| size_t num_handles() const { return header()->num_dispatchers; } |
| |
| const PortsMessage& ports_message() const { return *message_; } |
| |
| std::unique_ptr<PortsMessage> TakePortsMessage() { |
| return std::move(message_); |
| } |
| |
| private: |
| explicit MessageForTransit(std::unique_ptr<PortsMessage> message); |
| |
| const MessageForTransit::MessageHeader* header() const { |
| DCHECK(message_); |
| return static_cast<const MessageForTransit::MessageHeader*>( |
| message_->payload_bytes()); |
| } |
| |
| std::unique_ptr<PortsMessage> message_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MessageForTransit); |
| }; |
| |
| } // namespace edk |
| } // namespace mojo |
| |
| #endif // MOJO_EDK_SYSTEM_MESSAGE_FOR_TRANSIT_H_ |