1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_ARRAY_WRAPPER_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_ARRAY_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 C array buffers, providing an interface suitable for 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// SerializeObject and DeserializeObject. This class serializes to the same 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// format as std::vector, and may be substituted for std::vector during 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// serialization and deserialization. This substitution makes handling of C 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// arrays more efficient by avoiding unnecessary copies when remote method 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// signatures specify std::vector arguments or return values. 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T> 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ArrayWrapper { 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 ArrayWrapper() : buffer_(nullptr), capacity_(0), end_(0) {} 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ArrayWrapper(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 ArrayWrapper(pointer buffer, size_type size) 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : ArrayWrapper(buffer, size, size) {} 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ArrayWrapper(const ArrayWrapper& other) { *this = other; } 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ArrayWrapper(ArrayWrapper&& other) { *this = std::move(other); } 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ArrayWrapper& operator=(const ArrayWrapper& 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 ArrayWrapper& operator=(ArrayWrapper&& 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 // Moves the end marker to |size|, clamping the end marker to the max capacity 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // of the underlying array. This method does not change the size of the 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // underlying array. 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void resize(size_type size) { 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (size <= capacity_) 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko end_ = size; 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko end_ = capacity_; 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko reference operator[](size_type pos) { return buffer_[pos]; } 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_reference operator[](size_type pos) const { return buffer_[pos]; } 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pointer buffer_; 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type capacity_; 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type end_; 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename SizeType = std::size_t> 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoArrayWrapper<T> WrapArray(T* buffer, SizeType size) { 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ArrayWrapper<T>(buffer, size); 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace rpc 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_PDX_RPC_ARRAY_WRAPPER_H_ 112