1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2007-2009 Torch Mobile, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include "config.h"
23 #include "PlatformString.h"
24
25 #include "CString.h"
26 #include "FloatConversion.h"
27 #include "StringBuffer.h"
28 #include "TextEncoding.h"
29 #include <wtf/dtoa.h>
30 #include <limits>
31 #include <stdarg.h>
32 #include <wtf/ASCIICType.h>
33 #include <wtf/StringExtras.h>
34 #include <wtf/Vector.h>
35 #include <wtf/unicode/Unicode.h>
36 #include <wtf/unicode/UTF8.h>
37
38 #if USE(JSC)
39 using JSC::Identifier;
40 using JSC::UString;
41 #endif
42
43 using namespace WTF;
44 using namespace WTF::Unicode;
45
46 namespace WebCore {
47
String(const UChar * str,unsigned len)48 String::String(const UChar* str, unsigned len)
49 {
50 if (!str)
51 return;
52 m_impl = StringImpl::create(str, len);
53 }
54
String(const UChar * str)55 String::String(const UChar* str)
56 {
57 if (!str)
58 return;
59
60 int len = 0;
61 while (str[len] != UChar(0))
62 len++;
63
64 m_impl = StringImpl::create(str, len);
65 }
66
String(const char * str)67 String::String(const char* str)
68 {
69 if (!str)
70 return;
71 m_impl = StringImpl::create(str);
72 }
73
String(const char * str,unsigned length)74 String::String(const char* str, unsigned length)
75 {
76 if (!str)
77 return;
78 m_impl = StringImpl::create(str, length);
79 }
80
append(const String & str)81 void String::append(const String& str)
82 {
83 // FIXME: This is extremely inefficient. So much so that we might want to take this
84 // out of String's API. We can make it better by optimizing the case where exactly
85 // one String is pointing at this StringImpl, but even then it's going to require a
86 // call to fastMalloc every single time.
87 if (str.m_impl) {
88 if (m_impl) {
89 UChar* data;
90 RefPtr<StringImpl> newImpl =
91 StringImpl::createUninitialized(m_impl->length() + str.length(), data);
92 memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar));
93 memcpy(data + m_impl->length(), str.characters(), str.length() * sizeof(UChar));
94 m_impl = newImpl.release();
95 } else
96 m_impl = str.m_impl;
97 }
98 }
99
append(char c)100 void String::append(char c)
101 {
102 // FIXME: This is extremely inefficient. So much so that we might want to take this
103 // out of String's API. We can make it better by optimizing the case where exactly
104 // one String is pointing at this StringImpl, but even then it's going to require a
105 // call to fastMalloc every single time.
106 if (m_impl) {
107 UChar* data;
108 RefPtr<StringImpl> newImpl =
109 StringImpl::createUninitialized(m_impl->length() + 1, data);
110 memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar));
111 data[m_impl->length()] = c;
112 m_impl = newImpl.release();
113 } else
114 m_impl = StringImpl::create(&c, 1);
115 }
116
append(UChar c)117 void String::append(UChar c)
118 {
119 // FIXME: This is extremely inefficient. So much so that we might want to take this
120 // out of String's API. We can make it better by optimizing the case where exactly
121 // one String is pointing at this StringImpl, but even then it's going to require a
122 // call to fastMalloc every single time.
123 if (m_impl) {
124 UChar* data;
125 RefPtr<StringImpl> newImpl =
126 StringImpl::createUninitialized(m_impl->length() + 1, data);
127 memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar));
128 data[m_impl->length()] = c;
129 m_impl = newImpl.release();
130 } else
131 m_impl = StringImpl::create(&c, 1);
132 }
133
operator +(const String & a,const String & b)134 String operator+(const String& a, const String& b)
135 {
136 if (a.isEmpty())
137 return b;
138 if (b.isEmpty())
139 return a;
140 String c = a;
141 c += b;
142 return c;
143 }
144
operator +(const String & s,const char * cs)145 String operator+(const String& s, const char* cs)
146 {
147 return s + String(cs);
148 }
149
operator +(const char * cs,const String & s)150 String operator+(const char* cs, const String& s)
151 {
152 return String(cs) + s;
153 }
154
insert(const String & str,unsigned pos)155 void String::insert(const String& str, unsigned pos)
156 {
157 if (str.isEmpty()) {
158 if (str.isNull())
159 return;
160 if (isNull())
161 m_impl = str.impl();
162 return;
163 }
164 insert(str.characters(), str.length(), pos);
165 }
166
append(const UChar * charactersToAppend,unsigned lengthToAppend)167 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
168 {
169 if (!m_impl) {
170 if (!charactersToAppend)
171 return;
172 m_impl = StringImpl::create(charactersToAppend, lengthToAppend);
173 return;
174 }
175
176 if (!lengthToAppend)
177 return;
178
179 ASSERT(charactersToAppend);
180 UChar* data;
181 RefPtr<StringImpl> newImpl =
182 StringImpl::createUninitialized(length() + lengthToAppend, data);
183 memcpy(data, characters(), length() * sizeof(UChar));
184 memcpy(data + length(), charactersToAppend, lengthToAppend * sizeof(UChar));
185 m_impl = newImpl.release();
186 }
187
insert(const UChar * charactersToInsert,unsigned lengthToInsert,unsigned position)188 void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, unsigned position)
189 {
190 if (position >= length()) {
191 append(charactersToInsert, lengthToInsert);
192 return;
193 }
194
195 ASSERT(m_impl);
196
197 if (!lengthToInsert)
198 return;
199
200 ASSERT(charactersToInsert);
201 UChar* data;
202 RefPtr<StringImpl> newImpl =
203 StringImpl::createUninitialized(length() + lengthToInsert, data);
204 memcpy(data, characters(), position * sizeof(UChar));
205 memcpy(data + position, charactersToInsert, lengthToInsert * sizeof(UChar));
206 memcpy(data + position + lengthToInsert, characters() + position, (length() - position) * sizeof(UChar));
207 m_impl = newImpl.release();
208 }
209
operator [](unsigned i) const210 UChar String::operator[](unsigned i) const
211 {
212 if (!m_impl || i >= m_impl->length())
213 return 0;
214 return m_impl->characters()[i];
215 }
216
characterStartingAt(unsigned i) const217 UChar32 String::characterStartingAt(unsigned i) const
218 {
219 if (!m_impl || i >= m_impl->length())
220 return 0;
221 return m_impl->characterStartingAt(i);
222 }
223
length() const224 unsigned String::length() const
225 {
226 if (!m_impl)
227 return 0;
228 return m_impl->length();
229 }
230
truncate(unsigned position)231 void String::truncate(unsigned position)
232 {
233 if (position >= length())
234 return;
235 UChar* data;
236 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(position, data);
237 memcpy(data, characters(), position * sizeof(UChar));
238 m_impl = newImpl.release();
239 }
240
remove(unsigned position,int lengthToRemove)241 void String::remove(unsigned position, int lengthToRemove)
242 {
243 if (lengthToRemove <= 0)
244 return;
245 if (position >= length())
246 return;
247 if (static_cast<unsigned>(lengthToRemove) > length() - position)
248 lengthToRemove = length() - position;
249 UChar* data;
250 RefPtr<StringImpl> newImpl =
251 StringImpl::createUninitialized(length() - lengthToRemove, data);
252 memcpy(data, characters(), position * sizeof(UChar));
253 memcpy(data + position, characters() + position + lengthToRemove,
254 (length() - lengthToRemove - position) * sizeof(UChar));
255 m_impl = newImpl.release();
256 }
257
substring(unsigned pos,unsigned len) const258 String String::substring(unsigned pos, unsigned len) const
259 {
260 if (!m_impl)
261 return String();
262 return m_impl->substring(pos, len);
263 }
264
substringCopy(unsigned pos,unsigned len) const265 String String::substringCopy(unsigned pos, unsigned len) const
266 {
267 if (!m_impl)
268 return String();
269 return m_impl->substringCopy(pos, len);
270 }
271
lower() const272 String String::lower() const
273 {
274 if (!m_impl)
275 return String();
276 return m_impl->lower();
277 }
278
upper() const279 String String::upper() const
280 {
281 if (!m_impl)
282 return String();
283 return m_impl->upper();
284 }
285
stripWhiteSpace() const286 String String::stripWhiteSpace() const
287 {
288 if (!m_impl)
289 return String();
290 return m_impl->stripWhiteSpace();
291 }
292
simplifyWhiteSpace() const293 String String::simplifyWhiteSpace() const
294 {
295 if (!m_impl)
296 return String();
297 return m_impl->simplifyWhiteSpace();
298 }
299
removeCharacters(CharacterMatchFunctionPtr findMatch) const300 String String::removeCharacters(CharacterMatchFunctionPtr findMatch) const
301 {
302 if (!m_impl)
303 return String();
304 return m_impl->removeCharacters(findMatch);
305 }
306
foldCase() const307 String String::foldCase() const
308 {
309 if (!m_impl)
310 return String();
311 return m_impl->foldCase();
312 }
313
percentage(int & result) const314 bool String::percentage(int& result) const
315 {
316 if (!m_impl || !m_impl->length())
317 return false;
318
319 if ((*m_impl)[m_impl->length() - 1] != '%')
320 return false;
321
322 result = charactersToIntStrict(m_impl->characters(), m_impl->length() - 1);
323 return true;
324 }
325
characters() const326 const UChar* String::characters() const
327 {
328 if (!m_impl)
329 return 0;
330 return m_impl->characters();
331 }
332
charactersWithNullTermination()333 const UChar* String::charactersWithNullTermination()
334 {
335 if (!m_impl)
336 return 0;
337 if (m_impl->hasTerminatingNullCharacter())
338 return m_impl->characters();
339 m_impl = StringImpl::createWithTerminatingNullCharacter(*m_impl);
340 return m_impl->characters();
341 }
342
format(const char * format,...)343 String String::format(const char *format, ...)
344 {
345 #if PLATFORM(QT)
346 // Use QString::vsprintf to avoid the locale dependent formatting of vsnprintf.
347 // https://bugs.webkit.org/show_bug.cgi?id=18994
348 va_list args;
349 va_start(args, format);
350
351 QString buffer;
352 buffer.vsprintf(format, args);
353
354 va_end(args);
355
356 return buffer;
357
358 #elif PLATFORM(WINCE)
359 va_list args;
360 va_start(args, format);
361
362 Vector<char, 256> buffer;
363
364 int bufferSize = 256;
365 buffer.resize(bufferSize);
366 for (;;) {
367 int written = vsnprintf(buffer.data(), bufferSize, format, args);
368 va_end(args);
369
370 if (written == 0)
371 return String("");
372 if (written > 0)
373 return StringImpl::create(buffer.data(), written);
374
375 bufferSize <<= 1;
376 buffer.resize(bufferSize);
377 va_start(args, format);
378 }
379
380 #else
381 va_list args;
382 va_start(args, format);
383
384 Vector<char, 256> buffer;
385
386 // Do the format once to get the length.
387 #if COMPILER(MSVC)
388 int result = _vscprintf(format, args);
389 #else
390 char ch;
391 int result = vsnprintf(&ch, 1, format, args);
392 // We need to call va_end() and then va_start() again here, as the
393 // contents of args is undefined after the call to vsnprintf
394 // according to http://man.cx/snprintf(3)
395 //
396 // Not calling va_end/va_start here happens to work on lots of
397 // systems, but fails e.g. on 64bit Linux.
398 va_end(args);
399 va_start(args, format);
400 #endif
401
402 if (result == 0)
403 return String("");
404 if (result < 0)
405 return String();
406 unsigned len = result;
407 buffer.grow(len + 1);
408
409 // Now do the formatting again, guaranteed to fit.
410 vsnprintf(buffer.data(), buffer.size(), format, args);
411
412 va_end(args);
413
414 return StringImpl::create(buffer.data(), len);
415 #endif
416 }
417
number(short n)418 String String::number(short n)
419 {
420 return String::format("%hd", n);
421 }
422
number(unsigned short n)423 String String::number(unsigned short n)
424 {
425 return String::format("%hu", n);
426 }
427
number(int n)428 String String::number(int n)
429 {
430 return String::format("%d", n);
431 }
432
number(unsigned n)433 String String::number(unsigned n)
434 {
435 return String::format("%u", n);
436 }
437
number(long n)438 String String::number(long n)
439 {
440 return String::format("%ld", n);
441 }
442
number(unsigned long n)443 String String::number(unsigned long n)
444 {
445 return String::format("%lu", n);
446 }
447
number(long long n)448 String String::number(long long n)
449 {
450 #if PLATFORM(WIN_OS)
451 return String::format("%I64i", n);
452 #else
453 return String::format("%lli", n);
454 #endif
455 }
456
number(unsigned long long n)457 String String::number(unsigned long long n)
458 {
459 #if PLATFORM(WIN_OS)
460 return String::format("%I64u", n);
461 #else
462 return String::format("%llu", n);
463 #endif
464 }
465
number(double n)466 String String::number(double n)
467 {
468 return String::format("%.6lg", n);
469 }
470
toIntStrict(bool * ok,int base) const471 int String::toIntStrict(bool* ok, int base) const
472 {
473 if (!m_impl) {
474 if (ok)
475 *ok = false;
476 return 0;
477 }
478 return m_impl->toIntStrict(ok, base);
479 }
480
toUIntStrict(bool * ok,int base) const481 unsigned String::toUIntStrict(bool* ok, int base) const
482 {
483 if (!m_impl) {
484 if (ok)
485 *ok = false;
486 return 0;
487 }
488 return m_impl->toUIntStrict(ok, base);
489 }
490
toInt64Strict(bool * ok,int base) const491 int64_t String::toInt64Strict(bool* ok, int base) const
492 {
493 if (!m_impl) {
494 if (ok)
495 *ok = false;
496 return 0;
497 }
498 return m_impl->toInt64Strict(ok, base);
499 }
500
toUInt64Strict(bool * ok,int base) const501 uint64_t String::toUInt64Strict(bool* ok, int base) const
502 {
503 if (!m_impl) {
504 if (ok)
505 *ok = false;
506 return 0;
507 }
508 return m_impl->toUInt64Strict(ok, base);
509 }
510
toIntPtrStrict(bool * ok,int base) const511 intptr_t String::toIntPtrStrict(bool* ok, int base) const
512 {
513 if (!m_impl) {
514 if (ok)
515 *ok = false;
516 return 0;
517 }
518 return m_impl->toIntPtrStrict(ok, base);
519 }
520
521
toInt(bool * ok) const522 int String::toInt(bool* ok) const
523 {
524 if (!m_impl) {
525 if (ok)
526 *ok = false;
527 return 0;
528 }
529 return m_impl->toInt(ok);
530 }
531
toUInt(bool * ok) const532 unsigned String::toUInt(bool* ok) const
533 {
534 if (!m_impl) {
535 if (ok)
536 *ok = false;
537 return 0;
538 }
539 return m_impl->toUInt(ok);
540 }
541
toInt64(bool * ok) const542 int64_t String::toInt64(bool* ok) const
543 {
544 if (!m_impl) {
545 if (ok)
546 *ok = false;
547 return 0;
548 }
549 return m_impl->toInt64(ok);
550 }
551
toUInt64(bool * ok) const552 uint64_t String::toUInt64(bool* ok) const
553 {
554 if (!m_impl) {
555 if (ok)
556 *ok = false;
557 return 0;
558 }
559 return m_impl->toUInt64(ok);
560 }
561
toIntPtr(bool * ok) const562 intptr_t String::toIntPtr(bool* ok) const
563 {
564 if (!m_impl) {
565 if (ok)
566 *ok = false;
567 return 0;
568 }
569 return m_impl->toIntPtr(ok);
570 }
571
toDouble(bool * ok) const572 double String::toDouble(bool* ok) const
573 {
574 if (!m_impl) {
575 if (ok)
576 *ok = false;
577 return 0.0;
578 }
579 return m_impl->toDouble(ok);
580 }
581
toFloat(bool * ok) const582 float String::toFloat(bool* ok) const
583 {
584 if (!m_impl) {
585 if (ok)
586 *ok = false;
587 return 0.0f;
588 }
589 return m_impl->toFloat(ok);
590 }
591
copy() const592 String String::copy() const
593 {
594 if (!m_impl)
595 return String();
596 return m_impl->copy();
597 }
598
isEmpty() const599 bool String::isEmpty() const
600 {
601 return !m_impl || !m_impl->length();
602 }
603
split(const String & separator,bool allowEmptyEntries,Vector<String> & result) const604 void String::split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const
605 {
606 result.clear();
607
608 int startPos = 0;
609 int endPos;
610 while ((endPos = find(separator, startPos)) != -1) {
611 if (allowEmptyEntries || startPos != endPos)
612 result.append(substring(startPos, endPos - startPos));
613 startPos = endPos + separator.length();
614 }
615 if (allowEmptyEntries || startPos != static_cast<int>(length()))
616 result.append(substring(startPos));
617 }
618
split(const String & separator,Vector<String> & result) const619 void String::split(const String& separator, Vector<String>& result) const
620 {
621 return split(separator, false, result);
622 }
623
split(UChar separator,bool allowEmptyEntries,Vector<String> & result) const624 void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const
625 {
626 result.clear();
627
628 int startPos = 0;
629 int endPos;
630 while ((endPos = find(separator, startPos)) != -1) {
631 if (allowEmptyEntries || startPos != endPos)
632 result.append(substring(startPos, endPos - startPos));
633 startPos = endPos + 1;
634 }
635 if (allowEmptyEntries || startPos != static_cast<int>(length()))
636 result.append(substring(startPos));
637 }
638
split(UChar separator,Vector<String> & result) const639 void String::split(UChar separator, Vector<String>& result) const
640 {
641 return split(String(&separator, 1), false, result);
642 }
643
644 #ifndef NDEBUG
ascii() const645 Vector<char> String::ascii() const
646 {
647 if (m_impl)
648 return m_impl->ascii();
649
650 const char* nullMsg = "(null impl)";
651 Vector<char, 2048> buffer;
652 for (int i = 0; nullMsg[i]; ++i)
653 buffer.append(nullMsg[i]);
654
655 buffer.append('\0');
656 return buffer;
657 }
658 #endif
659
latin1() const660 CString String::latin1() const
661 {
662 return Latin1Encoding().encode(characters(), length(), QuestionMarksForUnencodables);
663 }
664
utf8() const665 CString String::utf8() const
666 {
667 return UTF8Encoding().encode(characters(), length(), QuestionMarksForUnencodables);
668 }
669
fromUTF8(const char * string,size_t size)670 String String::fromUTF8(const char* string, size_t size)
671 {
672 if (!string)
673 return String();
674 return UTF8Encoding().decode(string, size);
675 }
676
fromUTF8(const char * string)677 String String::fromUTF8(const char* string)
678 {
679 if (!string)
680 return String();
681 return UTF8Encoding().decode(string, strlen(string));
682 }
683
fromUTF8WithLatin1Fallback(const char * string,size_t size)684 String String::fromUTF8WithLatin1Fallback(const char* string, size_t size)
685 {
686 String result = fromUTF8(string, size);
687 if (!result)
688 result = String(string, size);
689
690 return result;
691 }
692
693 #if USE(JSC)
String(const Identifier & str)694 String::String(const Identifier& str)
695 {
696 if (str.isNull())
697 return;
698 m_impl = StringImpl::create(str.ustring());
699 }
700
String(const UString & str)701 String::String(const UString& str)
702 {
703 if (str.isNull())
704 return;
705 m_impl = StringImpl::create(str);
706 }
707
operator UString() const708 String::operator UString() const
709 {
710 if (!m_impl)
711 return UString();
712 return m_impl->ustring();
713 }
714 #endif
715
716 // String Operations
717
isCharacterAllowedInBase(UChar c,int base)718 static bool isCharacterAllowedInBase(UChar c, int base)
719 {
720 if (c > 0x7F)
721 return false;
722 if (isASCIIDigit(c))
723 return c - '0' < base;
724 if (isASCIIAlpha(c)) {
725 if (base > 36)
726 base = 36;
727 return (c >= 'a' && c < 'a' + base - 10)
728 || (c >= 'A' && c < 'A' + base - 10);
729 }
730 return false;
731 }
732
733 template <typename IntegralType>
toIntegralType(const UChar * data,size_t length,bool * ok,int base)734 static inline IntegralType toIntegralType(const UChar* data, size_t length, bool* ok, int base)
735 {
736 static const IntegralType integralMax = std::numeric_limits<IntegralType>::max();
737 static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
738 const IntegralType maxMultiplier = integralMax / base;
739
740 IntegralType value = 0;
741 bool isOk = false;
742 bool isNegative = false;
743
744 if (!data)
745 goto bye;
746
747 // skip leading whitespace
748 while (length && isSpaceOrNewline(*data)) {
749 length--;
750 data++;
751 }
752
753 if (isSigned && length && *data == '-') {
754 length--;
755 data++;
756 isNegative = true;
757 } else if (length && *data == '+') {
758 length--;
759 data++;
760 }
761
762 if (!length || !isCharacterAllowedInBase(*data, base))
763 goto bye;
764
765 while (length && isCharacterAllowedInBase(*data, base)) {
766 length--;
767 IntegralType digitValue;
768 UChar c = *data;
769 if (isASCIIDigit(c))
770 digitValue = c - '0';
771 else if (c >= 'a')
772 digitValue = c - 'a' + 10;
773 else
774 digitValue = c - 'A' + 10;
775
776 if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integralMax % base) + isNegative))
777 goto bye;
778
779 value = base * value + digitValue;
780 data++;
781 }
782
783 #if COMPILER(MSVC)
784 #pragma warning(push, 0)
785 #pragma warning(disable:4146)
786 #endif
787
788 if (isNegative)
789 value = -value;
790
791 #if COMPILER(MSVC)
792 #pragma warning(pop)
793 #endif
794
795 // skip trailing space
796 while (length && isSpaceOrNewline(*data)) {
797 length--;
798 data++;
799 }
800
801 if (!length)
802 isOk = true;
803 bye:
804 if (ok)
805 *ok = isOk;
806 return isOk ? value : 0;
807 }
808
lengthOfCharactersAsInteger(const UChar * data,size_t length)809 static unsigned lengthOfCharactersAsInteger(const UChar* data, size_t length)
810 {
811 size_t i = 0;
812
813 // Allow leading spaces.
814 for (; i != length; ++i) {
815 if (!isSpaceOrNewline(data[i]))
816 break;
817 }
818
819 // Allow sign.
820 if (i != length && (data[i] == '+' || data[i] == '-'))
821 ++i;
822
823 // Allow digits.
824 for (; i != length; ++i) {
825 if (!isASCIIDigit(data[i]))
826 break;
827 }
828
829 return i;
830 }
831
charactersToIntStrict(const UChar * data,size_t length,bool * ok,int base)832 int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base)
833 {
834 return toIntegralType<int>(data, length, ok, base);
835 }
836
charactersToUIntStrict(const UChar * data,size_t length,bool * ok,int base)837 unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base)
838 {
839 return toIntegralType<unsigned>(data, length, ok, base);
840 }
841
charactersToInt64Strict(const UChar * data,size_t length,bool * ok,int base)842 int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base)
843 {
844 return toIntegralType<int64_t>(data, length, ok, base);
845 }
846
charactersToUInt64Strict(const UChar * data,size_t length,bool * ok,int base)847 uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, int base)
848 {
849 return toIntegralType<uint64_t>(data, length, ok, base);
850 }
851
charactersToIntPtrStrict(const UChar * data,size_t length,bool * ok,int base)852 intptr_t charactersToIntPtrStrict(const UChar* data, size_t length, bool* ok, int base)
853 {
854 return toIntegralType<intptr_t>(data, length, ok, base);
855 }
856
charactersToInt(const UChar * data,size_t length,bool * ok)857 int charactersToInt(const UChar* data, size_t length, bool* ok)
858 {
859 return toIntegralType<int>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
860 }
861
charactersToUInt(const UChar * data,size_t length,bool * ok)862 unsigned charactersToUInt(const UChar* data, size_t length, bool* ok)
863 {
864 return toIntegralType<unsigned>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
865 }
866
charactersToInt64(const UChar * data,size_t length,bool * ok)867 int64_t charactersToInt64(const UChar* data, size_t length, bool* ok)
868 {
869 return toIntegralType<int64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
870 }
871
charactersToUInt64(const UChar * data,size_t length,bool * ok)872 uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok)
873 {
874 return toIntegralType<uint64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
875 }
876
charactersToIntPtr(const UChar * data,size_t length,bool * ok)877 intptr_t charactersToIntPtr(const UChar* data, size_t length, bool* ok)
878 {
879 return toIntegralType<intptr_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
880 }
881
charactersToDouble(const UChar * data,size_t length,bool * ok)882 double charactersToDouble(const UChar* data, size_t length, bool* ok)
883 {
884 if (!length) {
885 if (ok)
886 *ok = false;
887 return 0.0;
888 }
889
890 Vector<char, 256> bytes(length + 1);
891 for (unsigned i = 0; i < length; ++i)
892 bytes[i] = data[i] < 0x7F ? data[i] : '?';
893 bytes[length] = '\0';
894 char* end;
895 double val = WTF::strtod(bytes.data(), &end);
896 if (ok)
897 *ok = (end == 0 || *end == '\0');
898 return val;
899 }
900
charactersToFloat(const UChar * data,size_t length,bool * ok)901 float charactersToFloat(const UChar* data, size_t length, bool* ok)
902 {
903 // FIXME: This will return ok even when the string fits into a double but not a float.
904 return narrowPrecisionToFloat(charactersToDouble(data, length, ok));
905 }
906
utf8Buffer(const String & string)907 PassRefPtr<SharedBuffer> utf8Buffer(const String& string)
908 {
909 // Allocate a buffer big enough to hold all the characters.
910 const int length = string.length();
911 Vector<char> buffer(length * 3);
912
913 // Convert to runs of 8-bit characters.
914 char* p = buffer.data();
915 const UChar* d = string.characters();
916 ConversionResult result = convertUTF16ToUTF8(&d, d + length, &p, p + buffer.size(), true);
917 if (result != conversionOK)
918 return 0;
919
920 buffer.shrink(p - buffer.data());
921 return SharedBuffer::adoptVector(buffer);
922 }
923
924 } // namespace WebCore
925
926 #ifndef NDEBUG
927 // For use in the debugger - leaks memory
928 WebCore::String* string(const char*);
929
string(const char * s)930 WebCore::String* string(const char* s)
931 {
932 return new WebCore::String(s);
933 }
934 #endif
935