Home | History | Annotate | Download | only in rpc
      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 
     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 
     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 
    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 
    149 template <typename T, typename SizeType = std::size_t>
    150 BufferWrapper<T*> WrapBuffer(T* buffer, SizeType size) {
    151   return BufferWrapper<T*>(buffer, size);
    152 }
    153 
    154 template <typename SizeType = std::size_t>
    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>
    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>>
    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