Home | History | Annotate | Download | only in rpc
      1 #ifndef ANDROID_PDX_RPC_STRING_WRAPPER_H_
      2 #define ANDROID_PDX_RPC_STRING_WRAPPER_H_
      3 
      4 #include <cstddef>
      5 #include <cstring>
      6 #include <string>
      7 #include <type_traits>
      8 
      9 namespace android {
     10 namespace pdx {
     11 namespace rpc {
     12 
     13 // Wrapper class for C string buffers, providing an interface suitable for
     14 // SerializeObject and DeserializeObject. This class serializes to the same
     15 // format as std::basic_string, and may be substituted for std::basic_string
     16 // during serialization and deserialization. This substitution makes handling of
     17 // C strings more efficient by avoiding unnecessary copies when remote method
     18 // signatures specify std::basic_string arguments or return values.
     19 template <typename CharT = std::string::value_type,
     20           typename Traits = std::char_traits<CharT>>
     21 class StringWrapper {
     22  public:
     23   // Define types in the style of STL strings to support STL operators.
     24   typedef Traits traits_type;
     25   typedef typename Traits::char_type value_type;
     26   typedef std::size_t size_type;
     27   typedef value_type& reference;
     28   typedef const value_type& const_reference;
     29   typedef value_type* pointer;
     30   typedef const value_type* const_pointer;
     31 
     32   StringWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
     33 
     34   StringWrapper(pointer buffer, size_type capacity, size_type size)
     35       : buffer_(&buffer[0]),
     36         capacity_(capacity),
     37         end_(capacity < size ? capacity : size) {}
     38 
     39   StringWrapper(pointer buffer, size_type size)
     40       : StringWrapper(buffer, size, size) {}
     41 
     42   explicit StringWrapper(pointer buffer)
     43       : StringWrapper(buffer, std::strlen(buffer)) {}
     44 
     45   StringWrapper(const StringWrapper& other) { *this = other; }
     46 
     47   StringWrapper(StringWrapper&& other) { *this = std::move(other); }
     48 
     49   StringWrapper& operator=(const StringWrapper& other) {
     50     if (&other == this) {
     51       return *this;
     52     } else {
     53       buffer_ = other.buffer_;
     54       capacity_ = other.capacity_;
     55       end_ = other.end_;
     56     }
     57 
     58     return *this;
     59   }
     60 
     61   StringWrapper& operator=(StringWrapper&& other) {
     62     if (&other == this) {
     63       return *this;
     64     } else {
     65       buffer_ = other.buffer_;
     66       capacity_ = other.capacity_;
     67       end_ = other.end_;
     68       other.buffer_ = nullptr;
     69       other.capacity_ = 0;
     70       other.end_ = 0;
     71     }
     72 
     73     return *this;
     74   }
     75 
     76   pointer data() { return buffer_; }
     77   const_pointer data() const { return buffer_; }
     78 
     79   pointer begin() { return &buffer_[0]; }
     80   pointer end() { return &buffer_[end_]; }
     81   const_pointer begin() const { return &buffer_[0]; }
     82   const_pointer end() const { return &buffer_[end_]; }
     83 
     84   size_type size() const { return end_; }
     85   size_type length() const { return end_; }
     86   size_type max_size() const { return capacity_; }
     87   size_type capacity() const { return capacity_; }
     88 
     89   void resize(size_type size) {
     90     if (size <= capacity_)
     91       end_ = size;
     92     else
     93       end_ = capacity_;
     94   }
     95 
     96   reference operator[](size_type pos) { return buffer_[pos]; }
     97   const_reference operator[](size_type pos) const { return buffer_[pos]; }
     98 
     99  private:
    100   pointer buffer_;
    101   size_type capacity_;
    102   size_type end_;
    103 };
    104 
    105 // Utility functions that infer the underlying type of the string, simplifying
    106 // the wrapper interface.
    107 
    108 // TODO(eieio): Wrapping std::basic_string is here for completeness, but is it
    109 // useful?
    110 template <typename T, typename... Any>
    111 StringWrapper<const T> WrapString(const std::basic_string<T, Any...>& s) {
    112   return StringWrapper<const T>(s.c_str(), s.length());
    113 }
    114 
    115 template <typename T, typename SizeType = std::size_t>
    116 StringWrapper<T> WrapString(T* s, SizeType size) {
    117   return StringWrapper<T>(s, size);
    118 }
    119 
    120 template <typename T>
    121 StringWrapper<T> WrapString(T* s) {
    122   return StringWrapper<T>(s);
    123 }
    124 
    125 }  // namespace rpc
    126 }  // namespace pdx
    127 }  // namespace android
    128 
    129 #endif  // ANDROID_PDX_RPC_STRING_WRAPPER_H_
    130