OLD | NEW |
1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * | 3 // found in the LICENSE file. |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public License | |
15 * along with this library; see the file COPYING.LIB. If not, write to | |
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 * Boston, MA 02110-1301, USA. | |
18 * | |
19 */ | |
20 | 4 |
21 #ifndef AtomicString_h | 5 #include "platform/wtf/text/AtomicString.h" |
22 #define AtomicString_h | |
23 | 6 |
24 #include "wtf/Allocator.h" | 7 // The contents of this header was moved to platform/wtf as part of |
25 #include "wtf/HashTableDeletedValueType.h" | 8 // WTF migration project. See the following post for details: |
26 #include "wtf/WTFExport.h" | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
27 #include "wtf/text/CString.h" | |
28 #include "wtf/text/StringView.h" | |
29 #include "wtf/text/WTFString.h" | |
30 #include <cstring> | |
31 #include <iosfwd> | |
32 | |
33 namespace WTF { | |
34 | |
35 struct AtomicStringHash; | |
36 | |
37 // An AtomicString instance represents a string, and multiple AtomicString | |
38 // instances can share their string storage if the strings are | |
39 // identical. Comparing two AtomicString instances is much faster than comparing | |
40 // two String instances because we just check string storage identity. | |
41 // | |
42 // AtomicString instances are not thread-safe. An AtomicString instance created | |
43 // in a thread must be used only in the creator thread. If multiple threads | |
44 // access a single AtomicString instance, we have race condition of a reference | |
45 // count in StringImpl, and would hit a runtime CHECK in | |
46 // AtomicStringTable::remove(). | |
47 // | |
48 // Exception: nullAtom and emptyAtom, are shared in multiple threads, and are | |
49 // never stored in AtomicStringTable. | |
50 class WTF_EXPORT AtomicString { | |
51 USING_FAST_MALLOC(AtomicString); | |
52 | |
53 public: | |
54 // The function is defined in StringStatics.cpp. | |
55 static void init(); | |
56 | |
57 AtomicString() {} | |
58 AtomicString(const LChar* chars) | |
59 : AtomicString(chars, | |
60 chars ? strlen(reinterpret_cast<const char*>(chars)) : 0) { | |
61 } | |
62 AtomicString(const char* chars) | |
63 : AtomicString(reinterpret_cast<const LChar*>(chars)) {} | |
64 AtomicString(const LChar* chars, unsigned length); | |
65 AtomicString(const UChar* chars, unsigned length); | |
66 AtomicString(const UChar* chars); | |
67 AtomicString(const char16_t* chars) | |
68 : AtomicString(reinterpret_cast<const UChar*>(chars)) {} | |
69 | |
70 template <size_t inlineCapacity> | |
71 explicit AtomicString(const Vector<UChar, inlineCapacity>& vector) | |
72 : AtomicString(vector.data(), vector.size()) {} | |
73 | |
74 // Constructing an AtomicString from a String / StringImpl can be expensive if | |
75 // the StringImpl is not already atomic. | |
76 explicit AtomicString(StringImpl* impl) : m_string(add(impl)) {} | |
77 explicit AtomicString(const String& s) : m_string(add(s.impl())) {} | |
78 | |
79 // Hash table deleted values, which are only constructed and never copied or | |
80 // destroyed. | |
81 AtomicString(WTF::HashTableDeletedValueType) | |
82 : m_string(WTF::HashTableDeletedValue) {} | |
83 bool isHashTableDeletedValue() const { | |
84 return m_string.isHashTableDeletedValue(); | |
85 } | |
86 | |
87 explicit operator bool() const { return !isNull(); } | |
88 operator const String&() const { return m_string; } | |
89 const String& getString() const { return m_string; } | |
90 | |
91 StringImpl* impl() const { return m_string.impl(); } | |
92 | |
93 bool is8Bit() const { return m_string.is8Bit(); } | |
94 const LChar* characters8() const { return m_string.characters8(); } | |
95 const UChar* characters16() const { return m_string.characters16(); } | |
96 unsigned length() const { return m_string.length(); } | |
97 | |
98 UChar operator[](unsigned i) const { return m_string[i]; } | |
99 | |
100 // Find characters. | |
101 size_t find(UChar c, unsigned start = 0) const { | |
102 return m_string.find(c, start); | |
103 } | |
104 size_t find(LChar c, unsigned start = 0) const { | |
105 return m_string.find(c, start); | |
106 } | |
107 size_t find(char c, unsigned start = 0) const { | |
108 return find(static_cast<LChar>(c), start); | |
109 } | |
110 size_t find(CharacterMatchFunctionPtr matchFunction, | |
111 unsigned start = 0) const { | |
112 return m_string.find(matchFunction, start); | |
113 } | |
114 | |
115 // Find substrings. | |
116 size_t find(const StringView& value, | |
117 unsigned start = 0, | |
118 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { | |
119 return m_string.find(value, start, caseSensitivity); | |
120 } | |
121 | |
122 // Unicode aware case insensitive string matching. Non-ASCII characters might | |
123 // match to ASCII characters. This function is rarely used to implement web | |
124 // platform features. | |
125 size_t findIgnoringCase(const StringView& value, unsigned start = 0) const { | |
126 return m_string.findIgnoringCase(value, start); | |
127 } | |
128 | |
129 // ASCII case insensitive string matching. | |
130 size_t findIgnoringASCIICase(const StringView& value, | |
131 unsigned start = 0) const { | |
132 return m_string.findIgnoringASCIICase(value, start); | |
133 } | |
134 | |
135 bool contains(char c) const { return find(c) != kNotFound; } | |
136 bool contains(const StringView& value, | |
137 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { | |
138 return find(value, 0, caseSensitivity) != kNotFound; | |
139 } | |
140 | |
141 // Find the last instance of a single character or string. | |
142 size_t reverseFind(UChar c, unsigned start = UINT_MAX) const { | |
143 return m_string.reverseFind(c, start); | |
144 } | |
145 size_t reverseFind(const StringView& value, unsigned start = UINT_MAX) const { | |
146 return m_string.reverseFind(value, start); | |
147 } | |
148 | |
149 bool startsWith( | |
150 const StringView& prefix, | |
151 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { | |
152 return m_string.startsWith(prefix, caseSensitivity); | |
153 } | |
154 bool startsWith(UChar character) const { | |
155 return m_string.startsWith(character); | |
156 } | |
157 | |
158 bool endsWith(const StringView& suffix, | |
159 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { | |
160 return m_string.endsWith(suffix, caseSensitivity); | |
161 } | |
162 bool endsWith(UChar character) const { return m_string.endsWith(character); } | |
163 | |
164 // Returns a lowercase version of the string. This function might | |
165 // convert non-ASCII characters to ASCII characters. For example, | |
166 // lower() for U+212A is 'k'. | |
167 // This function is rarely used to implement web platform features. | |
168 AtomicString lower() const; | |
169 | |
170 // Returns a lowercase/uppercase version of the string. | |
171 // These functions convert ASCII characters only. | |
172 AtomicString lowerASCII() const; | |
173 AtomicString upperASCII() const; | |
174 | |
175 int toInt(bool* ok = 0) const { return m_string.toInt(ok); } | |
176 double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); } | |
177 float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); } | |
178 | |
179 static AtomicString number(int); | |
180 static AtomicString number(unsigned); | |
181 static AtomicString number(long); | |
182 static AtomicString number(unsigned long); | |
183 static AtomicString number(long long); | |
184 static AtomicString number(unsigned long long); | |
185 | |
186 static AtomicString number(double, unsigned precision = 6); | |
187 | |
188 bool isNull() const { return m_string.isNull(); } | |
189 bool isEmpty() const { return m_string.isEmpty(); } | |
190 | |
191 #ifdef __OBJC__ | |
192 AtomicString(NSString* s) : m_string(add((CFStringRef)s)) {} | |
193 operator NSString*() const { return m_string; } | |
194 #endif | |
195 // AtomicString::fromUTF8 will return a null string if | |
196 // the input data contains invalid UTF-8 sequences. | |
197 // NOTE: Passing a zero size means use the whole string. | |
198 static AtomicString fromUTF8(const char*, size_t length); | |
199 static AtomicString fromUTF8(const char*); | |
200 | |
201 CString ascii() const { return m_string.ascii(); } | |
202 CString latin1() const { return m_string.latin1(); } | |
203 CString utf8(UTF8ConversionMode mode = LenientUTF8Conversion) const { | |
204 return m_string.utf8(mode); | |
205 } | |
206 | |
207 size_t charactersSizeInBytes() const { | |
208 return m_string.charactersSizeInBytes(); | |
209 } | |
210 | |
211 bool isSafeToSendToAnotherThread() const { | |
212 return m_string.isSafeToSendToAnotherThread(); | |
213 } | |
214 | |
215 #ifndef NDEBUG | |
216 void show() const; | |
217 #endif | |
218 | |
219 private: | |
220 String m_string; | |
221 | |
222 ALWAYS_INLINE static PassRefPtr<StringImpl> add(StringImpl* r) { | |
223 if (!r || r->isAtomic()) | |
224 return r; | |
225 return addSlowCase(r); | |
226 } | |
227 static PassRefPtr<StringImpl> addSlowCase(StringImpl*); | |
228 #if OS(MACOSX) | |
229 static PassRefPtr<StringImpl> add(CFStringRef); | |
230 #endif | |
231 }; | |
232 | |
233 inline bool operator==(const AtomicString& a, const AtomicString& b) { | |
234 return a.impl() == b.impl(); | |
235 } | |
236 inline bool operator==(const AtomicString& a, const String& b) { | |
237 // We don't use equalStringView so we get the isAtomic() optimization inside | |
238 // WTF::equal. | |
239 return equal(a.impl(), b.impl()); | |
240 } | |
241 inline bool operator==(const String& a, const AtomicString& b) { | |
242 return b == a; | |
243 } | |
244 inline bool operator==(const AtomicString& a, const char* b) { | |
245 return equalStringView(a, b); | |
246 } | |
247 inline bool operator==(const char* a, const AtomicString& b) { | |
248 return b == a; | |
249 } | |
250 | |
251 inline bool operator!=(const AtomicString& a, const AtomicString& b) { | |
252 return a.impl() != b.impl(); | |
253 } | |
254 inline bool operator!=(const AtomicString& a, const String& b) { | |
255 return !(a == b); | |
256 } | |
257 inline bool operator!=(const String& a, const AtomicString& b) { | |
258 return !(a == b); | |
259 } | |
260 inline bool operator!=(const AtomicString& a, const char* b) { | |
261 return !(a == b); | |
262 } | |
263 inline bool operator!=(const char* a, const AtomicString& b) { | |
264 return !(a == b); | |
265 } | |
266 | |
267 // Define external global variables for the commonly used atomic strings. | |
268 // These are only usable from the main thread. | |
269 WTF_EXPORT extern const AtomicString& nullAtom; | |
270 WTF_EXPORT extern const AtomicString& emptyAtom; | |
271 WTF_EXPORT extern const AtomicString& starAtom; | |
272 WTF_EXPORT extern const AtomicString& xmlAtom; | |
273 WTF_EXPORT extern const AtomicString& xmlnsAtom; | |
274 WTF_EXPORT extern const AtomicString& xlinkAtom; | |
275 WTF_EXPORT extern const AtomicString& httpAtom; | |
276 WTF_EXPORT extern const AtomicString& httpsAtom; | |
277 | |
278 // AtomicStringHash is the default hash for AtomicString | |
279 template <typename T> | |
280 struct DefaultHash; | |
281 template <> | |
282 struct DefaultHash<AtomicString> { | |
283 typedef AtomicStringHash Hash; | |
284 }; | |
285 | |
286 // Pretty printer for gtest and base/logging.*. It prepends and appends | |
287 // double-quotes, and escapes chracters other than ASCII printables. | |
288 WTF_EXPORT std::ostream& operator<<(std::ostream&, const AtomicString&); | |
289 | |
290 inline StringView::StringView(const AtomicString& string, | |
291 unsigned offset, | |
292 unsigned length) | |
293 : StringView(string.impl(), offset, length) {} | |
294 inline StringView::StringView(const AtomicString& string, unsigned offset) | |
295 : StringView(string.impl(), offset) {} | |
296 inline StringView::StringView(const AtomicString& string) | |
297 : StringView(string.impl()) {} | |
298 | |
299 } // namespace WTF | |
300 | |
301 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(AtomicString); | |
302 | |
303 using WTF::AtomicString; | |
304 using WTF::nullAtom; | |
305 using WTF::emptyAtom; | |
306 using WTF::starAtom; | |
307 using WTF::xmlAtom; | |
308 using WTF::xmlnsAtom; | |
309 using WTF::xlinkAtom; | |
310 | |
311 #include "wtf/text/StringConcatenate.h" | |
312 #endif // AtomicString_h | |
OLD | NEW |