1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRING_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_STRING_H_ 7 8 #include <string> 9 10 #include "mojo/public/cpp/bindings/lib/array_internal.h" 11 #include "mojo/public/cpp/bindings/type_converter.h" 12 #include "mojo/public/cpp/environment/logging.h" 13 14 namespace mojo { 15 16 class String { 17 public: 18 typedef internal::String_Data Data_; 19 String()20 String() : is_null_(true) {} String(const std::string & str)21 String(const std::string& str) : value_(str), is_null_(false) {} String(const char * chars)22 String(const char* chars) : is_null_(!chars) { 23 if (chars) 24 value_ = chars; 25 } String(const char * chars,size_t num_chars)26 String(const char* chars, size_t num_chars) 27 : value_(chars, num_chars), 28 is_null_(false) { 29 } 30 template <size_t N> String(const char chars[N])31 String(const char chars[N]) : value_(chars, N-1), is_null_(false) {} 32 33 template <typename U> From(const U & other)34 static String From(const U& other) { 35 return TypeConverter<String, U>::Convert(other); 36 } 37 38 template <typename U> To()39 U To() const { 40 return TypeConverter<U, String>::Convert(*this); 41 } 42 43 String& operator=(const std::string& str) { 44 value_ = str; 45 is_null_ = false; 46 return *this; 47 } 48 String& operator=(const char* chars) { 49 is_null_ = !chars; 50 if (chars) { 51 value_ = chars; 52 } else { 53 value_.clear(); 54 } 55 return *this; 56 } 57 reset()58 void reset() { 59 value_.clear(); 60 is_null_ = true; 61 } 62 is_null()63 bool is_null() const { return is_null_; } 64 size()65 size_t size() const { return value_.size(); } 66 data()67 const char* data() const { return value_.data(); } 68 at(size_t offset)69 const char& at(size_t offset) const { return value_.at(offset); } 70 const char& operator[](size_t offset) const { return value_[offset]; } 71 get()72 const std::string& get() const { return value_; } 73 operator const std::string&() const { return value_; } 74 Swap(String * other)75 void Swap(String* other) { 76 std::swap(is_null_, other->is_null_); 77 value_.swap(other->value_); 78 } 79 Swap(std::string * other)80 void Swap(std::string* other) { 81 is_null_ = false; 82 value_.swap(*other); 83 } 84 85 private: 86 typedef std::string String::*Testable; 87 88 public: Testable()89 operator Testable() const { return is_null_ ? 0 : &String::value_; } 90 91 private: 92 std::string value_; 93 bool is_null_; 94 }; 95 96 inline bool operator==(const String& a, const String& b) { 97 return a.is_null() == b.is_null() && a.get() == b.get(); 98 } 99 inline bool operator==(const char* a, const String& b) { 100 return !b.is_null() && a == b.get(); 101 } 102 inline bool operator==(const String& a, const char* b) { 103 return !a.is_null() && a.get() == b; 104 } 105 inline bool operator!=(const String& a, const String& b) { return !(a == b); } 106 inline bool operator!=(const char* a, const String& b) { return !(a == b); } 107 inline bool operator!=(const String& a, const char* b) { return !(a == b); } 108 109 inline std::ostream& operator<<(std::ostream& out, const String& s) { 110 return out << s.get(); 111 } 112 113 // TODO(darin): Add similar variants of operator<,<=,>,>= 114 115 template <> 116 struct TypeConverter<String, std::string> { 117 static String Convert(const std::string& input) { return String(input); } 118 }; 119 120 template <> 121 struct TypeConverter<std::string, String> { 122 static std::string Convert(const String& input) { return input; } 123 }; 124 125 template <size_t N> 126 struct TypeConverter<String, char[N]> { 127 static String Convert(const char input[N]) { 128 MOJO_DCHECK(input); 129 return String(input, N-1); 130 } 131 }; 132 133 // Appease MSVC. 134 template <size_t N> 135 struct TypeConverter<String, const char[N]> { 136 static String Convert(const char input[N]) { 137 MOJO_DCHECK(input); 138 return String(input, N-1); 139 } 140 }; 141 142 template <> 143 struct TypeConverter<String, const char*> { 144 // |input| may be null, in which case a null String will be returned. 145 static String Convert(const char* input) { return String(input); } 146 }; 147 148 } // namespace mojo 149 150 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_H_ 151