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