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" 2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "Heap.h" 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Identifier.h" 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Operations.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <ctype.h> 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <limits.h> 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <limits> 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h> 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdlib.h> 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/ASCIICType.h> 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h> 385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include <wtf/DecimalNumber.h> 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h> 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/StringExtras.h> 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h> 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/unicode/UTF8.h> 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if HAVE(STRINGS_H) 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <strings.h> 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF; 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF::Unicode; 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectextern const double NaN; 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectextern const double Inf; 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 57e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockCOMPILE_ASSERT(sizeof(UString) == sizeof(void*), UString_should_stay_small); 58e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 59f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// Construct a string with UTF-16 data. 60f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString::UString(const UChar* characters, unsigned length) 61f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick : m_impl(characters ? StringImpl::create(characters, length) : 0) 62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 65f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// Construct a string with UTF-16 data, from a null-terminated source. 66f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString::UString(const UChar* characters) 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 68f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!characters) 69f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return; 70f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 71f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick int length = 0; 72f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while (characters[length] != UChar(0)) 73f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ++length; 74f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 75f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_impl = StringImpl::create(characters, length); 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 78f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// Construct a string with latin1 data. 79f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString::UString(const char* characters, unsigned length) 80f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick : m_impl(characters ? StringImpl::create(characters, length) : 0) 81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 84f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// Construct a string with latin1 data, from a null-terminated source. 85f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString::UString(const char* characters) 86f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick : m_impl(characters ? StringImpl::create(characters) : 0) 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 90f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString UString::number(int i) 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar buf[1 + sizeof(i) * 3]; 93e14391e94c850b8bd03680c23b38978db68687a8John Reck UChar* end = buf + WTF_ARRAY_LENGTH(buf); 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar* p = end; 958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (i == 0) 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = '0'; 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (i == INT_MIN) { 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char minBuf[1 + sizeof(i) * 3]; 100ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block snprintf(minBuf, sizeof(minBuf), "%d", INT_MIN); 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return UString(minBuf); 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool negative = false; 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (i < 0) { 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project negative = true; 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project i = -i; 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (i) { 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = static_cast<unsigned short>((i % 10) + '0'); 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project i /= 10; 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (negative) 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = '-'; 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 116692e5dbf12901edacf14812a6fae25462920af42Steve Block return UString(p, static_cast<unsigned>(end - p)); 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 119f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString UString::number(long long i) 120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block UChar buf[1 + sizeof(i) * 3]; 122e14391e94c850b8bd03680c23b38978db68687a8John Reck UChar* end = buf + WTF_ARRAY_LENGTH(buf); 123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block UChar* p = end; 124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (i == 0) 126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *--p = '0'; 127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block else if (i == std::numeric_limits<long long>::min()) { 128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block char minBuf[1 + sizeof(i) * 3]; 129d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS) 130ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block snprintf(minBuf, sizeof(minBuf), "%I64d", std::numeric_limits<long long>::min()); 131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else 132ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min()); 133231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return UString(minBuf); 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } else { 136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool negative = false; 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (i < 0) { 138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block negative = true; 139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block i = -i; 140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block while (i) { 142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *--p = static_cast<unsigned short>((i % 10) + '0'); 143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block i /= 10; 144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (negative) 146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *--p = '-'; 147231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 148231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 149692e5dbf12901edacf14812a6fae25462920af42Steve Block return UString(p, static_cast<unsigned>(end - p)); 150231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 152f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString UString::number(unsigned u) 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar buf[sizeof(u) * 3]; 155e14391e94c850b8bd03680c23b38978db68687a8John Reck UChar* end = buf + WTF_ARRAY_LENGTH(buf); 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar* p = end; 1578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (u == 0) 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = '0'; 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (u) { 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = static_cast<unsigned short>((u % 10) + '0'); 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project u /= 10; 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1668a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 167692e5dbf12901edacf14812a6fae25462920af42Steve Block return UString(p, static_cast<unsigned>(end - p)); 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 170f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString UString::number(long l) 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar buf[1 + sizeof(l) * 3]; 173e14391e94c850b8bd03680c23b38978db68687a8John Reck UChar* end = buf + WTF_ARRAY_LENGTH(buf); 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar* p = end; 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l == 0) 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = '0'; 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (l == LONG_MIN) { 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char minBuf[1 + sizeof(l) * 3]; 180ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block snprintf(minBuf, sizeof(minBuf), "%ld", LONG_MIN); 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return UString(minBuf); 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool negative = false; 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l < 0) { 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project negative = true; 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project l = -l; 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (l) { 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = static_cast<unsigned short>((l % 10) + '0'); 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project l /= 10; 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (negative) 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *--p = '-'; 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 196692e5dbf12901edacf14812a6fae25462920af42Steve Block return UString(p, end - p); 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 199f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString UString::number(double d) 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 201e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block NumberToStringBuffer buffer; 2025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen unsigned length = numberToString(d, buffer); 2035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return UString(buffer, length); 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 206f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickUString UString::substringSharingImpl(unsigned offset, unsigned length) const 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 208f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // FIXME: We used to check against a limit of Heap::minExtraCost / sizeof(UChar). 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 210f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned stringLength = this->length(); 211f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick offset = min(offset, stringLength); 212f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick length = min(length, stringLength - offset); 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 214f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!offset && length == stringLength) 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return *this; 216f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return UString(StringImpl::create(m_impl, offset, length)); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool operator==(const UString& s1, const char *s2) 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (s2 == 0) 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return s1.isEmpty(); 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 224f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* u = s1.characters(); 225f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* uend = u + s1.length(); 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (u != uend && *s2) { 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (u[0] != (unsigned char)*s2) 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project s2++; 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project u++; 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return u == uend && *s2 == 0; 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool operator<(const UString& s1, const UString& s2) 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 238f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const unsigned l1 = s1.length(); 239f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const unsigned l2 = s2.length(); 240692e5dbf12901edacf14812a6fae25462920af42Steve Block const unsigned lmin = l1 < l2 ? l1 : l2; 241f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* c1 = s1.characters(); 242f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* c2 = s2.characters(); 243692e5dbf12901edacf14812a6fae25462920af42Steve Block unsigned l = 0; 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (l < lmin && *c1 == *c2) { 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project c1++; 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project c2++; 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project l++; 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l < lmin) 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (c1[0] < c2[0]); 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (l1 < l2); 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool operator>(const UString& s1, const UString& s2) 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 257f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const unsigned l1 = s1.length(); 258f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const unsigned l2 = s2.length(); 259692e5dbf12901edacf14812a6fae25462920af42Steve Block const unsigned lmin = l1 < l2 ? l1 : l2; 260f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* c1 = s1.characters(); 261f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* c2 = s2.characters(); 262692e5dbf12901edacf14812a6fae25462920af42Steve Block unsigned l = 0; 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (l < lmin && *c1 == *c2) { 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project c1++; 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project c2++; 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project l++; 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (l < lmin) 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (c1[0] > c2[0]); 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (l1 > l2); 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 274f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickCString UString::ascii() const 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 276f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are 277f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // preserved, characters outside of this range are converted to '?'. 278f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 279f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned length = this->length(); 280f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* characters = this->characters(); 281f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 282f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick char* characterBuffer; 283f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick CString result = CString::newUninitialized(length, characterBuffer); 284f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 285f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick for (unsigned i = 0; i < length; ++i) { 286f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick UChar ch = characters[i]; 287f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick characterBuffer[i] = ch && (ch < 0x20 || ch >= 0x7f) ? '?' : ch; 288f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 289f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 290f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return result; 291f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 292f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 293f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickCString UString::latin1() const 294f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 295f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are 296f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // preserved, characters outside of this range are converted to '?'. 297f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 298f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned length = this->length(); 299f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* characters = this->characters(); 300f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 301f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick char* characterBuffer; 302f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick CString result = CString::newUninitialized(length, characterBuffer); 303f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 304f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick for (unsigned i = 0; i < length; ++i) { 305f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick UChar ch = characters[i]; 306f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick characterBuffer[i] = ch > 0xff ? '?' : ch; 307f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 308f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 309f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return result; 310f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 311f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 312f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available. 313f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickstatic inline void putUTF8Triple(char*& buffer, UChar ch) 314f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 315f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT(ch >= 0x0800); 316f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); 317f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); 318f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); 319f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 320f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 321f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickCString UString::utf8(bool strict) const 322f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 323f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned length = this->length(); 324f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* characters = this->characters(); 325f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 326f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Allocate a buffer big enough to hold all the characters 327f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). 328f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Optimization ideas, if we find this function is hot: 329f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // * We could speculatively create a CStringBuffer to contain 'length' 330f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // characters, and resize if necessary (i.e. if the buffer contains 331f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // non-ascii characters). (Alternatively, scan the buffer first for 332f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // ascii characters, so we know this will be sufficient). 333f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // * We could allocate a CStringBuffer with an appropriate size to 334f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // have a good chance of being able to write the string into the 335f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // buffer without reallocing (say, 1.5 x length). 336e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (length > numeric_limits<unsigned>::max() / 3) 337e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return CString(); 338f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick Vector<char, 1024> bufferVector(length * 3); 339f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 340f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick char* buffer = bufferVector.data(); 341f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); 342f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT(result != targetExhausted); // (length * 3) should be sufficient for any conversion 343f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 344f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Only produced from strict conversion. 345f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (result == sourceIllegal) 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return CString(); 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 348f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check for an unconverted high surrogate. 349f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (result == sourceExhausted) { 350f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (strict) 351f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return CString(); 352f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // This should be one unpaired high surrogate. Treat it the same 353f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // was as an unpaired high surrogate would have been handled in 354f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // the middle of a string with non-strict conversion - which is 355f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // to say, simply encode it to UTF-8. 356f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT((characters + 1) == (this->characters() + length)); 357f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); 358f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // There should be room left, since one UChar hasn't been converted. 359f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT((buffer + 3) <= (buffer + bufferVector.size())); 360f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick putUTF8Triple(buffer, *characters); 361f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 362f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 363f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return CString(bufferVector.data(), buffer - bufferVector.data()); 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 367