| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #include <objc/objc.h> | 39 #include <objc/objc.h> |
| 40 #endif | 40 #endif |
| 41 | 41 |
| 42 namespace WTF { | 42 namespace WTF { |
| 43 | 43 |
| 44 class CString; | 44 class CString; |
| 45 struct StringHash; | 45 struct StringHash; |
| 46 | 46 |
| 47 // Declarations of string operations | 47 // Declarations of string operations |
| 48 | 48 |
| 49 WTF_EXPORT int charactersToIntStrict(const LChar*, size_t, bool* ok = 0, int bas
e = 10); | 49 WTF_EXPORT int charactersToIntStrict(const LChar*, |
| 50 WTF_EXPORT int charactersToIntStrict(const UChar*, size_t, bool* ok = 0, int bas
e = 10); | 50 size_t, |
| 51 WTF_EXPORT unsigned charactersToUIntStrict(const LChar*, size_t, bool* ok = 0, i
nt base = 10); | 51 bool* ok = 0, |
| 52 WTF_EXPORT unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = 0, i
nt base = 10); | 52 int base = 10); |
| 53 WTF_EXPORT int64_t charactersToInt64Strict(const LChar*, size_t, bool* ok = 0, i
nt base = 10); | 53 WTF_EXPORT int charactersToIntStrict(const UChar*, |
| 54 WTF_EXPORT int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = 0, i
nt base = 10); | 54 size_t, |
| 55 WTF_EXPORT uint64_t charactersToUInt64Strict(const LChar*, size_t, bool* ok = 0,
int base = 10); | 55 bool* ok = 0, |
| 56 WTF_EXPORT uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = 0,
int base = 10); | 56 int base = 10); |
| 57 WTF_EXPORT unsigned charactersToUIntStrict(const LChar*, |
| 58 size_t, |
| 59 bool* ok = 0, |
| 60 int base = 10); |
| 61 WTF_EXPORT unsigned charactersToUIntStrict(const UChar*, |
| 62 size_t, |
| 63 bool* ok = 0, |
| 64 int base = 10); |
| 65 WTF_EXPORT int64_t charactersToInt64Strict(const LChar*, |
| 66 size_t, |
| 67 bool* ok = 0, |
| 68 int base = 10); |
| 69 WTF_EXPORT int64_t charactersToInt64Strict(const UChar*, |
| 70 size_t, |
| 71 bool* ok = 0, |
| 72 int base = 10); |
| 73 WTF_EXPORT uint64_t charactersToUInt64Strict(const LChar*, |
| 74 size_t, |
| 75 bool* ok = 0, |
| 76 int base = 10); |
| 77 WTF_EXPORT uint64_t charactersToUInt64Strict(const UChar*, |
| 78 size_t, |
| 79 bool* ok = 0, |
| 80 int base = 10); |
| 57 | 81 |
| 58 WTF_EXPORT int charactersToInt(const LChar*, size_t, bool* ok = 0); // ignores t
railing garbage | 82 WTF_EXPORT int charactersToInt(const LChar*, |
| 59 WTF_EXPORT int charactersToInt(const UChar*, size_t, bool* ok = 0); // ignores t
railing garbage | 83 size_t, |
| 60 WTF_EXPORT unsigned charactersToUInt(const LChar*, size_t, bool* ok = 0); // ign
ores trailing garbage | 84 bool* ok = 0); // ignores trailing garbage |
| 61 WTF_EXPORT unsigned charactersToUInt(const UChar*, size_t, bool* ok = 0); // ign
ores trailing garbage | 85 WTF_EXPORT int charactersToInt(const UChar*, |
| 62 WTF_EXPORT int64_t charactersToInt64(const LChar*, size_t, bool* ok = 0); // ign
ores trailing garbage | 86 size_t, |
| 63 WTF_EXPORT int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ign
ores trailing garbage | 87 bool* ok = 0); // ignores trailing garbage |
| 64 WTF_EXPORT uint64_t charactersToUInt64(const LChar*, size_t, bool* ok = 0); // i
gnores trailing garbage | 88 WTF_EXPORT unsigned charactersToUInt(const LChar*, |
| 65 WTF_EXPORT uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // i
gnores trailing garbage | 89 size_t, |
| 90 bool* ok = 0); // ignores trailing garbage |
| 91 WTF_EXPORT unsigned charactersToUInt(const UChar*, |
| 92 size_t, |
| 93 bool* ok = 0); // ignores trailing garbage |
| 94 WTF_EXPORT int64_t charactersToInt64(const LChar*, |
| 95 size_t, |
| 96 bool* ok = 0); // ignores trailing garbage |
| 97 WTF_EXPORT int64_t charactersToInt64(const UChar*, |
| 98 size_t, |
| 99 bool* ok = 0); // ignores trailing garbage |
| 100 WTF_EXPORT uint64_t |
| 101 charactersToUInt64(const LChar*, |
| 102 size_t, |
| 103 bool* ok = 0); // ignores trailing garbage |
| 104 WTF_EXPORT uint64_t |
| 105 charactersToUInt64(const UChar*, |
| 106 size_t, |
| 107 bool* ok = 0); // ignores trailing garbage |
| 66 | 108 |
| 67 // FIXME: Like the strict functions above, these give false for "ok" when there | 109 // FIXME: Like the strict functions above, these give false for "ok" when there |
| 68 // is trailing garbage. Like the non-strict functions above, these return the | 110 // is trailing garbage. Like the non-strict functions above, these return the |
| 69 // value when there is trailing garbage. It would be better if these were more | 111 // value when there is trailing garbage. It would be better if these were more |
| 70 // consistent with the above functions instead. | 112 // consistent with the above functions instead. |
| 71 WTF_EXPORT double charactersToDouble(const LChar*, size_t, bool* ok = 0); | 113 WTF_EXPORT double charactersToDouble(const LChar*, size_t, bool* ok = 0); |
| 72 WTF_EXPORT double charactersToDouble(const UChar*, size_t, bool* ok = 0); | 114 WTF_EXPORT double charactersToDouble(const UChar*, size_t, bool* ok = 0); |
| 73 WTF_EXPORT float charactersToFloat(const LChar*, size_t, bool* ok = 0); | 115 WTF_EXPORT float charactersToFloat(const LChar*, size_t, bool* ok = 0); |
| 74 WTF_EXPORT float charactersToFloat(const UChar*, size_t, bool* ok = 0); | 116 WTF_EXPORT float charactersToFloat(const UChar*, size_t, bool* ok = 0); |
| 75 WTF_EXPORT float charactersToFloat(const LChar*, size_t, size_t& parsedLength); | 117 WTF_EXPORT float charactersToFloat(const LChar*, size_t, size_t& parsedLength); |
| 76 WTF_EXPORT float charactersToFloat(const UChar*, size_t, size_t& parsedLength); | 118 WTF_EXPORT float charactersToFloat(const UChar*, size_t, size_t& parsedLength); |
| 77 | 119 |
| 78 enum TrailingZerosTruncatingPolicy { | 120 enum TrailingZerosTruncatingPolicy { KeepTrailingZeros, TruncateTrailingZeros }; |
| 79 KeepTrailingZeros, | 121 |
| 80 TruncateTrailingZeros | 122 enum UTF8ConversionMode { |
| 123 LenientUTF8Conversion, |
| 124 StrictUTF8Conversion, |
| 125 StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD |
| 81 }; | 126 }; |
| 82 | 127 |
| 83 enum UTF8ConversionMode { | 128 #define DISPATCH_CASE_OP(caseSensitivity, op, args) \ |
| 84 LenientUTF8Conversion, | 129 ((caseSensitivity == TextCaseSensitive) \ |
| 85 StrictUTF8Conversion, | 130 ? op args \ |
| 86 StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD | 131 : (caseSensitivity == TextCaseASCIIInsensitive) \ |
| 87 }; | 132 ? op##IgnoringASCIICase args \ |
| 88 | 133 : op##IgnoringCase args) |
| 89 #define DISPATCH_CASE_OP(caseSensitivity, op, args) \ | 134 |
| 90 ((caseSensitivity == TextCaseSensitive) ? op args : \ | 135 template <bool isSpecialCharacter(UChar), typename CharacterType> |
| 91 (caseSensitivity == TextCaseASCIIInsensitive) ? op##IgnoringASCIICase args
: \ | |
| 92 op##IgnoringCase args) | |
| 93 | |
| 94 template<bool isSpecialCharacter(UChar), typename CharacterType> | |
| 95 bool isAllSpecialCharacters(const CharacterType*, size_t); | 136 bool isAllSpecialCharacters(const CharacterType*, size_t); |
| 96 | 137 |
| 97 // You can find documentation about this class in this doc: | 138 // You can find documentation about this class in this doc: |
| 98 // https://docs.google.com/document/d/1kOCUlJdh2WJMJGDf-WoEQhmnjKLaOYRbiHz5TiGJl
14/edit?usp=sharing | 139 // https://docs.google.com/document/d/1kOCUlJdh2WJMJGDf-WoEQhmnjKLaOYRbiHz5TiGJl
14/edit?usp=sharing |
| 99 class WTF_EXPORT String { | 140 class WTF_EXPORT String { |
| 100 USING_FAST_MALLOC(String); | 141 USING_FAST_MALLOC(String); |
| 101 public: | 142 |
| 102 // Construct a null string, distinguishable from an empty string. | 143 public: |
| 103 String() { } | 144 // Construct a null string, distinguishable from an empty string. |
| 104 | 145 String() {} |
| 105 // Construct a string with UTF-16 data. | 146 |
| 106 String(const UChar* characters, unsigned length); | 147 // Construct a string with UTF-16 data. |
| 107 | 148 String(const UChar* characters, unsigned length); |
| 108 // Construct a string by copying the contents of a vector. | 149 |
| 109 // This method will never create a null string. Vectors with size() == 0 | 150 // Construct a string by copying the contents of a vector. |
| 110 // will return the empty string. | 151 // This method will never create a null string. Vectors with size() == 0 |
| 111 // NOTE: This is different from String(vector.data(), vector.size()) | 152 // will return the empty string. |
| 112 // which will sometimes return a null string when vector.data() is null | 153 // NOTE: This is different from String(vector.data(), vector.size()) |
| 113 // which can only occur for vectors without inline capacity. | 154 // which will sometimes return a null string when vector.data() is null |
| 114 // See: https://bugs.webkit.org/show_bug.cgi?id=109792 | 155 // which can only occur for vectors without inline capacity. |
| 115 template<size_t inlineCapacity> | 156 // See: https://bugs.webkit.org/show_bug.cgi?id=109792 |
| 116 explicit String(const Vector<UChar, inlineCapacity>&); | 157 template <size_t inlineCapacity> |
| 117 | 158 explicit String(const Vector<UChar, inlineCapacity>&); |
| 118 // Construct a string with UTF-16 data, from a null-terminated source. | 159 |
| 119 String(const UChar*); | 160 // Construct a string with UTF-16 data, from a null-terminated source. |
| 120 | 161 String(const UChar*); |
| 121 // Construct a string with latin1 data. | 162 |
| 122 String(const LChar* characters, unsigned length); | 163 // Construct a string with latin1 data. |
| 123 String(const char* characters, unsigned length); | 164 String(const LChar* characters, unsigned length); |
| 124 | 165 String(const char* characters, unsigned length); |
| 125 // Construct a string with latin1 data, from a null-terminated source. | 166 |
| 126 String(const LChar* characters); | 167 // Construct a string with latin1 data, from a null-terminated source. |
| 127 String(const char* characters); | 168 String(const LChar* characters); |
| 128 | 169 String(const char* characters); |
| 129 // Construct a string referencing an existing StringImpl. | 170 |
| 130 String(StringImpl* impl) : m_impl(impl) { } | 171 // Construct a string referencing an existing StringImpl. |
| 131 String(PassRefPtr<StringImpl> impl) : m_impl(impl) { } | 172 String(StringImpl* impl) : m_impl(impl) {} |
| 132 | 173 String(PassRefPtr<StringImpl> impl) : m_impl(impl) {} |
| 133 void swap(String& o) { m_impl.swap(o.m_impl); } | 174 |
| 134 | 175 void swap(String& o) { m_impl.swap(o.m_impl); } |
| 135 template<typename CharType> | 176 |
| 136 static String adopt(StringBuffer<CharType>& buffer) | 177 template <typename CharType> |
| 137 { | 178 static String adopt(StringBuffer<CharType>& buffer) { |
| 138 if (!buffer.length()) | 179 if (!buffer.length()) |
| 139 return StringImpl::empty(); | 180 return StringImpl::empty(); |
| 140 return String(buffer.release()); | 181 return String(buffer.release()); |
| 141 } | 182 } |
| 142 | 183 |
| 143 bool isNull() const { return !m_impl; } | 184 bool isNull() const { return !m_impl; } |
| 144 bool isEmpty() const { return !m_impl || !m_impl->length(); } | 185 bool isEmpty() const { return !m_impl || !m_impl->length(); } |
| 145 | 186 |
| 146 StringImpl* impl() const { return m_impl.get(); } | 187 StringImpl* impl() const { return m_impl.get(); } |
| 147 PassRefPtr<StringImpl> releaseImpl() { return m_impl.release(); } | 188 PassRefPtr<StringImpl> releaseImpl() { return m_impl.release(); } |
| 148 | 189 |
| 149 unsigned length() const | 190 unsigned length() const { |
| 150 { | 191 if (!m_impl) |
| 151 if (!m_impl) | 192 return 0; |
| 152 return 0; | 193 return m_impl->length(); |
| 153 return m_impl->length(); | 194 } |
| 154 } | 195 |
| 155 | 196 const LChar* characters8() const { |
| 156 const LChar* characters8() const | 197 if (!m_impl) |
| 157 { | 198 return 0; |
| 158 if (!m_impl) | 199 ASSERT(m_impl->is8Bit()); |
| 159 return 0; | 200 return m_impl->characters8(); |
| 160 ASSERT(m_impl->is8Bit()); | 201 } |
| 161 return m_impl->characters8(); | 202 |
| 162 } | 203 const UChar* characters16() const { |
| 163 | 204 if (!m_impl) |
| 164 const UChar* characters16() const | 205 return 0; |
| 165 { | 206 ASSERT(!m_impl->is8Bit()); |
| 166 if (!m_impl) | 207 return m_impl->characters16(); |
| 167 return 0; | 208 } |
| 168 ASSERT(!m_impl->is8Bit()); | 209 |
| 169 return m_impl->characters16(); | 210 // Return characters8() or characters16() depending on CharacterType. |
| 170 } | 211 template <typename CharacterType> |
| 171 | 212 inline const CharacterType* getCharacters() const; |
| 172 // Return characters8() or characters16() depending on CharacterType. | 213 |
| 173 template <typename CharacterType> | 214 bool is8Bit() const { return m_impl->is8Bit(); } |
| 174 inline const CharacterType* getCharacters() const; | 215 |
| 175 | 216 unsigned sizeInBytes() const { |
| 176 bool is8Bit() const { return m_impl->is8Bit(); } | 217 if (!m_impl) |
| 177 | 218 return 0; |
| 178 unsigned sizeInBytes() const | 219 return m_impl->length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar)); |
| 179 { | 220 } |
| 180 if (!m_impl) | 221 |
| 181 return 0; | 222 CString ascii() const; |
| 182 return m_impl->length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar)); | 223 CString latin1() const; |
| 183 } | 224 CString utf8(UTF8ConversionMode = LenientUTF8Conversion) const; |
| 184 | 225 |
| 185 CString ascii() const; | 226 UChar operator[](unsigned index) const { |
| 186 CString latin1() const; | 227 if (!m_impl || index >= m_impl->length()) |
| 187 CString utf8(UTF8ConversionMode = LenientUTF8Conversion) const; | 228 return 0; |
| 188 | 229 return (*m_impl)[index]; |
| 189 UChar operator[](unsigned index) const | 230 } |
| 190 { | 231 |
| 191 if (!m_impl || index >= m_impl->length()) | 232 static String number(int); |
| 192 return 0; | 233 static String number(unsigned); |
| 193 return (*m_impl)[index]; | 234 static String number(long); |
| 194 } | 235 static String number(unsigned long); |
| 195 | 236 static String number(long long); |
| 196 static String number(int); | 237 static String number(unsigned long long); |
| 197 static String number(unsigned); | 238 |
| 198 static String number(long); | 239 static String number(double, |
| 199 static String number(unsigned long); | 240 unsigned precision = 6, |
| 200 static String number(long long); | 241 TrailingZerosTruncatingPolicy = TruncateTrailingZeros); |
| 201 static String number(unsigned long long); | 242 |
| 202 | 243 // Number to String conversion following the ECMAScript definition. |
| 203 static String number(double, unsigned precision = 6, TrailingZerosTruncating
Policy = TruncateTrailingZeros); | 244 static String numberToStringECMAScript(double); |
| 204 | 245 static String numberToStringFixedWidth(double, unsigned decimalPlaces); |
| 205 // Number to String conversion following the ECMAScript definition. | 246 |
| 206 static String numberToStringECMAScript(double); | 247 // Find a single character or string, also with match function & latin1 |
| 207 static String numberToStringFixedWidth(double, unsigned decimalPlaces); | 248 // forms. |
| 208 | 249 size_t find(UChar c, unsigned start = 0) const { |
| 209 // Find a single character or string, also with match function & latin1 | 250 return m_impl ? m_impl->find(c, start) : kNotFound; |
| 210 // forms. | 251 } |
| 211 size_t find(UChar c, unsigned start = 0) const | 252 size_t find(LChar c, unsigned start = 0) const { |
| 212 { return m_impl ? m_impl->find(c, start) : kNotFound; } | 253 return m_impl ? m_impl->find(c, start) : kNotFound; |
| 213 size_t find(LChar c, unsigned start = 0) const | 254 } |
| 214 { return m_impl ? m_impl->find(c, start) : kNotFound; } | 255 size_t find(char c, unsigned start = 0) const { |
| 215 size_t find(char c, unsigned start = 0) const { return find(static_cast<LCha
r>(c), start); } | 256 return find(static_cast<LChar>(c), start); |
| 216 | 257 } |
| 217 size_t find(const String& str) const | 258 |
| 218 { return m_impl ? m_impl->find(str.impl()) : kNotFound; } | 259 size_t find(const String& str) const { |
| 219 size_t find(const String& str, unsigned start) const | 260 return m_impl ? m_impl->find(str.impl()) : kNotFound; |
| 220 { return m_impl ? m_impl->find(str.impl(), start) : kNotFound; } | 261 } |
| 221 | 262 size_t find(const String& str, unsigned start) const { |
| 222 size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) con
st | 263 return m_impl ? m_impl->find(str.impl(), start) : kNotFound; |
| 223 { return m_impl ? m_impl->find(matchFunction, start) : kNotFound; } | 264 } |
| 224 size_t find(const LChar* str, unsigned start = 0) const | 265 |
| 225 { return m_impl ? m_impl->find(str, start) : kNotFound; } | 266 size_t find(CharacterMatchFunctionPtr matchFunction, |
| 226 | 267 unsigned start = 0) const { |
| 227 size_t findNextLineStart(unsigned start = 0) const | 268 return m_impl ? m_impl->find(matchFunction, start) : kNotFound; |
| 228 { return m_impl ? m_impl->findNextLineStart(start) : kNotFound; } | 269 } |
| 229 | 270 size_t find(const LChar* str, unsigned start = 0) const { |
| 230 // Find the last instance of a single character or string. | 271 return m_impl ? m_impl->find(str, start) : kNotFound; |
| 231 size_t reverseFind(UChar c, unsigned start = UINT_MAX) const | 272 } |
| 232 { return m_impl ? m_impl->reverseFind(c, start) : kNotFound; } | 273 |
| 233 size_t reverseFind(const String& str, unsigned start = UINT_MAX) const | 274 size_t findNextLineStart(unsigned start = 0) const { |
| 234 { return m_impl ? m_impl->reverseFind(str.impl(), start) : kNotFound; } | 275 return m_impl ? m_impl->findNextLineStart(start) : kNotFound; |
| 235 | 276 } |
| 236 // Case insensitive string matching. | 277 |
| 237 size_t findIgnoringCase(const LChar* str, unsigned start = 0) const | 278 // Find the last instance of a single character or string. |
| 238 { return m_impl ? m_impl->findIgnoringCase(str, start) : kNotFound; } | 279 size_t reverseFind(UChar c, unsigned start = UINT_MAX) const { |
| 239 size_t findIgnoringCase(const String& str, unsigned start = 0) const | 280 return m_impl ? m_impl->reverseFind(c, start) : kNotFound; |
| 240 { return m_impl ? m_impl->findIgnoringCase(str.impl(), start) : kNotFoun
d; } | 281 } |
| 241 | 282 size_t reverseFind(const String& str, unsigned start = UINT_MAX) const { |
| 242 // ASCII case insensitive string matching. | 283 return m_impl ? m_impl->reverseFind(str.impl(), start) : kNotFound; |
| 243 size_t findIgnoringASCIICase(const String& str, unsigned start = 0) const | 284 } |
| 244 { return m_impl ? m_impl->findIgnoringASCIICase(str.impl(), start) : kNo
tFound; } | 285 |
| 245 | 286 // Case insensitive string matching. |
| 246 // Wrappers for find adding dynamic sensitivity check. | 287 size_t findIgnoringCase(const LChar* str, unsigned start = 0) const { |
| 247 size_t find(const LChar* str, unsigned start, TextCaseSensitivity caseSensit
ivity) const | 288 return m_impl ? m_impl->findIgnoringCase(str, start) : kNotFound; |
| 248 { return DISPATCH_CASE_OP(caseSensitivity, find, (str, start)); } | 289 } |
| 249 size_t find(const String& str, unsigned start, TextCaseSensitivity caseSensi
tivity) const | 290 size_t findIgnoringCase(const String& str, unsigned start = 0) const { |
| 250 { return DISPATCH_CASE_OP(caseSensitivity, find, (str, start)); } | 291 return m_impl ? m_impl->findIgnoringCase(str.impl(), start) : kNotFound; |
| 251 | 292 } |
| 252 Vector<UChar> charactersWithNullTermination() const; | 293 |
| 253 unsigned copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const; | 294 // ASCII case insensitive string matching. |
| 254 | 295 size_t findIgnoringASCIICase(const String& str, unsigned start = 0) const { |
| 255 template<size_t inlineCapacity> | 296 return m_impl ? m_impl->findIgnoringASCIICase(str.impl(), start) |
| 256 void appendTo(Vector<UChar, inlineCapacity>&, unsigned pos = 0, unsigned len
= UINT_MAX) const; | 297 : kNotFound; |
| 257 | 298 } |
| 258 template<typename BufferType> | 299 |
| 259 void appendTo(BufferType&, unsigned pos = 0, unsigned len = UINT_MAX) const; | 300 // Wrappers for find adding dynamic sensitivity check. |
| 260 | 301 size_t find(const LChar* str, |
| 261 template<size_t inlineCapacity> | 302 unsigned start, |
| 262 void prependTo(Vector<UChar, inlineCapacity>&, unsigned pos = 0, unsigned le
n = UINT_MAX) const; | 303 TextCaseSensitivity caseSensitivity) const { |
| 263 | 304 return DISPATCH_CASE_OP(caseSensitivity, find, (str, start)); |
| 264 UChar32 characterStartingAt(unsigned) const; | 305 } |
| 265 template<typename CharacterType> | 306 size_t find(const String& str, |
| 266 bool contains(CharacterType c) const { return find(c) != kNotFound; } | 307 unsigned start, |
| 267 bool contains(const LChar* str, TextCaseSensitivity caseSensitivity = TextCa
seSensitive) const { return find(str, 0, caseSensitivity) != kNotFound; } | 308 TextCaseSensitivity caseSensitivity) const { |
| 268 bool contains(const String& str, TextCaseSensitivity caseSensitivity = TextC
aseSensitive) const { return find(str, 0, caseSensitivity) != kNotFound; } | 309 return DISPATCH_CASE_OP(caseSensitivity, find, (str, start)); |
| 269 | 310 } |
| 270 bool startsWith(const String& s, TextCaseSensitivity caseSensitivity = TextC
aseSensitive) const | 311 |
| 271 { return m_impl ? DISPATCH_CASE_OP(caseSensitivity, m_impl->startsWith,
(s.impl())) : s.isEmpty(); } | 312 Vector<UChar> charactersWithNullTermination() const; |
| 272 bool startsWith(UChar character) const | 313 unsigned copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const; |
| 273 { return m_impl ? m_impl->startsWith(character) : false; } | 314 |
| 274 template<unsigned matchLength> | 315 template <size_t inlineCapacity> |
| 275 bool startsWith(const char (&prefix)[matchLength], TextCaseSensitivity caseS
ensitivity = TextCaseSensitive) const | 316 void appendTo(Vector<UChar, inlineCapacity>&, |
| 276 { return m_impl ? DISPATCH_CASE_OP(caseSensitivity, m_impl->startsWith,
(prefix, matchLength - 1)) : !matchLength; } | 317 unsigned pos = 0, |
| 277 | 318 unsigned len = UINT_MAX) const; |
| 278 bool endsWith(const String& s, TextCaseSensitivity caseSensitivity = TextCas
eSensitive) const | 319 |
| 279 { return m_impl ? DISPATCH_CASE_OP(caseSensitivity, m_impl->endsWith, (s
.impl())) : s.isEmpty(); } | 320 template <typename BufferType> |
| 280 bool endsWith(UChar character) const | 321 void appendTo(BufferType&, unsigned pos = 0, unsigned len = UINT_MAX) const; |
| 281 { return m_impl ? m_impl->endsWith(character) : false; } | 322 |
| 282 template<unsigned matchLength> | 323 template <size_t inlineCapacity> |
| 283 bool endsWith(const char (&prefix)[matchLength], TextCaseSensitivity caseSen
sitivity = TextCaseSensitive) const | 324 void prependTo(Vector<UChar, inlineCapacity>&, |
| 284 { return m_impl ? DISPATCH_CASE_OP(caseSensitivity, m_impl->endsWith, (p
refix, matchLength - 1)) : !matchLength; } | 325 unsigned pos = 0, |
| 285 | 326 unsigned len = UINT_MAX) const; |
| 286 void append(const String&); | 327 |
| 287 void append(LChar); | 328 UChar32 characterStartingAt(unsigned) const; |
| 288 void append(char c) { append(static_cast<LChar>(c)); } | 329 template <typename CharacterType> |
| 289 void append(UChar); | 330 bool contains(CharacterType c) const { |
| 290 void append(const LChar*, unsigned length); | 331 return find(c) != kNotFound; |
| 291 void append(const char* charactersToAppend, unsigned length) { append(reinte
rpret_cast<const LChar*>(charactersToAppend), length); } | 332 } |
| 292 void append(const UChar*, unsigned length); | 333 bool contains(const LChar* str, |
| 293 void insert(const String&, unsigned pos); | 334 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { |
| 294 void insert(const LChar*, unsigned length, unsigned pos); | 335 return find(str, 0, caseSensitivity) != kNotFound; |
| 295 void insert(const UChar*, unsigned length, unsigned pos); | 336 } |
| 296 | 337 bool contains(const String& str, |
| 297 String& replace(UChar a, UChar b) | 338 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { |
| 298 { | 339 return find(str, 0, caseSensitivity) != kNotFound; |
| 299 if (m_impl) | 340 } |
| 300 m_impl = m_impl->replace(a, b); | 341 |
| 301 return *this; | 342 bool startsWith( |
| 302 } | 343 const String& s, |
| 303 String& replace(UChar a, const String& b) | 344 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { |
| 304 { | 345 return m_impl ? DISPATCH_CASE_OP(caseSensitivity, m_impl->startsWith, |
| 305 if (m_impl) | 346 (s.impl())) |
| 306 m_impl = m_impl->replace(a, b.impl()); | 347 : s.isEmpty(); |
| 307 return *this; | 348 } |
| 308 } | 349 bool startsWith(UChar character) const { |
| 309 String& replace(const String& a, const String& b) | 350 return m_impl ? m_impl->startsWith(character) : false; |
| 310 { | 351 } |
| 311 if (m_impl) | 352 template <unsigned matchLength> |
| 312 m_impl = m_impl->replace(a.impl(), b.impl()); | 353 bool startsWith( |
| 313 return *this; | 354 const char (&prefix)[matchLength], |
| 314 } | 355 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { |
| 315 String& replace(unsigned index, unsigned len, const String& b) | 356 return m_impl ? DISPATCH_CASE_OP(caseSensitivity, m_impl->startsWith, |
| 316 { | 357 (prefix, matchLength - 1)) |
| 317 if (m_impl) | 358 : !matchLength; |
| 318 m_impl = m_impl->replace(index, len, b.impl()); | 359 } |
| 319 return *this; | 360 |
| 320 } | 361 bool endsWith(const String& s, |
| 321 | 362 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { |
| 322 template<unsigned charactersCount> | 363 return m_impl |
| 323 ALWAYS_INLINE String& replaceWithLiteral(UChar a, const char (&characters)[c
haractersCount]) | 364 ? DISPATCH_CASE_OP(caseSensitivity, m_impl->endsWith, (s.impl())) |
| 324 { | 365 : s.isEmpty(); |
| 325 if (m_impl) | 366 } |
| 326 m_impl = m_impl->replace(a, characters, charactersCount - 1); | 367 bool endsWith(UChar character) const { |
| 327 | 368 return m_impl ? m_impl->endsWith(character) : false; |
| 328 return *this; | 369 } |
| 329 } | 370 template <unsigned matchLength> |
| 330 | 371 bool endsWith(const char (&prefix)[matchLength], |
| 331 void fill(UChar c) | 372 TextCaseSensitivity caseSensitivity = TextCaseSensitive) const { |
| 332 { | 373 return m_impl ? DISPATCH_CASE_OP(caseSensitivity, m_impl->endsWith, |
| 333 if (m_impl) | 374 (prefix, matchLength - 1)) |
| 334 m_impl = m_impl->fill(c); | 375 : !matchLength; |
| 335 } | 376 } |
| 336 | 377 |
| 337 void ensure16Bit(); | 378 void append(const String&); |
| 338 | 379 void append(LChar); |
| 339 void truncate(unsigned len); | 380 void append(char c) { append(static_cast<LChar>(c)); } |
| 340 void remove(unsigned pos, int len = 1); | 381 void append(UChar); |
| 341 | 382 void append(const LChar*, unsigned length); |
| 342 String substring(unsigned pos, unsigned len = UINT_MAX) const; | 383 void append(const char* charactersToAppend, unsigned length) { |
| 343 String left(unsigned len) const { return substring(0, len); } | 384 append(reinterpret_cast<const LChar*>(charactersToAppend), length); |
| 344 String right(unsigned len) const { return substring(length() - len, len); } | 385 } |
| 345 | 386 void append(const UChar*, unsigned length); |
| 346 StringView createView() const { return StringView(impl()); } | 387 void insert(const String&, unsigned pos); |
| 347 StringView createView(unsigned offset, unsigned length) const { return Strin
gView(impl(), offset, length); } | 388 void insert(const LChar*, unsigned length, unsigned pos); |
| 348 | 389 void insert(const UChar*, unsigned length, unsigned pos); |
| 349 // Returns a lowercase/uppercase version of the string | 390 |
| 350 String lower() const; | 391 String& replace(UChar a, UChar b) { |
| 351 String upper() const; | 392 if (m_impl) |
| 352 | 393 m_impl = m_impl->replace(a, b); |
| 353 String lower(const AtomicString& localeIdentifier) const; | 394 return *this; |
| 354 String upper(const AtomicString& localeIdentifier) const; | 395 } |
| 355 | 396 String& replace(UChar a, const String& b) { |
| 356 String stripWhiteSpace() const; | 397 if (m_impl) |
| 357 String stripWhiteSpace(IsWhiteSpaceFunctionPtr) const; | 398 m_impl = m_impl->replace(a, b.impl()); |
| 358 String simplifyWhiteSpace(StripBehavior = StripExtraWhiteSpace) const; | 399 return *this; |
| 359 String simplifyWhiteSpace(IsWhiteSpaceFunctionPtr, StripBehavior = StripExtr
aWhiteSpace) const; | 400 } |
| 360 | 401 String& replace(const String& a, const String& b) { |
| 361 String removeCharacters(CharacterMatchFunctionPtr) const; | 402 if (m_impl) |
| 362 template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters() const
; | 403 m_impl = m_impl->replace(a.impl(), b.impl()); |
| 363 | 404 return *this; |
| 364 // Return the string with case folded for case insensitive comparison. | 405 } |
| 365 String foldCase() const; | 406 String& replace(unsigned index, unsigned len, const String& b) { |
| 366 | 407 if (m_impl) |
| 367 static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2); | 408 m_impl = m_impl->replace(index, len, b.impl()); |
| 368 | 409 return *this; |
| 369 // Returns an uninitialized string. The characters needs to be written | 410 } |
| 370 // into the buffer returned in data before the returned string is used. | 411 |
| 371 // Failure to do this will have unpredictable results. | 412 template <unsigned charactersCount> |
| 372 static String createUninitialized(unsigned length, UChar*& data) { return St
ringImpl::createUninitialized(length, data); } | 413 ALWAYS_INLINE String& replaceWithLiteral( |
| 373 static String createUninitialized(unsigned length, LChar*& data) { return St
ringImpl::createUninitialized(length, data); } | 414 UChar a, |
| 374 | 415 const char (&characters)[charactersCount]) { |
| 375 void split(const String& separator, bool allowEmptyEntries, Vector<String>&
result) const; | 416 if (m_impl) |
| 376 void split(const String& separator, Vector<String>& result) const | 417 m_impl = m_impl->replace(a, characters, charactersCount - 1); |
| 377 { | 418 |
| 378 split(separator, false, result); | 419 return *this; |
| 379 } | 420 } |
| 380 void split(UChar separator, bool allowEmptyEntries, Vector<String>& result)
const; | 421 |
| 381 void split(UChar separator, Vector<String>& result) const | 422 void fill(UChar c) { |
| 382 { | 423 if (m_impl) |
| 383 split(separator, false, result); | 424 m_impl = m_impl->fill(c); |
| 384 } | 425 } |
| 385 | 426 |
| 386 int toIntStrict(bool* ok = 0, int base = 10) const; | 427 void ensure16Bit(); |
| 387 unsigned toUIntStrict(bool* ok = 0, int base = 10) const; | 428 |
| 388 int64_t toInt64Strict(bool* ok = 0, int base = 10) const; | 429 void truncate(unsigned len); |
| 389 uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const; | 430 void remove(unsigned pos, int len = 1); |
| 390 | 431 |
| 391 int toInt(bool* ok = 0) const; | 432 String substring(unsigned pos, unsigned len = UINT_MAX) const; |
| 392 unsigned toUInt(bool* ok = 0) const; | 433 String left(unsigned len) const { return substring(0, len); } |
| 393 int64_t toInt64(bool* ok = 0) const; | 434 String right(unsigned len) const { return substring(length() - len, len); } |
| 394 uint64_t toUInt64(bool* ok = 0) const; | 435 |
| 395 | 436 StringView createView() const { return StringView(impl()); } |
| 396 // FIXME: Like the strict functions above, these give false for "ok" when | 437 StringView createView(unsigned offset, unsigned length) const { |
| 397 // there is trailing garbage. Like the non-strict functions above, these | 438 return StringView(impl(), offset, length); |
| 398 // return the value when there is trailing garbage. It would be better if | 439 } |
| 399 // these were more consistent with the above functions instead. | 440 |
| 400 double toDouble(bool* ok = 0) const; | 441 // Returns a lowercase/uppercase version of the string |
| 401 float toFloat(bool* ok = 0) const; | 442 String lower() const; |
| 402 | 443 String upper() const; |
| 403 String isolatedCopy() const; | 444 |
| 404 bool isSafeToSendToAnotherThread() const; | 445 String lower(const AtomicString& localeIdentifier) const; |
| 446 String upper(const AtomicString& localeIdentifier) const; |
| 447 |
| 448 String stripWhiteSpace() const; |
| 449 String stripWhiteSpace(IsWhiteSpaceFunctionPtr) const; |
| 450 String simplifyWhiteSpace(StripBehavior = StripExtraWhiteSpace) const; |
| 451 String simplifyWhiteSpace(IsWhiteSpaceFunctionPtr, |
| 452 StripBehavior = StripExtraWhiteSpace) const; |
| 453 |
| 454 String removeCharacters(CharacterMatchFunctionPtr) const; |
| 455 template <bool isSpecialCharacter(UChar)> |
| 456 bool isAllSpecialCharacters() const; |
| 457 |
| 458 // Return the string with case folded for case insensitive comparison. |
| 459 String foldCase() const; |
| 460 |
| 461 static String format(const char*, ...) WTF_ATTRIBUTE_PRINTF(1, 2); |
| 462 |
| 463 // Returns an uninitialized string. The characters needs to be written |
| 464 // into the buffer returned in data before the returned string is used. |
| 465 // Failure to do this will have unpredictable results. |
| 466 static String createUninitialized(unsigned length, UChar*& data) { |
| 467 return StringImpl::createUninitialized(length, data); |
| 468 } |
| 469 static String createUninitialized(unsigned length, LChar*& data) { |
| 470 return StringImpl::createUninitialized(length, data); |
| 471 } |
| 472 |
| 473 void split(const String& separator, |
| 474 bool allowEmptyEntries, |
| 475 Vector<String>& result) const; |
| 476 void split(const String& separator, Vector<String>& result) const { |
| 477 split(separator, false, result); |
| 478 } |
| 479 void split(UChar separator, |
| 480 bool allowEmptyEntries, |
| 481 Vector<String>& result) const; |
| 482 void split(UChar separator, Vector<String>& result) const { |
| 483 split(separator, false, result); |
| 484 } |
| 485 |
| 486 int toIntStrict(bool* ok = 0, int base = 10) const; |
| 487 unsigned toUIntStrict(bool* ok = 0, int base = 10) const; |
| 488 int64_t toInt64Strict(bool* ok = 0, int base = 10) const; |
| 489 uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const; |
| 490 |
| 491 int toInt(bool* ok = 0) const; |
| 492 unsigned toUInt(bool* ok = 0) const; |
| 493 int64_t toInt64(bool* ok = 0) const; |
| 494 uint64_t toUInt64(bool* ok = 0) const; |
| 495 |
| 496 // FIXME: Like the strict functions above, these give false for "ok" when |
| 497 // there is trailing garbage. Like the non-strict functions above, these |
| 498 // return the value when there is trailing garbage. It would be better if |
| 499 // these were more consistent with the above functions instead. |
| 500 double toDouble(bool* ok = 0) const; |
| 501 float toFloat(bool* ok = 0) const; |
| 502 |
| 503 String isolatedCopy() const; |
| 504 bool isSafeToSendToAnotherThread() const; |
| 405 | 505 |
| 406 #ifdef __OBJC__ | 506 #ifdef __OBJC__ |
| 407 String(NSString*); | 507 String(NSString*); |
| 408 | 508 |
| 409 // This conversion maps null string to "", which loses the meaning of null | 509 // This conversion maps null string to "", which loses the meaning of null |
| 410 // string, but we need this mapping because AppKit crashes when passed nil | 510 // string, but we need this mapping because AppKit crashes when passed nil |
| 411 // NSStrings. | 511 // NSStrings. |
| 412 operator NSString*() const | 512 operator NSString*() const { |
| 413 { | 513 if (!m_impl) |
| 414 if (!m_impl) | 514 return @""; |
| 415 return @""; | 515 return *m_impl; |
| 416 return *m_impl; | 516 } |
| 417 } | |
| 418 #endif | 517 #endif |
| 419 | 518 |
| 420 static String make8BitFrom16BitSource(const UChar*, size_t); | 519 static String make8BitFrom16BitSource(const UChar*, size_t); |
| 421 template<size_t inlineCapacity> | 520 template <size_t inlineCapacity> |
| 422 static String make8BitFrom16BitSource(const Vector<UChar, inlineCapacity>& b
uffer) | 521 static String make8BitFrom16BitSource( |
| 423 { | 522 const Vector<UChar, inlineCapacity>& buffer) { |
| 424 return make8BitFrom16BitSource(buffer.data(), buffer.size()); | 523 return make8BitFrom16BitSource(buffer.data(), buffer.size()); |
| 425 } | 524 } |
| 426 | 525 |
| 427 static String make16BitFrom8BitSource(const LChar*, size_t); | 526 static String make16BitFrom8BitSource(const LChar*, size_t); |
| 428 | 527 |
| 429 // String::fromUTF8 will return a null string if | 528 // String::fromUTF8 will return a null string if |
| 430 // the input data contains invalid UTF-8 sequences. | 529 // the input data contains invalid UTF-8 sequences. |
| 431 static String fromUTF8(const LChar*, size_t); | 530 static String fromUTF8(const LChar*, size_t); |
| 432 static String fromUTF8(const LChar*); | 531 static String fromUTF8(const LChar*); |
| 433 static String fromUTF8(const char* s, size_t length) { return fromUTF8(reint
erpret_cast<const LChar*>(s), length); } | 532 static String fromUTF8(const char* s, size_t length) { |
| 434 static String fromUTF8(const char* s) { return fromUTF8(reinterpret_cast<con
st LChar*>(s)); } | 533 return fromUTF8(reinterpret_cast<const LChar*>(s), length); |
| 435 static String fromUTF8(const CString&); | 534 } |
| 436 | 535 static String fromUTF8(const char* s) { |
| 437 // Tries to convert the passed in string to UTF-8, but will fall back to | 536 return fromUTF8(reinterpret_cast<const LChar*>(s)); |
| 438 // Latin-1 if the string is not valid UTF-8. | 537 } |
| 439 static String fromUTF8WithLatin1Fallback(const LChar*, size_t); | 538 static String fromUTF8(const CString&); |
| 440 static String fromUTF8WithLatin1Fallback(const char* s, size_t length) { ret
urn fromUTF8WithLatin1Fallback(reinterpret_cast<const LChar*>(s), length); } | 539 |
| 441 | 540 // Tries to convert the passed in string to UTF-8, but will fall back to |
| 442 bool containsOnlyASCII() const; | 541 // Latin-1 if the string is not valid UTF-8. |
| 443 bool containsOnlyLatin1() const; | 542 static String fromUTF8WithLatin1Fallback(const LChar*, size_t); |
| 444 bool containsOnlyWhitespace() const { return !m_impl || m_impl->containsOnly
Whitespace(); } | 543 static String fromUTF8WithLatin1Fallback(const char* s, size_t length) { |
| 445 | 544 return fromUTF8WithLatin1Fallback(reinterpret_cast<const LChar*>(s), |
| 446 // Hash table deleted values, which are only constructed and never copied or | 545 length); |
| 447 // destroyed. | 546 } |
| 448 String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue)
{ } | 547 |
| 449 bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue
(); } | 548 bool containsOnlyASCII() const; |
| 549 bool containsOnlyLatin1() const; |
| 550 bool containsOnlyWhitespace() const { |
| 551 return !m_impl || m_impl->containsOnlyWhitespace(); |
| 552 } |
| 553 |
| 554 // Hash table deleted values, which are only constructed and never copied or |
| 555 // destroyed. |
| 556 String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) {} |
| 557 bool isHashTableDeletedValue() const { |
| 558 return m_impl.isHashTableDeletedValue(); |
| 559 } |
| 450 | 560 |
| 451 #ifndef NDEBUG | 561 #ifndef NDEBUG |
| 452 void show() const; | 562 void show() const; |
| 453 #endif | 563 #endif |
| 454 | 564 |
| 455 // Workaround for a compiler bug. Use operator[] instead. | 565 // Workaround for a compiler bug. Use operator[] instead. |
| 456 UChar characterAt(unsigned index) const | 566 UChar characterAt(unsigned index) const { |
| 457 { | 567 if (!m_impl || index >= m_impl->length()) |
| 458 if (!m_impl || index >= m_impl->length()) | 568 return 0; |
| 459 return 0; | 569 return (*m_impl)[index]; |
| 460 return (*m_impl)[index]; | 570 } |
| 461 } | 571 |
| 462 | 572 private: |
| 463 private: | 573 typedef struct ImplicitConversionFromWTFStringToBoolDisallowed*( |
| 464 typedef struct ImplicitConversionFromWTFStringToBoolDisallowed* (String::*Un
specifiedBoolType); | 574 String::*UnspecifiedBoolType); |
| 465 operator UnspecifiedBoolType() const; | 575 operator UnspecifiedBoolType() const; |
| 466 | 576 |
| 467 template <typename CharacterType> | 577 template <typename CharacterType> |
| 468 void removeInternal(const CharacterType*, unsigned, int); | 578 void removeInternal(const CharacterType*, unsigned, int); |
| 469 | 579 |
| 470 template <typename CharacterType> | 580 template <typename CharacterType> |
| 471 void appendInternal(CharacterType); | 581 void appendInternal(CharacterType); |
| 472 | 582 |
| 473 RefPtr<StringImpl> m_impl; | 583 RefPtr<StringImpl> m_impl; |
| 474 }; | 584 }; |
| 475 | 585 |
| 476 #undef DISPATCH_CASE_OP | 586 #undef DISPATCH_CASE_OP |
| 477 | 587 |
| 478 inline bool operator==(const String& a, const String& b) { return equal(a.impl()
, b.impl()); } | 588 inline bool operator==(const String& a, const String& b) { |
| 479 inline bool operator==(const String& a, const LChar* b) { return equal(a.impl(),
b); } | 589 return equal(a.impl(), b.impl()); |
| 480 inline bool operator==(const String& a, const char* b) { return equal(a.impl(),
reinterpret_cast<const LChar*>(b)); } | 590 } |
| 481 inline bool operator==(const LChar* a, const String& b) { return equal(a, b.impl
()); } | 591 inline bool operator==(const String& a, const LChar* b) { |
| 482 inline bool operator==(const char* a, const String& b) { return equal(reinterpre
t_cast<const LChar*>(a), b.impl()); } | 592 return equal(a.impl(), b); |
| 483 template<size_t inlineCapacity> | 593 } |
| 484 inline bool operator==(const Vector<char, inlineCapacity>& a, const String& b) {
return equal(b.impl(), a.data(), a.size()); } | 594 inline bool operator==(const String& a, const char* b) { |
| 485 template<size_t inlineCapacity> | 595 return equal(a.impl(), reinterpret_cast<const LChar*>(b)); |
| 486 inline bool operator==(const String& a, const Vector<char, inlineCapacity>& b) {
return b == a; } | 596 } |
| 487 | 597 inline bool operator==(const LChar* a, const String& b) { |
| 488 | 598 return equal(a, b.impl()); |
| 489 inline bool operator!=(const String& a, const String& b) { return !equal(a.impl(
), b.impl()); } | 599 } |
| 490 inline bool operator!=(const String& a, const LChar* b) { return !equal(a.impl()
, b); } | 600 inline bool operator==(const char* a, const String& b) { |
| 491 inline bool operator!=(const String& a, const char* b) { return !equal(a.impl(),
reinterpret_cast<const LChar*>(b)); } | 601 return equal(reinterpret_cast<const LChar*>(a), b.impl()); |
| 492 inline bool operator!=(const LChar* a, const String& b) { return !equal(a, b.imp
l()); } | 602 } |
| 493 inline bool operator!=(const char* a, const String& b) { return !equal(reinterpr
et_cast<const LChar*>(a), b.impl()); } | 603 template <size_t inlineCapacity> |
| 494 template<size_t inlineCapacity> | 604 inline bool operator==(const Vector<char, inlineCapacity>& a, const String& b) { |
| 495 inline bool operator!=(const Vector<char, inlineCapacity>& a, const String& b) {
return !(a == b); } | 605 return equal(b.impl(), a.data(), a.size()); |
| 496 template<size_t inlineCapacity> | 606 } |
| 497 inline bool operator!=(const String& a, const Vector<char, inlineCapacity>& b) {
return b != a; } | 607 template <size_t inlineCapacity> |
| 498 | 608 inline bool operator==(const String& a, const Vector<char, inlineCapacity>& b) { |
| 499 inline bool equalIgnoringCase(const String& a, const String& b) { return equalIg
noringCase(a.impl(), b.impl()); } | 609 return b == a; |
| 500 inline bool equalIgnoringCase(const String& a, const LChar* b) { return equalIgn
oringCase(a.impl(), b); } | 610 } |
| 501 inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgno
ringCase(a.impl(), reinterpret_cast<const LChar*>(b)); } | 611 |
| 502 inline bool equalIgnoringCase(const LChar* a, const String& b) { return equalIgn
oringCase(a, b.impl()); } | 612 inline bool operator!=(const String& a, const String& b) { |
| 503 inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgno
ringCase(reinterpret_cast<const LChar*>(a), b.impl()); } | 613 return !equal(a.impl(), b.impl()); |
| 504 | 614 } |
| 505 inline bool equalPossiblyIgnoringCase(const String& a, const String& b, bool ign
oreCase) | 615 inline bool operator!=(const String& a, const LChar* b) { |
| 506 { | 616 return !equal(a.impl(), b); |
| 507 return ignoreCase ? equalIgnoringCase(a, b) : (a == b); | 617 } |
| 508 } | 618 inline bool operator!=(const String& a, const char* b) { |
| 509 | 619 return !equal(a.impl(), reinterpret_cast<const LChar*>(b)); |
| 510 inline bool equalIgnoringNullity(const String& a, const String& b) { return equa
lIgnoringNullity(a.impl(), b.impl()); } | 620 } |
| 511 | 621 inline bool operator!=(const LChar* a, const String& b) { |
| 512 template<size_t inlineCapacity> | 622 return !equal(a, b.impl()); |
| 513 inline bool equalIgnoringNullity(const Vector<UChar, inlineCapacity>& a, const S
tring& b) { return equalIgnoringNullity(a, b.impl()); } | 623 } |
| 514 | 624 inline bool operator!=(const char* a, const String& b) { |
| 515 inline bool operator!(const String& str) { return str.isNull(); } | 625 return !equal(reinterpret_cast<const LChar*>(a), b.impl()); |
| 516 | 626 } |
| 517 inline void swap(String& a, String& b) { a.swap(b); } | 627 template <size_t inlineCapacity> |
| 628 inline bool operator!=(const Vector<char, inlineCapacity>& a, const String& b) { |
| 629 return !(a == b); |
| 630 } |
| 631 template <size_t inlineCapacity> |
| 632 inline bool operator!=(const String& a, const Vector<char, inlineCapacity>& b) { |
| 633 return b != a; |
| 634 } |
| 635 |
| 636 inline bool equalIgnoringCase(const String& a, const String& b) { |
| 637 return equalIgnoringCase(a.impl(), b.impl()); |
| 638 } |
| 639 inline bool equalIgnoringCase(const String& a, const LChar* b) { |
| 640 return equalIgnoringCase(a.impl(), b); |
| 641 } |
| 642 inline bool equalIgnoringCase(const String& a, const char* b) { |
| 643 return equalIgnoringCase(a.impl(), reinterpret_cast<const LChar*>(b)); |
| 644 } |
| 645 inline bool equalIgnoringCase(const LChar* a, const String& b) { |
| 646 return equalIgnoringCase(a, b.impl()); |
| 647 } |
| 648 inline bool equalIgnoringCase(const char* a, const String& b) { |
| 649 return equalIgnoringCase(reinterpret_cast<const LChar*>(a), b.impl()); |
| 650 } |
| 651 |
| 652 inline bool equalPossiblyIgnoringCase(const String& a, |
| 653 const String& b, |
| 654 bool ignoreCase) { |
| 655 return ignoreCase ? equalIgnoringCase(a, b) : (a == b); |
| 656 } |
| 657 |
| 658 inline bool equalIgnoringNullity(const String& a, const String& b) { |
| 659 return equalIgnoringNullity(a.impl(), b.impl()); |
| 660 } |
| 661 |
| 662 template <size_t inlineCapacity> |
| 663 inline bool equalIgnoringNullity(const Vector<UChar, inlineCapacity>& a, |
| 664 const String& b) { |
| 665 return equalIgnoringNullity(a, b.impl()); |
| 666 } |
| 667 |
| 668 inline bool operator!(const String& str) { |
| 669 return str.isNull(); |
| 670 } |
| 671 |
| 672 inline void swap(String& a, String& b) { |
| 673 a.swap(b); |
| 674 } |
| 518 | 675 |
| 519 // Definitions of string operations | 676 // Definitions of string operations |
| 520 | 677 |
| 521 template<size_t inlineCapacity> | 678 template <size_t inlineCapacity> |
| 522 String::String(const Vector<UChar, inlineCapacity>& vector) | 679 String::String(const Vector<UChar, inlineCapacity>& vector) |
| 523 : m_impl(vector.size() ? StringImpl::create(vector.data(), vector.size()) :
StringImpl::empty()) | 680 : m_impl(vector.size() ? StringImpl::create(vector.data(), vector.size()) |
| 524 { | 681 : StringImpl::empty()) {} |
| 525 } | 682 |
| 526 | 683 template <> |
| 527 template<> | 684 inline const LChar* String::getCharacters<LChar>() const { |
| 528 inline const LChar* String::getCharacters<LChar>() const | 685 ASSERT(is8Bit()); |
| 529 { | 686 return characters8(); |
| 530 ASSERT(is8Bit()); | 687 } |
| 531 return characters8(); | 688 |
| 532 } | 689 template <> |
| 533 | 690 inline const UChar* String::getCharacters<UChar>() const { |
| 534 template<> | 691 ASSERT(!is8Bit()); |
| 535 inline const UChar* String::getCharacters<UChar>() const | 692 return characters16(); |
| 536 { | 693 } |
| 537 ASSERT(!is8Bit()); | 694 |
| 538 return characters16(); | 695 inline bool String::containsOnlyLatin1() const { |
| 539 } | 696 if (isEmpty()) |
| 540 | 697 return true; |
| 541 inline bool String::containsOnlyLatin1() const | 698 |
| 542 { | 699 if (is8Bit()) |
| 543 if (isEmpty()) | 700 return true; |
| 544 return true; | 701 |
| 545 | 702 const UChar* characters = characters16(); |
| 546 if (is8Bit()) | 703 UChar ored = 0; |
| 547 return true; | 704 for (size_t i = 0; i < m_impl->length(); ++i) |
| 548 | 705 ored |= characters[i]; |
| 549 const UChar* characters = characters16(); | 706 return !(ored & 0xFF00); |
| 550 UChar ored = 0; | 707 } |
| 551 for (size_t i = 0; i < m_impl->length(); ++i) | |
| 552 ored |= characters[i]; | |
| 553 return !(ored & 0xFF00); | |
| 554 } | |
| 555 | |
| 556 | 708 |
| 557 #ifdef __OBJC__ | 709 #ifdef __OBJC__ |
| 558 // This is for situations in WebKit where the long standing behavior has been | 710 // This is for situations in WebKit where the long standing behavior has been |
| 559 // "nil if empty", so we try to maintain longstanding behavior for the sake of | 711 // "nil if empty", so we try to maintain longstanding behavior for the sake of |
| 560 // entrenched clients | 712 // entrenched clients |
| 561 inline NSString* nsStringNilIfEmpty(const String& str) { return str.isEmpty() ?
nil : (NSString*)str; } | 713 inline NSString* nsStringNilIfEmpty(const String& str) { |
| 714 return str.isEmpty() ? nil : (NSString*)str; |
| 715 } |
| 562 #endif | 716 #endif |
| 563 | 717 |
| 564 inline bool String::containsOnlyASCII() const | 718 inline bool String::containsOnlyASCII() const { |
| 565 { | 719 if (isEmpty()) |
| 566 if (isEmpty()) | 720 return true; |
| 567 return true; | 721 |
| 568 | 722 if (is8Bit()) |
| 569 if (is8Bit()) | 723 return charactersAreAllASCII(characters8(), m_impl->length()); |
| 570 return charactersAreAllASCII(characters8(), m_impl->length()); | 724 |
| 571 | 725 return charactersAreAllASCII(characters16(), m_impl->length()); |
| 572 return charactersAreAllASCII(characters16(), m_impl->length()); | |
| 573 } | 726 } |
| 574 | 727 |
| 575 WTF_EXPORT int codePointCompare(const String&, const String&); | 728 WTF_EXPORT int codePointCompare(const String&, const String&); |
| 576 | 729 |
| 577 inline bool codePointCompareLessThan(const String& a, const String& b) | 730 inline bool codePointCompareLessThan(const String& a, const String& b) { |
| 578 { | 731 return codePointCompare(a.impl(), b.impl()) < 0; |
| 579 return codePointCompare(a.impl(), b.impl()) < 0; | 732 } |
| 580 } | 733 |
| 581 | 734 template <size_t inlineCapacity> |
| 582 template<size_t inlineCapacity> | 735 inline void append(Vector<UChar, inlineCapacity>& vector, |
| 583 inline void append(Vector<UChar, inlineCapacity>& vector, const String& string) | 736 const String& string) { |
| 584 { | 737 unsigned length = string.length(); |
| 585 unsigned length = string.length(); | 738 if (!length) |
| 586 if (!length) | 739 return; |
| 587 return; | 740 if (string.is8Bit()) { |
| 588 if (string.is8Bit()) { | 741 const LChar* characters8 = string.characters8(); |
| 589 const LChar* characters8 = string.characters8(); | 742 vector.reserveCapacity(vector.size() + length); |
| 590 vector.reserveCapacity(vector.size() + length); | 743 for (size_t i = 0; i < length; ++i) |
| 591 for (size_t i = 0; i < length; ++i) | 744 vector.uncheckedAppend(characters8[i]); |
| 592 vector.uncheckedAppend(characters8[i]); | 745 } else { |
| 593 } else { | 746 vector.append(string.characters16(), length); |
| 594 vector.append(string.characters16(), length); | 747 } |
| 595 } | 748 } |
| 596 } | 749 |
| 597 | 750 template <bool isSpecialCharacter(UChar), typename CharacterType> |
| 598 template<bool isSpecialCharacter(UChar), typename CharacterType> | 751 inline bool isAllSpecialCharacters(const CharacterType* characters, |
| 599 inline bool isAllSpecialCharacters(const CharacterType* characters, size_t lengt
h) | 752 size_t length) { |
| 600 { | 753 for (size_t i = 0; i < length; ++i) { |
| 601 for (size_t i = 0; i < length; ++i) { | 754 if (!isSpecialCharacter(characters[i])) |
| 602 if (!isSpecialCharacter(characters[i])) | 755 return false; |
| 603 return false; | 756 } |
| 604 } | 757 return true; |
| 758 } |
| 759 |
| 760 template <bool isSpecialCharacter(UChar)> |
| 761 inline bool String::isAllSpecialCharacters() const { |
| 762 size_t len = length(); |
| 763 |
| 764 if (!len) |
| 605 return true; | 765 return true; |
| 606 } | 766 |
| 607 | 767 if (is8Bit()) |
| 608 template<bool isSpecialCharacter(UChar)> | 768 return WTF::isAllSpecialCharacters<isSpecialCharacter, LChar>(characters8(), |
| 609 inline bool String::isAllSpecialCharacters() const | 769 len); |
| 610 { | 770 return WTF::isAllSpecialCharacters<isSpecialCharacter, UChar>(characters16(), |
| 611 size_t len = length(); | 771 len); |
| 612 | 772 } |
| 613 if (!len) | 773 |
| 614 return true; | 774 template <size_t inlineCapacity> |
| 615 | 775 inline void String::appendTo(Vector<UChar, inlineCapacity>& result, |
| 616 if (is8Bit()) | 776 unsigned pos, |
| 617 return WTF::isAllSpecialCharacters<isSpecialCharacter, LChar>(characters
8(), len); | 777 unsigned len) const { |
| 618 return WTF::isAllSpecialCharacters<isSpecialCharacter, UChar>(characters16()
, len); | 778 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); |
| 619 } | 779 if (!numberOfCharactersToCopy) |
| 620 | 780 return; |
| 621 template<size_t inlineCapacity> | 781 result.reserveCapacity(result.size() + numberOfCharactersToCopy); |
| 622 inline void String::appendTo(Vector<UChar, inlineCapacity>& result, unsigned pos
, unsigned len) const | 782 if (is8Bit()) { |
| 623 { | 783 const LChar* characters8 = m_impl->characters8(); |
| 624 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); | 784 for (size_t i = 0; i < numberOfCharactersToCopy; ++i) |
| 625 if (!numberOfCharactersToCopy) | 785 result.uncheckedAppend(characters8[pos + i]); |
| 626 return; | 786 } else { |
| 627 result.reserveCapacity(result.size() + numberOfCharactersToCopy); | 787 const UChar* characters16 = m_impl->characters16(); |
| 628 if (is8Bit()) { | 788 result.append(characters16 + pos, numberOfCharactersToCopy); |
| 629 const LChar* characters8 = m_impl->characters8(); | 789 } |
| 630 for (size_t i = 0; i < numberOfCharactersToCopy; ++i) | 790 } |
| 631 result.uncheckedAppend(characters8[pos + i]); | 791 |
| 632 } else { | 792 template <typename BufferType> |
| 633 const UChar* characters16 = m_impl->characters16(); | 793 inline void String::appendTo(BufferType& result, |
| 634 result.append(characters16 + pos, numberOfCharactersToCopy); | 794 unsigned pos, |
| 635 } | 795 unsigned len) const { |
| 636 } | 796 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); |
| 637 | 797 if (!numberOfCharactersToCopy) |
| 638 template<typename BufferType> | 798 return; |
| 639 inline void String::appendTo(BufferType& result, unsigned pos, unsigned len) con
st | 799 if (is8Bit()) |
| 640 { | 800 result.append(m_impl->characters8() + pos, numberOfCharactersToCopy); |
| 641 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); | 801 else |
| 642 if (!numberOfCharactersToCopy) | 802 result.append(m_impl->characters16() + pos, numberOfCharactersToCopy); |
| 643 return; | 803 } |
| 644 if (is8Bit()) | 804 |
| 645 result.append(m_impl->characters8() + pos, numberOfCharactersToCopy); | 805 template <size_t inlineCapacity> |
| 646 else | 806 inline void String::prependTo(Vector<UChar, inlineCapacity>& result, |
| 647 result.append(m_impl->characters16() + pos, numberOfCharactersToCopy); | 807 unsigned pos, |
| 648 } | 808 unsigned len) const { |
| 649 | 809 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); |
| 650 template<size_t inlineCapacity> | 810 if (!numberOfCharactersToCopy) |
| 651 inline void String::prependTo(Vector<UChar, inlineCapacity>& result, unsigned po
s, unsigned len) const | 811 return; |
| 652 { | 812 if (is8Bit()) { |
| 653 unsigned numberOfCharactersToCopy = std::min(len, length() - pos); | 813 size_t oldSize = result.size(); |
| 654 if (!numberOfCharactersToCopy) | 814 result.resize(oldSize + numberOfCharactersToCopy); |
| 655 return; | 815 memmove(result.data() + numberOfCharactersToCopy, result.data(), |
| 656 if (is8Bit()) { | 816 oldSize * sizeof(UChar)); |
| 657 size_t oldSize = result.size(); | 817 StringImpl::copyChars(result.data(), m_impl->characters8() + pos, |
| 658 result.resize(oldSize + numberOfCharactersToCopy); | 818 numberOfCharactersToCopy); |
| 659 memmove(result.data() + numberOfCharactersToCopy, result.data(), oldSize
* sizeof(UChar)); | 819 } else { |
| 660 StringImpl::copyChars(result.data(), m_impl->characters8() + pos, number
OfCharactersToCopy); | 820 result.prepend(m_impl->characters16() + pos, numberOfCharactersToCopy); |
| 661 } else { | 821 } |
| 662 result.prepend(m_impl->characters16() + pos, numberOfCharactersToCopy); | |
| 663 } | |
| 664 } | 822 } |
| 665 | 823 |
| 666 // StringHash is the default hash for String | 824 // StringHash is the default hash for String |
| 667 template<typename T> struct DefaultHash; | 825 template <typename T> |
| 668 template<> struct DefaultHash<String> { | 826 struct DefaultHash; |
| 669 typedef StringHash Hash; | 827 template <> |
| 828 struct DefaultHash<String> { |
| 829 typedef StringHash Hash; |
| 670 }; | 830 }; |
| 671 | 831 |
| 672 // Shared global empty string. | 832 // Shared global empty string. |
| 673 WTF_EXPORT const String& emptyString(); | 833 WTF_EXPORT const String& emptyString(); |
| 674 WTF_EXPORT const String& emptyString16Bit(); | 834 WTF_EXPORT const String& emptyString16Bit(); |
| 675 WTF_EXPORT extern const String& xmlnsWithColon; | 835 WTF_EXPORT extern const String& xmlnsWithColon; |
| 676 | 836 |
| 677 // Pretty printer for gtest. Declared here to avoid ODR violations. | 837 // Pretty printer for gtest. Declared here to avoid ODR violations. |
| 678 WTF_UNITTEST_HELPERS_EXPORT std::ostream& operator<<(std::ostream&, const String
&); | 838 WTF_UNITTEST_HELPERS_EXPORT std::ostream& operator<<(std::ostream&, |
| 839 const String&); |
| 679 | 840 |
| 680 } // namespace WTF | 841 } // namespace WTF |
| 681 | 842 |
| 682 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(String); | 843 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(String); |
| 683 | 844 |
| 684 using WTF::CString; | 845 using WTF::CString; |
| 685 using WTF::KeepTrailingZeros; | 846 using WTF::KeepTrailingZeros; |
| 686 using WTF::StrictUTF8Conversion; | 847 using WTF::StrictUTF8Conversion; |
| 687 using WTF::StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD; | 848 using WTF::StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD; |
| 688 using WTF::String; | 849 using WTF::String; |
| 689 using WTF::emptyString; | 850 using WTF::emptyString; |
| 690 using WTF::emptyString16Bit; | 851 using WTF::emptyString16Bit; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 701 using WTF::charactersToDouble; | 862 using WTF::charactersToDouble; |
| 702 using WTF::charactersToFloat; | 863 using WTF::charactersToFloat; |
| 703 using WTF::equal; | 864 using WTF::equal; |
| 704 using WTF::equalIgnoringCase; | 865 using WTF::equalIgnoringCase; |
| 705 using WTF::find; | 866 using WTF::find; |
| 706 using WTF::isAllSpecialCharacters; | 867 using WTF::isAllSpecialCharacters; |
| 707 using WTF::isSpaceOrNewline; | 868 using WTF::isSpaceOrNewline; |
| 708 using WTF::reverseFind; | 869 using WTF::reverseFind; |
| 709 | 870 |
| 710 #include "wtf/text/AtomicString.h" | 871 #include "wtf/text/AtomicString.h" |
| 711 #endif // WTFString_h | 872 #endif // WTFString_h |
| OLD | NEW |