Home | History | Annotate | Download | only in rpc
      1 #ifndef ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
      2 #define ANDROID_PDX_RPC_ARRAY_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 C array buffers, providing an interface suitable for
     14 // SerializeObject and DeserializeObject. This class serializes to the same
     15 // format as std::vector, and may be substituted for std::vector during
     16 // serialization and deserialization. This substitution makes handling of C
     17 // arrays more efficient by avoiding unnecessary copies when remote method
     18 // signatures specify std::vector arguments or return values.
     19 template <typename T>
     20 class ArrayWrapper {
     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   ArrayWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
     31 
     32   ArrayWrapper(pointer buffer, size_type capacity, size_type size)
     33       : buffer_(&buffer[0]),
     34         capacity_(capacity),
     35         end_(capacity < size ? capacity : size) {}
     36 
     37   ArrayWrapper(pointer buffer, size_type size)
     38       : ArrayWrapper(buffer, size, size) {}
     39 
     40   ArrayWrapper(const ArrayWrapper& other) { *this = other; }
     41 
     42   ArrayWrapper(ArrayWrapper&& other) noexcept { *this = std::move(other); }
     43 
     44   ArrayWrapper& operator=(const ArrayWrapper& 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   ArrayWrapper& operator=(ArrayWrapper&& 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 
     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   // Moves the end marker to |size|, clamping the end marker to the max capacity
     84   // of the underlying array. This method does not change the size of the
     85   // underlying array.
     86   void resize(size_type size) {
     87     if (size <= capacity_)
     88       end_ = size;
     89     else
     90       end_ = capacity_;
     91   }
     92 
     93   reference operator[](size_type pos) { return buffer_[pos]; }
     94   const_reference operator[](size_type pos) const { return buffer_[pos]; }
     95 
     96  private:
     97   pointer buffer_;
     98   size_type capacity_;
     99   size_type end_;
    100 };
    101 
    102 template <typename T, typename SizeType = std::size_t>
    103 ArrayWrapper<T> WrapArray(T* buffer, SizeType size) {
    104   return ArrayWrapper<T>(buffer, size);
    105 }
    106 
    107 }  // namespace rpc
    108 }  // namespace pdx
    109 }  // namespace android
    110 
    111 #endif  // ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
    112