1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_BUFFER_WRAPPER_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_BUFFER_WRAPPER_H_ 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstddef> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <memory> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <type_traits> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <vector> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace rpc { 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Wrapper class for buffers, providing an interface suitable for 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// SerializeObject and DeserializeObject. This class supports serialization of 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// buffers as raw bytes. 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T> 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferWrapper; 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T> 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferWrapper<T*> { 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Define types in the style of STL containers to support STL operators. 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typedef T value_type; 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typedef std::size_t size_type; 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typedef T& reference; 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typedef const T& const_reference; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typedef T* pointer; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typedef const T* const_pointer; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper() : buffer_(nullptr), capacity_(0), end_(0) {} 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(pointer buffer, size_type capacity, size_type size) 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : buffer_(&buffer[0]), 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko capacity_(capacity), 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko end_(capacity < size ? capacity : size) {} 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(pointer buffer, size_type size) 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BufferWrapper(buffer, size, size) {} 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(const BufferWrapper& other) { *this = other; } 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(BufferWrapper&& other) { *this = std::move(other); } 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper& operator=(const BufferWrapper& other) { 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (&other == this) { 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_ = other.buffer_; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko capacity_ = other.capacity_; 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko end_ = other.end_; 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper& operator=(BufferWrapper&& other) { 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (&other == this) { 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_ = other.buffer_; 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko capacity_ = other.capacity_; 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko end_ = other.end_; 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko other.buffer_ = nullptr; 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko other.capacity_ = 0; 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko other.end_ = 0; 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pointer data() { return buffer_; } 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_pointer data() const { return buffer_; } 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pointer begin() { return &buffer_[0]; } 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pointer end() { return &buffer_[end_]; } 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_pointer begin() const { return &buffer_[0]; } 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_pointer end() const { return &buffer_[end_]; } 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type size() const { return end_; } 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type max_size() const { return capacity_; } 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type capacity() const { return capacity_; } 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void resize(size_type size) { 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (size <= capacity_) 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko end_ = size; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko end_ = capacity_; 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko reference operator[](size_type pos) { return buffer_[pos]; } 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_reference operator[](size_type pos) const { return buffer_[pos]; } 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pointer buffer_; 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type capacity_; 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type end_; 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator> 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferWrapper<std::vector<T, Allocator>> { 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using BufferType = typename std::vector<T, Allocator>; 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using value_type = typename BufferType::value_type; 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using size_type = typename BufferType::size_type; 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using reference = typename BufferType::reference; 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using const_reference = typename BufferType::const_reference; 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using pointer = typename BufferType::pointer; 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using const_pointer = typename BufferType::const_pointer; 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using iterator = typename BufferType::iterator; 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using const_iterator = typename BufferType::const_iterator; 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper() {} 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(const BufferType& buffer) : buffer_(buffer) {} 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(const BufferType& buffer, const Allocator& allocator) 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : buffer_(buffer, allocator) {} 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {} 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(BufferType&& buffer, const Allocator& allocator) 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : buffer_(std::move(buffer), allocator) {} 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(const BufferWrapper&) = default; 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper(BufferWrapper&&) = default; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper& operator=(const BufferWrapper&) = default; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferWrapper& operator=(BufferWrapper&&) = default; 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pointer data() { return buffer_.data(); } 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_pointer data() const { return buffer_.data(); } 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iterator begin() { return buffer_.begin(); } 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iterator end() { return buffer_.end(); } 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_iterator begin() const { return buffer_.begin(); } 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_iterator end() const { return buffer_.end(); } 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type size() const { return buffer_.size(); } 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type max_size() const { return buffer_.capacity(); } 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type capacity() const { return buffer_.capacity(); } 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void resize(size_type size) { buffer_.resize(size); } 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void reserve(size_type size) { buffer_.reserve(size); } 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko reference operator[](size_type pos) { return buffer_[pos]; } 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_reference operator[](size_type pos) const { return buffer_[pos]; } 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferType& buffer() { return buffer_; } 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BufferType& buffer() const { return buffer_; } 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferType buffer_; 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename SizeType = std::size_t> 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferWrapper<T*> WrapBuffer(T* buffer, SizeType size) { 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return BufferWrapper<T*>(buffer, size); 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename SizeType = std::size_t> 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferWrapper<std::uint8_t*> WrapBuffer(void* buffer, SizeType size) { 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return BufferWrapper<std::uint8_t*>(static_cast<std::uint8_t*>(buffer), size); 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename SizeType = std::size_t> 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferWrapper<const std::uint8_t*> WrapBuffer(const void* buffer, 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SizeType size) { 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return BufferWrapper<const std::uint8_t*>( 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static_cast<const std::uint8_t*>(buffer), size); 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator = std::allocator<T>> 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferWrapper<std::vector<T, Allocator>> WrapBuffer( 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<T, Allocator>&& buffer) { 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return BufferWrapper<std::vector<T, Allocator>>( 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::forward<std::vector<T, Allocator>>(buffer)); 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace rpc 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_PDX_RPC_BUFFER_WRAPPER_H_ 178