18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
35f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
55f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *  Copyright (C) 2009 Google Inc. All rights reserved.
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Library General Public
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Library General Public License for more details.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Library General Public License
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  along with this library; see the file COPYING.LIB.  If not, write to
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Boston, MA 02110-1301, USA.
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "UString.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSGlobalObjectFunctions.h"
28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Collector.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "dtoa.h"
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Identifier.h"
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Operations.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <ctype.h>
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <limits.h>
34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <limits>
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdlib.h>
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <string.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/ASCIICType.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h>
42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/StringExtras.h>
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h>
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/unicode/UTF8.h>
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/StringExtras.h>
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if HAVE(STRINGS_H)
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <strings.h>
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF::Unicode;
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectextern const double NaN;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectextern const double Inf;
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString::CString(const char* c)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_length(strlen(c))
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_data(new char[m_length + 1])
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memcpy(m_data, c, m_length + 1);
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString::CString(const char* c, size_t length)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_length(length)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_data(new char[length + 1])
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memcpy(m_data, c, m_length);
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data[m_length] = 0;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString::CString(const CString& b)
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_length = b.m_length;
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (b.m_data) {
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_data = new char[m_length + 1];
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memcpy(m_data, b.m_data, m_length + 1);
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_data = 0;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString::~CString()
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete [] m_data;
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString CString::adopt(char* c, size_t length)
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CString s;
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s.m_data = c;
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s.m_length = length;
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return s;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString& CString::append(const CString& t)
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* n;
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n = new char[m_length + t.m_length + 1];
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_length)
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memcpy(n, m_data, m_length);
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (t.m_length)
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memcpy(n + m_length, t.m_data, t.m_length);
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_length += t.m_length;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n[m_length] = 0;
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete [] m_data;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data = n;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *this;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString& CString::operator=(const char* c)
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_data)
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        delete [] m_data;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_length = strlen(c);
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data = new char[m_length + 1];
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memcpy(m_data, c, m_length + 1);
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *this;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString& CString::operator=(const CString& str)
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (this == &str)
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *this;
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_data)
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        delete [] m_data;
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_length = str.m_length;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (str.m_data) {
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_data = new char[m_length + 1];
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memcpy(m_data, str.m_data, m_length + 1);
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_data = 0;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *this;
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool operator==(const CString& c1, const CString& c2)
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t len = c1.size();
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return len == c2.size() && (len == 0 || memcmp(c1.c_str(), c2.c_str(), len) == 0);
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// These static strings are immutable, except for rc, whose initial value is chosen to
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic UChar sharedEmptyChar;
152d0825bca7fe65beaee391d30da42e937db621564Steve BlockUStringImpl* UStringImpl::s_empty;
1538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockUString::Rep* UString::s_nullRep;
1558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockUString* UString::s_nullUString;
156635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
157635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid initializeUString()
158635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
159d0825bca7fe65beaee391d30da42e937db621564Steve Block    UStringImpl::s_empty = new UStringImpl(&sharedEmptyChar, 0, UStringImpl::ConstructStaticString);
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    UString::s_nullRep = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
1628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    UString::s_nullUString = new UString;
163643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString::UString(const char* c)
1668a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    : m_rep(Rep::create(c))
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
170643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockUString::UString(const char* c, int length)
1718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    : m_rep(Rep::create(c, length))
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString::UString(const UChar* c, int length)
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (length == 0)
178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_rep = &Rep::empty();
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_rep = Rep::create(c, length);
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString UString::from(int i)
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar buf[1 + sizeof(i) * 3];
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar* end = buf + sizeof(buf) / sizeof(UChar);
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar* p = end;
1888a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (i == 0)
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *--p = '0';
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (i == INT_MIN) {
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char minBuf[1 + sizeof(i) * 3];
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sprintf(minBuf, "%d", INT_MIN);
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return UString(minBuf);
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool negative = false;
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (i < 0) {
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            negative = true;
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i = -i;
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (i) {
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *--p = static_cast<unsigned short>((i % 10) + '0');
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i /= 10;
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (negative)
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *--p = '-';
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return UString(p, static_cast<int>(end - p));
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockUString UString::from(long long i)
213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    UChar buf[1 + sizeof(i) * 3];
215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    UChar* end = buf + sizeof(buf) / sizeof(UChar);
216231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    UChar* p = end;
217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
218231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (i == 0)
219231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        *--p = '0';
220231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else if (i == std::numeric_limits<long long>::min()) {
221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        char minBuf[1 + sizeof(i) * 3];
222d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS)
223231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", std::numeric_limits<long long>::min());
224231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else
225231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        snprintf(minBuf, sizeof(minBuf) - 1, "%lld", std::numeric_limits<long long>::min());
226231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif
227231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return UString(minBuf);
228231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else {
229231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bool negative = false;
230231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (i < 0) {
231231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            negative = true;
232231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            i = -i;
233231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
234231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        while (i) {
235231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            *--p = static_cast<unsigned short>((i % 10) + '0');
236231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            i /= 10;
237231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
238231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (negative)
239231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            *--p = '-';
240231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return UString(p, static_cast<int>(end - p));
243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString UString::from(unsigned int u)
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar buf[sizeof(u) * 3];
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar* end = buf + sizeof(buf) / sizeof(UChar);
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar* p = end;
2508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (u == 0)
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *--p = '0';
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (u) {
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *--p = static_cast<unsigned short>((u % 10) + '0');
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            u /= 10;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return UString(p, static_cast<int>(end - p));
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString UString::from(long l)
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar buf[1 + sizeof(l) * 3];
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar* end = buf + sizeof(buf) / sizeof(UChar);
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar* p = end;
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (l == 0)
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *--p = '0';
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (l == LONG_MIN) {
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char minBuf[1 + sizeof(l) * 3];
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sprintf(minBuf, "%ld", LONG_MIN);
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return UString(minBuf);
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool negative = false;
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (l < 0) {
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            negative = true;
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            l = -l;
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (l) {
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *--p = static_cast<unsigned short>((l % 10) + '0');
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            l /= 10;
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (negative)
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *--p = '-';
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return UString(p, static_cast<int>(end - p));
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString UString::from(double d)
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
294643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    DtoaBuffer buffer;
295643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    unsigned length;
296643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    doubleToStringInJavaScriptFormat(d, buffer, &length);
297643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return UString(buffer, length);
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool UString::getCString(CStringBuffer& buffer) const
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int length = size();
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int neededSize = length + 1;
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer.resize(neededSize);
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* buf = buffer.data();
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar ored = 0;
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* p = data();
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* q = buf;
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* limit = p + length;
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (p != limit) {
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UChar c = p[0];
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ored |= c;
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *q = static_cast<char>(c);
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ++p;
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ++q;
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *q = '\0';
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return !(ored & 0xFF00);
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectchar* UString::ascii() const
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
325d0825bca7fe65beaee391d30da42e937db621564Steve Block    static char* asciiBuffer = 0;
326d0825bca7fe65beaee391d30da42e937db621564Steve Block
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int length = size();
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int neededSize = length + 1;
329d0825bca7fe65beaee391d30da42e937db621564Steve Block    delete[] asciiBuffer;
330d0825bca7fe65beaee391d30da42e937db621564Steve Block    asciiBuffer = new char[neededSize];
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* p = data();
333d0825bca7fe65beaee391d30da42e937db621564Steve Block    char* q = asciiBuffer;
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* limit = p + length;
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (p != limit) {
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *q = static_cast<char>(p[0]);
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ++p;
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ++q;
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *q = '\0';
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
342d0825bca7fe65beaee391d30da42e937db621564Steve Block    return asciiBuffer;
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool UString::is8Bit() const
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* u = data();
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* limit = u + size();
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (u < limit) {
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (u[0] > 0xFF)
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ++u;
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUChar UString::operator[](int pos) const
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos >= size())
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return '\0';
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return data()[pos];
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (size() == 1) {
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UChar c = data()[0];
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isASCIIDigit(c))
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return c - '0';
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isASCIISpace(c) && tolerateEmptyString)
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NaN;
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // after the number, so this is too strict a check.
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CStringBuffer s;
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!getCString(s))
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NaN;
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char* c = s.data();
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // skip leading white space
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (isASCIISpace(*c))
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c++;
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // empty string ?
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (*c == '\0')
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return tolerateEmptyString ? 0.0 : NaN;
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double d;
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // hex number ?
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) {
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const char* firstDigitPosition = c + 2;
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c++;
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        d = 0.0;
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (*(++c)) {
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (*c >= '0' && *c <= '9')
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                d = d * 16.0 + *c - '0';
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (d >= mantissaOverflowLowerBound)
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            d = parseIntOverflow(firstDigitPosition, c - firstDigitPosition, 16);
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // regular number ?
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char* end;
412635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        d = WTF::strtod(c, &end);
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((d != 0.0 || end != c) && d != Inf && d != -Inf) {
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            c = end;
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            double sign = 1.0;
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (*c == '+')
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                c++;
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else if (*c == '-') {
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                sign = -1.0;
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                c++;
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We used strtod() to do the conversion. However, strtod() handles
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // infinite values slightly differently than JavaScript in that it
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // converts the string "inf" with any capitalization to infinity,
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // whereas the ECMA spec requires that it be converted to NaN.
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            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') {
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                d = sign * Inf;
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                c += 8;
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if ((d == Inf || d == -Inf) && *c != 'I' && *c != 'i')
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                c = end;
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return NaN;
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // allow trailing white space
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (isASCIISpace(*c))
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c++;
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // don't allow anything after - unless tolerant=true
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!tolerateTrailingJunk && *c != '\0')
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        d = NaN;
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return d;
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble UString::toDouble(bool tolerateTrailingJunk) const
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return toDouble(tolerateTrailingJunk, true);
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble UString::toDouble() const
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return toDouble(false, true);
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectuint32_t UString::toUInt32(bool* ok) const
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double d = toDouble();
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool b = true;
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d != static_cast<uint32_t>(d)) {
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        b = false;
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        d = 0;
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ok)
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *ok = b;
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<uint32_t>(d);
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectuint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double d = toDouble(false, tolerateEmptyString);
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool b = true;
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d != static_cast<uint32_t>(d)) {
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        b = false;
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        d = 0;
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ok)
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *ok = b;
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<uint32_t>(d);
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectuint32_t UString::toStrictUInt32(bool* ok) const
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ok)
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *ok = false;
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Empty string is not OK.
498d0825bca7fe65beaee391d30da42e937db621564Steve Block    int len = m_rep->size();
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (len == 0)
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* p = m_rep->data();
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned short c = p[0];
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the first digit is 0, only 0 itself is OK.
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (c == '0') {
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (len == 1 && ok)
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *ok = true;
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Convert to UInt32, checking for overflow.
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    uint32_t i = 0;
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (1) {
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Process character, turning it into a digit.
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (c < '0' || c > '9')
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const unsigned d = c - '0';
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Multiply by 10, checking for overflow out of 32 bits.
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (i > 0xFFFFFFFFU / 10)
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        i *= 10;
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add in the digit, checking for overflow out of 32 bits.
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const unsigned max = 0xFFFFFFFFU - d;
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (i > max)
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        i += d;
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Handle end of string.
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (--len == 0) {
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (ok)
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                *ok = true;
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return i;
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Get next character.
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c = *(++p);
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint UString::find(const UString& f, int pos) const
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int fsz = f.size();
545635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos < 0)
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = 0;
548635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
549635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (fsz == 1) {
550635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        UChar ch = f[0];
551635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        const UChar* end = data() + size();
552635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        for (const UChar* c = data() + pos; c < end; c++) {
553635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (*c == ch)
554635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return static_cast<int>(c - data());
555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
556635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return -1;
557635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
559635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int sz = size();
560635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (sz < fsz)
561635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return -1;
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fsz == 0)
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return pos;
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* end = data() + sz - fsz;
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int fsizeminusone = (fsz - 1) * sizeof(UChar);
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* fdata = f.data();
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned short fchar = fdata[0];
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++fdata;
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (const UChar* c = data() + pos; c <= end; c++) {
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return static_cast<int>(c - data());
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint UString::find(UChar ch, int pos) const
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos < 0)
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = 0;
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* end = data() + size();
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (const UChar* c = data() + pos; c < end; c++) {
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*c == ch)
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return static_cast<int>(c - data());
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint UString::rfind(const UString& f, int pos) const
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int sz = size();
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int fsz = f.size();
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (sz < fsz)
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos < 0)
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = 0;
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos > sz - fsz)
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = sz - fsz;
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fsz == 0)
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return pos;
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int fsizeminusone = (fsz - 1) * sizeof(UChar);
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* fdata = f.data();
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (const UChar* c = data() + pos; c >= data(); c--) {
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return static_cast<int>(c - data());
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint UString::rfind(UChar ch, int pos) const
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isEmpty())
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos + 1 >= size())
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = size() - 1;
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (const UChar* c = data() + pos; c >= data(); c--) {
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*c == ch)
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return static_cast<int>(c - data());
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString UString::substr(int pos, int len) const
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int s = size();
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos < 0)
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = 0;
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (pos >= s)
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = s;
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (len < 0)
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        len = s;
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos + len >= s)
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        len = s - pos;
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pos == 0 && len == s)
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *this;
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return UString(Rep::create(m_rep, pos, len));
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool operator==(const UString& s1, const char *s2)
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (s2 == 0)
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return s1.isEmpty();
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* u = s1.data();
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* uend = u + s1.size();
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (u != uend && *s2) {
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (u[0] != (unsigned char)*s2)
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s2++;
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        u++;
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return u == uend && *s2 == 0;
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool operator<(const UString& s1, const UString& s2)
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int l1 = s1.size();
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int l2 = s2.size();
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int lmin = l1 < l2 ? l1 : l2;
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* c1 = s1.data();
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* c2 = s2.data();
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int l = 0;
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (l < lmin && *c1 == *c2) {
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c1++;
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c2++;
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        l++;
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (l < lmin)
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return (c1[0] < c2[0]);
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (l1 < l2);
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool operator>(const UString& s1, const UString& s2)
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int l1 = s1.size();
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int l2 = s2.size();
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int lmin = l1 < l2 ? l1 : l2;
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* c1 = s1.data();
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* c2 = s2.data();
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int l = 0;
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (l < lmin && *c1 == *c2) {
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c1++;
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c2++;
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        l++;
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (l < lmin)
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return (c1[0] > c2[0]);
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (l1 > l2);
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint compare(const UString& s1, const UString& s2)
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int l1 = s1.size();
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int l2 = s2.size();
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int lmin = l1 < l2 ? l1 : l2;
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* c1 = s1.data();
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* c2 = s2.data();
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int l = 0;
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (l < lmin && *c1 == *c2) {
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c1++;
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c2++;
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        l++;
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (l < lmin)
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return (c1[0] > c2[0]) ? 1 : -1;
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (l1 == l2)
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (l1 > l2) ? 1 : -1;
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool equal(const UString::Rep* r, const UString::Rep* b)
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
725d0825bca7fe65beaee391d30da42e937db621564Steve Block    int length = r->size();
726d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (length != b->size())
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* d = r->data();
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* s = b->data();
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i != length; ++i) {
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (d[i] != s[i])
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString UString::UTF8String(bool strict) const
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Allocate a buffer big enough to hold all the characters.
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const int length = size();
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<char, 1024> buffer(length * 3);
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Convert to runs of 8-bit characters.
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* p = buffer.data();
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* d = reinterpret_cast<const UChar*>(&data()[0]);
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ConversionResult result = convertUTF16ToUTF8(&d, d + length, &p, p + buffer.size(), strict);
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result != conversionOK)
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return CString();
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return CString(buffer.data(), p - buffer.data());
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
754