source: webkit/trunk/JavaScriptCore/runtime/UString.cpp@ 65177

Last change on this file since 65177 was 65177, checked in by [email protected], 15 years ago

Rubber stamps by Darin Adler & Sam Weinig.

Bug 43867 - Some UString cleanup

Change JSC::UString data(), size(), and from(), to characters(), length(), and number() to match WTF::String.
Move string concatenation methods to a new header to simplify down UString.h. Remove is8Bit().

JavaScriptCore:

  • API/JSClassRef.cpp:

(OpaqueJSClass::~OpaqueJSClass):
(OpaqueJSClass::className):

  • API/OpaqueJSString.cpp:

(OpaqueJSString::create):

(JSC::constantName):
(JSC::idName):
(JSC::CodeBlock::registerName):
(JSC::regexpName):

  • bytecode/EvalCodeCache.h:

(JSC::EvalCodeCache::get):

  • bytecompiler/NodesCodegen.cpp:

(JSC::ResolveNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::processClauseList):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createRegex):

  • parser/ParserArena.h:

(JSC::IdentifierArena::makeNumericIdentifier):

  • parser/SourceProvider.h:

(JSC::UStringSourceProvider::data):
(JSC::UStringSourceProvider::length):

  • profiler/Profiler.cpp:
  • runtime/Arguments.cpp:

(JSC::Arguments::getOwnPropertySlot):
(JSC::Arguments::getOwnPropertyNames):
(JSC::Arguments::put):
(JSC::Arguments::deleteProperty):

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncToString):

  • runtime/DatePrototype.cpp:

(JSC::formatLocaleDate):

  • runtime/ExceptionHelpers.cpp:
  • runtime/FunctionConstructor.cpp:
  • runtime/FunctionPrototype.cpp:

(JSC::insertSemicolonIfNeeded):

  • runtime/Identifier.h:

(JSC::Identifier::characters):
(JSC::Identifier::length):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::decode):
(JSC::parseInt):
(JSC::parseFloat):
(JSC::globalFuncEscape):
(JSC::globalFuncUnescape):

  • runtime/JSNumberCell.cpp:

(JSC::JSNumberCell::toString):

  • runtime/JSONObject.cpp:

(JSC::gap):
(JSC::Stringifier::appendQuotedString):
(JSC::Stringifier::appendStringifiedValue):
(JSC::Stringifier::indent):
(JSC::Stringifier::unindent):
(JSC::Walker::walk):

  • runtime/JSString.cpp:

(JSC::JSString::replaceCharacter):
(JSC::JSString::getIndexSlowCase):

  • runtime/JSString.h:

(JSC::RopeBuilder::JSString):
(JSC::RopeBuilder::appendValueInConstructAndIncrementLength):
(JSC::RopeBuilder::fiberCount):
(JSC::jsSingleCharacterSubstring):
(JSC::jsNontrivialString):
(JSC::JSString::getIndex):
(JSC::jsString):
(JSC::jsStringWithFinalizer):
(JSC::jsSubstring):
(JSC::jsOwnedString):

  • runtime/JSStringBuilder.h:

(JSC::JSStringBuilder::append):

  • runtime/LiteralParser.h:

(JSC::LiteralParser::Lexer::Lexer):

  • runtime/NumberPrototype.cpp:

(JSC::numberProtoFuncToString):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToPrecision):

  • runtime/NumericStrings.h:

(JSC::NumericStrings::add):
(JSC::NumericStrings::lookupSmallString):

  • runtime/Operations.h:

(JSC::jsString):

  • runtime/RegExp.cpp:

(JSC::RegExp::match):

  • runtime/RegExpCache.cpp:

(JSC::RegExpCache::lookupOrCreate):
(JSC::RegExpCache::create):

  • runtime/RegExpConstructor.cpp:

(JSC::RegExpConstructor::getRightContext):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::match):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncToString):

  • runtime/StringBuilder.h:

(JSC::StringBuilder::append):

  • runtime/StringConcatenate.h: Copied from JavaScriptCore/runtime/UString.h.

