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 <iosfwd> | |
9 #include <string> | |
10 | |
11 #include "mojo/public/cpp/bindings/lib/array_internal.h" | |
12 #include "mojo/public/cpp/bindings/type_converter.h" | |
13 #include "mojo/public/cpp/environment/logging.h" | |
14 | |
15 namespace mojo { | |
16 | |
17 // A UTF-8 encoded character string that can be null. Provides functions that | |
18 // are similar to std::string, along with access to the underlying std::string | |
19 // object. | |
20 class String { | |
21 public: | |
22 typedef internal::String_Data Data_; | |
23 | |
24 String() : is_null_(true) {} | |
25 String(const std::string& str) : value_(str), is_null_(false) {} | |
26 String(const char* chars) : is_null_(!chars) { | |
27 if (chars) | |
28 value_ = chars; | |
29 } | |
30 String(const char* chars, size_t num_chars) | |
31 : value_(chars, num_chars), is_null_(false) {} | |
32 String(const mojo::String& str) | |
33 : value_(str.value_), is_null_(str.is_null_) {} | |
34 | |
35 template <size_t N> | |
36 String(const char chars[N]) | |
37 : value_(chars, N - 1), is_null_(false) {} | |
38 | |
39 template <typename U> | |
40 static String From(const U& other) { | |
41 return TypeConverter<String, U>::Convert(other); | |
42 } | |
43 | |
44 template <typename U> | |
45 U To() const { | |
46 return TypeConverter<U, String>::Convert(*this); | |
47 } | |
48 | |
49 String& operator=(const mojo::String& str) { | |
50 value_ = str.value_; | |
51 is_null_ = str.is_null_; | |
52 return *this; | |
53 } | |
54 String& operator=(const std::string& str) { | |
55 value_ = str; | |
56 is_null_ = false; | |
57 return *this; | |
58 } | |
59 String& operator=(const char* chars) { | |
60 is_null_ = !chars; | |
61 if (chars) { | |
62 value_ = chars; | |
63 } else { | |
64 value_.clear(); | |
65 } | |
66 return *this; | |
67 } | |
68 | |
69 void reset() { | |
70 value_.clear(); | |
71 is_null_ = true; | |
72 } | |
73 | |
74 // Tests as true if non-null, false if null. | |
75 explicit operator bool() const { return !is_null_; } | |
76 | |
77 bool is_null() const { return is_null_; } | |
78 | |
79 size_t size() const { return value_.size(); } | |
80 | |
81 const char* data() const { return value_.data(); } | |
82 | |
83 const char& at(size_t offset) const { return value_.at(offset); } | |
84 char& at(size_t offset) { return value_.at(offset); } | |
85 | |
86 const char& operator[](size_t offset) const { return value_[offset]; } | |
87 char& operator[](size_t offset) { return value_[offset]; } | |
88 | |
89 const std::string& get() const { return value_; } | |
90 operator const std::string&() const { return value_; } | |
91 | |
92 void Swap(String* other) { | |
93 std::swap(is_null_, other->is_null_); | |
94 value_.swap(other->value_); | |
95 } | |
96 | |
97 void Swap(std::string* other) { | |
98 is_null_ = false; | |
99 value_.swap(*other); | |
100 } | |
101 | |
102 private: | |
103 std::string value_; | |
104 bool is_null_; | |
105 }; | |
106 | |
107 inline bool operator==(const String& a, const String& b) { | |
108 return a.is_null() == b.is_null() && a.get() == b.get(); | |
109 } | |
110 inline bool operator==(const char* a, const String& b) { | |
111 return !b.is_null() && a == b.get(); | |
112 } | |
113 inline bool operator==(const String& a, const char* b) { | |
114 return !a.is_null() && a.get() == b; | |
115 } | |
116 inline bool operator!=(const String& a, const String& b) { | |
117 return !(a == b); | |
118 } | |
119 inline bool operator!=(const char* a, const String& b) { | |
120 return !(a == b); | |
121 } | |
122 inline bool operator!=(const String& a, const char* b) { | |
123 return !(a == b); | |
124 } | |
125 | |
126 // TODO(jeffbrown): Decide whether this should print a sentinel value | |
127 // such as "<null>" when formatting null strings. | |
128 inline std::ostream& operator<<(std::ostream& out, const String& s) { | |
129 return out << s.get(); | |
130 } | |
131 | |
132 inline bool operator<(const String& a, const String& b) { | |
133 if (a.is_null()) | |
134 return !b.is_null(); | |
135 if (b.is_null()) | |
136 return false; | |
137 | |
138 return a.get() < b.get(); | |
139 } | |
140 | |
141 // TODO(darin): Add similar variants of operator<,<=,>,>= | |
142 | |
143 template <> | |
144 struct TypeConverter<String, std::string> { | |
145 static String Convert(const std::string& input) { return String(input); } | |
146 }; | |
147 | |
148 template <> | |
149 struct TypeConverter<std::string, String> { | |
150 static std::string Convert(const String& input) { return input; } | |
151 }; | |
152 | |
153 template <size_t N> | |
154 struct TypeConverter<String, char[N]> { | |
155 static String Convert(const char input[N]) { | |
156 MOJO_DCHECK(input); | |
157 return String(input, N - 1); | |
158 } | |
159 }; | |
160 | |
161 // Appease MSVC. | |
162 template <size_t N> | |
163 struct TypeConverter<String, const char[N]> { | |
164 static String Convert(const char input[N]) { | |
165 MOJO_DCHECK(input); | |
166 return String(input, N - 1); | |
167 } | |
168 }; | |
169 | |
170 template <> | |
171 struct TypeConverter<String, const char*> { | |
172 // |input| may be null, in which case a null String will be returned. | |
173 static String Convert(const char* input) { return String(input); } | |
174 }; | |
175 | |
176 } // namespace mojo | |
177 | |
178 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_H_ | |
OLD | NEW |