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. MessagePayload()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. Cursor()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. ConstCursor()34 typename BufferType::const_iterator& ConstCursor() { return const_cursor_; } 35 36 // Returns a const iterator marking the end of the underlying MessageBuffer. ConstEnd()37 typename BufferType::const_iterator ConstEnd() { return buffer_.cend(); } 38 39 // Resizes the underlying MessageBuffer and sets the cursor to the beginning. Resize(std::size_t size)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. Rewind()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. Extend(std::size_t size)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. Clear()59 void Clear() { 60 buffer_.clear(); 61 cursor_ = buffer_.begin(); 62 const_cursor_ = buffer_.cbegin(); 63 } 64 Data()65 ValueType* Data() { return buffer_.data(); } Data()66 const ValueType* Data() const { return buffer_.data(); } Size()67 std::size_t Size() const { return buffer_.size(); } Capacity()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: ServicePayload(Message & message)86 explicit ServicePayload(Message& message) : message_(message) {} 87 88 // MessageWriter GetNextWriteBufferSection(size_t size)89 void* GetNextWriteBufferSection(size_t size) override { 90 this->Extend(size); 91 return &*this->Cursor(); 92 } 93 GetOutputResourceMapper()94 OutputResourceMapper* GetOutputResourceMapper() override { return &message_; } 95 96 // MessageReader GetNextReadBufferSection()97 BufferSection GetNextReadBufferSection() override { 98 return {&*this->ConstCursor(), &*this->ConstEnd()}; 99 } 100 ConsumeReadBufferSectionData(const void * new_start)101 void ConsumeReadBufferSectionData(const void* new_start) override { 102 std::advance(this->ConstCursor(), 103 PointerDistance(new_start, &*this->ConstCursor())); 104 } 105 GetInputResourceMapper()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 ClientPayload(Transaction & transaction)123 explicit ClientPayload(Transaction& transaction) 124 : transaction_{transaction} {} 125 126 // MessageWriter GetNextWriteBufferSection(size_t size)127 void* GetNextWriteBufferSection(size_t size) override { 128 this->Extend(size); 129 return &*this->Cursor(); 130 } 131 GetOutputResourceMapper()132 OutputResourceMapper* GetOutputResourceMapper() override { 133 return &transaction_; 134 } 135 136 // MessageReader GetNextReadBufferSection()137 BufferSection GetNextReadBufferSection() override { 138 return {&*this->ConstCursor(), &*this->ConstEnd()}; 139 } 140 ConsumeReadBufferSectionData(const void * new_start)141 void ConsumeReadBufferSectionData(const void* new_start) override { 142 std::advance(this->ConstCursor(), 143 PointerDistance(new_start, &*this->ConstCursor())); 144 } 145 GetInputResourceMapper()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