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