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 10namespace android { 11namespace pdx { 12namespace rpc { 13 14// Implements the payload interface, required by Serialize/Deserialize, on top 15// of a thread-local MessageBuffer. 16template <typename Slot> 17class 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. 81template <typename Slot> 82class ServicePayload : public MessagePayload<Slot>, 83 public MessageWriter, 84 public MessageReader { 85 public: 86 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. 114template <typename Slot> 115class 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 ClientPayload(Transaction& transaction) : transaction_{transaction} {} 124 125 // MessageWriter 126 void* GetNextWriteBufferSection(size_t size) override { 127 this->Extend(size); 128 return &*this->Cursor(); 129 } 130 131 OutputResourceMapper* GetOutputResourceMapper() override { 132 return &transaction_; 133 } 134 135 // MessageReader 136 BufferSection GetNextReadBufferSection() override { 137 return {&*this->ConstCursor(), &*this->ConstEnd()}; 138 } 139 140 void ConsumeReadBufferSectionData(const void* new_start) override { 141 std::advance(this->ConstCursor(), 142 PointerDistance(new_start, &*this->ConstCursor())); 143 } 144 145 InputResourceMapper* GetInputResourceMapper() override { 146 return &transaction_; 147 } 148 149 private: 150 Transaction& transaction_; 151}; 152 153} // namespace rpc 154} // namespace pdx 155} // namespace android 156 157#endif // ANDROID_PDX_RPC_PAYLOAD_H_ 158