- }
-
- int l = static_cast<int>(strlen(c));
- UChar* d = 0;
- m_rep = Rep::tryCreateUninitialized(l, d);
- if (m_rep) {
- for (int i = 0; i < l; i++)
- d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
- } else
- makeNull();
-
- return *this;
-}
-
-bool UString::is8Bit() const
-{
- const UChar* u = data();
- const UChar* limit = u + size();
- while (u < limit) {
- if (u[0] > 0xFF)
- return false;
- ++u;
- }
-
- return true;
-}
-
-UChar UString::operator[](int pos) const
-{
- if (pos >= size())
- return '\0';
- return data()[pos];
-}
-
-double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
-{
- if (size() == 1) {
- UChar c = data()[0];
- if (isASCIIDigit(c))
- return c - '0';
- if (isASCIISpace(c) && tolerateEmptyString)
- return 0;
- return NaN;
- }
-
- // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk
- // after the number, so this is too strict a check.
- CStringBuffer s;
- if (!getCString(s))
- return NaN;
- const char* c = s.data();
-
- // skip leading white space
- while (isASCIISpace(*c))
- c++;
-
- // empty string ?
- if (*c == '\0')
- return tolerateEmptyString ? 0.0 : NaN;
-
- double d;
-
- // hex number ?
- if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) {
- const char* firstDigitPosition = c + 2;
- c++;
- d = 0.0;
- while (*(++c)) {
- if (*c >= '0' && *c <= '9')
- d = d * 16.0 + *c - '0';
- else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
- d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
- else
- break;
- }
-
- if (d >= mantissaOverflowLowerBound)
- d = parseIntOverflow(firstDigitPosition, c - firstDigitPosition, 16);
- } else {
- // regular number ?
- char* end;
- d = WTF::strtod(c, &end);
- if ((d != 0.0 || end != c) && d != Inf && d != -Inf) {
- c = end;
- } else {
- double sign = 1.0;
-
- if (*c == '+')
- c++;
- else if (*c == '-') {
- sign = -1.0;
- c++;
- }
-
- // We used strtod() to do the conversion. However, strtod() handles
- // infinite values slightly differently than JavaScript in that it
- // converts the string "inf" with any capitalization to infinity,
- // whereas the ECMA spec requires that it be converted to NaN.
-
- if (c[0] == 'I' && c[1] == 'n' && c[2] == 'f' && c[3] == 'i' && c[4] == 'n' && c[5] == 'i' && c[6] == 't' && c[7] == 'y') {
- d = sign * Inf;
- c += 8;
- } else if ((d == Inf || d == -Inf) && *c != 'I' && *c != 'i')
- c = end;
- else
- return NaN;
- }
- }
-
- // allow trailing white space
- while (isASCIISpace(*c))
- c++;
- // don't allow anything after - unless tolerant=true
- if (!tolerateTrailingJunk && *c != '\0')
- d = NaN;
-
- return d;
-}
-
-double UString::toDouble(bool tolerateTrailingJunk) const
-{
- return toDouble(tolerateTrailingJunk, true);
-}
-
-double UString::toDouble() const
-{
- return toDouble(false, true);
-}
-
-uint32_t UString::toUInt32(bool* ok) const
-{
- double d = toDouble();
- bool b = true;
-
- if (d != static_cast<uint32_t>(d)) {
- b = false;
- d = 0;
- }
-
- if (ok)
- *ok = b;
-
- return static_cast<uint32_t>(d);
-}
-
-uint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const
-{
- double d = toDouble(false, tolerateEmptyString);
- bool b = true;
-
- if (d != static_cast<uint32_t>(d)) {
- b = false;
- d = 0;
- }
-
- if (ok)
- *ok = b;
-
- return static_cast<uint32_t>(d);
-}
-
-uint32_t UString::toStrictUInt32(bool* ok) const
-{
- if (ok)
- *ok = false;
-
- // Empty string is not OK.
- int len = m_rep->size();
- if (len == 0)
- return 0;
- const UChar* p = m_rep->data();
- unsigned short c = p[0];
-
- // If the first digit is 0, only 0 itself is OK.
- if (c == '0') {
- if (len == 1 && ok)
- *ok = true;
- return 0;
- }
-
- // Convert to UInt32, checking for overflow.
- uint32_t i = 0;
- while (1) {
- // Process character, turning it into a digit.
- if (c < '0' || c > '9')
- return 0;
- const unsigned d = c - '0';
-
- // Multiply by 10, checking for overflow out of 32 bits.
- if (i > 0xFFFFFFFFU / 10)
- return 0;
- i *= 10;
-
- // Add in the digit, checking for overflow out of 32 bits.
- const unsigned max = 0xFFFFFFFFU - d;
- if (i > max)
- return 0;
- i += d;
-
- // Handle end of string.
- if (--len == 0) {
- if (ok)
- *ok = true;
- return i;
- }
-
- // Get next character.
- c = *(++p);
- }
-}
-
-int UString::find(const UString& f, int pos) const
-{
- int fsz = f.size();
-
- if (pos < 0)
- pos = 0;
-
- if (fsz == 1) {
- UChar ch = f[0];
- const UChar* end = data() + size();
- for (const UChar* c = data() + pos; c < end; c++) {
- if (*c == ch)
- return static_cast<int>(c - data());
- }
- return -1;
- }
-
- int sz = size();
- if (sz < fsz)
- return -1;
- if (fsz == 0)
- return pos;
- const UChar* end = data() + sz - fsz;
- int fsizeminusone = (fsz - 1) * sizeof(UChar);
- const UChar* fdata = f.data();
- unsigned short fchar = fdata[0];
- ++fdata;
- for (const UChar* c = data() + pos; c <= end; c++) {
- if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
- return static_cast<int>(c - data());
- }
-
- return -1;
-}
-
-int UString::find(UChar ch, int pos) const
-{
- if (pos < 0)
- pos = 0;
- const UChar* end = data() + size();
- for (const UChar* c = data() + pos; c < end; c++) {
- if (*c == ch)
- return static_cast<int>(c - data());
- }
-
- return -1;
-}
-
-int UString::rfind(const UString& f, int pos) const
-{
- int sz = size();
- int fsz = f.size();
- if (sz < fsz)
- return -1;
- if (pos < 0)
- pos = 0;
- if (pos > sz - fsz)
- pos = sz - fsz;
- if (fsz == 0)
- return pos;
- int fsizeminusone = (fsz - 1) * sizeof(UChar);
- const UChar* fdata = f.data();
- for (const UChar* c = data() + pos; c >= data(); c--) {
- if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
- return static_cast<int>(c - data());
- }
-
- return -1;
-}
-
-int UString::rfind(UChar ch, int pos) const
-{
- if (isEmpty())
- return -1;
- if (pos + 1 >= size())
- pos = size() - 1;
- for (const UChar* c = data() + pos; c >= data(); c--) {
- if (*c == ch)
- return static_cast<int>(c - data());
- }
-
- return -1;
-}
-
-UString UString::substr(int pos, int len) const
-{
- int s = size();
-
- if (pos < 0)
- pos = 0;
- else if (pos >= s)
- pos = s;
- if (len < 0)
- len = s;
- if (pos + len >= s)
- len = s - pos;
-
- if (pos == 0 && len == s)
- return *this;
-
- return UString(Rep::create(m_rep, pos, len));