Home | History | Annotate | Download | only in rpc
      1 #ifndef ANDROID_PDX_RPC_PAYLOAD_H_
      2 #define ANDROID_PDX_RPC_PAYLOAD_H_
      3 
      4 #include <iterator>
      5 
      6 #include <pdx/client.h>
      7 #include <pdx/rpc/message_buffer.h>
      8 #include <pdx/service.h>
      9 
     10 namespace android {
     11 namespace pdx {
     12 namespace rpc {
     13 
     14 // Implements the payload interface, required by Serialize/Deserialize, on top
     15 // of a thread-local MessageBuffer.
     16 template <typename Slot>
     17 class MessagePayload {
     18  public:
     19   using BufferType = typename MessageBuffer<Slot>::BufferType;
     20   using ValueType = typename MessageBuffer<Slot>::ValueType;
     21 
     22   // Constructs a MessagePayload with an empty TLS buffer.
     23   MessagePayload()
     24       : buffer_(MessageBuffer<Slot>::GetEmptyBuffer()),
     25         cursor_(buffer_.begin()),
     26         const_cursor_(buffer_.cbegin()) {}
     27 
     28   // Returns a reference to the cursor iterator to be used during serialization
     29   // into the underlying MessageBuffer.
     30   typename BufferType::iterator& Cursor() { return cursor_; }
     31 
     32   // Returns a reference to the const cursor iterator at the beginning of the
     33   // underlying MessageBuffer.
     34   typename BufferType::const_iterator& ConstCursor() { return const_cursor_; }
     35 
     36   // Returns a const iterator marking the end of the underlying MessageBuffer.
     37   typename BufferType::const_iterator ConstEnd() { return buffer_.cend(); }
     38 
     39   // Resizes the underlying MessageBuffer and sets the cursor to the beginning.
     40   void Resize(std::size_t size) {
     41     buffer_.resize(size);
     42     cursor_ = buffer_.begin();
     43     const_cursor_ = buffer_.cbegin();
     44   }
     45 
     46   // Resets the read cursor so that data can be read from the buffer again.
     47   void Rewind() { const_cursor_ = buffer_.cbegin(); }
     48 
     49   // Adds |size| bytes to the size of the underlying MessageBuffer and positions
     50   // the cursor at the beginning of the extended region.
     51   void Extend(std::size_t size) {
     52     const std::size_t offset = buffer_.size();
     53     buffer_.resize(offset + size);
     54     cursor_ = buffer_.begin() + offset;
     55     const_cursor_ = buffer_.cbegin() + offset;
     56   }
     57 
     58   // Clears the underlying MessageBuffer and sets the cursor to the beginning.
     59   void Clear() {
     60     buffer_.clear();
     61     cursor_ = buffer_.begin();
     62     const_cursor_ = buffer_.cbegin();
     63   }
     64 
     65   ValueType* Data() { return buffer_.data(); }
     66   const ValueType* Data() const { return buffer_.data(); }
     67   std::size_t Size() const { return buffer_.size(); }
     68   std::size_t Capacity() const { return buffer_.capacity(); }
     69 
     70  private:
     71   BufferType& buffer_;
     72   typename BufferType::iterator cursor_;
     73   typename BufferType::const_iterator const_cursor_;
     74 
     75   MessagePayload(const MessagePayload<Slot>&) = delete;
     76   void operator=(const MessagePayload<Slot>&) = delete;
     77 };
     78 
     79 // Implements the payload interface for service-side RPCs. Handles translating
     80 // between remote and local handle spaces automatically.
     81 template <typename Slot>
     82 class ServicePayload : public MessagePayload<Slot>,
     83                        public MessageWriter,
     84                        public MessageReader {
     85  public:
     86   explicit ServicePayload(Message& message) : message_(message) {}
     87 
     88   // MessageWriter
     89   void* GetNextWriteBufferSection(size_t size) override {
     90     this->Extend(size);
     91     return &*this->Cursor();
     92   }
     93 
     94   OutputResourceMapper* GetOutputResourceMapper() override { return &message_; }
     95 
     96   // MessageReader
     97   BufferSection GetNextReadBufferSection() override {
     98     return {&*this->ConstCursor(), &*this->ConstEnd()};
     99   }
    100 
    101   void ConsumeReadBufferSectionData(const void* new_start) override {
    102     std::advance(this->ConstCursor(),
    103                  PointerDistance(new_start, &*this->ConstCursor()));
    104   }
    105 
    106   InputResourceMapper* GetInputResourceMapper() override { return &message_; }
    107 
    108  private:
    109   Message& message_;
    110 };
    111 
    112 // Implements the payload interface for client-side RPCs. Handles gathering file
    113 // handles to be sent over IPC automatically.
    114 template <typename Slot>
    115 class ClientPayload : public MessagePayload<Slot>,
    116                       public MessageWriter,
    117                       public MessageReader {
    118  public:
    119   using ContainerType =
    120       MessageBuffer<ThreadLocalTypeSlot<ClientPayload<Slot>>, 1024u, int>;
    121   using BufferType = typename ContainerType::BufferType;
    122 
    123   explicit ClientPayload(Transaction& transaction)
    124       : transaction_{transaction} {}
    125 
    126   // MessageWriter
    127   void* GetNextWriteBufferSection(size_t size) override {
    128     this->Extend(size);
    129     return &*this->Cursor();
    130   }
    131 
    132   OutputResourceMapper* GetOutputResourceMapper() override {
    133     return &transaction_;
    134   }
    135 
    136   // MessageReader
    137   BufferSection GetNextReadBufferSection() override {
    138     return {&*this->ConstCursor(), &*this->ConstEnd()};
    139   }
    140 
    141   void ConsumeReadBufferSectionData(const void* new_start) override {
    142     std::advance(this->ConstCursor(),
    143                  PointerDistance(new_start, &*this->ConstCursor()));
    144   }
    145 
    146   InputResourceMapper* GetInputResourceMapper() override {
    147     return &transaction_;
    148   }
    149 
    150  private:
    151   Transaction& transaction_;
    152 };
    153 
    154 }  // namespace rpc
    155 }  // namespace pdx
    156 }  // namespace android
    157 
    158 #endif  // ANDROID_PDX_RPC_PAYLOAD_H_
    159