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, 2010, 2012 Apple Inc. All rights
reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights
reserved. |
4 * Copyright (C) 2007-2009 Torch Mobile, Inc. | 4 * Copyright (C) 2007-2009 Torch Mobile, Inc. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "wtf/MathExtras.h" | 29 #include "wtf/MathExtras.h" |
30 #include "wtf/StringExtras.h" | 30 #include "wtf/StringExtras.h" |
31 #include "wtf/Vector.h" | 31 #include "wtf/Vector.h" |
32 #include "wtf/dtoa.h" | 32 #include "wtf/dtoa.h" |
33 #include "wtf/text/CString.h" | 33 #include "wtf/text/CString.h" |
34 #include "wtf/text/CharacterNames.h" | 34 #include "wtf/text/CharacterNames.h" |
35 #include "wtf/text/UTF8.h" | 35 #include "wtf/text/UTF8.h" |
36 #include "wtf/text/Unicode.h" | 36 #include "wtf/text/Unicode.h" |
37 #include <stdarg.h> | 37 #include <stdarg.h> |
38 | 38 |
39 using namespace std; | |
40 | |
41 namespace WTF { | 39 namespace WTF { |
42 | 40 |
43 using namespace Unicode; | 41 using namespace Unicode; |
44 using namespace std; | |
45 | 42 |
46 // Construct a string with UTF-16 data. | 43 // Construct a string with UTF-16 data. |
47 String::String(const UChar* characters, unsigned length) | 44 String::String(const UChar* characters, unsigned length) |
48 : m_impl(characters ? StringImpl::create(characters, length) : nullptr) | 45 : m_impl(characters ? StringImpl::create(characters, length) : nullptr) |
49 { | 46 { |
50 } | 47 } |
51 | 48 |
52 // Construct a string with UTF-16 data, from a null-terminated source. | 49 // Construct a string with UTF-16 data, from a null-terminated source. |
53 String::String(const UChar* str) | 50 String::String(const UChar* str) |
54 { | 51 { |
(...skipping 26 matching lines...) Expand all Loading... |
81 | 78 |
82 void String::append(const String& string) | 79 void String::append(const String& string) |
83 { | 80 { |
84 if (string.isEmpty()) | 81 if (string.isEmpty()) |
85 return; | 82 return; |
86 if (!m_impl) { | 83 if (!m_impl) { |
87 m_impl = string.m_impl; | 84 m_impl = string.m_impl; |
88 return; | 85 return; |
89 } | 86 } |
90 | 87 |
91 // FIXME: This is extremely inefficient. So much so that we might want to ta
ke this | 88 // FIXME: This is extremely inefficient. So much so that we might want to |
92 // out of String's API. We can make it better by optimizing the case where e
xactly | 89 // take this out of String's API. We can make it better by optimizing the |
93 // one String is pointing at this StringImpl, but even then it's going to re
quire a | 90 // case where exactly one String is pointing at this StringImpl, but even |
94 // call into the allocator every single time. | 91 // then it's going to require a call into the allocator every single time. |
95 | 92 |
96 if (m_impl->is8Bit() && string.m_impl->is8Bit()) { | 93 if (m_impl->is8Bit() && string.m_impl->is8Bit()) { |
97 LChar* data; | 94 LChar* data; |
98 RELEASE_ASSERT(string.length() <= numeric_limits<unsigned>::max() - m_im
pl->length()); | 95 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() -
m_impl->length()); |
99 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->len
gth() + string.length(), data); | 96 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->len
gth() + string.length(), data); |
100 memcpy(data, m_impl->characters8(), m_impl->length() * sizeof(LChar)); | 97 memcpy(data, m_impl->characters8(), m_impl->length() * sizeof(LChar)); |
101 memcpy(data + m_impl->length(), string.characters8(), string.length() *
sizeof(LChar)); | 98 memcpy(data + m_impl->length(), string.characters8(), string.length() *
sizeof(LChar)); |
102 m_impl = newImpl.release(); | 99 m_impl = newImpl.release(); |
103 return; | 100 return; |
104 } | 101 } |
105 | 102 |
106 UChar* data; | 103 UChar* data; |
107 RELEASE_ASSERT(string.length() <= numeric_limits<unsigned>::max() - m_impl->
length()); | 104 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_i
mpl->length()); |
108 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + string.length(), data); | 105 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + string.length(), data); |
109 | 106 |
110 if (m_impl->is8Bit()) | 107 if (m_impl->is8Bit()) |
111 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); | 108 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); |
112 else | 109 else |
113 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); | 110 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); |
114 | 111 |
115 if (string.impl()->is8Bit()) | 112 if (string.impl()->is8Bit()) |
116 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
8(), string.impl()->length()); | 113 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
8(), string.impl()->length()); |
117 else | 114 else |
118 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
16(), string.impl()->length()); | 115 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
16(), string.impl()->length()); |
119 | 116 |
120 m_impl = newImpl.release(); | 117 m_impl = newImpl.release(); |
121 } | 118 } |
122 | 119 |
123 template <typename CharacterType> | 120 template <typename CharacterType> |
124 inline void String::appendInternal(CharacterType c) | 121 inline void String::appendInternal(CharacterType c) |
125 { | 122 { |
126 // FIXME: This is extremely inefficient. So much so that we might want to ta
ke this | 123 // FIXME: This is extremely inefficient. So much so that we might want to |
127 // out of String's API. We can make it better by optimizing the case where e
xactly | 124 // take this out of String's API. We can make it better by optimizing the |
128 // one String is pointing at this StringImpl, but even then it's going to re
quire a | 125 // case where exactly one String is pointing at this StringImpl, but even |
129 // call into the allocator every single time. | 126 // then it's going to require a call into the allocator every single time. |
130 if (!m_impl) { | 127 if (!m_impl) { |
131 m_impl = StringImpl::create(&c, 1); | 128 m_impl = StringImpl::create(&c, 1); |
132 return; | 129 return; |
133 } | 130 } |
134 | 131 |
135 UChar* data; // FIXME: We should be able to create an 8 bit string via this
code path. | 132 // FIXME: We should be able to create an 8 bit string via this code path. |
136 RELEASE_ASSERT(m_impl->length() < numeric_limits<unsigned>::max()); | 133 UChar* data; |
| 134 RELEASE_ASSERT(m_impl->length() < std::numeric_limits<unsigned>::max()); |
137 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + 1, data); | 135 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + 1, data); |
138 if (m_impl->is8Bit()) | 136 if (m_impl->is8Bit()) |
139 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); | 137 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); |
140 else | 138 else |
141 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); | 139 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); |
142 data[m_impl->length()] = c; | 140 data[m_impl->length()] = c; |
143 m_impl = newImpl.release(); | 141 m_impl = newImpl.release(); |
144 } | 142 } |
145 | 143 |
146 void String::append(LChar c) | 144 void String::append(LChar c) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 } | 182 } |
185 | 183 |
186 if (!lengthToAppend) | 184 if (!lengthToAppend) |
187 return; | 185 return; |
188 | 186 |
189 ASSERT(charactersToAppend); | 187 ASSERT(charactersToAppend); |
190 | 188 |
191 unsigned strLength = m_impl->length(); | 189 unsigned strLength = m_impl->length(); |
192 | 190 |
193 if (m_impl->is8Bit()) { | 191 if (m_impl->is8Bit()) { |
194 RELEASE_ASSERT(lengthToAppend <= numeric_limits<unsigned>::max() - strLe
ngth); | 192 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() -
strLength); |
195 LChar* data; | 193 LChar* data; |
196 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength +
lengthToAppend, data); | 194 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength +
lengthToAppend, data); |
197 StringImpl::copyChars(data, m_impl->characters8(), strLength); | 195 StringImpl::copyChars(data, m_impl->characters8(), strLength); |
198 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppe
nd); | 196 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppe
nd); |
199 m_impl = newImpl.release(); | 197 m_impl = newImpl.release(); |
200 return; | 198 return; |
201 } | 199 } |
202 | 200 |
203 RELEASE_ASSERT(lengthToAppend <= numeric_limits<unsigned>::max() - strLength
); | 201 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL
ength); |
204 UChar* data; | 202 UChar* data; |
205 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + leng
thToAppend, data); | 203 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + leng
thToAppend, data); |
206 StringImpl::copyChars(data, m_impl->characters16(), strLength); | 204 StringImpl::copyChars(data, m_impl->characters16(), strLength); |
207 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); | 205 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); |
208 m_impl = newImpl.release(); | 206 m_impl = newImpl.release(); |
209 } | 207 } |
210 | 208 |
211 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) | 209 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) |
212 { | 210 { |
213 if (!m_impl) { | 211 if (!m_impl) { |
214 if (!charactersToAppend) | 212 if (!charactersToAppend) |
215 return; | 213 return; |
216 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); | 214 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); |
217 return; | 215 return; |
218 } | 216 } |
219 | 217 |
220 if (!lengthToAppend) | 218 if (!lengthToAppend) |
221 return; | 219 return; |
222 | 220 |
223 unsigned strLength = m_impl->length(); | 221 unsigned strLength = m_impl->length(); |
224 | 222 |
225 ASSERT(charactersToAppend); | 223 ASSERT(charactersToAppend); |
226 RELEASE_ASSERT(lengthToAppend <= numeric_limits<unsigned>::max() - strLength
); | 224 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL
ength); |
227 UChar* data; | 225 UChar* data; |
228 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + len
gthToAppend, data); | 226 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + len
gthToAppend, data); |
229 if (m_impl->is8Bit()) | 227 if (m_impl->is8Bit()) |
230 StringImpl::copyChars(data, characters8(), strLength); | 228 StringImpl::copyChars(data, characters8(), strLength); |
231 else | 229 else |
232 StringImpl::copyChars(data, characters16(), strLength); | 230 StringImpl::copyChars(data, characters16(), strLength); |
233 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); | 231 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); |
234 m_impl = newImpl.release(); | 232 m_impl = newImpl.release(); |
235 } | 233 } |
236 | 234 |
237 template<typename CharType> | 235 template<typename CharType> |
238 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp
e* charactersToInsert, unsigned lengthToInsert, unsigned position) | 236 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp
e* charactersToInsert, unsigned lengthToInsert, unsigned position) |
239 { | 237 { |
240 if (!lengthToInsert) | 238 if (!lengthToInsert) |
241 return impl; | 239 return impl; |
242 | 240 |
243 ASSERT(charactersToInsert); | 241 ASSERT(charactersToInsert); |
244 UChar* data; // FIXME: We should be able to create an 8 bit string here. | 242 UChar* data; // FIXME: We should be able to create an 8 bit string here. |
245 RELEASE_ASSERT(lengthToInsert <= numeric_limits<unsigned>::max() - impl->len
gth()); | 243 RELEASE_ASSERT(lengthToInsert <= std::numeric_limits<unsigned>::max() - impl
->length()); |
246 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length()
+ lengthToInsert, data); | 244 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length()
+ lengthToInsert, data); |
247 | 245 |
248 if (impl->is8Bit()) | 246 if (impl->is8Bit()) |
249 StringImpl::copyChars(data, impl->characters8(), position); | 247 StringImpl::copyChars(data, impl->characters8(), position); |
250 else | 248 else |
251 StringImpl::copyChars(data, impl->characters16(), position); | 249 StringImpl::copyChars(data, impl->characters16(), position); |
252 | 250 |
253 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert); | 251 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert); |
254 | 252 |
255 if (impl->is8Bit()) | 253 if (impl->is8Bit()) |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 // Allocate a buffer big enough to hold all the characters | 764 // Allocate a buffer big enough to hold all the characters |
767 // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). | 765 // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). |
768 // Optimization ideas, if we find this function is hot: | 766 // Optimization ideas, if we find this function is hot: |
769 // * We could speculatively create a CStringBuffer to contain 'length' | 767 // * We could speculatively create a CStringBuffer to contain 'length' |
770 // characters, and resize if necessary (i.e. if the buffer contains | 768 // characters, and resize if necessary (i.e. if the buffer contains |
771 // non-ascii characters). (Alternatively, scan the buffer first for | 769 // non-ascii characters). (Alternatively, scan the buffer first for |
772 // ascii characters, so we know this will be sufficient). | 770 // ascii characters, so we know this will be sufficient). |
773 // * We could allocate a CStringBuffer with an appropriate size to | 771 // * We could allocate a CStringBuffer with an appropriate size to |
774 // have a good chance of being able to write the string into the | 772 // have a good chance of being able to write the string into the |
775 // buffer without reallocing (say, 1.5 x length). | 773 // buffer without reallocing (say, 1.5 x length). |
776 if (length > numeric_limits<unsigned>::max() / 3) | 774 if (length > std::numeric_limits<unsigned>::max() / 3) |
777 return CString(); | 775 return CString(); |
778 Vector<char, 1024> bufferVector(length * 3); | 776 Vector<char, 1024> bufferVector(length * 3); |
779 | 777 |
780 char* buffer = bufferVector.data(); | 778 char* buffer = bufferVector.data(); |
781 | 779 |
782 if (is8Bit()) { | 780 if (is8Bit()) { |
783 const LChar* characters = this->characters8(); | 781 const LChar* characters = this->characters8(); |
784 | 782 |
785 ConversionResult result = convertLatin1ToUTF8(&characters, characters +
length, &buffer, buffer + bufferVector.size()); | 783 ConversionResult result = convertLatin1ToUTF8(&characters, characters +
length, &buffer, buffer + bufferVector.size()); |
786 ASSERT_UNUSED(result, result != targetExhausted); // (length * 3) should
be sufficient for any conversion | 784 ASSERT_UNUSED(result, result != targetExhausted); // (length * 3) should
be sufficient for any conversion |
787 } else { | 785 } else { |
788 const UChar* characters = this->characters16(); | 786 const UChar* characters = this->characters16(); |
789 | 787 |
790 if (mode == StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD) { | 788 if (mode == StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD) { |
791 const UChar* charactersEnd = characters + length; | 789 const UChar* charactersEnd = characters + length; |
792 char* bufferEnd = buffer + bufferVector.size(); | 790 char* bufferEnd = buffer + bufferVector.size(); |
793 while (characters < charactersEnd) { | 791 while (characters < charactersEnd) { |
794 // Use strict conversion to detect unpaired surrogates. | 792 // Use strict conversion to detect unpaired surrogates. |
795 ConversionResult result = convertUTF16ToUTF8(&characters, charac
tersEnd, &buffer, bufferEnd, true); | 793 ConversionResult result = convertUTF16ToUTF8(&characters, charac
tersEnd, &buffer, bufferEnd, true); |
796 ASSERT(result != targetExhausted); | 794 ASSERT(result != targetExhausted); |
797 // Conversion fails when there is an unpaired surrogate. | 795 // Conversion fails when there is an unpaired surrogate. Put |
798 // Put replacement character (U+FFFD) instead of the unpaired su
rrogate. | 796 // replacement character (U+FFFD) instead of the unpaired |
| 797 // surrogate. |
799 if (result != conversionOK) { | 798 if (result != conversionOK) { |
800 ASSERT((0xD800 <= *characters && *characters <= 0xDFFF)); | 799 ASSERT((0xD800 <= *characters && *characters <= 0xDFFF)); |
801 // There should be room left, since one UChar hasn't been co
nverted. | 800 // There should be room left, since one UChar hasn't been |
| 801 // converted. |
802 ASSERT((buffer + 3) <= bufferEnd); | 802 ASSERT((buffer + 3) <= bufferEnd); |
803 putUTF8Triple(buffer, replacementCharacter); | 803 putUTF8Triple(buffer, replacementCharacter); |
804 ++characters; | 804 ++characters; |
805 } | 805 } |
806 } | 806 } |
807 } else { | 807 } else { |
808 bool strict = mode == StrictUTF8Conversion; | 808 bool strict = mode == StrictUTF8Conversion; |
809 ConversionResult result = convertUTF16ToUTF8(&characters, characters
+ length, &buffer, buffer + bufferVector.size(), strict); | 809 ConversionResult result = convertUTF16ToUTF8(&characters, characters
+ length, &buffer, buffer + bufferVector.size(), strict); |
810 ASSERT(result != targetExhausted); // (length * 3) should be suffici
ent for any conversion | 810 ASSERT(result != targetExhausted); // (length * 3) should be suffici
ent for any conversion |
811 | 811 |
812 // Only produced from strict conversion. | 812 // Only produced from strict conversion. |
813 if (result == sourceIllegal) { | 813 if (result == sourceIllegal) { |
814 ASSERT(strict); | 814 ASSERT(strict); |
815 return CString(); | 815 return CString(); |
816 } | 816 } |
817 | 817 |
818 // Check for an unconverted high surrogate. | 818 // Check for an unconverted high surrogate. |
819 if (result == sourceExhausted) { | 819 if (result == sourceExhausted) { |
820 if (strict) | 820 if (strict) |
821 return CString(); | 821 return CString(); |
822 // This should be one unpaired high surrogate. Treat it the same | 822 // This should be one unpaired high surrogate. Treat it the same |
823 // was as an unpaired high surrogate would have been handled in | 823 // was as an unpaired high surrogate would have been handled in |
824 // the middle of a string with non-strict conversion - which is | 824 // the middle of a string with non-strict conversion - which is |
825 // to say, simply encode it to UTF-8. | 825 // to say, simply encode it to UTF-8. |
826 ASSERT((characters + 1) == (this->characters16() + length)); | 826 ASSERT((characters + 1) == (this->characters16() + length)); |
827 ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); | 827 ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); |
828 // There should be room left, since one UChar hasn't been conver
ted. | 828 // There should be room left, since one UChar hasn't been |
| 829 // converted. |
829 ASSERT((buffer + 3) <= (buffer + bufferVector.size())); | 830 ASSERT((buffer + 3) <= (buffer + bufferVector.size())); |
830 putUTF8Triple(buffer, *characters); | 831 putUTF8Triple(buffer, *characters); |
831 } | 832 } |
832 } | 833 } |
833 } | 834 } |
834 | 835 |
835 return CString(bufferVector.data(), buffer - bufferVector.data()); | 836 return CString(bufferVector.data(), buffer - bufferVector.data()); |
836 } | 837 } |
837 | 838 |
838 String String::make8BitFrom16BitSource(const UChar* source, size_t length) | 839 String String::make8BitFrom16BitSource(const UChar* source, size_t length) |
(...skipping 17 matching lines...) Expand all Loading... |
856 UChar* destination; | 857 UChar* destination; |
857 String result = String::createUninitialized(length, destination); | 858 String result = String::createUninitialized(length, destination); |
858 | 859 |
859 StringImpl::copyChars(destination, source, length); | 860 StringImpl::copyChars(destination, source, length); |
860 | 861 |
861 return result; | 862 return result; |
862 } | 863 } |
863 | 864 |
864 String String::fromUTF8(const LChar* stringStart, size_t length) | 865 String String::fromUTF8(const LChar* stringStart, size_t length) |
865 { | 866 { |
866 RELEASE_ASSERT(length <= numeric_limits<unsigned>::max()); | 867 RELEASE_ASSERT(length <= std::numeric_limits<unsigned>::max()); |
867 | 868 |
868 if (!stringStart) | 869 if (!stringStart) |
869 return String(); | 870 return String(); |
870 | 871 |
871 if (!length) | 872 if (!length) |
872 return emptyString(); | 873 return emptyString(); |
873 | 874 |
874 if (charactersAreAllASCII(stringStart, length)) | 875 if (charactersAreAllASCII(stringStart, length)) |
875 return StringImpl::create(stringStart, length); | 876 return StringImpl::create(stringStart, length); |
876 | 877 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 base = 36; | 921 base = 36; |
921 return (c >= 'a' && c < 'a' + base - 10) | 922 return (c >= 'a' && c < 'a' + base - 10) |
922 || (c >= 'A' && c < 'A' + base - 10); | 923 || (c >= 'A' && c < 'A' + base - 10); |
923 } | 924 } |
924 return false; | 925 return false; |
925 } | 926 } |
926 | 927 |
927 template <typename IntegralType, typename CharType> | 928 template <typename IntegralType, typename CharType> |
928 static inline IntegralType toIntegralType(const CharType* data, size_t length, b
ool* ok, int base) | 929 static inline IntegralType toIntegralType(const CharType* data, size_t length, b
ool* ok, int base) |
929 { | 930 { |
930 static const IntegralType integralMax = numeric_limits<IntegralType>::max(); | 931 static const IntegralType integralMax = std::numeric_limits<IntegralType>::m
ax(); |
931 static const bool isSigned = numeric_limits<IntegralType>::is_signed; | 932 static const bool isSigned = std::numeric_limits<IntegralType>::is_signed; |
932 const IntegralType maxMultiplier = integralMax / base; | 933 const IntegralType maxMultiplier = integralMax / base; |
933 | 934 |
934 IntegralType value = 0; | 935 IntegralType value = 0; |
935 bool isOk = false; | 936 bool isOk = false; |
936 bool isNegative = false; | 937 bool isNegative = false; |
937 | 938 |
938 if (!data) | 939 if (!data) |
939 goto bye; | 940 goto bye; |
940 | 941 |
941 // skip leading whitespace | 942 // skip leading whitespace |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 } | 1134 } |
1134 | 1135 |
1135 double charactersToDouble(const UChar* data, size_t length, bool* ok) | 1136 double charactersToDouble(const UChar* data, size_t length, bool* ok) |
1136 { | 1137 { |
1137 size_t parsedLength; | 1138 size_t parsedLength; |
1138 return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLen
gth); | 1139 return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLen
gth); |
1139 } | 1140 } |
1140 | 1141 |
1141 float charactersToFloat(const LChar* data, size_t length, bool* ok) | 1142 float charactersToFloat(const LChar* data, size_t length, bool* ok) |
1142 { | 1143 { |
1143 // FIXME: This will return ok even when the string fits into a double but no
t a float. | 1144 // FIXME: This will return ok even when the string fits into a double but |
| 1145 // not a float. |
1144 size_t parsedLength; | 1146 size_t parsedLength; |
1145 return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(data, le
ngth, ok, parsedLength)); | 1147 return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(data, le
ngth, ok, parsedLength)); |
1146 } | 1148 } |
1147 | 1149 |
1148 float charactersToFloat(const UChar* data, size_t length, bool* ok) | 1150 float charactersToFloat(const UChar* data, size_t length, bool* ok) |
1149 { | 1151 { |
1150 // FIXME: This will return ok even when the string fits into a double but no
t a float. | 1152 // FIXME: This will return ok even when the string fits into a double but |
| 1153 // not a float. |
1151 size_t parsedLength; | 1154 size_t parsedLength; |
1152 return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(data, le
ngth, ok, parsedLength)); | 1155 return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(data, le
ngth, ok, parsedLength)); |
1153 } | 1156 } |
1154 | 1157 |
1155 float charactersToFloat(const LChar* data, size_t length, size_t& parsedLength) | 1158 float charactersToFloat(const LChar* data, size_t length, size_t& parsedLength) |
1156 { | 1159 { |
1157 // FIXME: This will return ok even when the string fits into a double but no
t a float. | 1160 // FIXME: This will return ok even when the string fits into a double but |
| 1161 // not a float. |
1158 return static_cast<float>(toDoubleType<LChar, AllowTrailingJunk>(data, lengt
h, 0, parsedLength)); | 1162 return static_cast<float>(toDoubleType<LChar, AllowTrailingJunk>(data, lengt
h, 0, parsedLength)); |
1159 } | 1163 } |
1160 | 1164 |
1161 float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength) | 1165 float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength) |
1162 { | 1166 { |
1163 // FIXME: This will return ok even when the string fits into a double but no
t a float. | 1167 // FIXME: This will return ok even when the string fits into a double but |
| 1168 // not a float. |
1164 return static_cast<float>(toDoubleType<UChar, AllowTrailingJunk>(data, lengt
h, 0, parsedLength)); | 1169 return static_cast<float>(toDoubleType<UChar, AllowTrailingJunk>(data, lengt
h, 0, parsedLength)); |
1165 } | 1170 } |
1166 | 1171 |
1167 const String& emptyString() | 1172 const String& emptyString() |
1168 { | 1173 { |
1169 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty())); | 1174 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty())); |
1170 return emptyString; | 1175 return emptyString; |
1171 } | 1176 } |
1172 | 1177 |
1173 const String& emptyString16Bit() | 1178 const String& emptyString16Bit() |
1174 { | 1179 { |
1175 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty16Bit())); | 1180 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty16Bit())); |
1176 return emptyString; | 1181 return emptyString; |
1177 } | 1182 } |
1178 | 1183 |
1179 } // namespace WTF | 1184 } // namespace WTF |
1180 | 1185 |
1181 #ifndef NDEBUG | 1186 #ifndef NDEBUG |
1182 // For use in the debugger | 1187 // For use in the debugger |
1183 String* string(const char*); | 1188 String* string(const char*); |
1184 Vector<char> asciiDebug(StringImpl* impl); | 1189 Vector<char> asciiDebug(StringImpl*); |
1185 Vector<char> asciiDebug(String& string); | 1190 Vector<char> asciiDebug(String&); |
1186 | 1191 |
1187 void String::show() const | 1192 void String::show() const |
1188 { | 1193 { |
1189 dataLogF("%s\n", asciiDebug(impl()).data()); | 1194 dataLogF("%s\n", asciiDebug(impl()).data()); |
1190 } | 1195 } |
1191 | 1196 |
1192 String* string(const char* s) | 1197 String* string(const char* s) |
1193 { | 1198 { |
1194 // leaks memory! | 1199 // leaks memory! |
1195 return new String(s); | 1200 return new String(s); |
(...skipping 20 matching lines...) Expand all Loading... |
1216 buffer.append('\0'); | 1221 buffer.append('\0'); |
1217 return buffer; | 1222 return buffer; |
1218 } | 1223 } |
1219 | 1224 |
1220 Vector<char> asciiDebug(String& string) | 1225 Vector<char> asciiDebug(String& string) |
1221 { | 1226 { |
1222 return asciiDebug(string.impl()); | 1227 return asciiDebug(string.impl()); |
1223 } | 1228 } |
1224 | 1229 |
1225 #endif | 1230 #endif |
OLD | NEW |