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
StringWrapper()32 StringWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
33
StringWrapper(pointer buffer,size_type capacity,size_type size)34 StringWrapper(pointer buffer, size_type capacity, size_type size)
35 : buffer_(&buffer[0]),
36 capacity_(capacity),
37 end_(capacity < size ? capacity : size) {}
38
StringWrapper(pointer buffer,size_type size)39 StringWrapper(pointer buffer, size_type size)
40 : StringWrapper(buffer, size, size) {}
41
StringWrapper(pointer buffer)42 explicit StringWrapper(pointer buffer)
43 : StringWrapper(buffer, std::strlen(buffer)) {}
44
StringWrapper(const StringWrapper & other)45 StringWrapper(const StringWrapper& other) { *this = other; }
46
StringWrapper(StringWrapper && other)47 StringWrapper(StringWrapper&& other) noexcept { *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) noexcept {
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
data()76 pointer data() { return buffer_; }
data()77 const_pointer data() const { return buffer_; }
78
begin()79 pointer begin() { return &buffer_[0]; }
end()80 pointer end() { return &buffer_[end_]; }
begin()81 const_pointer begin() const { return &buffer_[0]; }
end()82 const_pointer end() const { return &buffer_[end_]; }
83
size()84 size_type size() const { return end_; }
length()85 size_type length() const { return end_; }
max_size()86 size_type max_size() const { return capacity_; }
capacity()87 size_type capacity() const { return capacity_; }
88
resize(size_type size)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>
WrapString(const std::basic_string<T,Any...> & s)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>
WrapString(T * s,SizeType size)116 StringWrapper<T> WrapString(T* s, SizeType size) {
117 return StringWrapper<T>(s, size);
118 }
119
120 template <typename T>
WrapString(T * s)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