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