OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef String16STL_h | 5 #ifndef String16STL_h |
6 #define String16STL_h | 6 #define String16STL_h |
7 | 7 |
8 #include <cctype> | 8 #include <cctype> |
9 #include <cstdlib> | 9 #include <cstdlib> |
10 #include <cstring> | 10 #include <cstring> |
11 #include <stdint.h> | 11 #include <stdint.h> |
12 #include <string> | 12 #include <string> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 using UChar = uint16_t; | 15 using UChar = uint16_t; |
16 using UChar32 = uint32_t; | |
17 using LChar = unsigned char; | |
18 // presubmit: allow wstring | |
19 using wstring = std::basic_string<UChar>; | |
20 const size_t kNotFound = static_cast<size_t>(-1); | |
21 | 16 |
22 namespace blink { | 17 namespace blink { |
23 namespace protocol { | 18 namespace protocol { |
24 | 19 |
25 class String16 { | 20 class String16 : public String16Base<String16, UChar> { |
26 public: | 21 public: |
| 22 static const size_t kNotFound = static_cast<size_t>(-1); |
| 23 |
27 String16() { } | 24 String16() { } |
28 String16(const String16& other) : m_impl(other.m_impl) { } | 25 String16(const String16& other) : m_impl(other.m_impl) { } |
29 // presubmit: allow wstring | 26 String16(const UChar* characters, size_t size) : m_impl(characters, size) {
} |
30 String16(const wstring& impl) : m_impl(impl) { } | |
31 String16(const UChar* characters) : m_impl(characters) { } | 27 String16(const UChar* characters) : m_impl(characters) { } |
32 String16(const char* characters) : String16(characters, std::strlen(characte
rs)) { } | 28 String16(const char* characters) : String16(characters, std::strlen(characte
rs)) { } |
33 String16(const char* characters, size_t size) | 29 String16(const char* characters, size_t size) |
34 { | 30 { |
35 m_impl.resize(size); | 31 m_impl.resize(size); |
36 for (size_t i = 0; i < size; ++i) | 32 for (size_t i = 0; i < size; ++i) |
37 m_impl[i] = characters[i]; | 33 m_impl[i] = characters[i]; |
38 } | 34 } |
39 String16(const UChar* characters, size_t size) : m_impl(characters, size) {
} | 35 |
40 String16 isolatedCopy() const { return String16(m_impl); } | 36 String16 isolatedCopy() const { return String16(m_impl); } |
41 | |
42 size_t charactersSizeInBytes() const { return m_impl.size() * sizeof(UChar);
} | |
43 const UChar* characters16() const { return m_impl.c_str(); } | 37 const UChar* characters16() const { return m_impl.c_str(); } |
44 std::string utf8() const; | |
45 static String16 fromUTF8(const char* stringStart, size_t length); | |
46 static String16 fromInteger(int i) { return String16(String16::intToString(i
).c_str()); } | |
47 static String16 fromDouble(double d) { return String16(String16::doubleToStr
ing(d).c_str()); } | |
48 static String16 fromDoubleFixedPrecision(double d, int len) { return String1
6(String16::doubleToString(d).c_str()); } | |
49 | |
50 static double charactersToDouble(const UChar* characters, size_t length, boo
l* ok = 0) | |
51 { | |
52 std::string str; | |
53 str.resize(length); | |
54 for (size_t i = 0; i < length; ++i) | |
55 str[i] = static_cast<char>(characters[i]); | |
56 | |
57 const char* buffer = str.c_str(); | |
58 char* endptr; | |
59 double result = strtod(buffer, &endptr); | |
60 if (ok) | |
61 *ok = buffer + length == endptr; | |
62 return result; | |
63 } | |
64 | |
65 String16 substring(unsigned pos, unsigned len = 0xFFFFFFFF) const | |
66 { | |
67 return String16(m_impl.substr(pos, len)); | |
68 } | |
69 | |
70 String16 stripWhiteSpace() const; | |
71 | |
72 int toInt(bool* ok = 0) const | |
73 { | |
74 size_t length = m_impl.length(); | |
75 std::string str; | |
76 str.resize(length); | |
77 for (size_t i = 0; i < length; ++i) | |
78 str[i] = static_cast<char>(m_impl[i]); | |
79 | |
80 const char* buffer = str.c_str(); | |
81 char* endptr; | |
82 int result = strtol(buffer, &endptr, 10); | |
83 if (ok) | |
84 *ok = buffer + length == endptr; | |
85 return result; | |
86 } | |
87 | |
88 size_t length() const { return m_impl.length(); } | 38 size_t length() const { return m_impl.length(); } |
89 bool isEmpty() const { return !m_impl.length(); } | 39 bool isEmpty() const { return !m_impl.length(); } |
90 UChar operator[](unsigned index) const { return m_impl[index]; } | 40 UChar operator[](unsigned index) const { return m_impl[index]; } |
| 41 String16 substring(unsigned pos, unsigned len = 0xFFFFFFFF) const { return S
tring16(m_impl.substr(pos, len)); } |
| 42 size_t find(const String16& str, unsigned start = 0) const { return m_impl.f
ind(str.m_impl, start); } |
| 43 size_t reverseFind(const String16& str, unsigned start = 0xFFFFFFFF) const {
return m_impl.rfind(str.m_impl, start); } |
91 | 44 |
92 size_t find(UChar c, unsigned start = 0) const | 45 // Convenience methods. |
93 { | 46 std::string utf8() const; |
94 return m_impl.find(c, start); | 47 static String16 fromUTF8(const char* stringStart, size_t length); |
95 } | |
96 | 48 |
97 size_t find(const String16& str, unsigned start = 0) const | 49 const std::basic_string<UChar>& impl() const { return m_impl; } |
98 { | 50 explicit String16(const std::basic_string<UChar>& impl) : m_impl(impl) { } |
99 return m_impl.find(str.m_impl, start); | |
100 } | |
101 | |
102 size_t reverseFind(const String16& str, unsigned start = 0xFFFFFFFF) const | |
103 { | |
104 return m_impl.rfind(str.m_impl, start); | |
105 } | |
106 | |
107 bool startWith(const String16& s) const | |
108 { | |
109 if (m_impl.length() < s.m_impl.length()) | |
110 return false; | |
111 return m_impl.substr(0, s.m_impl.length()) == s.m_impl; | |
112 } | |
113 | |
114 bool endsWith(UChar character) const | |
115 { | |
116 return m_impl.length() && m_impl[m_impl.length() - 1] == character; | |
117 } | |
118 | |
119 // presubmit: allow wstring | |
120 const wstring& impl() const { return m_impl; } | |
121 | 51 |
122 std::size_t hash() const | 52 std::size_t hash() const |
123 { | 53 { |
124 if (!has_hash) { | 54 if (!has_hash) { |
125 size_t hash = 0; | 55 size_t hash = 0; |
126 for (size_t i = 0; i < length(); ++i) | 56 for (size_t i = 0; i < length(); ++i) |
127 hash = 31 * hash + m_impl[i]; | 57 hash = 31 * hash + m_impl[i]; |
128 hash_code = hash; | 58 hash_code = hash; |
129 has_hash = true; | 59 has_hash = true; |
130 } | 60 } |
131 return hash_code; | 61 return hash_code; |
132 } | 62 } |
133 | 63 |
134 private: | 64 private: |
135 static std::string intToString(int); | 65 std::basic_string<UChar> m_impl; |
136 static std::string doubleToString(double); | |
137 // presubmit: allow wstring | |
138 wstring m_impl; | |
139 mutable bool has_hash = false; | 66 mutable bool has_hash = false; |
140 mutable std::size_t hash_code = 0; | 67 mutable std::size_t hash_code = 0; |
141 }; | 68 }; |
142 | 69 |
143 static inline bool isSpaceOrNewline(UChar c) | |
144 { | |
145 return std::isspace(c); // NOLINT | |
146 } | |
147 | |
148 class String16Builder { | |
149 public: | |
150 String16Builder() { } | |
151 | |
152 void append(const String16& str) | |
153 { | |
154 m_impl += str.impl(); | |
155 } | |
156 | |
157 void append(UChar c) | |
158 { | |
159 m_impl += c; | |
160 } | |
161 | |
162 void append(LChar c) | |
163 { | |
164 m_impl += c; | |
165 } | |
166 | |
167 void append(char c) | |
168 { | |
169 m_impl += c; | |
170 } | |
171 | |
172 void appendNumber(int i) | |
173 { | |
174 m_impl = m_impl + String16::fromInteger(i).impl(); | |
175 } | |
176 | |
177 void appendNumber(double d) | |
178 { | |
179 m_impl = m_impl + String16::fromDoubleFixedPrecision(d, 6).impl(); | |
180 } | |
181 | |
182 void append(const UChar* c, size_t length) | |
183 { | |
184 // presubmit: allow wstring | |
185 m_impl += wstring(c, length); | |
186 } | |
187 | |
188 void append(const char* c, size_t length) | |
189 { | |
190 m_impl += String16(c, length).impl(); | |
191 } | |
192 | |
193 String16 toString() | |
194 { | |
195 return String16(m_impl); | |
196 } | |
197 | |
198 void reserveCapacity(unsigned newCapacity) | |
199 { | |
200 } | |
201 | |
202 private: | |
203 // presubmit: allow wstring | |
204 wstring m_impl; | |
205 }; | |
206 | |
207 inline bool operator==(const String16& a, const String16& b) { return a.impl() =
= b.impl(); } | 70 inline bool operator==(const String16& a, const String16& b) { return a.impl() =
= b.impl(); } |
208 inline bool operator!=(const String16& a, const String16& b) { return a.impl() !
= b.impl(); } | 71 inline bool operator!=(const String16& a, const String16& b) { return a.impl() !
= b.impl(); } |
209 inline bool operator==(const String16& a, const char* b) { return a.impl() == St
ring16(b).impl(); } | 72 inline bool operator==(const String16& a, const char* b) { return a.impl() == St
ring16(b).impl(); } |
210 inline bool operator<(const String16& a, const String16& b) { return a.impl() <
b.impl(); } | 73 inline String16 operator+(const String16& a, const char* b) { return String16(a.
impl() + String16(b).impl()); } |
211 | 74 inline String16 operator+(const char* a, const String16& b) { return String16(St
ring16(a).impl() + b.impl()); } |
212 inline String16 operator+(const String16& a, const char* b) | 75 inline String16 operator+(const String16& a, const String16& b) { return String1
6(a.impl() + b.impl()); } |
213 { | |
214 return String16(a.impl() + String16(b).impl()); | |
215 } | |
216 | |
217 inline String16 operator+(const char* a, const String16& b) | |
218 { | |
219 return String16(String16(a).impl() + b.impl()); | |
220 } | |
221 | |
222 inline String16 operator+(const String16& a, const String16& b) | |
223 { | |
224 return String16(a.impl() + b.impl()); | |
225 } | |
226 | 76 |
227 } // namespace protocol | 77 } // namespace protocol |
228 } // namespace blink | 78 } // namespace blink |
229 | 79 |
230 using String16 = blink::protocol::String16; | |
231 using String16Builder = blink::protocol::String16Builder; | |
232 | |
233 | |
234 namespace WTF { | |
235 // Interim solution for those headers that reference WTF::String for overrides. | |
236 // It does nothing. If the code actually relies on WTF:String, it will not | |
237 // compile! | |
238 // TODO(eostroukhov): Eradicate | |
239 class String { | |
240 public: | |
241 String() {}; | |
242 String(const String16& other) {}; | |
243 operator String16() const { return String16(); }; | |
244 }; | |
245 } // namespace WTF | |
246 | |
247 #if !defined(__APPLE__) || defined(_LIBCPP_VERSION) | 80 #if !defined(__APPLE__) || defined(_LIBCPP_VERSION) |
248 | 81 |
249 namespace std { | 82 namespace std { |
250 template<> struct hash<String16> { | 83 template<> struct hash<blink::protocol::String16> { |
251 std::size_t operator()(const String16& string) const | 84 std::size_t operator()(const blink::protocol::String16& string) const |
252 { | 85 { |
253 return string.hash(); | 86 return string.hash(); |
254 } | 87 } |
255 }; | 88 }; |
256 | 89 |
257 } // namespace std | 90 } // namespace std |
258 | 91 |
259 #endif // !defined(__APPLE__) || defined(_LIBCPP_VERSION) | 92 #endif // !defined(__APPLE__) || defined(_LIBCPP_VERSION) |
260 | 93 |
261 using String = WTF::String; | 94 class InspectorProtocolConvenienceStringType { |
| 95 public: |
| 96 // This class should not be ever instantiated, so we don't implement constru
ctors. |
| 97 InspectorProtocolConvenienceStringType(); |
| 98 InspectorProtocolConvenienceStringType(const blink::protocol::String16& othe
r); |
| 99 operator blink::protocol::String16() const { return blink::protocol::String1
6(); }; |
| 100 }; |
262 | 101 |
263 #endif // !defined(String16STL_h) | 102 #endif // !defined(String16STL_h) |
OLD | NEW |