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