blob: a48a64ce1514b949886cb50ad5d2a4928edfdaaf [file] [log] [blame]
#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:
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;
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_