(JSC::):
(JSC::sumWithOverflow):
(JSC::tryMakeString):
(JSC::makeString):

  • runtime/StringObject.cpp:

(JSC::StringObject::getOwnPropertyNames):

  • runtime/StringPrototype.cpp:

(JSC::substituteBackreferencesSlow):
(JSC::localeCompare):
(JSC::jsSpliceSubstringsWithSeparators):
(JSC::stringProtoFuncReplace):
(JSC::stringProtoFuncCharAt):
(JSC::stringProtoFuncCharCodeAt):
(JSC::stringProtoFuncIndexOf):
(JSC::stringProtoFuncLastIndexOf):
(JSC::stringProtoFuncSlice):
(JSC::stringProtoFuncSplit):
(JSC::stringProtoFuncSubstr):
(JSC::stringProtoFuncSubstring):
(JSC::stringProtoFuncToLowerCase):
(JSC::stringProtoFuncToUpperCase):
(JSC::stringProtoFuncFontsize):
(JSC::stringProtoFuncLink):
(JSC::trimString):

  • runtime/UString.cpp:

(JSC::UString::number):
(JSC::UString::ascii):
(JSC::UString::operator[]):
(JSC::UString::toDouble):
(JSC::UString::find):
(JSC::UString::rfind):
(JSC::UString::substr):
(JSC::operator==):
(JSC::operator<):
(JSC::operator>):
(JSC::UString::UTF8String):

  • runtime/UString.h:

(JSC::UString::UString):
(JSC::UString::adopt):
(JSC::UString::length):
(JSC::UString::characters):
(JSC::UString::isNull):
(JSC::UString::isEmpty):
(JSC::UString::impl):
(JSC::UString::cost):
(JSC::operator==):
(JSC::operator!=):
(JSC::codePointCompare):
(JSC::UString::toArrayIndex):
(JSC::IdentifierRepHash::hash):
(WTF::):

  • yarr/RegexJIT.cpp:

(JSC::Yarr::jitCompileRegex):

  • yarr/RegexParser.h:

(JSC::Yarr::Parser::Parser):

JavaScriptGlue:

  • JSUtils.cpp:

(UStringToCFString):
(KJSValueToCFTypeInternal):

  • JavaScriptGlue.xcodeproj/project.pbxproj:

WebCore:

  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSCSSStyleDeclarationCustom.cpp:

(WebCore::hasCSSPropertyNamePrefix):
(WebCore::cssPropertyName):

  • bindings/js/JSLocationCustom.cpp:

(WebCore::JSLocation::setPort):

  • bindings/js/ScriptDebugServer.cpp:

(WebCore::ScriptDebugServer::dispatchDidParseSource):

  • bindings/js/ScriptString.h:

(WebCore::ScriptString::size):

  • bindings/js/ScriptValue.cpp:

(WebCore::jsToInspectorValue):

  • bindings/objc/WebScriptObject.mm:

(+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):

  • bridge/jni/jni_jsobject.mm:

(JavaJSObject::convertValueToJObject):

  • bridge/jni/jsc/JNIUtilityPrivate.cpp:

(JSC::Bindings::convertArrayInstanceToJavaArray):
(JSC::Bindings::convertValueToJValue):

  • bridge/objc/objc_runtime.mm:

(JSC::Bindings::callObjCFallbackObject):

WebKit/mac:

  • WebView/WebScriptDebugger.mm:

(toNSString):

  • Property svn:eol-style set to native
