#ifndef ANDROID_PDX_RPC_PAYLOAD_H_ #define ANDROID_PDX_RPC_PAYLOAD_H_ #include #include #include #include namespace android { namespace pdx { namespace rpc { // Implements the payload interface, required by Serialize/Deserialize, on top // of a thread-local MessageBuffer. template class MessagePayload { public: using BufferType = typename MessageBuffer::BufferType; using ValueType = typename MessageBuffer::ValueType; // Constructs a MessagePayload with an empty TLS buffer. MessagePayload() : buffer_(MessageBuffer::GetEmptyBuffer()), cursor_(buffer_.begin()), const_cursor_(buffer_.cbegin()) {} // Returns a reference to the cursor iterator to be used during serialization // into the underlying MessageBuffer. typename BufferType::iterator& Cursor() { return cursor_; } // Returns a reference to the const cursor iterator at the beginning of the // underlying MessageBuffer. typename BufferType::const_iterator& ConstCursor() { return const_cursor_; } // Returns a const iterator marking the end of the underlying MessageBuffer. typename BufferType::const_iterator ConstEnd() { return buffer_.cend(); } // Resizes the underlying MessageBuffer and sets the cursor to the beginning. void Resize(std::size_t size) { buffer_.resize(size); cursor_ = buffer_.begin(); const_cursor_ = buffer_.cbegin(); } // Resets the read cursor so that data can be read from the buffer again. void Rewind() { const_cursor_ = buffer_.cbegin(); } // Adds |size| bytes to the size of the underlying MessageBuffer and positions // the cursor at the beginning of the extended region. void Extend(std::size_t size) { const std::size_t offset = buffer_.size(); buffer_.resize(offset + size); cursor_ = buffer_.begin() + offset; const_cursor_ = buffer_.cbegin() + offset; } // Clears the underlying MessageBuffer and sets the cursor to the beginning. void Clear() { buffer_.clear(); cursor_ = buffer_.begin(); const_cursor_ = buffer_.cbegin(); } ValueType* Data() { return buffer_.data(); } const ValueType* Data() const { return buffer_.data(); } std::size_t Size() const { return buffer_.size(); } std::size_t Capacity() const { return buffer_.capacity(); } private: BufferType& buffer_; typename BufferType::iterator cursor_; typename BufferType::const_iterator const_cursor_; MessagePayload(const MessagePayload&) = delete; void operator=(const MessagePayload&) = delete; }; // Implements the payload interface for service-side RPCs. Handles translating // between remote and local handle spaces automatically. template class ServicePayload : public MessagePayload, public MessageWriter, public MessageReader { public: explicit ServicePayload(Message& message) : message_(message) {} // MessageWriter void* GetNextWriteBufferSection(size_t size) override { this->Extend(size); return &*this->Cursor(); } OutputResourceMapper* GetOutputResourceMapper() override { return &message_; } // MessageReader BufferSection GetNextReadBufferSection() override { return {&*this->ConstCursor(), &*this->ConstEnd()}; } void ConsumeReadBufferSectionData(const void* new_start) override { std::advance(this->ConstCursor(), PointerDistance(new_start, &*this->ConstCursor())); } InputResourceMapper* GetInputResourceMapper() override { return &message_; } private: Message& message_; }; // Implements the payload interface for client-side RPCs. Handles gathering file // handles to be sent over IPC automatically. template class ClientPayload : public MessagePayload, public MessageWriter, public MessageReader { public: using ContainerType = MessageBuffer>, 1024u, int>; using BufferType = typename ContainerType::BufferType; explicit ClientPayload(Transaction& transaction) : transaction_{transaction} {} // MessageWriter void* GetNextWriteBufferSection(size_t size) override { this->Extend(size); return &*this->Cursor(); } OutputResourceMapper* GetOutputResourceMapper() override { return &transaction_; } // MessageReader BufferSection GetNextReadBufferSection() override { return {&*this->ConstCursor(), &*this->ConstEnd()}; } void ConsumeReadBufferSectionData(const void* new_start) override { std::advance(this->ConstCursor(), PointerDistance(new_start, &*this->ConstCursor())); } InputResourceMapper* GetInputResourceMapper() override { return &transaction_; } private: Transaction& transaction_; }; } // namespace rpc } // namespace pdx } // namespace android #endif // ANDROID_PDX_RPC_PAYLOAD_H_