159 lines
4.9 KiB
C++
159 lines
4.9 KiB
C++
#ifndef ANDROID_PDX_RPC_PAYLOAD_H_
|
|
#define ANDROID_PDX_RPC_PAYLOAD_H_
|
|
|
|
#include <iterator>
|
|
|
|
#include <pdx/client.h>
|
|
#include <pdx/rpc/message_buffer.h>
|
|
#include <pdx/service.h>
|
|
|
|
namespace android {
|
|
namespace pdx {
|
|
namespace rpc {
|
|
|
|
// Implements the payload interface, required by Serialize/Deserialize, on top
|
|
// of a thread-local MessageBuffer.
|
|
template <typename Slot>
|
|
class MessagePayload {
|
|
public:
|
|
using BufferType = typename MessageBuffer<Slot>::BufferType;
|
|
using ValueType = typename MessageBuffer<Slot>::ValueType;
|
|
|
|
// Constructs a MessagePayload with an empty TLS buffer.
|
|
MessagePayload()
|
|
: buffer_(MessageBuffer<Slot>::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<Slot>&) = delete;
|
|
void operator=(const MessagePayload<Slot>&) = delete;
|
|
};
|
|
|
|
// Implements the payload interface for service-side RPCs. Handles translating
|
|
// between remote and local handle spaces automatically.
|
|
template <typename Slot>
|
|
class ServicePayload : public MessagePayload<Slot>,
|
|
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 <typename Slot>
|
|
class ClientPayload : public MessagePayload<Slot>,
|
|
public MessageWriter,
|
|
public MessageReader {
|
|
public:
|
|
using ContainerType =
|
|
MessageBuffer<ThreadLocalTypeSlot<ClientPayload<Slot>>, 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_
|