Home | History | Annotate | Download | only in system
      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.
     65   static std::unique_ptr<MessageForTransit> WrapPortsMessage(
     66       std::unique_ptr<PortsMessage> message) {
     67     return base::WrapUnique(new MessageForTransit(std::move(message)));
     68   }
     69 
     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 
     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 
     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 
     90   size_t num_handles() const { return header()->num_dispatchers; }
     91 
     92   const PortsMessage& ports_message() const { return *message_; }
     93 
     94   std::unique_ptr<PortsMessage> TakePortsMessage() {
     95     return std::move(message_);
     96   }
     97 
     98  private:
     99   explicit MessageForTransit(std::unique_ptr<PortsMessage> message);
    100 
    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