File size: 15.1 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Cameron Zwarich ([email protected])
5 * Copyright (C) 2009 Google Inc. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25#include "UString.h"
26
27#include "JSGlobalObjectFunctions.h"
28#include "Collector.h"
29#include "dtoa.h"
30#include "Identifier.h"
31#include "Operations.h"
32#include <ctype.h>
33#include <limits.h>
34#include <limits>
35#include <stdio.h>
36#include <stdlib.h>
37#include <wtf/ASCIICType.h>
38#include <wtf/Assertions.h>
39#include <wtf/MathExtras.h>
40#include <wtf/StringExtras.h>
41#include <wtf/Vector.h>
42#include <wtf/unicode/UTF8.h>
43
44#if HAVE(STRINGS_H)
45#include <strings.h>
46#endif
47
48using namespace WTF;
49using namespace WTF::Unicode;
50using namespace std;
51
52namespace JSC {
53
54extern const double NaN;
55extern const double Inf;
56
57COMPILE_ASSERT(sizeof(UString) == sizeof(void*), UString_should_stay_small);
58
59UString::UString(const char* c)
60 : m_impl(StringImpl::create(c))
61{
62}
63
64UString::UString(const char* c, unsigned length)
65 : m_impl(StringImpl::create(c, length))
66{
67}
68
69UString::UString(const UChar* c, unsigned length)
70 : m_impl(StringImpl::create(c, length))
71{
72}
73
74UString UString::number(int i)
75{
76 UChar buf[1 + sizeof(i) * 3];
77 UChar* end = buf + sizeof(buf) / sizeof(UChar);
78 UChar* p = end;
79
80 if (i == 0)
81 *--p = '0';
82 else if (i == INT_MIN) {
83 char minBuf[1 + sizeof(i) * 3];
84 snprintf(minBuf, sizeof(minBuf), "%d", INT_MIN);
85 return UString(minBuf);
86 } else {
87 bool negative = false;
88 if (i < 0) {
89 negative = true;
90 i = -i;
91 }
92 while (i) {
93 *--p = static_cast<unsigned short>((i % 10) + '0');
94 i /= 10;
95 }
96 if (negative)
97 *--p = '-';
98 }
99
100 return UString(p, static_cast<unsigned>(end - p));
101}
102
103UString UString::number(long long i)
104{
105 UChar buf[1 + sizeof(i) * 3];
106 UChar* end = buf + sizeof(buf) / sizeof(UChar);
107 UChar* p = end;
108
109 if (i == 0)
110 *--p = '0';
111 else if (i == std::numeric_limits<long long>::min()) {
112 char minBuf[1 + sizeof(i) * 3];
113#if OS(WINDOWS)
114 snprintf(minBuf, sizeof(minBuf), "%I64d", std::numeric_limits<long long>::min());
115#else
116 snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min());
117#endif
118 return UString(minBuf);
119 } else {
120 bool negative = false;
121 if (i < 0) {
122 negative = true;
123 i = -i;
124 }
125 while (i) {
126 *--p = static_cast<unsigned short>((i % 10) + '0');
127 i /= 10;
128 }
129 if (negative)
130 *--p = '-';
131 }
132
133 return UString(p, static_cast<unsigned>(end - p));
134}
135
136UString UString::number(unsigned u)
137{
138 UChar buf[sizeof(u) * 3];
139 UChar* end = buf + sizeof(buf) / sizeof(UChar);
140 UChar* p = end;
141
142 if (u == 0)
143 *--p = '0';
144 else {
145 while (u) {
146 *--p = static_cast<unsigned short>((u % 10) + '0');
147 u /= 10;
148 }
149 }
150
151 return UString(p, static_cast<unsigned>(end - p));
152}
153
154UString UString::number(long l)
155{
156 UChar buf[1 + sizeof(l) * 3];
157 UChar* end = buf + sizeof(buf) / sizeof(UChar);
158 UChar* p = end;
159
160 if (l == 0)
161 *--p = '0';
162 else if (l == LONG_MIN) {
163 char minBuf[1 + sizeof(l) * 3];
164 snprintf(minBuf, sizeof(minBuf), "%ld", LONG_MIN);
165 return UString(minBuf);
166 } else {
167 bool negative = false;
168 if (l < 0) {
169 negative = true;
170 l = -l;
171 }
172 while (l) {
173 *--p = static_cast<unsigned short>((l % 10) + '0');
174 l /= 10;
175 }
176 if (negative)
177 *--p = '-';
178 }
179
180 return UString(p, end - p);
181}
182
183UString UString::number(double d)
184{
185 DtoaBuffer buffer;
186 unsigned length;
187 doubleToStringInJavaScriptFormat(d, buffer, &length);
188 return UString(buffer, length);
189}
190
191char* UString::ascii() const
192{
193 static char* asciiBuffer = 0;
194
195 unsigned len = length();
196 unsigned neededSize = len + 1;
197 delete[] asciiBuffer;
198 asciiBuffer = new char[neededSize];
199
200 const UChar* p = characters();
201 char* q = asciiBuffer;
202 const UChar* limit = p + len;
203 while (p != limit) {
204 *q = static_cast<char>(p[0]);
205 ++p;
206 ++q;
207 }
208 *q = '\0';
209
210 return asciiBuffer;
211}
212
213UChar UString::operator[](unsigned pos) const
214{
215 if (pos >= length())
216 return '\0';
217 return characters()[pos];
218}
219
220static inline bool isInfinity(double number)
221{
222 return number == Inf || number == -Inf;
223}
224
225static bool isInfinity(const UChar* data, const UChar* end)
226{
227 return data + 7 < end
228 && data[0] == 'I'
229 && data[1] == 'n'
230 && data[2] == 'f'
231 && data[3] == 'i'
232 && data[4] == 'n'
233 && data[5] == 'i'
234 && data[6] == 't'
235 && data[7] == 'y';
236}
237
238double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
239{
240 unsigned size = this->length();
241
242 if (size == 1) {
243 UChar c = characters()[0];
244 if (isASCIIDigit(c))
245 return c - '0';
246 if (isStrWhiteSpace(c) && tolerateEmptyString)
247 return 0;
248 return NaN;
249 }
250
251 // FIXME: If tolerateTrailingJunk is true, then we want to tolerate junk
252 // after the number, even if it contains invalid UTF-16 sequences. So we
253 // shouldn't use the UTF8String function, which returns null when it
254 // encounters invalid UTF-16. Further, we have no need to convert the
255 // non-ASCII characters to UTF-8, so the UTF8String does quite a bit of
256 // unnecessary work.
257
258 // FIXME: The space skipping code below skips only ASCII spaces, but callers
259 // need to skip all StrWhiteSpace. The isStrWhiteSpace function does the
260 // right thing but requires UChar, not char, for its argument.
261
262 const UChar* data = this->characters();
263 const UChar* end = data + size;
264
265 // Skip leading white space.
266 for (; data < end; ++data) {
267 if (!isStrWhiteSpace(*data))
268 break;
269 }
270
271 // Empty string.
272 if (data == end)
273 return tolerateEmptyString ? 0.0 : NaN;
274
275 double number;
276
277 if (data[0] == '0' && data + 2 < end && (data[1] | 0x20) == 'x' && isASCIIHexDigit(data[2])) {
278 // Hex number.
279 data += 2;
280 const UChar* firstDigitPosition = data;
281 number = 0;
282 while (true) {
283 number = number * 16 + toASCIIHexValue(*data);
284 ++data;
285 if (data == end)
286 break;
287 if (!isASCIIHexDigit(*data))
288 break;
289 }
290 if (number >= mantissaOverflowLowerBound)
291 number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 16);
292 } else {
293 // Decimal number.
294
295 // Put into a null-terminated byte buffer.
296 Vector<char, 32> byteBuffer;
297 for (const UChar* characters = data; characters < end; ++characters) {
298 UChar character = *characters;
299 byteBuffer.append(isASCII(character) ? character : 0);
300 }
301 byteBuffer.append(0);
302
303 char* byteBufferEnd;
304 number = WTF::strtod(byteBuffer.data(), &byteBufferEnd);
305 const UChar* pastNumber = data + (byteBufferEnd - byteBuffer.data());
306
307 if ((number || pastNumber != data) && !isInfinity(number))
308 data = pastNumber;
309 else {
310 // We used strtod() to do the conversion. However, strtod() handles
311 // infinite values slightly differently than JavaScript in that it
312 // converts the string "inf" with any capitalization to infinity,
313 // whereas the ECMA spec requires that it be converted to NaN.
314
315 double signedInfinity = Inf;
316 if (data < end) {
317 if (*data == '+')
318 data++;
319 else if (*data == '-') {
320 signedInfinity = -Inf;
321 data++;
322 }
323 }
324 if (isInfinity(data, end)) {
325 number = signedInfinity;
326 data += 8;
327 } else if (isInfinity(number) && data < end && (*data | 0x20) != 'i')
328 data = pastNumber;
329 else
330 return NaN;
331 }
332 }
333
334 // Look for trailing junk.
335 if (!tolerateTrailingJunk) {
336 // Allow trailing white space.
337 for (; data < end; ++data) {
338 if (!isStrWhiteSpace(*data))
339 break;
340 }
341 if (data != end)
342 return NaN;
343 }
344
345 return number;
346}
347
348double UString::toDouble(bool tolerateTrailingJunk) const
349{
350 return toDouble(tolerateTrailingJunk, true);
351}
352
353double UString::toDouble() const
354{
355 return toDouble(false, true);
356}
357
358uint32_t UString::toUInt32(bool* ok) const
359{
360 double d = toDouble();
361 bool b = true;
362
363 if (d != static_cast<uint32_t>(d)) {
364 b = false;
365 d = 0;
366 }
367
368 if (ok)
369 *ok = b;
370
371 return static_cast<uint32_t>(d);
372}
373
374uint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const
375{
376 double d = toDouble(false, tolerateEmptyString);
377 bool b = true;
378
379 if (d != static_cast<uint32_t>(d)) {
380 b = false;
381 d = 0;
382 }
383
384 if (ok)
385 *ok = b;
386
387 return static_cast<uint32_t>(d);
388}
389
390uint32_t UString::toStrictUInt32(bool* ok) const
391{
392 if (ok)
393 *ok = false;
394
395 // Empty string is not OK.
396 unsigned len = m_impl->length();
397 if (len == 0)
398 return 0;
399 const UChar* p = m_impl->characters();
400 unsigned short c = p[0];
401
402 // If the first digit is 0, only 0 itself is OK.
403 if (c == '0') {
404 if (len == 1 && ok)
405 *ok = true;
406 return 0;
407 }
408
409 // Convert to UInt32, checking for overflow.
410 uint32_t i = 0;
411 while (1) {
412 // Process character, turning it into a digit.
413 if (c < '0' || c > '9')
414 return 0;
415 const unsigned d = c - '0';
416
417 // Multiply by 10, checking for overflow out of 32 bits.
418 if (i > 0xFFFFFFFFU / 10)
419 return 0;
420 i *= 10;
421
422 // Add in the digit, checking for overflow out of 32 bits.
423 const unsigned max = 0xFFFFFFFFU - d;
424 if (i > max)
425 return 0;
426 i += d;
427
428 // Handle end of string.
429 if (--len == 0) {
430 if (ok)
431 *ok = true;
432 return i;
433 }
434
435 // Get next character.
436 c = *(++p);
437 }
438}
439
440unsigned UString::find(const UString& f, unsigned pos) const
441{
442 unsigned fsz = f.length();
443
444 if (fsz == 1) {
445 UChar ch = f[0];
446 const UChar* end = characters() + length();
447 for (const UChar* c = characters() + pos; c < end; c++) {
448 if (*c == ch)
449 return static_cast<unsigned>(c - characters());
450 }
451 return NotFound;
452 }
453
454 unsigned sz = length();
455 if (sz < fsz)
456 return NotFound;
457 if (fsz == 0)
458 return pos;
459 const UChar* end = characters() + sz - fsz;
460 unsigned fsizeminusone = (fsz - 1) * sizeof(UChar);
461 const UChar* fdata = f.characters();
462 unsigned short fchar = fdata[0];
463 ++fdata;
464 for (const UChar* c = characters() + pos; c <= end; c++) {
465 if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
466 return static_cast<unsigned>(c - characters());
467 }
468
469 return NotFound;
470}
471
472unsigned UString::find(UChar ch, unsigned pos) const
473{
474 const UChar* end = characters() + length();
475 for (const UChar* c = characters() + pos; c < end; c++) {
476 if (*c == ch)
477 return static_cast<unsigned>(c - characters());
478 }
479
480 return NotFound;
481}
482
483unsigned UString::rfind(const UString& f, unsigned pos) const
484{
485 unsigned sz = length();
486 unsigned fsz = f.length();
487 if (sz < fsz)
488 return NotFound;
489 if (pos > sz - fsz)
490 pos = sz - fsz;
491 if (fsz == 0)
492 return pos;
493 unsigned fsizeminusone = (fsz - 1) * sizeof(UChar);
494 const UChar* fdata = f.characters();
495 for (const UChar* c = characters() + pos; c >= characters(); c--) {
496 if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
497 return static_cast<unsigned>(c - characters());
498 }
499
500 return NotFound;
501}
502
503unsigned UString::rfind(UChar ch, unsigned pos) const
504{
505 if (isEmpty())
506 return NotFound;
507 if (pos + 1 >= length())
508 pos = length() - 1;
509 for (const UChar* c = characters() + pos; c >= characters(); c--) {
510 if (*c == ch)
511 return static_cast<unsigned>(c - characters());
512 }
513
514 return NotFound;
515}
516
517UString UString::substr(unsigned pos, unsigned len) const
518{
519 unsigned s = length();
520
521 if (pos >= s)
522 pos = s;
523 unsigned limit = s - pos;
524 if (len > limit)
525 len = limit;
526
527 if (pos == 0 && len == s)
528 return *this;
529
530 return UString(StringImpl::create(m_impl, pos, len));
531}
532
533bool operator==(const UString& s1, const char *s2)
534{
535 if (s2 == 0)
536 return s1.isEmpty();
537
538 const UChar* u = s1.characters();
539 const UChar* uend = u + s1.length();
540 while (u != uend && *s2) {
541 if (u[0] != (unsigned char)*s2)
542 return false;
543 s2++;
544 u++;
545 }
546
547 return u == uend && *s2 == 0;
548}
549
550bool operator<(const UString& s1, const UString& s2)
551{
552 const unsigned l1 = s1.length();
553 const unsigned l2 = s2.length();
554 const unsigned lmin = l1 < l2 ? l1 : l2;
555 const UChar* c1 = s1.characters();
556 const UChar* c2 = s2.characters();
557 unsigned l = 0;
558 while (l < lmin && *c1 == *c2) {
559 c1++;
560 c2++;
561 l++;
562 }
563 if (l < lmin)
564 return (c1[0] < c2[0]);
565
566 return (l1 < l2);
567}
568
569bool operator>(const UString& s1, const UString& s2)
570{
571 const unsigned l1 = s1.length();
572 const unsigned l2 = s2.length();
573 const unsigned lmin = l1 < l2 ? l1 : l2;
574 const UChar* c1 = s1.characters();
575 const UChar* c2 = s2.characters();
576 unsigned l = 0;
577 while (l < lmin && *c1 == *c2) {
578 c1++;
579 c2++;
580 l++;
581 }
582 if (l < lmin)
583 return (c1[0] > c2[0]);
584
585 return (l1 > l2);
586}
587
588CString UString::UTF8String(bool strict) const
589{
590 // Allocate a buffer big enough to hold all the characters.
591 const unsigned len = length();
592 Vector<char, 1024> buffer(len * 3);
593
594 // Convert to runs of 8-bit characters.
595 char* p = buffer.data();
596 const UChar* d = reinterpret_cast<const UChar*>(&characters()[0]);
597 ConversionResult result = convertUTF16ToUTF8(&d, d + len, &p, p + buffer.size(), strict);
598 if (result != conversionOK)
599 return CString();
600
601 return CString(buffer.data(), p - buffer.data());
602}
603
604} // namespace JSC
Note: See TracBrowser for help on using the repository browser.