| OLD | NEW |
| (Empty) |
| 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 <stddef.h> | |
| 9 | |
| 10 #include <functional> | |
| 11 #include <string> | |
| 12 | |
| 13 #include "base/logging.h" | |
| 14 #include "mojo/public/cpp/bindings/lib/array_internal.h" | |
| 15 #include "mojo/public/cpp/bindings/lib/hash_util.h" | |
| 16 #include "mojo/public/cpp/bindings/type_converter.h" | |
| 17 | |
| 18 namespace mojo { | |
| 19 | |
| 20 // A UTF-8 encoded character string that can be null. Provides functions that | |
| 21 // are similar to std::string, along with access to the underlying std::string | |
| 22 // object. | |
| 23 class String { | |
| 24 public: | |
| 25 // Constructs an empty string. | |
| 26 String() : is_null_(false) {} | |
| 27 String(const std::string& str) : value_(str), is_null_(false) {} | |
| 28 String(const char* chars) : is_null_(!chars) { | |
| 29 if (chars) | |
| 30 value_ = chars; | |
| 31 } | |
| 32 String(const char* chars, size_t num_chars) | |
| 33 : value_(chars, num_chars), is_null_(false) {} | |
| 34 String(const mojo::String& str) | |
| 35 : value_(str.value_), is_null_(str.is_null_) {} | |
| 36 | |
| 37 template <size_t N> | |
| 38 String(const char chars[N]) | |
| 39 : value_(chars, N - 1), is_null_(false) {} | |
| 40 | |
| 41 String(std::string&& other) : value_(std::move(other)), is_null_(false) {} | |
| 42 String(String&& other) : is_null_(true) { Swap(&other); } | |
| 43 | |
| 44 template <typename U> | |
| 45 static String From(const U& other) { | |
| 46 return TypeConverter<String, U>::Convert(other); | |
| 47 } | |
| 48 | |
| 49 template <typename U> | |
| 50 U To() const { | |
| 51 return TypeConverter<U, String>::Convert(*this); | |
| 52 } | |
| 53 | |
| 54 String& operator=(const mojo::String& str) { | |
| 55 value_ = str.value_; | |
| 56 is_null_ = str.is_null_; | |
| 57 return *this; | |
| 58 } | |
| 59 String& operator=(const std::string& str) { | |
| 60 value_ = str; | |
| 61 is_null_ = false; | |
| 62 return *this; | |
| 63 } | |
| 64 String& operator=(const char* chars) { | |
| 65 is_null_ = !chars; | |
| 66 if (chars) { | |
| 67 value_ = chars; | |
| 68 } else { | |
| 69 value_.clear(); | |
| 70 } | |
| 71 return *this; | |
| 72 } | |
| 73 | |
| 74 String& operator=(std::string&& other) { | |
| 75 value_ = std::move(other); | |
| 76 is_null_ = false; | |
| 77 return *this; | |
| 78 } | |
| 79 String& operator=(String&& other) { | |
| 80 is_null_ = true; | |
| 81 value_.clear(); | |
| 82 Swap(&other); | |
| 83 return *this; | |
| 84 } | |
| 85 | |
| 86 bool is_null() const { return is_null_; } | |
| 87 | |
| 88 size_t size() const { return value_.size(); } | |
| 89 | |
| 90 const char* data() const { return value_.data(); } | |
| 91 | |
| 92 const char& at(size_t offset) const { return value_.at(offset); } | |
| 93 const char& operator[](size_t offset) const { return value_[offset]; } | |
| 94 | |
| 95 const std::string& get() const { return value_; } | |
| 96 operator const std::string&() const { return value_; } | |
| 97 | |
| 98 // Returns a const reference to the |std::string| managed by this class. If | |
| 99 // the string is null, this will be an empty std::string. | |
| 100 const std::string& storage() const { return value_; } | |
| 101 | |
| 102 // Passes the underlying storage and resets this string to null. | |
| 103 std::string PassStorage() { | |
| 104 is_null_ = true; | |
| 105 return std::move(value_); | |
| 106 } | |
| 107 | |
| 108 void Swap(String* other) { | |
| 109 std::swap(is_null_, other->is_null_); | |
| 110 value_.swap(other->value_); | |
| 111 } | |
| 112 | |
| 113 void Swap(std::string* other) { | |
| 114 is_null_ = false; | |
| 115 value_.swap(*other); | |
| 116 } | |
| 117 | |
| 118 private: | |
| 119 typedef std::string String::*Testable; | |
| 120 | |
| 121 public: | |
| 122 operator Testable() const { return is_null_ ? 0 : &String::value_; } | |
| 123 | |
| 124 private: | |
| 125 std::string value_; | |
| 126 bool is_null_; | |
| 127 }; | |
| 128 | |
| 129 inline bool operator==(const String& a, const String& b) { | |
| 130 return a.is_null() == b.is_null() && a.get() == b.get(); | |
| 131 } | |
| 132 inline bool operator==(const char* a, const String& b) { | |
| 133 return !b.is_null() && a == b.get(); | |
| 134 } | |
| 135 inline bool operator==(const String& a, const char* b) { | |
| 136 return !a.is_null() && a.get() == b; | |
| 137 } | |
| 138 inline bool operator!=(const String& a, const String& b) { | |
| 139 return !(a == b); | |
| 140 } | |
| 141 inline bool operator!=(const char* a, const String& b) { | |
| 142 return !(a == b); | |
| 143 } | |
| 144 inline bool operator!=(const String& a, const char* b) { | |
| 145 return !(a == b); | |
| 146 } | |
| 147 | |
| 148 inline std::ostream& operator<<(std::ostream& out, const String& s) { | |
| 149 return out << s.get(); | |
| 150 } | |
| 151 | |
| 152 inline bool operator<(const String& a, const String& b) { | |
| 153 if (a.is_null()) | |
| 154 return !b.is_null(); | |
| 155 if (b.is_null()) | |
| 156 return false; | |
| 157 | |
| 158 return a.get() < b.get(); | |
| 159 } | |
| 160 | |
| 161 // TODO(darin): Add similar variants of operator<,<=,>,>= | |
| 162 | |
| 163 template <> | |
| 164 struct TypeConverter<String, std::string> { | |
| 165 static String Convert(const std::string& input) { return String(input); } | |
| 166 }; | |
| 167 | |
| 168 template <> | |
| 169 struct TypeConverter<std::string, String> { | |
| 170 static std::string Convert(const String& input) { return input; } | |
| 171 }; | |
| 172 | |
| 173 template <size_t N> | |
| 174 struct TypeConverter<String, char[N]> { | |
| 175 static String Convert(const char input[N]) { | |
| 176 DCHECK(input); | |
| 177 return String(input, N - 1); | |
| 178 } | |
| 179 }; | |
| 180 | |
| 181 // Appease MSVC. | |
| 182 template <size_t N> | |
| 183 struct TypeConverter<String, const char[N]> { | |
| 184 static String Convert(const char input[N]) { | |
| 185 DCHECK(input); | |
| 186 return String(input, N - 1); | |
| 187 } | |
| 188 }; | |
| 189 | |
| 190 template <> | |
| 191 struct TypeConverter<String, const char*> { | |
| 192 // |input| may be null, in which case a null String will be returned. | |
| 193 static String Convert(const char* input) { return String(input); } | |
| 194 }; | |
| 195 | |
| 196 } // namespace mojo | |
| 197 | |
| 198 namespace std { | |
| 199 | |
| 200 template <> | |
| 201 struct hash<mojo::String> { | |
| 202 size_t operator()(const mojo::String& value) const { | |
| 203 return value.is_null() ? 0 : hash<std::string>()(value.get()); | |
| 204 } | |
| 205 }; | |
| 206 | |
| 207 } // namespace std | |
| 208 | |
| 209 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_H_ | |
| OLD | NEW |