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