• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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