1#ifndef ANDROID_PDX_RPC_ARRAY_WRAPPER_H_ 2#define ANDROID_PDX_RPC_ARRAY_WRAPPER_H_ 3 4#include <cstddef> 5#include <memory> 6#include <type_traits> 7#include <vector> 8 9namespace android { 10namespace pdx { 11namespace rpc { 12 13// Wrapper class for C array buffers, providing an interface suitable for 14// SerializeObject and DeserializeObject. This class serializes to the same 15// format as std::vector, and may be substituted for std::vector during 16// serialization and deserialization. This substitution makes handling of C 17// arrays more efficient by avoiding unnecessary copies when remote method 18// signatures specify std::vector arguments or return values. 19template <typename T> 20class ArrayWrapper { 21 public: 22 // Define types in the style of STL containers to support STL operators. 23 typedef T value_type; 24 typedef std::size_t size_type; 25 typedef T& reference; 26 typedef const T& const_reference; 27 typedef T* pointer; 28 typedef const T* const_pointer; 29 30 ArrayWrapper() : buffer_(nullptr), capacity_(0), end_(0) {} 31 32 ArrayWrapper(pointer buffer, size_type capacity, size_type size) 33 : buffer_(&buffer[0]), 34 capacity_(capacity), 35 end_(capacity < size ? capacity : size) {} 36 37 ArrayWrapper(pointer buffer, size_type size) 38 : ArrayWrapper(buffer, size, size) {} 39 40 ArrayWrapper(const ArrayWrapper& other) { *this = other; } 41 42 ArrayWrapper(ArrayWrapper&& other) { *this = std::move(other); } 43 44 ArrayWrapper& operator=(const ArrayWrapper& other) { 45 if (&other == this) { 46 return *this; 47 } else { 48 buffer_ = other.buffer_; 49 capacity_ = other.capacity_; 50 end_ = other.end_; 51 } 52 53 return *this; 54 } 55 56 ArrayWrapper& operator=(ArrayWrapper&& other) { 57 if (&other == this) { 58 return *this; 59 } else { 60 buffer_ = other.buffer_; 61 capacity_ = other.capacity_; 62 end_ = other.end_; 63 other.buffer_ = nullptr; 64 other.capacity_ = 0; 65 other.end_ = 0; 66 } 67 68 return *this; 69 } 70 71 pointer data() { return buffer_; } 72 const_pointer data() const { return buffer_; } 73 74 pointer begin() { return &buffer_[0]; } 75 pointer end() { return &buffer_[end_]; } 76 const_pointer begin() const { return &buffer_[0]; } 77 const_pointer end() const { return &buffer_[end_]; } 78 79 size_type size() const { return end_; } 80 size_type max_size() const { return capacity_; } 81 size_type capacity() const { return capacity_; } 82 83 // Moves the end marker to |size|, clamping the end marker to the max capacity 84 // of the underlying array. This method does not change the size of the 85 // underlying array. 86 void resize(size_type size) { 87 if (size <= capacity_) 88 end_ = size; 89 else 90 end_ = capacity_; 91 } 92 93 reference operator[](size_type pos) { return buffer_[pos]; } 94 const_reference operator[](size_type pos) const { return buffer_[pos]; } 95 96 private: 97 pointer buffer_; 98 size_type capacity_; 99 size_type end_; 100}; 101 102template <typename T, typename SizeType = std::size_t> 103ArrayWrapper<T> WrapArray(T* buffer, SizeType size) { 104 return ArrayWrapper<T>(buffer, size); 105} 106 107} // namespace rpc 108} // namespace pdx 109} // namespace android 110 111#endif // ANDROID_PDX_RPC_ARRAY_WRAPPER_H_ 112