buffer_wrapper.h revision e4eec20f6263f4a42ae462456f60ea6c4518bb0a
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
9namespace android {
10namespace pdx {
11namespace 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.
16template <typename T>
17class BufferWrapper;
18
19template <typename T>
20class 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
30  BufferWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
31
32  BufferWrapper(pointer buffer, size_type capacity, size_type size)
33      : buffer_(&buffer[0]),
34        capacity_(capacity),
35        end_(capacity < size ? capacity : size) {}
36
37  BufferWrapper(pointer buffer, size_type size)
38      : BufferWrapper(buffer, size, size) {}
39
40  BufferWrapper(const BufferWrapper& other) { *this = other; }
41
42  BufferWrapper(BufferWrapper&& other) { *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) {
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  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
99template <typename T, typename Allocator>
100class 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
112  BufferWrapper() {}
113  BufferWrapper(const BufferType& buffer) : buffer_(buffer) {}
114  BufferWrapper(const BufferType& buffer, const Allocator& allocator)
115      : buffer_(buffer, allocator) {}
116  BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {}
117  BufferWrapper(BufferType&& buffer, const Allocator& allocator)
118      : buffer_(std::move(buffer), allocator) {}
119  BufferWrapper(const BufferWrapper&) = default;
120  BufferWrapper(BufferWrapper&&) = default;
121  BufferWrapper& operator=(const BufferWrapper&) = default;
122  BufferWrapper& operator=(BufferWrapper&&) = default;
123
124  pointer data() { return buffer_.data(); }
125  const_pointer data() const { return buffer_.data(); }
126
127  iterator begin() { return buffer_.begin(); }
128  iterator end() { return buffer_.end(); }
129  const_iterator begin() const { return buffer_.begin(); }
130  const_iterator end() const { return buffer_.end(); }
131
132  size_type size() const { return buffer_.size(); }
133  size_type max_size() const { return buffer_.capacity(); }
134  size_type capacity() const { return buffer_.capacity(); }
135
136  void resize(size_type size) { buffer_.resize(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
142  BufferType& buffer() { return buffer_; }
143  const BufferType& buffer() const { return buffer_; }
144
145 private:
146  BufferType buffer_;
147};
148
149template <typename T, typename SizeType = std::size_t>
150BufferWrapper<T*> WrapBuffer(T* buffer, SizeType size) {
151  return BufferWrapper<T*>(buffer, size);
152}
153
154template <typename SizeType = std::size_t>
155BufferWrapper<std::uint8_t*> WrapBuffer(void* buffer, SizeType size) {
156  return BufferWrapper<std::uint8_t*>(static_cast<std::uint8_t*>(buffer), size);
157}
158
159template <typename SizeType = std::size_t>
160BufferWrapper<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
166template <typename T, typename Allocator = std::allocator<T>>
167BufferWrapper<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