diff options
Diffstat (limited to 'JavaScriptCore/wtf')
53 files changed, 2411 insertions, 449 deletions
diff --git a/JavaScriptCore/wtf/CMakeLists.txt b/JavaScriptCore/wtf/CMakeLists.txt index 896794e..898d19b 100644 --- a/JavaScriptCore/wtf/CMakeLists.txt +++ b/JavaScriptCore/wtf/CMakeLists.txt @@ -2,6 +2,7 @@ SET(WTF_SOURCES Assertions.cpp ByteArray.cpp CurrentTime.cpp + DecimalNumber.cpp FastMalloc.cpp HashTable.cpp MainThread.cpp @@ -16,6 +17,7 @@ SET(WTF_SOURCES text/AtomicString.cpp text/CString.cpp + text/StringBuilder.cpp text/StringImpl.cpp text/StringStatics.cpp text/WTFString.cpp diff --git a/JavaScriptCore/wtf/CMakeListsEfl.txt b/JavaScriptCore/wtf/CMakeListsEfl.txt index 6a714ae..e5d8bd7 100644 --- a/JavaScriptCore/wtf/CMakeListsEfl.txt +++ b/JavaScriptCore/wtf/CMakeListsEfl.txt @@ -1,4 +1,10 @@ -ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1) +IF (ENABLE_FAST_MALLOC) + LIST(APPEND WTF_SOURCES + TCSystemAlloc.cpp + ) +ELSE () + ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1) +ENDIF() LIST(APPEND WTF_SOURCES efl/MainThreadEfl.cpp @@ -16,7 +22,12 @@ IF (ENABLE_GLIB_SUPPORT) ) LIST(APPEND WTF_INCLUDE_DIRECTORIES - ${JAVASCRIPTCORE_DIR}/wtf/gobject + ${Glib_INCLUDE_DIRS} + ${JAVASCRIPTCORE_DIR}/wtf/gobject + ) + + LIST(APPEND WTF_LIBRARIES + ${Glib_LIBRARIES} ) ENDIF () diff --git a/JavaScriptCore/wtf/CurrentTime.h b/JavaScriptCore/wtf/CurrentTime.h index dcb1f6c..7119656 100644 --- a/JavaScriptCore/wtf/CurrentTime.h +++ b/JavaScriptCore/wtf/CurrentTime.h @@ -61,6 +61,7 @@ namespace WTF { } // namespace WTF using WTF::currentTime; +using WTF::currentTimeMS; using WTF::getLocalTime; #endif // CurrentTime_h diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp index b9a0207..d005859 100644 --- a/JavaScriptCore/wtf/DateMath.cpp +++ b/JavaScriptCore/wtf/DateMath.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * Copyright (C) 2009 Google Inc. All rights reserved. * Copyright (C) 2007-2009 Torch Mobile, Inc. + * Copyright (C) 2010 &yet, LLC. (nate@andyet.net) * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. @@ -479,7 +480,7 @@ void initializeDates() equivalentYearForDST(2000); // Need to call once to initialize a static used in this function. } -static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second) +static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, double second) { double days = (day - 32075) + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4) @@ -557,6 +558,162 @@ static bool parseLong(const char* string, char** stopPosition, int base, long* r return true; } +double parseES5DateFromNullTerminatedCharacters(const char* dateString) +{ + // This parses a date of the form defined in ECMA-262-5, section 15.9.1.15 + // (similar to RFC 3339 / ISO 8601: YYYY-MM-DDTHH:mm:ss[.sss]Z). + // In most cases it is intentionally strict (e.g. correct field widths, no stray whitespace). + + static const long daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + const char* currentPosition = dateString; + char* postParsePosition; + + // This is a bit more lenient on the year string than ES5 specifies: + // instead of restricting to 4 digits (or 6 digits with mandatory +/-), + // it accepts any integer value. Consider this an implementation fallback. + long year; + if (!parseLong(currentPosition, &postParsePosition, 10, &year)) + return NaN; + if (*postParsePosition != '-') + return NaN; + currentPosition = postParsePosition + 1; + + long month; + if (!isASCIIDigit(*currentPosition)) + return NaN; + if (!parseLong(currentPosition, &postParsePosition, 10, &month)) + return NaN; + if (*postParsePosition != '-' || (postParsePosition - currentPosition) != 2) + return NaN; + currentPosition = postParsePosition + 1; + + long day; + if (!isASCIIDigit(*currentPosition)) + return NaN; + if (!parseLong(currentPosition, &postParsePosition, 10, &day)) + return NaN; + if (*postParsePosition != 'T' || (postParsePosition - currentPosition) != 2) + return NaN; + currentPosition = postParsePosition + 1; + + long hours; + if (!isASCIIDigit(*currentPosition)) + return NaN; + if (!parseLong(currentPosition, &postParsePosition, 10, &hours)) + return NaN; + if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2) + return NaN; + currentPosition = postParsePosition + 1; + + long minutes; + if (!isASCIIDigit(*currentPosition)) + return NaN; + if (!parseLong(currentPosition, &postParsePosition, 10, &minutes)) + return NaN; + if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2) + return NaN; + currentPosition = postParsePosition + 1; + + long intSeconds; + if (!isASCIIDigit(*currentPosition)) + return NaN; + if (!parseLong(currentPosition, &postParsePosition, 10, &intSeconds)) + return NaN; + if ((postParsePosition - currentPosition) != 2) + return NaN; + + double seconds = intSeconds; + if (*postParsePosition == '.') { + currentPosition = postParsePosition + 1; + + // In ECMA-262-5 it's a bit unclear if '.' can be present without milliseconds, but + // a reasonable interpretation guided by the given examples and RFC 3339 says "no". + // We check the next character to avoid reading +/- timezone hours after an invalid decimal. + if (!isASCIIDigit(*currentPosition)) + return NaN; + + // We are more lenient than ES5 by accepting more or less than 3 fraction digits. + long fracSeconds; + if (!parseLong(currentPosition, &postParsePosition, 10, &fracSeconds)) + return NaN; + + long numFracDigits = postParsePosition - currentPosition; + seconds += fracSeconds * pow(10.0, static_cast<double>(-numFracDigits)); + } + currentPosition = postParsePosition; + + // A few of these checks could be done inline above, but since many of them are interrelated + // we would be sacrificing readability to "optimize" the (presumably less common) failure path. + if (month < 1 || month > 12) + return NaN; + if (day < 1 || day > daysPerMonth[month - 1]) + return NaN; + if (month == 2 && day > 28 && !isLeapYear(year)) + return NaN; + if (hours < 0 || hours > 24) + return NaN; + if (hours == 24 && (minutes || seconds)) + return NaN; + if (minutes < 0 || minutes > 59) + return NaN; + if (seconds < 0 || seconds >= 61) + return NaN; + if (seconds > 60) { + // Discard leap seconds by clamping to the end of a minute. + seconds = 60; + } + + long timeZoneSeconds = 0; + if (*currentPosition != 'Z') { + bool tzNegative; + if (*currentPosition == '-') + tzNegative = true; + else if (*currentPosition == '+') + tzNegative = false; + else + return NaN; + currentPosition += 1; + + long tzHours; + long tzHoursAbs; + long tzMinutes; + + if (!isASCIIDigit(*currentPosition)) + return NaN; + if (!parseLong(currentPosition, &postParsePosition, 10, &tzHours)) + return NaN; + if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2) + return NaN; + tzHoursAbs = abs(tzHours); + currentPosition = postParsePosition + 1; + + if (!isASCIIDigit(*currentPosition)) + return NaN; + if (!parseLong(currentPosition, &postParsePosition, 10, &tzMinutes)) + return NaN; + if ((postParsePosition - currentPosition) != 2) + return NaN; + currentPosition = postParsePosition; + + if (tzHoursAbs > 24) + return NaN; + if (tzMinutes < 0 || tzMinutes > 59) + return NaN; + + timeZoneSeconds = 60 * (tzMinutes + (60 * tzHoursAbs)); + if (tzNegative) + timeZoneSeconds = -timeZoneSeconds; + } else { + currentPosition += 1; + } + if (*currentPosition) + return NaN; + + double dateSeconds = ymdhmsToSeconds(year, month, day, hours, minutes, seconds) - timeZoneSeconds; + return dateSeconds * msPerSecond; +} + // Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore. static double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset) { diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h index 033d25e..be51947 100644 --- a/JavaScriptCore/wtf/DateMath.h +++ b/JavaScriptCore/wtf/DateMath.h @@ -53,7 +53,8 @@ namespace WTF { void initializeDates(); int equivalentYearForDST(int year); -// Not really math related, but this is currently the only shared place to put these. +// Not really math related, but this is currently the only shared place to put these. +double parseES5DateFromNullTerminatedCharacters(const char* dateString); double parseDateFromNullTerminatedCharacters(const char* dateString); double timeClip(double); @@ -94,6 +95,7 @@ using WTF::msPerDay; using WTF::msPerSecond; using WTF::msToYear; using WTF::secondsPerMinute; +using WTF::parseDateFromNullTerminatedCharacters; #if USE(JSC) namespace JSC { diff --git a/JavaScriptCore/wtf/DecimalNumber.cpp b/JavaScriptCore/wtf/DecimalNumber.cpp new file mode 100644 index 0000000..70304e2 --- /dev/null +++ b/JavaScriptCore/wtf/DecimalNumber.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DecimalNumber.h" +#include <math.h> +#include <wtf/MathExtras.h> +#include <wtf/text/WTFString.h> + +namespace WTF { + +unsigned DecimalNumber::bufferLengthForStringDecimal() const +{ + unsigned length = 0; + // if the exponent is negative the number decimal representation is of the form: + // [<sign>]0.[<zeros>]<significand> + if (m_exponent < 0) { + if (m_sign) + ++length; + length += 2; // for "0." + length += -m_exponent - 1; + length += m_precision; + return length; + } + + unsigned digitsBeforeDecimalPoint = m_exponent + 1; + + // If the precision is <= than the number of digits to get up to the decimal + // point, then there is no fractional part, number is of the form: + // [<sign>]<significand>[<zeros>] + if (m_precision <= digitsBeforeDecimalPoint) { + if (m_sign) + ++length; + length += m_precision; + length += digitsBeforeDecimalPoint - m_precision; + return length; + } + + // If we get here, number starts before the decimal point, and ends after it, + // as such is of the form: + // [<sign>]<significand-begin>.<significand-end> + if (m_sign) + ++length; + length += digitsBeforeDecimalPoint; + ++length; // for decimal point + length += m_precision - digitsBeforeDecimalPoint; + + return length; +} + +unsigned DecimalNumber::bufferLengthForStringExponential() const +{ + unsigned length = 0; + if (m_sign) + ++length; + + // Add the significand + ++length; + + if (m_precision > 1) { + ++length; // for decimal point + length += m_precision - 1; + } + + // Add "e+" or "e-" + length += 2; + + int exponent = (m_exponent >= 0) ? m_exponent : -m_exponent; + + // Add the exponent + if (exponent >= 100) + ++length; + if (exponent >= 10) + ++length; + ++length; + + return length; +} + +unsigned DecimalNumber::toStringDecimal(UChar* buffer, unsigned bufferLength) const +{ + ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringDecimal()); + + // Should always be at least one digit to add to the string! + ASSERT(m_precision); + UChar* next = buffer; + + // if the exponent is negative the number decimal representation is of the form: + // [<sign>]0.[<zeros>]<significand> + if (m_exponent < 0) { + unsigned zeros = -m_exponent - 1; + + if (m_sign) + *next++ = '-'; + *next++ = '0'; + *next++ = '.'; + for (unsigned i = 0; i < zeros; ++i) + *next++ = '0'; + for (unsigned i = 0; i < m_precision; ++i) + *next++ = m_significand[i]; + + return next - buffer; + } + + unsigned digitsBeforeDecimalPoint = m_exponent + 1; + + // If the precision is <= than the number of digits to get up to the decimal + // point, then there is no fractional part, number is of the form: + // [<sign>]<significand>[<zeros>] + if (m_precision <= digitsBeforeDecimalPoint) { + if (m_sign) + *next++ = '-'; + for (unsigned i = 0; i < m_precision; ++i) + *next++ = m_significand[i]; + for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i) + *next++ = '0'; + + return next - buffer; + } + + // If we get here, number starts before the decimal point, and ends after it, + // as such is of the form: + // [<sign>]<significand-begin>.<significand-end> + + if (m_sign) + *next++ = '-'; + for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i) + *next++ = m_significand[i]; + *next++ = '.'; + for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i) + *next++ = m_significand[i]; + + return next - buffer; +} + +unsigned DecimalNumber::toStringExponential(UChar* buffer, unsigned bufferLength) const +{ + ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringExponential()); + + // Should always be at least one digit to add to the string! + ASSERT(m_precision); + UChar* next = buffer; + + // Add the sign + if (m_sign) + *next++ = '-'; + + // Add the significand + *next++ = m_significand[0]; + if (m_precision > 1) { + *next++ = '.'; + for (unsigned i = 1; i < m_precision; ++i) + *next++ = m_significand[i]; + } + + // Add "e+" or "e-" + *next++ = 'e'; + int exponent; + if (m_exponent >= 0) { + *next++ = '+'; + exponent = m_exponent; + } else { + *next++ = '-'; + exponent = -m_exponent; + } + + // Add the exponent + if (exponent >= 100) + *next++ = '0' + exponent / 100; + if (exponent >= 10) + *next++ = '0' + (exponent % 100) / 10; + *next++ = '0' + exponent % 10; + + return next - buffer; +} + +} // namespace WTF diff --git a/JavaScriptCore/wtf/DecimalNumber.h b/JavaScriptCore/wtf/DecimalNumber.h index 3a831b7..c42f00b 100644 --- a/JavaScriptCore/wtf/DecimalNumber.h +++ b/JavaScriptCore/wtf/DecimalNumber.h @@ -81,104 +81,16 @@ public: ASSERT(m_significand[0] != '0' || !m_exponent); } - unsigned toStringDecimal(NumberToStringBuffer buffer) - { - // Should always be at least one digit to add to the string! - ASSERT(m_precision); - UChar* next = buffer; - - // if the exponent is negative the number decimal representation is of the form: - // [<sign>]0.[<zeros>]<significand> - if (m_exponent < 0) { - unsigned zeros = -m_exponent - 1; - - if (m_sign) - *next++ = '-'; - *next++ = '0'; - *next++ = '.'; - for (unsigned i = 0; i < zeros; ++i) - *next++ = '0'; - for (unsigned i = 0; i < m_precision; ++i) - *next++ = m_significand[i]; - - return next - buffer; - } - - unsigned digitsBeforeDecimalPoint = m_exponent + 1; - - // If the precision is <= than the number of digits to get up to the decimal - // point, then there is no fractional part, number is of the form: - // [<sign>]<significand>[<zeros>] - if (m_precision <= digitsBeforeDecimalPoint) { - if (m_sign) - *next++ = '-'; - for (unsigned i = 0; i < m_precision; ++i) - *next++ = m_significand[i]; - for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i) - *next++ = '0'; - - return next - buffer; - } - - // If we get here, number starts before the decimal point, and ends after it, - // as such is of the form: - // [<sign>]<significand-begin>.<significand-end> - - if (m_sign) - *next++ = '-'; - for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i) - *next++ = m_significand[i]; - *next++ = '.'; - for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i) - *next++ = m_significand[i]; - - return next - buffer; - } + unsigned bufferLengthForStringDecimal() const; + unsigned bufferLengthForStringExponential() const; - unsigned toStringExponential(NumberToStringBuffer buffer) - { - // Should always be at least one digit to add to the string! - ASSERT(m_precision); - - UChar* next = buffer; - - // Add the sign - if (m_sign) - *next++ = '-'; - - // Add the significand - *next++ = m_significand[0]; - if (m_precision > 1) { - *next++ = '.'; - for (unsigned i = 1; i < m_precision; ++i) - *next++ = m_significand[i]; - } - - // Add "e+" or "e-" - *next++ = 'e'; - int exponent; - if (m_exponent >= 0) { - *next++ = '+'; - exponent = m_exponent; - } else { - *next++ = '-'; - exponent = -m_exponent; - } - - // Add the exponent - if (exponent >= 100) - *next++ = '0' + exponent / 100; - if (exponent >= 10) - *next++ = '0' + (exponent % 100) / 10; - *next++ = '0' + exponent % 10; - - return next - buffer; - } + unsigned toStringDecimal(UChar* buffer, unsigned bufferLength) const; + unsigned toStringExponential(UChar* buffer, unsigned bufferLength) const; - bool sign() { return m_sign; } - int exponent() { return m_exponent; } - const char* significand() { return m_significand; } // significand contains precision characters, is not null-terminated. - unsigned precision() { return m_precision; } + bool sign() const { return m_sign; } + int exponent() const { return m_exponent; } + const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated. + unsigned precision() const { return m_precision; } private: bool m_sign; diff --git a/JavaScriptCore/wtf/FastAllocBase.h b/JavaScriptCore/wtf/FastAllocBase.h index 81b1de0..bb1825e 100644 --- a/JavaScriptCore/wtf/FastAllocBase.h +++ b/JavaScriptCore/wtf/FastAllocBase.h @@ -85,38 +85,41 @@ namespace WTF { - class FastAllocBase { - public: - // Placement operator new. - void* operator new(size_t, void* p) { return p; } - void* operator new[](size_t, void* p) { return p; } - - void* operator new(size_t size) - { - void* p = fastMalloc(size); - fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNew); - return p; - } - - void operator delete(void* p) - { - fastMallocMatchValidateFree(p, Internal::AllocTypeClassNew); - fastFree(p); - } - - void* operator new[](size_t size) - { - void* p = fastMalloc(size); - fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNewArray); - return p; - } - - void operator delete[](void* p) - { - fastMallocMatchValidateFree(p, Internal::AllocTypeClassNewArray); - fastFree(p); - } - }; +#define WTF_MAKE_FAST_ALLOCATED \ +public: \ + void* operator new(size_t, void* p) { return p; } \ + void* operator new[](size_t, void* p) { return p; } \ + \ + void* operator new(size_t size) \ + { \ + void* p = ::WTF::fastMalloc(size); \ + ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNew); \ + return p; \ + } \ + \ + void operator delete(void* p) \ + { \ + ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNew); \ + ::WTF::fastFree(p); \ + } \ + \ + void* operator new[](size_t size) \ + { \ + void* p = ::WTF::fastMalloc(size); \ + ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNewArray); \ + return p; \ + } \ + \ + void operator delete[](void* p) \ + { \ + ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNewArray); \ + ::WTF::fastFree(p); \ + } \ +private: + +class FastAllocBase { + WTF_MAKE_FAST_ALLOCATED +}; // fastNew / fastDelete diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp index 1e537b9..bbbdaf2 100644 --- a/JavaScriptCore/wtf/FastMalloc.cpp +++ b/JavaScriptCore/wtf/FastMalloc.cpp @@ -2185,10 +2185,10 @@ class TCMalloc_ThreadCache { // Total byte size in cache size_t Size() const { return size_; } - void* Allocate(size_t size); + ALWAYS_INLINE void* Allocate(size_t size); void Deallocate(void* ptr, size_t size_class); - void FetchFromCentralCache(size_t cl, size_t allocationSize); + ALWAYS_INLINE void FetchFromCentralCache(size_t cl, size_t allocationSize); void ReleaseToCentralCache(size_t cl, int N); void Scavenge(); void Print() const; @@ -2289,12 +2289,12 @@ class TCMalloc_Central_FreeList { // REQUIRES: lock_ is held // Release an object to spans. // May temporarily release lock_. - void ReleaseToSpans(void* object); + ALWAYS_INLINE void ReleaseToSpans(void* object); // REQUIRES: lock_ is held // Populate cache by fetching from the page heap. // May temporarily release lock_. - void Populate(); + ALWAYS_INLINE void Populate(); // REQUIRES: lock is held. // Tries to make room for a TCEntry. If the cache is full it will try to @@ -2307,7 +2307,7 @@ class TCMalloc_Central_FreeList { // just iterates over the sizeclasses but does so without taking a lock. // Returns true on success. // May temporarily lock a "random" size class. - static bool EvictRandomSizeClass(size_t locked_size_class, bool force); + static ALWAYS_INLINE bool EvictRandomSizeClass(size_t locked_size_class, bool force); // REQUIRES: lock_ is *not* held. // Tries to shrink the Cache. If force is true it will relase objects to @@ -3705,7 +3705,7 @@ extern "C" #define do_malloc do_malloc<crashOnFailure> template <bool crashOnFailure> -void* malloc(size_t); +ALWAYS_INLINE void* malloc(size_t); void* fastMalloc(size_t size) { @@ -3766,7 +3766,7 @@ void free(void* ptr) { extern "C" #else template <bool crashOnFailure> -void* calloc(size_t, size_t); +ALWAYS_INLINE void* calloc(size_t, size_t); void* fastCalloc(size_t n, size_t elem_size) { @@ -3830,7 +3830,7 @@ void cfree(void* ptr) { extern "C" #else template <bool crashOnFailure> -void* realloc(void*, size_t); +ALWAYS_INLINE void* realloc(void*, size_t); void* fastRealloc(void* old_ptr, size_t new_size) { diff --git a/JavaScriptCore/wtf/MD5.cpp b/JavaScriptCore/wtf/MD5.cpp index 375446e..c926a7b 100644 --- a/JavaScriptCore/wtf/MD5.cpp +++ b/JavaScriptCore/wtf/MD5.cpp @@ -76,7 +76,7 @@ static void expectMD5(CString input, CString expected) snprintf(buf, 3, "%02x", digest.at(i)); buf += 2; } - ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%d] actual:%s expected:%s", input.data(), input.length(), actual.data(), expected.data()); + ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%lu] actual:%s expected:%s", input.data(), static_cast<unsigned long>(input.length()), actual.data(), expected.data()); } static void testMD5() diff --git a/JavaScriptCore/wtf/Noncopyable.h b/JavaScriptCore/wtf/Noncopyable.h index 898c1ba..285ed2e 100644 --- a/JavaScriptCore/wtf/Noncopyable.h +++ b/JavaScriptCore/wtf/Noncopyable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public diff --git a/JavaScriptCore/wtf/NullPtr.h b/JavaScriptCore/wtf/NullPtr.h new file mode 100644 index 0000000..10a5814 --- /dev/null +++ b/JavaScriptCore/wtf/NullPtr.h @@ -0,0 +1,48 @@ +/* + +Copyright (C) 2010 Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef NullPtr_h +#define NullPtr_h + +// For compilers and standard libraries that do not yet include it, this adds the +// nullptr_t type and nullptr object. They are defined in the same namespaces they +// would be in compiler and library that had the support. + +#ifndef __has_feature + #define __has_feature(feature) 0 +#endif + +#if !__has_feature(cxx_nullptr) + +namespace std { + class nullptr_t { }; +} + +extern std::nullptr_t nullptr; + +#endif + +#endif diff --git a/JavaScriptCore/wtf/OwnArrayPtr.h b/JavaScriptCore/wtf/OwnArrayPtr.h index ce056b3..643b90b 100644 --- a/JavaScriptCore/wtf/OwnArrayPtr.h +++ b/JavaScriptCore/wtf/OwnArrayPtr.h @@ -23,6 +23,7 @@ #include "Assertions.h" #include "Noncopyable.h" +#include "NullPtr.h" #include "OwnArrayPtrCommon.h" #include <algorithm> @@ -73,6 +74,7 @@ public: #endif OwnArrayPtr& operator=(const PassOwnArrayPtr<T>&); + OwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; } template<typename U> OwnArrayPtr& operator=(const PassOwnArrayPtr<U>&); void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); } diff --git a/JavaScriptCore/wtf/OwnPtr.h b/JavaScriptCore/wtf/OwnPtr.h index cadfad2..cdc277c 100644 --- a/JavaScriptCore/wtf/OwnPtr.h +++ b/JavaScriptCore/wtf/OwnPtr.h @@ -23,6 +23,7 @@ #include "Assertions.h" #include "Noncopyable.h" +#include "NullPtr.h" #include "OwnPtrCommon.h" #include "TypeTraits.h" #include <algorithm> @@ -72,6 +73,7 @@ namespace WTF { operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; } OwnPtr& operator=(const PassOwnPtr<T>&); + OwnPtr& operator=(std::nullptr_t) { clear(); return *this; } template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&); void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); } diff --git a/JavaScriptCore/wtf/PassOwnArrayPtr.h b/JavaScriptCore/wtf/PassOwnArrayPtr.h index 597339c..6a55491 100644 --- a/JavaScriptCore/wtf/PassOwnArrayPtr.h +++ b/JavaScriptCore/wtf/PassOwnArrayPtr.h @@ -27,6 +27,7 @@ #define WTF_PassOwnArrayPtr_h #include "Assertions.h" +#include "NullPtr.h" #include "OwnArrayPtrCommon.h" #include "TypeTraits.h" @@ -72,6 +73,7 @@ public: #endif PassOwnArrayPtr& operator=(const PassOwnArrayPtr<T>&); + PassOwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; } template<typename U> PassOwnArrayPtr& operator=(const PassOwnArrayPtr<U>&); template<typename U> friend PassOwnArrayPtr<U> adoptArrayPtr(U*); diff --git a/JavaScriptCore/wtf/PassOwnPtr.h b/JavaScriptCore/wtf/PassOwnPtr.h index a223fa9..60453fc 100644 --- a/JavaScriptCore/wtf/PassOwnPtr.h +++ b/JavaScriptCore/wtf/PassOwnPtr.h @@ -27,6 +27,7 @@ #define WTF_PassOwnPtr_h #include "Assertions.h" +#include "NullPtr.h" #include "OwnPtrCommon.h" #include "TypeTraits.h" @@ -71,6 +72,7 @@ namespace WTF { operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnPtr::m_ptr : 0; } PassOwnPtr& operator=(const PassOwnPtr<T>&); + PassOwnPtr& operator=(std::nullptr_t) { clear(); return *this; } template<typename U> PassOwnPtr& operator=(const PassOwnPtr<U>&); template<typename U> friend PassOwnPtr<U> adoptPtr(U*); diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h index 052d6e2..b179cef 100644 --- a/JavaScriptCore/wtf/PassRefPtr.h +++ b/JavaScriptCore/wtf/PassRefPtr.h @@ -22,6 +22,7 @@ #define WTF_PassRefPtr_h #include "AlwaysInline.h" +#include "NullPtr.h" namespace WTF { @@ -90,6 +91,7 @@ namespace WTF { PassRefPtr& operator=(T*); PassRefPtr& operator=(const PassRefPtr&); + PassRefPtr& operator=(std::nullptr_t) { clear(); return *this; } template<typename U> PassRefPtr& operator=(const PassRefPtr<U>&); template<typename U> PassRefPtr& operator=(const RefPtr<U>&); diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 1843bea..9895824 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -398,7 +398,7 @@ /* OS(NETBSD) - NetBSD */ #if defined(__NetBSD__) -#define WTF_PLATFORM_NETBSD 1 +#define WTF_OS_NETBSD 1 #endif /* OS(OPENBSD) - OpenBSD */ @@ -574,6 +574,8 @@ #define WTF_USE_QT4_UNICODE 1 #elif OS(WINCE) #define WTF_USE_WINCE_UNICODE 1 +#elif PLATFORM(BREWMP) +#define WTF_USE_BREWMP_UNICODE 1 #elif PLATFORM(GTK) /* The GTK+ Unicode backend is configurable */ #else @@ -692,6 +694,10 @@ #define USE_SYSTEM_MALLOC 1 #endif +#if PLATFORM(BREWMP_SIMULATOR) +#define ENABLE_JIT 0 +#endif + #if !defined(HAVE_ACCESSIBILITY) #if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM) #define HAVE_ACCESSIBILITY 1 @@ -934,19 +940,17 @@ #define ENABLE_FULLSCREEN_API 0 #endif -#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) +#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) #if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) \ || (CPU(IA64) && !CPU(IA64_32)) \ || CPU(ALPHA) \ || CPU(SPARC64) \ || CPU(PPC64) #define WTF_USE_JSVALUE64 1 -#elif CPU(ARM_TRADITIONAL) && COMPILER(MSVC) -#define WTF_USE_JSVALUE32 1 #else #define WTF_USE_JSVALUE32_64 1 #endif -#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) */ +#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) */ #if !defined(ENABLE_REPAINT_THROTTLING) #define ENABLE_REPAINT_THROTTLING 0 @@ -986,10 +990,6 @@ #endif #endif - #if !defined(ENABLE_JIT_OPTIMIZE_NATIVE_CALL) && CPU(X86) && USE(JSVALUE32) - #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 - #endif - #ifndef ENABLE_JIT_OPTIMIZE_CALL #define ENABLE_JIT_OPTIMIZE_CALL 1 #endif diff --git a/JavaScriptCore/wtf/RandomNumber.cpp b/JavaScriptCore/wtf/RandomNumber.cpp index b20652b..7a9b6a8 100644 --- a/JavaScriptCore/wtf/RandomNumber.cpp +++ b/JavaScriptCore/wtf/RandomNumber.cpp @@ -44,6 +44,8 @@ extern "C" { #include <AEEAppGen.h> #include <AEESource.h> #include <AEEStdLib.h> +#include <wtf/brew/RefPtrBrew.h> +#include <wtf/brew/ShellBrew.h> #endif namespace WTF { @@ -97,12 +99,8 @@ double randomNumber() return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); #elif PLATFORM(BREWMP) uint32_t bits; - ISource* randomSource; - - IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell; - ISHELL_CreateInstance(shell, AEECLSID_RANDOM, reinterpret_cast<void**>(&randomSource)); - ISOURCE_Read(randomSource, reinterpret_cast<char*>(&bits), 4); - ISOURCE_Release(randomSource); + PlatformRefPtr<ISource> randomSource = createRefPtrInstance<ISource>(AEECLSID_RANDOM); + ISOURCE_Read(randomSource.get(), reinterpret_cast<char*>(&bits), 4); return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); #else diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h index ae414c0..1f1c00e 100644 --- a/JavaScriptCore/wtf/RandomNumberSeed.h +++ b/JavaScriptCore/wtf/RandomNumberSeed.h @@ -64,6 +64,8 @@ inline void initializeRandomNumberGenerator() init_by_array(initializationBuffer, 4); #elif COMPILER(MSVC) && defined(_CRT_RAND_S) // On Windows we use rand_s which initialises itself +#elif PLATFORM(BREWMP) + // On Brew MP we use AEECLSID_RANDOM which initialises itself #elif OS(UNIX) // srandomdev is not guaranteed to exist on linux so we use this poor seed, this should be improved timeval time; diff --git a/JavaScriptCore/wtf/RefPtr.h b/JavaScriptCore/wtf/RefPtr.h index 8bd1ac3..6afa886 100644 --- a/JavaScriptCore/wtf/RefPtr.h +++ b/JavaScriptCore/wtf/RefPtr.h @@ -24,7 +24,6 @@ #define WTF_RefPtr_h #include <algorithm> -#include "AlwaysInline.h" #include "FastAllocBase.h" #include "PassRefPtr.h" @@ -75,6 +74,7 @@ namespace WTF { RefPtr& operator=(T*); RefPtr& operator=(const PassRefPtr<T>&); RefPtr& operator=(const NonNullPassRefPtr<T>&); + RefPtr& operator=(std::nullptr_t) { clear(); return *this; } template<typename U> RefPtr& operator=(const RefPtr<U>&); template<typename U> RefPtr& operator=(const PassRefPtr<U>&); template<typename U> RefPtr& operator=(const NonNullPassRefPtr<U>&); diff --git a/JavaScriptCore/wtf/RetainPtr.h b/JavaScriptCore/wtf/RetainPtr.h index 68b5a04..8a14cfe 100644 --- a/JavaScriptCore/wtf/RetainPtr.h +++ b/JavaScriptCore/wtf/RetainPtr.h @@ -22,6 +22,7 @@ #define RetainPtr_h #include "HashTraits.h" +#include "NullPtr.h" #include "TypeTraits.h" #include <algorithm> #include <CoreFoundation/CoreFoundation.h> @@ -86,6 +87,7 @@ namespace WTF { template<typename U> RetainPtr& operator=(const RetainPtr<U>&); RetainPtr& operator=(PtrType); template<typename U> RetainPtr& operator=(U*); + RetainPtr& operator=(std::nullptr_t) { clear(); return *this; } void adoptCF(PtrType); void adoptNS(PtrType); diff --git a/JavaScriptCore/wtf/StringHashFunctions.h b/JavaScriptCore/wtf/StringHasher.h index 3ad7701..63ce74f 100644 --- a/JavaScriptCore/wtf/StringHashFunctions.h +++ b/JavaScriptCore/wtf/StringHasher.h @@ -18,8 +18,8 @@ * Boston, MA 02110-1301, USA. * */ -#ifndef WTF_StringHashFunctions_h -#define WTF_StringHashFunctions_h +#ifndef WTF_StringHasher_h +#define WTF_StringHasher_h #include <wtf/unicode/Unicode.h> @@ -167,4 +167,4 @@ private: } // namespace WTF -#endif // WTF_StringHashFunctions_h +#endif // WTF_StringHasher_h diff --git a/JavaScriptCore/wtf/TCSpinLock.h b/JavaScriptCore/wtf/TCSpinLock.h index 240b497..81b7d0c 100644 --- a/JavaScriptCore/wtf/TCSpinLock.h +++ b/JavaScriptCore/wtf/TCSpinLock.h @@ -38,8 +38,6 @@ #include <time.h> /* For nanosleep() */ -#include <sched.h> /* For sched_yield() */ - #if HAVE(STDINT_H) #include <stdint.h> #elif HAVE(INTTYPES_H) @@ -53,6 +51,8 @@ #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> +#else +#include <sched.h> /* For sched_yield() */ #endif static void TCMalloc_SlowLock(volatile unsigned int* lockword); @@ -135,7 +135,12 @@ struct TCMalloc_SpinLock { #define SPINLOCK_INITIALIZER { 0 } static void TCMalloc_SlowLock(volatile unsigned int* lockword) { - sched_yield(); // Yield immediately since fast path failed +// Yield immediately since fast path failed +#if OS(WINDOWS) + Sleep(0); +#else + sched_yield(); +#endif while (true) { int r; #if COMPILER(GCC) diff --git a/JavaScriptCore/wtf/TypeTraits.cpp b/JavaScriptCore/wtf/TypeTraits.cpp index a55019b..afeaa5e 100644 --- a/JavaScriptCore/wtf/TypeTraits.cpp +++ b/JavaScriptCore/wtf/TypeTraits.cpp @@ -136,4 +136,7 @@ COMPILE_ASSERT((IsSameType<int, RemovePointer<int>::Type>::value), WTF_Test_Remo COMPILE_ASSERT((IsSameType<int, RemovePointer<int*>::Type>::value), WTF_Test_RemovePointer_int_pointer); COMPILE_ASSERT((!IsSameType<int, RemovePointer<int**>::Type>::value), WTF_Test_RemovePointer_int_pointer_pointer); +COMPILE_ASSERT((IsSameType<int, RemoveReference<int>::Type>::value), WTF_Test_RemoveReference_int); +COMPILE_ASSERT((IsSameType<int, RemoveReference<int&>::Type>::value), WTF_Test_RemoveReference_int_reference); + } // namespace WTF diff --git a/JavaScriptCore/wtf/TypeTraits.h b/JavaScriptCore/wtf/TypeTraits.h index cf9b4af..44103cd 100644 --- a/JavaScriptCore/wtf/TypeTraits.h +++ b/JavaScriptCore/wtf/TypeTraits.h @@ -39,6 +39,7 @@ namespace WTF { // IsSameType<T, U>::value // // RemovePointer<T>::Type + // RemoveReference<T>::Type // RemoveConst<T>::Type // RemoveVolatile<T>::Type // RemoveConstVolatile<T>::Type @@ -170,6 +171,14 @@ namespace WTF { typedef T Type; }; + template <typename T> struct RemoveReference { + typedef T Type; + }; + + template <typename T> struct RemoveReference<T&> { + typedef T Type; + }; + #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace. diff --git a/JavaScriptCore/wtf/WTFThreadData.h b/JavaScriptCore/wtf/WTFThreadData.h index 7f91e1a..5019c33 100644 --- a/JavaScriptCore/wtf/WTFThreadData.h +++ b/JavaScriptCore/wtf/WTFThreadData.h @@ -95,12 +95,6 @@ public: } #if USE(JSC) - void initializeIdentifierTable(JSC::IdentifierTable* identifierTable) - { - m_defaultIdentifierTable = identifierTable; - m_currentIdentifierTable = identifierTable; - } - JSC::IdentifierTable* currentIdentifierTable() { return m_currentIdentifierTable; diff --git a/JavaScriptCore/wtf/brew/RefPtrBrew.h b/JavaScriptCore/wtf/brew/RefPtrBrew.h new file mode 100644 index 0000000..7fb0b7c --- /dev/null +++ b/JavaScriptCore/wtf/brew/RefPtrBrew.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Martin Robinson + * Copyright (C) 2010 Company 100, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef RefPtrBrew_h +#define RefPtrBrew_h + +#include "AlwaysInline.h" +#include "PlatformRefPtr.h" +#include <AEEIBase.h> +#include <algorithm> + +namespace WTF { + +// All Brew MP classes are derived from either IBase or IQI. +// Technically, IBase and IQI are different types. However, it is +// okay to cast both types to IBase because they have AddRef and Release +// in the same method vtable slots. +template <typename T> inline T* refPlatformPtr(T* ptr) +{ + if (ptr) + IBase_AddRef(reinterpret_cast<IBase*>(ptr)); + return ptr; +} + +template <typename T> inline void derefPlatformPtr(T* ptr) +{ + if (ptr) + IBase_Release(reinterpret_cast<IBase*>(ptr)); +} + +} // namespace WTF + +#endif // RefPtrBrew_h diff --git a/JavaScriptCore/wtf/brew/ShellBrew.h b/JavaScriptCore/wtf/brew/ShellBrew.h index 7416eca..faccc75 100644 --- a/JavaScriptCore/wtf/brew/ShellBrew.h +++ b/JavaScriptCore/wtf/brew/ShellBrew.h @@ -34,6 +34,7 @@ #include <wtf/Assertions.h> #include <wtf/PassOwnPtr.h> +#include <wtf/PlatformRefPtr.h> namespace WTF { @@ -49,8 +50,21 @@ static inline PassOwnPtr<T> createInstance(AEECLSID cls) return instance; } +template <typename T> +static inline PlatformRefPtr<T> createRefPtrInstance(AEECLSID cls) +{ + T* instance = 0; + + IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell; + ISHELL_CreateInstance(shell, cls, reinterpret_cast<void**>(&instance)); + ASSERT(instance); + + return adoptPlatformRef(instance); +} + } // namespace WTF using WTF::createInstance; +using WTF::createRefPtrInstance; #endif // ShellBrew_h diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp index 298bb27..c89c036 100644 --- a/JavaScriptCore/wtf/dtoa.cpp +++ b/JavaScriptCore/wtf/dtoa.cpp @@ -1824,8 +1824,8 @@ unsigned numberToString(double d, NumberToStringBuffer buffer) // Convert to decimal with rounding. DecimalNumber number(d); return number.exponent() >= -6 && number.exponent() < 21 - ? number.toStringDecimal(buffer) - : number.toStringExponential(buffer); + ? number.toStringDecimal(buffer, NumberToStringBufferLength) + : number.toStringExponential(buffer, NumberToStringBufferLength); } } // namespace WTF diff --git a/JavaScriptCore/wtf/dtoa.h b/JavaScriptCore/wtf/dtoa.h index 7e4fc41..3924a1c 100644 --- a/JavaScriptCore/wtf/dtoa.h +++ b/JavaScriptCore/wtf/dtoa.h @@ -39,7 +39,8 @@ void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exp void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision); // Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits. -typedef UChar NumberToStringBuffer[96]; +const unsigned NumberToStringBufferLength = 96; +typedef UChar NumberToStringBuffer[NumberToStringBufferLength]; unsigned numberToString(double, NumberToStringBuffer); } // namespace WTF diff --git a/JavaScriptCore/wtf/text/CString.cpp b/JavaScriptCore/wtf/text/CString.cpp index 7d09f12..c048a1b 100644 --- a/JavaScriptCore/wtf/text/CString.cpp +++ b/JavaScriptCore/wtf/text/CString.cpp @@ -36,12 +36,12 @@ CString::CString(const char* str) init(str, strlen(str)); } -CString::CString(const char* str, unsigned length) +CString::CString(const char* str, size_t length) { init(str, length); } -void CString::init(const char* str, unsigned length) +void CString::init(const char* str, size_t length) { if (!str) return; diff --git a/JavaScriptCore/wtf/text/CString.h b/JavaScriptCore/wtf/text/CString.h index d8250c5..343a7a5 100644 --- a/JavaScriptCore/wtf/text/CString.h +++ b/JavaScriptCore/wtf/text/CString.h @@ -40,8 +40,8 @@ public: private: friend class CString; - static PassRefPtr<CStringBuffer> create(unsigned length) { return adoptRef(new CStringBuffer(length)); } - CStringBuffer(unsigned length) : m_vector(length) { } + static PassRefPtr<CStringBuffer> create(size_t length) { return adoptRef(new CStringBuffer(length)); } + CStringBuffer(size_t length) : m_vector(length) { } char* mutableData() { return m_vector.data(); } Vector<char> m_vector; @@ -53,7 +53,7 @@ class CString { public: CString() { } CString(const char*); - CString(const char*, unsigned length); + CString(const char*, size_t length); CString(CStringBuffer* buffer) : m_buffer(buffer) { } static CString newUninitialized(size_t length, char*& characterBuffer); @@ -62,7 +62,7 @@ public: return m_buffer ? m_buffer->data() : 0; } char* mutableData(); - unsigned length() const + size_t length() const { return m_buffer ? m_buffer->length() - 1 : 0; } @@ -73,7 +73,7 @@ public: private: void copyBufferIfNeeded(); - void init(const char*, unsigned length); + void init(const char*, size_t length); RefPtr<CStringBuffer> m_buffer; }; diff --git a/JavaScriptCore/wtf/text/StringBuffer.h b/JavaScriptCore/wtf/text/StringBuffer.h index c29dd79..a546bf3 100644 --- a/JavaScriptCore/wtf/text/StringBuffer.h +++ b/JavaScriptCore/wtf/text/StringBuffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,6 +32,7 @@ #include <wtf/Assertions.h> #include <wtf/Noncopyable.h> #include <wtf/unicode/Unicode.h> +#include <limits> namespace WTF { @@ -39,9 +40,12 @@ class StringBuffer : public Noncopyable { public: explicit StringBuffer(unsigned length) : m_length(length) - , m_data(static_cast<UChar*>(fastMalloc(length * sizeof(UChar)))) { + if (m_length > std::numeric_limits<unsigned>::max() / sizeof(UChar)) + CRASH(); + m_data = static_cast<UChar*>(fastMalloc(m_length * sizeof(UChar))); } + ~StringBuffer() { fastFree(m_data); @@ -55,8 +59,11 @@ public: void resize(unsigned newLength) { - if (newLength > m_length) + if (newLength > m_length) { + if (newLength > std::numeric_limits<unsigned>::max() / sizeof(UChar)) + CRASH(); m_data = static_cast<UChar*>(fastRealloc(m_data, newLength * sizeof(UChar))); + } m_length = newLength; } @@ -72,8 +79,8 @@ private: UChar* m_data; }; -} +} // namespace WTF using WTF::StringBuffer; -#endif +#endif // StringBuffer_h diff --git a/JavaScriptCore/wtf/text/StringBuilder.cpp b/JavaScriptCore/wtf/text/StringBuilder.cpp new file mode 100644 index 0000000..dfc9ff3 --- /dev/null +++ b/JavaScriptCore/wtf/text/StringBuilder.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "StringBuilder.h" + +#include "WTFString.h" + +namespace WTF { + +void StringBuilder::reifyString() +{ + // Check if the string already exists. + if (!m_string.isNull()) { + ASSERT(m_string.length() == m_length); + return; + } + + // Check for empty. + if (!m_length) { + m_string = StringImpl::empty(); + return; + } + + // Must be valid in the buffer, take a substring (unless string fills the buffer). + ASSERT(m_buffer && m_length <= m_buffer->length()); + m_string = (m_length == m_buffer->length()) + ? m_buffer.get() + : StringImpl::create(m_buffer, 0, m_length); +} + +void StringBuilder::resize(unsigned newSize) +{ + // Check newSize < m_length, hence m_length > 0. + ASSERT(newSize <= m_length); + if (newSize == m_length) + return; + ASSERT(m_length); + + // If there is a buffer, we only need to duplicate it if it has more than one ref. + if (m_buffer) { + if (!m_buffer->hasOneRef()) + allocateBuffer(m_buffer->characters(), m_buffer->length()); + m_length = newSize; + m_string = String(); + return; + } + + // Since m_length && !m_buffer, the string must be valid in m_string, and m_string.length() > 0. + ASSERT(!m_string.isEmpty()); + ASSERT(m_length == m_string.length()); + ASSERT(newSize < m_string.length()); + m_length = newSize; + m_string = StringImpl::create(m_string.impl(), 0, newSize); +} + +void StringBuilder::reserveCapacity(unsigned newCapacity) +{ + if (m_buffer) { + // If there is already a buffer, then grow if necessary. + if (newCapacity > m_buffer->length()) + allocateBuffer(m_buffer->characters(), newCapacity); + } else { + // Grow the string, if necessary. + if (newCapacity > m_length) + allocateBuffer(m_string.characters(), newCapacity); + } +} + +// Allocate a new buffer, copying in currentCharacters (these may come from either m_string +// or m_buffer, neither will be reassigned until the copy has completed). +void StringBuilder::allocateBuffer(const UChar* currentCharacters, unsigned requiredLength) +{ + // Copy the existing data into a new buffer, set result to point to the end of the existing data. + RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters); + memcpy(m_bufferCharacters, currentCharacters, static_cast<size_t>(m_length) * sizeof(UChar)); // This can't overflow. + + // Update the builder state. + m_buffer = buffer.release(); + m_string = String(); +} + +// Make 'length' additional capacity be available in m_buffer, update m_string & m_length, +// return a pointer to the newly allocated storage. +UChar* StringBuilder::appendUninitialized(unsigned length) +{ + ASSERT(length); + + // Calcuate the new size of the builder after appending. + unsigned requiredLength = length + m_length; + if (requiredLength < length) + CRASH(); + + if (m_buffer) { + // If the buffer is valid it must be at least as long as the current builder contents! + ASSERT(m_buffer->length() >= m_length); + + // Check if the buffer already has sufficient capacity. + if (requiredLength <= m_buffer->length()) { + unsigned currentLength = m_length; + m_string = String(); + m_length = requiredLength; + return m_bufferCharacters + currentLength; + } + + // We need to realloc the buffer. + allocateBuffer(m_buffer->characters(), std::max(requiredLength, m_buffer->length() * 2)); + } else { + ASSERT(m_string.length() == m_length); + allocateBuffer(m_string.characters(), std::max(requiredLength, requiredLength * 2)); + } + + UChar* result = m_bufferCharacters + m_length; + m_length = requiredLength; + return result; +} + +void StringBuilder::append(const UChar* characters, unsigned length) +{ + if (!length) + return; + ASSERT(characters); + + memcpy(appendUninitialized(length), characters, static_cast<size_t>(length) * 2); +} + +void StringBuilder::append(const char* characters, unsigned length) +{ + if (!length) + return; + ASSERT(characters); + + UChar* dest = appendUninitialized(length); + const char* end = characters + length; + while (characters < end) + *(dest++) = *(const unsigned char*)(characters++); +} + +void StringBuilder::shrinkToFit() +{ + // If the buffer is at least 80% full, don't bother copying. Need to tune this heuristic! + if (m_buffer && m_buffer->length() > (m_length + (m_length >> 2))) { + UChar* result; + m_string = StringImpl::createUninitialized(m_length, result); + memcpy(result, m_buffer->characters(), static_cast<size_t>(m_length) * 2); // This can't overflow. + m_buffer = 0; + } +} + +} // namespace WTF diff --git a/JavaScriptCore/wtf/text/StringBuilder.h b/JavaScriptCore/wtf/text/StringBuilder.h new file mode 100644 index 0000000..f10af64 --- /dev/null +++ b/JavaScriptCore/wtf/text/StringBuilder.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef StringBuilder_h +#define StringBuilder_h + +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WTF { + +class StringBuilder { +public: + StringBuilder() + : m_length(0) + { + } + + void append(const UChar*, unsigned); + void append(const char*, unsigned); + + void append(const String& string) + { + // If we're appending to an empty string, and there is not buffer + // (in case reserveCapacity has been called) then just retain the + // string. + if (!m_length && !m_buffer) { + m_string = string; + m_length = string.length(); + return; + } + append(string.characters(), string.length()); + } + + void append(const char* characters) + { + if (characters) + append(characters, strlen(characters)); + } + + void append(UChar c) + { + if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) + m_bufferCharacters[m_length++] = c; + else + append(&c, 1); + } + + void append(char c) + { + if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) + m_bufferCharacters[m_length++] = (unsigned char)c; + else + append(&c, 1); + } + + String toString() + { + if (m_string.isNull()) { + shrinkToFit(); + reifyString(); + } + return m_string; + } + + String toStringPreserveCapacity() + { + if (m_string.isNull()) + reifyString(); + return m_string; + } + + unsigned length() const + { + return m_length; + } + + bool isEmpty() const { return !length(); } + + void reserveCapacity(unsigned newCapacity); + + void resize(unsigned newSize); + + void shrinkToFit(); + + UChar operator[](unsigned i) const + { + ASSERT(i < m_length); + if (!m_string.isNull()) + return m_string[i]; + ASSERT(m_buffer); + return m_buffer->characters()[i]; + } + + void clear() + { + m_length = 0; + m_string = String(); + m_buffer = 0; + } + +private: + void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength); + UChar* appendUninitialized(unsigned length); + void reifyString(); + + unsigned m_length; + String m_string; + RefPtr<StringImpl> m_buffer; + UChar* m_bufferCharacters; +}; + +} // namespace WTF + +using WTF::StringBuilder; + +#endif // StringBuilder_h diff --git a/JavaScriptCore/wtf/text/StringConcatenate.h b/JavaScriptCore/wtf/text/StringConcatenate.h new file mode 100644 index 0000000..b54a108 --- /dev/null +++ b/JavaScriptCore/wtf/text/StringConcatenate.h @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef StringConcatenate_h +#define StringConcatenate_h + +#include <wtf/text/WTFString.h> + +namespace WTF { + +template<typename StringType> +class StringTypeAdapter { +}; + +template<> +class StringTypeAdapter<char> { +public: + StringTypeAdapter<char>(char buffer) + : m_buffer(buffer) + { + } + + unsigned length() { return 1; } + void writeTo(UChar* destination) { *destination = m_buffer; } + +private: + unsigned char m_buffer; +}; + +template<> +class StringTypeAdapter<UChar> { +public: + StringTypeAdapter<UChar>(UChar buffer) + : m_buffer(buffer) + { + } + + unsigned length() { return 1; } + void writeTo(UChar* destination) { *destination = m_buffer; } + +private: + UChar m_buffer; +}; + +template<> +class StringTypeAdapter<char*> { +public: + StringTypeAdapter<char*>(char* buffer) + : m_buffer((unsigned char*)buffer) + , m_length(strlen(buffer)) + { + } + + unsigned length() { return m_length; } + + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_buffer[i]; + } + +private: + const unsigned char* m_buffer; + unsigned m_length; +}; + +template<> +class StringTypeAdapter<const char*> { +public: + StringTypeAdapter<const char*>(const char* buffer) + : m_buffer((unsigned char*)buffer) + , m_length(strlen(buffer)) + { + } + + unsigned length() { return m_length; } + + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_buffer[i]; + } + +private: + const unsigned char* m_buffer; + unsigned m_length; +}; + +template<> +class StringTypeAdapter<String> { +public: + StringTypeAdapter<String>(String& string) + : m_data(string.characters()) + , m_length(string.length()) + { + } + + unsigned length() { return m_length; } + + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_data[i]; + } + +private: + const UChar* m_data; + unsigned m_length; +}; + +inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) +{ + unsigned oldTotal = total; + total = oldTotal + addend; + if (total < oldTotal) + overflow = true; +} + +template<typename StringType1, typename StringType2> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + + UChar* buffer = 0; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + StringTypeAdapter<StringType7> adapter7(string7); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + sumWithOverflow(length, adapter7.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + result += adapter6.length(); + adapter7.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + StringTypeAdapter<StringType7> adapter7(string7); + StringTypeAdapter<StringType8> adapter8(string8); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + sumWithOverflow(length, adapter7.length(), overflow); + sumWithOverflow(length, adapter8.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + result += adapter6.length(); + adapter7.writeTo(result); + result += adapter7.length(); + adapter8.writeTo(result); + + return resultImpl; +} + +// Convenience only. +template<typename StringType1> +String makeString(StringType1 string1) +{ + return String(string1); +} + +template<typename StringType1, typename StringType2> +String makeString(StringType1 string1, StringType2 string2) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3> +String makeString(StringType1 string1, StringType2 string2, StringType3 string3) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> +String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> +String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> +String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> +String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> +String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +} // namespace WTF + +using WTF::makeString; + +#endif diff --git a/JavaScriptCore/wtf/text/StringHash.h b/JavaScriptCore/wtf/text/StringHash.h index bfd05eb..d7aabdb 100644 --- a/JavaScriptCore/wtf/text/StringHash.h +++ b/JavaScriptCore/wtf/text/StringHash.h @@ -26,7 +26,7 @@ #include "WTFString.h" #include <wtf/Forward.h> #include <wtf/HashTraits.h> -#include <wtf/StringHashFunctions.h> +#include <wtf/StringHasher.h> #include <wtf/unicode/Unicode.h> namespace WTF { @@ -97,99 +97,26 @@ namespace WTF { class CaseFoldingHash { public: - // Paul Hsieh's SuperFastHash - // http://www.azillionmonkeys.com/qed/hash.html + template<typename T> static inline UChar foldCase(T ch) + { + return WTF::Unicode::foldCase(ch); + } + static unsigned hash(const UChar* data, unsigned length) { - unsigned l = length; - const UChar* s = data; - uint32_t hash = WTF::stringHashingStartValue; - uint32_t tmp; - - int rem = l & 1; - l >>= 1; - - // Main loop. - for (; l > 0; l--) { - hash += WTF::Unicode::foldCase(s[0]); - tmp = (WTF::Unicode::foldCase(s[1]) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - s += 2; - hash += hash >> 11; - } - - // Handle end case. - if (rem) { - hash += WTF::Unicode::foldCase(s[0]); - hash ^= hash << 11; - hash += hash >> 17; - } - - // Force "avalanching" of final 127 bits. - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 2; - hash += hash >> 15; - hash ^= hash << 10; - - // This avoids ever returning a hash code of 0, since that is used to - // signal "hash not computed yet", using a value that is likely to be - // effectively the same as 0 when the low bits are masked. - hash |= !hash << 31; - - return hash; + return StringHasher::createHash<UChar, foldCase<UChar> >(data, length); } static unsigned hash(StringImpl* str) { return hash(str->characters(), str->length()); } - - static unsigned hash(const char* str, unsigned length) - { - // This hash is designed to work on 16-bit chunks at a time. But since the normal case - // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they - // were 16-bit chunks, which will give matching results. - unsigned l = length; - const char* s = str; - uint32_t hash = WTF::stringHashingStartValue; - uint32_t tmp; - - int rem = l & 1; - l >>= 1; - - // Main loop - for (; l > 0; l--) { - hash += WTF::Unicode::foldCase(s[0]); - tmp = (WTF::Unicode::foldCase(s[1]) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - s += 2; - hash += hash >> 11; - } - - // Handle end case - if (rem) { - hash += WTF::Unicode::foldCase(s[0]); - hash ^= hash << 11; - hash += hash >> 17; - } - - // Force "avalanching" of final 127 bits - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 2; - hash += hash >> 15; - hash ^= hash << 10; - - // this avoids ever returning a hash code of 0, since that is used to - // signal "hash not computed yet", using a value that is likely to be - // effectively the same as 0 when the low bits are masked - hash |= !hash << 31; - - return hash; + static unsigned hash(const char* data, unsigned length) + { + return StringHasher::createHash<char, foldCase<char> >(data, length); } - + static bool equal(const StringImpl* a, const StringImpl* b) { if (a == b) diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp index 7822c00..e1e08ee 100644 --- a/JavaScriptCore/wtf/text/StringImpl.cpp +++ b/JavaScriptCore/wtf/text/StringImpl.cpp @@ -81,7 +81,7 @@ PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& // Allocate a single buffer large enough to contain the StringImpl // struct as well as the data which it contains. This removes one // heap allocation from this call. - if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar))) + if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))) CRASH(); size_t size = sizeof(StringImpl) + length * sizeof(UChar); StringImpl* string = static_cast<StringImpl*>(fastMalloc(size)); diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h index 7025d9f..897751d 100644 --- a/JavaScriptCore/wtf/text/StringImpl.h +++ b/JavaScriptCore/wtf/text/StringImpl.h @@ -29,7 +29,7 @@ #include <wtf/Forward.h> #include <wtf/OwnFastMallocPtr.h> #include <wtf/StdLibExtras.h> -#include <wtf/StringHashFunctions.h> +#include <wtf/StringHasher.h> #include <wtf/Vector.h> #include <wtf/text/StringImplBase.h> #include <wtf/unicode/Unicode.h> @@ -165,7 +165,7 @@ public: return empty(); } - if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar))) { + if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))) { output = 0; return 0; } @@ -187,6 +187,8 @@ public: { if (size_t size = vector.size()) { ASSERT(vector.data()); + if (size > std::numeric_limits<unsigned>::max()) + CRASH(); return adoptRef(new StringImpl(vector.releaseBuffer(), size)); } return empty(); diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp index 9b53e81..5161477 100644 --- a/JavaScriptCore/wtf/text/WTFString.cpp +++ b/JavaScriptCore/wtf/text/WTFString.cpp @@ -48,9 +48,12 @@ String::String(const UChar* str) if (!str) return; - int len = 0; + size_t len = 0; while (str[len] != UChar(0)) len++; + + if (len > std::numeric_limits<unsigned>::max()) + CRASH(); m_impl = StringImpl::create(str, len); } @@ -175,6 +178,8 @@ void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) ASSERT(charactersToAppend); UChar* data; + if (lengthToAppend > std::numeric_limits<unsigned>::max() - length()) + CRASH(); RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToAppend, data); memcpy(data, characters(), length() * sizeof(UChar)); @@ -196,6 +201,8 @@ void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, un ASSERT(charactersToInsert); UChar* data; + if (lengthToInsert > std::numeric_limits<unsigned>::max() - length()) + CRASH(); RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToInsert, data); memcpy(data, characters(), position * sizeof(UChar)); @@ -718,6 +725,9 @@ CString String::utf8(bool strict) const String String::fromUTF8(const char* stringStart, size_t length) { + if (length > std::numeric_limits<unsigned>::max()) + CRASH(); + if (!stringStart) return String(); diff --git a/JavaScriptCore/wtf/unicode/Unicode.h b/JavaScriptCore/wtf/unicode/Unicode.h index c755c6c..50524b1 100644 --- a/JavaScriptCore/wtf/unicode/Unicode.h +++ b/JavaScriptCore/wtf/unicode/Unicode.h @@ -33,6 +33,8 @@ #include <wtf/unicode/glib/UnicodeGLib.h> #elif USE(WINCE_UNICODE) #include <wtf/unicode/wince/UnicodeWinCE.h> +#elif USE(BREWMP_UNICODE) +#include <wtf/unicode/brew/UnicodeBrew.h> #else #error "Unknown Unicode implementation" #endif diff --git a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp new file mode 100644 index 0000000..8367f17 --- /dev/null +++ b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * Copyright (C) 2010 Company 100, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "UnicodeBrew.h" + +#include <wchar.h> +#include <wctype.h> + +namespace WTF { +namespace Unicode { + +UChar toLower(UChar c) +{ + return towlower(c); +} + +UChar toUpper(UChar c) +{ + return towupper(c); +} + +UChar foldCase(UChar c) +{ + return towlower(c); +} + +bool isPrintableChar(UChar c) +{ + return !!iswprint(c); +} + +bool isUpper(UChar c) +{ + return !!iswupper(c); +} + +bool isLower(UChar c) +{ + return !!iswlower(c); +} + +bool isDigit(UChar c) +{ + return !!iswdigit(c); +} + +bool isPunct(UChar c) +{ + return !!iswpunct(c); +} + +bool isAlphanumeric(UChar c) +{ + return !!iswalnum(c); +} + +int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) +{ + const UChar* sourceIterator = source; + const UChar* sourceEnd = source + sourceLength; + UChar* resultIterator = result; + UChar* resultEnd = result + resultLength; + + if (sourceLength <= resultLength) { + while (sourceIterator < sourceEnd) + *resultIterator++ = towlower(*sourceIterator++); + } else { + while (resultIterator < resultEnd) + *resultIterator++ = towlower(*sourceIterator++); + } + + int remainingCharacters = sourceIterator < sourceEnd ? sourceEnd - sourceIterator : 0; + *isError = !!remainingCharacters; + if (resultIterator < resultEnd) + *resultIterator = 0; + + return (resultIterator - result) + remainingCharacters; +} + +int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) +{ + const UChar* sourceIterator = source; + const UChar* sourceEnd = source + sourceLength; + UChar* resultIterator = result; + UChar* resultEnd = result + resultLength; + + if (sourceLength <= resultLength) { + while (sourceIterator < sourceEnd) + *resultIterator++ = towupper(*sourceIterator++); + } else { + while (resultIterator < resultEnd) + *resultIterator++ = towupper(*sourceIterator++); + } + + int remainingCharacters = sourceIterator < sourceEnd ? sourceEnd - sourceIterator : 0; + *isError = !!remainingCharacters; + if (resultIterator < resultEnd) + *resultIterator = 0; + + return (resultIterator - result) + remainingCharacters; +} + +int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) +{ + *isError = false; + if (resultLength < sourceLength) { + *isError = true; + return sourceLength; + } + for (int i = 0; i < sourceLength; ++i) + result[i] = foldCase(source[i]); + return sourceLength; +} + +UChar toTitleCase(UChar c) +{ + return towupper(c); +} + +Direction direction(UChar32 c) +{ + return static_cast<Direction>(ICU::direction(c)); +} + +CharCategory category(unsigned int c) +{ + return static_cast<CharCategory>(TO_MASK((int8_t) ICU::category(c))); +} + +DecompositionType decompositionType(UChar32 c) +{ + return static_cast<DecompositionType>(ICU::decompositionType(c)); +} + +unsigned char combiningClass(UChar32 c) +{ + return ICU::combiningClass(c); +} + +UChar mirroredChar(UChar32 c) +{ + return ICU::mirroredChar(c); +} + +int digitValue(UChar c) +{ + return ICU::digitValue(c); +} + +bool isSpace(UChar c) +{ + return !!iswspace(c); +} + +bool isLetter(UChar c) +{ + return !!iswalpha(c); +} + +} // namespace Unicode +} // namespace WTF diff --git a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h new file mode 100644 index 0000000..1d7576f --- /dev/null +++ b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> + * Copyright (C) 2007 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * Copyright (C) 2010 Company 100, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef UnicodeBrew_h +#define UnicodeBrew_h + +#include "UnicodeFromICU.h" +#include "UnicodeMacrosFromICU.h" + +namespace WTF { +namespace Unicode { + +enum Direction { + LeftToRight = ICU::U_LEFT_TO_RIGHT, + RightToLeft = ICU::U_RIGHT_TO_LEFT, + EuropeanNumber = ICU::U_EUROPEAN_NUMBER, + EuropeanNumberSeparator = ICU::U_EUROPEAN_NUMBER_SEPARATOR, + EuropeanNumberTerminator = ICU::U_EUROPEAN_NUMBER_TERMINATOR, + ArabicNumber = ICU::U_ARABIC_NUMBER, + CommonNumberSeparator = ICU::U_COMMON_NUMBER_SEPARATOR, + BlockSeparator = ICU::U_BLOCK_SEPARATOR, + SegmentSeparator = ICU::U_SEGMENT_SEPARATOR, + WhiteSpaceNeutral = ICU::U_WHITE_SPACE_NEUTRAL, + OtherNeutral = ICU::U_OTHER_NEUTRAL, + LeftToRightEmbedding = ICU::U_LEFT_TO_RIGHT_EMBEDDING, + LeftToRightOverride = ICU::U_LEFT_TO_RIGHT_OVERRIDE, + RightToLeftArabic = ICU::U_RIGHT_TO_LEFT_ARABIC, + RightToLeftEmbedding = ICU::U_RIGHT_TO_LEFT_EMBEDDING, + RightToLeftOverride = ICU::U_RIGHT_TO_LEFT_OVERRIDE, + PopDirectionalFormat = ICU::U_POP_DIRECTIONAL_FORMAT, + NonSpacingMark = ICU::U_DIR_NON_SPACING_MARK, + BoundaryNeutral = ICU::U_BOUNDARY_NEUTRAL +}; + +enum DecompositionType { + DecompositionNone = ICU::U_DT_NONE, + DecompositionCanonical = ICU::U_DT_CANONICAL, + DecompositionCompat = ICU::U_DT_COMPAT, + DecompositionCircle = ICU::U_DT_CIRCLE, + DecompositionFinal = ICU::U_DT_FINAL, + DecompositionFont = ICU::U_DT_FONT, + DecompositionFraction = ICU::U_DT_FRACTION, + DecompositionInitial = ICU::U_DT_INITIAL, + DecompositionIsolated = ICU::U_DT_ISOLATED, + DecompositionMedial = ICU::U_DT_MEDIAL, + DecompositionNarrow = ICU::U_DT_NARROW, + DecompositionNoBreak = ICU::U_DT_NOBREAK, + DecompositionSmall = ICU::U_DT_SMALL, + DecompositionSquare = ICU::U_DT_SQUARE, + DecompositionSub = ICU::U_DT_SUB, + DecompositionSuper = ICU::U_DT_SUPER, + DecompositionVertical = ICU::U_DT_VERTICAL, + DecompositionWide = ICU::U_DT_WIDE, +}; + +enum CharCategory { + NoCategory = 0, + Other_NotAssigned = TO_MASK(ICU::U_GENERAL_OTHER_TYPES), + Letter_Uppercase = TO_MASK(ICU::U_UPPERCASE_LETTER), + Letter_Lowercase = TO_MASK(ICU::U_LOWERCASE_LETTER), + Letter_Titlecase = TO_MASK(ICU::U_TITLECASE_LETTER), + Letter_Modifier = TO_MASK(ICU::U_MODIFIER_LETTER), + Letter_Other = TO_MASK(ICU::U_OTHER_LETTER), + + Mark_NonSpacing = TO_MASK(ICU::U_NON_SPACING_MARK), + Mark_Enclosing = TO_MASK(ICU::U_ENCLOSING_MARK), + Mark_SpacingCombining = TO_MASK(ICU::U_COMBINING_SPACING_MARK), + + Number_DecimalDigit = TO_MASK(ICU::U_DECIMAL_DIGIT_NUMBER), + Number_Letter = TO_MASK(ICU::U_LETTER_NUMBER), + Number_Other = TO_MASK(ICU::U_OTHER_NUMBER), + + Separator_Space = TO_MASK(ICU::U_SPACE_SEPARATOR), + Separator_Line = TO_MASK(ICU::U_LINE_SEPARATOR), + Separator_Paragraph = TO_MASK(ICU::U_PARAGRAPH_SEPARATOR), + + Other_Control = TO_MASK(ICU::U_CONTROL_CHAR), + Other_Format = TO_MASK(ICU::U_FORMAT_CHAR), + Other_PrivateUse = TO_MASK(ICU::U_PRIVATE_USE_CHAR), + Other_Surrogate = TO_MASK(ICU::U_SURROGATE), + + Punctuation_Dash = TO_MASK(ICU::U_DASH_PUNCTUATION), + Punctuation_Open = TO_MASK(ICU::U_START_PUNCTUATION), + Punctuation_Close = TO_MASK(ICU::U_END_PUNCTUATION), + Punctuation_Connector = TO_MASK(ICU::U_CONNECTOR_PUNCTUATION), + Punctuation_Other = TO_MASK(ICU::U_OTHER_PUNCTUATION), + + Symbol_Math = TO_MASK(ICU::U_MATH_SYMBOL), + Symbol_Currency = TO_MASK(ICU::U_CURRENCY_SYMBOL), + Symbol_Modifier = TO_MASK(ICU::U_MODIFIER_SYMBOL), + Symbol_Other = TO_MASK(ICU::U_OTHER_SYMBOL), + + Punctuation_InitialQuote = TO_MASK(ICU::U_INITIAL_PUNCTUATION), + Punctuation_FinalQuote = TO_MASK(ICU::U_FINAL_PUNCTUATION) +}; + +UChar foldCase(UChar); + +int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); + +int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); + +UChar toUpper(UChar); +UChar toLower(UChar); + +bool isUpper(UChar); + +int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); + +UChar toTitleCase(UChar); + +inline bool isArabicChar(UChar32 c) +{ + return c >= 0x0600 && c <= 0x06FF; +} + +bool isAlphanumeric(UChar); + +CharCategory category(unsigned int); + +inline bool isSeparatorSpace(UChar c) +{ + return category(c) == Separator_Space; +} + +bool isPrintableChar(UChar); + +bool isDigit(UChar); + +bool isPunct(UChar); + +inline bool hasLineBreakingPropertyComplexContext(UChar32) +{ + // FIXME: implement! + return false; +} + +inline bool hasLineBreakingPropertyComplexContextOrIdeographic(UChar32 c) +{ + // FIXME + return false; +} + +UChar mirroredChar(UChar32); + +Direction direction(UChar32); + +bool isLower(UChar); + +int digitValue(UChar); + +unsigned char combiningClass(UChar32); + +DecompositionType decompositionType(UChar32); + +inline int umemcasecmp(const UChar* a, const UChar* b, int len) +{ + for (int i = 0; i < len; ++i) { + UChar c1 = foldCase(a[i]); + UChar c2 = foldCase(b[i]); + if (c1 != c2) + return c1 - c2; + } + return 0; +} + +bool isSpace(UChar); +bool isLetter(UChar); + +} // namespace Unicode +} // namespace WTF + +#endif diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h index 547ed32..eaa7a07 100644 --- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h +++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h @@ -31,6 +31,9 @@ #include <config.h> #include <stdint.h> +#if USE(QT_ICU_TEXT_BREAKING) +#include <unicode/ubrk.h> +#endif QT_BEGIN_NAMESPACE namespace QUnicodeTables { @@ -63,7 +66,10 @@ typedef wchar_t UChar; #else typedef uint16_t UChar; #endif + +#if !USE(QT_ICU_TEXT_BREAKING) typedef uint32_t UChar32; +#endif namespace WTF { namespace Unicode { @@ -150,7 +156,7 @@ enum CharCategory { inline UChar32 toLower(UChar32 ch) { - return QChar::toLower(ch); + return QChar::toLower(uint32_t(ch)); } inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) @@ -206,9 +212,9 @@ inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLen return rindex + needed; } -inline UChar32 toUpper(UChar32 ch) +inline UChar32 toUpper(UChar32 c) { - return QChar::toUpper(ch); + return QChar::toUpper(uint32_t(c)); } inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) @@ -266,12 +272,12 @@ inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLen inline int toTitleCase(UChar32 c) { - return QChar::toTitleCase(c); + return QChar::toTitleCase(uint32_t(c)); } inline UChar32 foldCase(UChar32 c) { - return QChar::toCaseFolded(c); + return QChar::toCaseFolded(uint32_t(c)); } inline int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) @@ -296,12 +302,12 @@ inline bool isPrintableChar(UChar32 c) { const uint test = U_MASK(QChar::Other_Control) | U_MASK(QChar::Other_NotAssigned); - return !(U_MASK(QChar::category(c)) & test); + return !(U_MASK(QChar::category(uint32_t(c))) & test); } inline bool isSeparatorSpace(UChar32 c) { - return QChar::category(c) == QChar::Separator_Space; + return QChar::category(uint32_t(c)) == QChar::Separator_Space; } inline bool isPunct(UChar32 c) @@ -313,12 +319,12 @@ inline bool isPunct(UChar32 c) U_MASK(QChar::Punctuation_InitialQuote) | U_MASK(QChar::Punctuation_FinalQuote) | U_MASK(QChar::Punctuation_Other); - return U_MASK(QChar::category(c)) & test; + return U_MASK(QChar::category(uint32_t(c))) & test; } inline bool isLower(UChar32 c) { - return QChar::category(c) == QChar::Letter_Lowercase; + return QChar::category(uint32_t(c)) == QChar::Letter_Lowercase; } inline bool hasLineBreakingPropertyComplexContext(UChar32) @@ -329,12 +335,12 @@ inline bool hasLineBreakingPropertyComplexContext(UChar32) inline UChar32 mirroredChar(UChar32 c) { - return QChar::mirroredChar(c); + return QChar::mirroredChar(uint32_t(c)); } inline uint8_t combiningClass(UChar32 c) { - return QChar::combiningClass(c); + return QChar::combiningClass(uint32_t(c)); } inline DecompositionType decompositionType(UChar32 c) @@ -356,12 +362,12 @@ inline int umemcasecmp(const UChar* a, const UChar* b, int len) inline Direction direction(UChar32 c) { - return (Direction)QChar::direction(c); + return (Direction)QChar::direction(uint32_t(c)); } inline CharCategory category(UChar32 c) { - return (CharCategory) U_MASK(QChar::category(c)); + return (CharCategory) U_MASK(QChar::category(uint32_t(c))); } } } diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp index b52b05c..96dac7d 100644 --- a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp +++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp @@ -27,62 +27,62 @@ namespace WTF { namespace Unicode { -wchar_t toLower(wchar_t c) +UChar toLower(UChar c) { return towlower(c); } -wchar_t toUpper(wchar_t c) +UChar toUpper(UChar c) { return towupper(c); } -wchar_t foldCase(wchar_t c) +UChar foldCase(UChar c) { return towlower(c); } -bool isPrintableChar(wchar_t c) +bool isPrintableChar(UChar c) { return !!iswprint(c); } -bool isSpace(wchar_t c) +bool isSpace(UChar c) { return !!iswspace(c); } -bool isLetter(wchar_t c) +bool isLetter(UChar c) { return !!iswalpha(c); } -bool isUpper(wchar_t c) +bool isUpper(UChar c) { return !!iswupper(c); } -bool isLower(wchar_t c) +bool isLower(UChar c) { return !!iswlower(c); } -bool isDigit(wchar_t c) +bool isDigit(UChar c) { return !!iswdigit(c); } -bool isPunct(wchar_t c) +bool isPunct(UChar c) { return !!iswpunct(c); } -bool isAlphanumeric(wchar_t c) +bool isAlphanumeric(UChar c) { return !!iswalnum(c); } -int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) { const UChar* sourceIterator = source; const UChar* sourceEnd = source + sourceLength; @@ -99,14 +99,14 @@ int toLower(wchar_t* result, int resultLength, const wchar_t* source, int source if (sourceIterator < sourceEnd) remainingCharacters += sourceEnd - sourceIterator; - *isError = (remainingCharacters != 0); + *isError = !!remainingCharacters; if (resultIterator < resultEnd) *resultIterator = 0; return (resultIterator - result) + remainingCharacters; } -int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) { const UChar* sourceIterator = source; const UChar* sourceEnd = source + sourceLength; @@ -123,14 +123,14 @@ int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int source if (sourceIterator < sourceEnd) remainingCharacters += sourceEnd - sourceIterator; - *isError = (remainingCharacters != 0); + *isError = !!remainingCharacters; if (resultIterator < resultEnd) *resultIterator = 0; return (resultIterator - result) + remainingCharacters; } -int foldCase(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) { *isError = false; if (resultLength < sourceLength) { @@ -142,7 +142,7 @@ int foldCase(wchar_t* result, int resultLength, const wchar_t* source, int sourc return sourceLength; } -wchar_t toTitleCase(wchar_t c) +UChar toTitleCase(UChar c) { return towupper(c); } @@ -167,12 +167,12 @@ unsigned char combiningClass(UChar32 c) return UnicodeCE::combiningClass(c); } -wchar_t mirroredChar(UChar32 c) +UChar mirroredChar(UChar32 c) { return UnicodeCE::mirroredChar(c); } -int digitValue(wchar_t c) +int digitValue(UChar c) { return UnicodeCE::digitValue(c); } diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h index 8cc9580..2688aa9 100644 --- a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h +++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h @@ -31,149 +31,147 @@ #define TO_MASK(x) (1 << (x)) namespace WTF { - - namespace Unicode { - - enum Direction { - LeftToRight = UnicodeCE::U_LEFT_TO_RIGHT, - RightToLeft = UnicodeCE::U_RIGHT_TO_LEFT, - EuropeanNumber = UnicodeCE::U_EUROPEAN_NUMBER, - EuropeanNumberSeparator = UnicodeCE::U_EUROPEAN_NUMBER_SEPARATOR, - EuropeanNumberTerminator = UnicodeCE::U_EUROPEAN_NUMBER_TERMINATOR, - ArabicNumber = UnicodeCE::U_ARABIC_NUMBER, - CommonNumberSeparator = UnicodeCE::U_COMMON_NUMBER_SEPARATOR, - BlockSeparator = UnicodeCE::U_BLOCK_SEPARATOR, - SegmentSeparator = UnicodeCE::U_SEGMENT_SEPARATOR, - WhiteSpaceNeutral = UnicodeCE::U_WHITE_SPACE_NEUTRAL, - OtherNeutral = UnicodeCE::U_OTHER_NEUTRAL, - LeftToRightEmbedding = UnicodeCE::U_LEFT_TO_RIGHT_EMBEDDING, - LeftToRightOverride = UnicodeCE::U_LEFT_TO_RIGHT_OVERRIDE, - RightToLeftArabic = UnicodeCE::U_RIGHT_TO_LEFT_ARABIC, - RightToLeftEmbedding = UnicodeCE::U_RIGHT_TO_LEFT_EMBEDDING, - RightToLeftOverride = UnicodeCE::U_RIGHT_TO_LEFT_OVERRIDE, - PopDirectionalFormat = UnicodeCE::U_POP_DIRECTIONAL_FORMAT, - NonSpacingMark = UnicodeCE::U_DIR_NON_SPACING_MARK, - BoundaryNeutral = UnicodeCE::U_BOUNDARY_NEUTRAL - }; - - enum DecompositionType { - DecompositionNone = UnicodeCE::U_DT_NONE, - DecompositionCanonical = UnicodeCE::U_DT_CANONICAL, - DecompositionCompat = UnicodeCE::U_DT_COMPAT, - DecompositionCircle = UnicodeCE::U_DT_CIRCLE, - DecompositionFinal = UnicodeCE::U_DT_FINAL, - DecompositionFont = UnicodeCE::U_DT_FONT, - DecompositionFraction = UnicodeCE::U_DT_FRACTION, - DecompositionInitial = UnicodeCE::U_DT_INITIAL, - DecompositionIsolated = UnicodeCE::U_DT_ISOLATED, - DecompositionMedial = UnicodeCE::U_DT_MEDIAL, - DecompositionNarrow = UnicodeCE::U_DT_NARROW, - DecompositionNoBreak = UnicodeCE::U_DT_NOBREAK, - DecompositionSmall = UnicodeCE::U_DT_SMALL, - DecompositionSquare = UnicodeCE::U_DT_SQUARE, - DecompositionSub = UnicodeCE::U_DT_SUB, - DecompositionSuper = UnicodeCE::U_DT_SUPER, - DecompositionVertical = UnicodeCE::U_DT_VERTICAL, - DecompositionWide = UnicodeCE::U_DT_WIDE, - }; - - enum CharCategory { - NoCategory = 0, - Other_NotAssigned = TO_MASK(UnicodeCE::U_GENERAL_OTHER_TYPES), - Letter_Uppercase = TO_MASK(UnicodeCE::U_UPPERCASE_LETTER), - Letter_Lowercase = TO_MASK(UnicodeCE::U_LOWERCASE_LETTER), - Letter_Titlecase = TO_MASK(UnicodeCE::U_TITLECASE_LETTER), - Letter_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_LETTER), - Letter_Other = TO_MASK(UnicodeCE::U_OTHER_LETTER), - - Mark_NonSpacing = TO_MASK(UnicodeCE::U_NON_SPACING_MARK), - Mark_Enclosing = TO_MASK(UnicodeCE::U_ENCLOSING_MARK), - Mark_SpacingCombining = TO_MASK(UnicodeCE::U_COMBINING_SPACING_MARK), - - Number_DecimalDigit = TO_MASK(UnicodeCE::U_DECIMAL_DIGIT_NUMBER), - Number_Letter = TO_MASK(UnicodeCE::U_LETTER_NUMBER), - Number_Other = TO_MASK(UnicodeCE::U_OTHER_NUMBER), - - Separator_Space = TO_MASK(UnicodeCE::U_SPACE_SEPARATOR), - Separator_Line = TO_MASK(UnicodeCE::U_LINE_SEPARATOR), - Separator_Paragraph = TO_MASK(UnicodeCE::U_PARAGRAPH_SEPARATOR), - - Other_Control = TO_MASK(UnicodeCE::U_CONTROL_CHAR), - Other_Format = TO_MASK(UnicodeCE::U_FORMAT_CHAR), - Other_PrivateUse = TO_MASK(UnicodeCE::U_PRIVATE_USE_CHAR), - Other_Surrogate = TO_MASK(UnicodeCE::U_SURROGATE), - - Punctuation_Dash = TO_MASK(UnicodeCE::U_DASH_PUNCTUATION), - Punctuation_Open = TO_MASK(UnicodeCE::U_START_PUNCTUATION), - Punctuation_Close = TO_MASK(UnicodeCE::U_END_PUNCTUATION), - Punctuation_Connector = TO_MASK(UnicodeCE::U_CONNECTOR_PUNCTUATION), - Punctuation_Other = TO_MASK(UnicodeCE::U_OTHER_PUNCTUATION), - - Symbol_Math = TO_MASK(UnicodeCE::U_MATH_SYMBOL), - Symbol_Currency = TO_MASK(UnicodeCE::U_CURRENCY_SYMBOL), - Symbol_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_SYMBOL), - Symbol_Other = TO_MASK(UnicodeCE::U_OTHER_SYMBOL), - - Punctuation_InitialQuote = TO_MASK(UnicodeCE::U_INITIAL_PUNCTUATION), - Punctuation_FinalQuote = TO_MASK(UnicodeCE::U_FINAL_PUNCTUATION) - }; - - CharCategory category(unsigned int); - - bool isSpace(wchar_t); - bool isLetter(wchar_t); - bool isPrintableChar(wchar_t); - bool isUpper(wchar_t); - bool isLower(wchar_t); - bool isPunct(wchar_t); - bool isDigit(wchar_t); - bool isAlphanumeric(wchar_t); - inline bool isSeparatorSpace(wchar_t c) { return category(c) == Separator_Space; } - inline bool isHighSurrogate(wchar_t c) { return (c & 0xfc00) == 0xd800; } - inline bool isLowSurrogate(wchar_t c) { return (c & 0xfc00) == 0xdc00; } - - wchar_t toLower(wchar_t); - wchar_t toUpper(wchar_t); - wchar_t foldCase(wchar_t); - wchar_t toTitleCase(wchar_t); - int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); - int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); - int foldCase(UChar* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); - - int digitValue(wchar_t); - - wchar_t mirroredChar(UChar32); - unsigned char combiningClass(UChar32); - DecompositionType decompositionType(UChar32); - Direction direction(UChar32); - inline bool isArabicChar(UChar32 c) - { - return c >= 0x0600 && c <= 0x06FF; - } - - inline bool hasLineBreakingPropertyComplexContext(UChar32) - { - return false; // FIXME: implement! - } - - inline int umemcasecmp(const wchar_t* a, const wchar_t* b, int len) - { - for (int i = 0; i < len; ++i) { - wchar_t c1 = foldCase(a[i]); - wchar_t c2 = foldCase(b[i]); - if (c1 != c2) - return c1 - c2; - } - return 0; - } - - inline UChar32 surrogateToUcs4(wchar_t high, wchar_t low) - { - return (UChar32(high) << 10) + low - 0x35fdc00; - } - - } // namespace Unicode - -} // namespace WTF +namespace Unicode { + +enum Direction { + LeftToRight = UnicodeCE::U_LEFT_TO_RIGHT, + RightToLeft = UnicodeCE::U_RIGHT_TO_LEFT, + EuropeanNumber = UnicodeCE::U_EUROPEAN_NUMBER, + EuropeanNumberSeparator = UnicodeCE::U_EUROPEAN_NUMBER_SEPARATOR, + EuropeanNumberTerminator = UnicodeCE::U_EUROPEAN_NUMBER_TERMINATOR, + ArabicNumber = UnicodeCE::U_ARABIC_NUMBER, + CommonNumberSeparator = UnicodeCE::U_COMMON_NUMBER_SEPARATOR, + BlockSeparator = UnicodeCE::U_BLOCK_SEPARATOR, + SegmentSeparator = UnicodeCE::U_SEGMENT_SEPARATOR, + WhiteSpaceNeutral = UnicodeCE::U_WHITE_SPACE_NEUTRAL, + OtherNeutral = UnicodeCE::U_OTHER_NEUTRAL, + LeftToRightEmbedding = UnicodeCE::U_LEFT_TO_RIGHT_EMBEDDING, + LeftToRightOverride = UnicodeCE::U_LEFT_TO_RIGHT_OVERRIDE, + RightToLeftArabic = UnicodeCE::U_RIGHT_TO_LEFT_ARABIC, + RightToLeftEmbedding = UnicodeCE::U_RIGHT_TO_LEFT_EMBEDDING, + RightToLeftOverride = UnicodeCE::U_RIGHT_TO_LEFT_OVERRIDE, + PopDirectionalFormat = UnicodeCE::U_POP_DIRECTIONAL_FORMAT, + NonSpacingMark = UnicodeCE::U_DIR_NON_SPACING_MARK, + BoundaryNeutral = UnicodeCE::U_BOUNDARY_NEUTRAL +}; + +enum DecompositionType { + DecompositionNone = UnicodeCE::U_DT_NONE, + DecompositionCanonical = UnicodeCE::U_DT_CANONICAL, + DecompositionCompat = UnicodeCE::U_DT_COMPAT, + DecompositionCircle = UnicodeCE::U_DT_CIRCLE, + DecompositionFinal = UnicodeCE::U_DT_FINAL, + DecompositionFont = UnicodeCE::U_DT_FONT, + DecompositionFraction = UnicodeCE::U_DT_FRACTION, + DecompositionInitial = UnicodeCE::U_DT_INITIAL, + DecompositionIsolated = UnicodeCE::U_DT_ISOLATED, + DecompositionMedial = UnicodeCE::U_DT_MEDIAL, + DecompositionNarrow = UnicodeCE::U_DT_NARROW, + DecompositionNoBreak = UnicodeCE::U_DT_NOBREAK, + DecompositionSmall = UnicodeCE::U_DT_SMALL, + DecompositionSquare = UnicodeCE::U_DT_SQUARE, + DecompositionSub = UnicodeCE::U_DT_SUB, + DecompositionSuper = UnicodeCE::U_DT_SUPER, + DecompositionVertical = UnicodeCE::U_DT_VERTICAL, + DecompositionWide = UnicodeCE::U_DT_WIDE +}; + +enum CharCategory { + NoCategory = 0, + Other_NotAssigned = TO_MASK(UnicodeCE::U_GENERAL_OTHER_TYPES), + Letter_Uppercase = TO_MASK(UnicodeCE::U_UPPERCASE_LETTER), + Letter_Lowercase = TO_MASK(UnicodeCE::U_LOWERCASE_LETTER), + Letter_Titlecase = TO_MASK(UnicodeCE::U_TITLECASE_LETTER), + Letter_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_LETTER), + Letter_Other = TO_MASK(UnicodeCE::U_OTHER_LETTER), + + Mark_NonSpacing = TO_MASK(UnicodeCE::U_NON_SPACING_MARK), + Mark_Enclosing = TO_MASK(UnicodeCE::U_ENCLOSING_MARK), + Mark_SpacingCombining = TO_MASK(UnicodeCE::U_COMBINING_SPACING_MARK), + + Number_DecimalDigit = TO_MASK(UnicodeCE::U_DECIMAL_DIGIT_NUMBER), + Number_Letter = TO_MASK(UnicodeCE::U_LETTER_NUMBER), + Number_Other = TO_MASK(UnicodeCE::U_OTHER_NUMBER), + + Separator_Space = TO_MASK(UnicodeCE::U_SPACE_SEPARATOR), + Separator_Line = TO_MASK(UnicodeCE::U_LINE_SEPARATOR), + Separator_Paragraph = TO_MASK(UnicodeCE::U_PARAGRAPH_SEPARATOR), + + Other_Control = TO_MASK(UnicodeCE::U_CONTROL_CHAR), + Other_Format = TO_MASK(UnicodeCE::U_FORMAT_CHAR), + Other_PrivateUse = TO_MASK(UnicodeCE::U_PRIVATE_USE_CHAR), + Other_Surrogate = TO_MASK(UnicodeCE::U_SURROGATE), + + Punctuation_Dash = TO_MASK(UnicodeCE::U_DASH_PUNCTUATION), + Punctuation_Open = TO_MASK(UnicodeCE::U_START_PUNCTUATION), + Punctuation_Close = TO_MASK(UnicodeCE::U_END_PUNCTUATION), + Punctuation_Connector = TO_MASK(UnicodeCE::U_CONNECTOR_PUNCTUATION), + Punctuation_Other = TO_MASK(UnicodeCE::U_OTHER_PUNCTUATION), + + Symbol_Math = TO_MASK(UnicodeCE::U_MATH_SYMBOL), + Symbol_Currency = TO_MASK(UnicodeCE::U_CURRENCY_SYMBOL), + Symbol_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_SYMBOL), + Symbol_Other = TO_MASK(UnicodeCE::U_OTHER_SYMBOL), + + Punctuation_InitialQuote = TO_MASK(UnicodeCE::U_INITIAL_PUNCTUATION), + Punctuation_FinalQuote = TO_MASK(UnicodeCE::U_FINAL_PUNCTUATION) +}; + +CharCategory category(unsigned int); + +bool isSpace(UChar); +bool isLetter(UChar); +bool isPrintableChar(UChar); +bool isUpper(UChar); +bool isLower(UChar); +bool isPunct(UChar); +bool isDigit(UChar); +bool isAlphanumeric(UChar); +inline bool isSeparatorSpace(UChar c) { return category(c) == Separator_Space; } +inline bool isHighSurrogate(UChar c) { return (c & 0xfc00) == 0xd800; } +inline bool isLowSurrogate(UChar c) { return (c & 0xfc00) == 0xdc00; } + +UChar toLower(UChar); +UChar toUpper(UChar); +UChar foldCase(UChar); +UChar toTitleCase(UChar); +int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); +int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); +int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); + +int digitValue(UChar); + +UChar mirroredChar(UChar32); +unsigned char combiningClass(UChar32); +DecompositionType decompositionType(UChar32); +Direction direction(UChar32); +inline bool isArabicChar(UChar32 c) +{ + return c >= 0x0600 && c <= 0x06FF; +} + +inline bool hasLineBreakingPropertyComplexContext(UChar32) +{ + return false; // FIXME: implement! +} + +inline int umemcasecmp(const UChar* a, const UChar* b, int len) +{ + for (int i = 0; i < len; ++i) { + UChar c1 = foldCase(a[i]); + UChar c2 = foldCase(b[i]); + if (c1 != c2) + return c1 - c2; + } + return 0; +} + +inline UChar32 surrogateToUcs4(UChar high, UChar low) +{ + return (UChar32(high) << 10) + low - 0x35fdc00; +} + +} // namespace Unicode +} // namespace WTF #endif // WTF_UnicodeWinCE_h diff --git a/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp b/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp new file mode 100644 index 0000000..ee2014e --- /dev/null +++ b/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp @@ -0,0 +1,173 @@ +// Copyright 2010, Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "config.h" +#include "URLCharacterTypes.h" + +namespace WTF { + +const unsigned char URLCharacterTypes::characterTypeTable[0x100] = { + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x00 - 0x0f + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x10 - 0x1f + InvalidCharacter, // 0x20 ' ' (escape spaces in queries) + QueryCharacter | UserInfoCharacter, // 0x21 ! + InvalidCharacter, // 0x22 " + InvalidCharacter, // 0x23 # (invalid in query since it marks the ref) + QueryCharacter | UserInfoCharacter, // 0x24 $ + QueryCharacter | UserInfoCharacter, // 0x25 % + QueryCharacter | UserInfoCharacter, // 0x26 & + QueryCharacter | UserInfoCharacter, // 0x27 ' + QueryCharacter | UserInfoCharacter, // 0x28 ( + QueryCharacter | UserInfoCharacter, // 0x29 ) + QueryCharacter | UserInfoCharacter, // 0x2a * + QueryCharacter | UserInfoCharacter, // 0x2b + + QueryCharacter | UserInfoCharacter, // 0x2c , + QueryCharacter | UserInfoCharacter, // 0x2d - + QueryCharacter | UserInfoCharacter | IPv4Character, // 0x2e . + QueryCharacter, // 0x2f / + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x30 0 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x31 1 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x32 2 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x33 3 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x34 4 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x35 5 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x36 6 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x37 7 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x38 8 + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x39 9 + QueryCharacter, // 0x3a : + QueryCharacter, // 0x3b ; + InvalidCharacter, // 0x3c < + QueryCharacter, // 0x3d = + InvalidCharacter, // 0x3e > + QueryCharacter, // 0x3f ? + QueryCharacter, // 0x40 @ + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x41 A + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x42 B + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x43 C + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x44 D + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x45 E + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x46 F + QueryCharacter | UserInfoCharacter, // 0x47 G + QueryCharacter | UserInfoCharacter, // 0x48 H + QueryCharacter | UserInfoCharacter, // 0x49 I + QueryCharacter | UserInfoCharacter, // 0x4a J + QueryCharacter | UserInfoCharacter, // 0x4b K + QueryCharacter | UserInfoCharacter, // 0x4c L + QueryCharacter | UserInfoCharacter, // 0x4d M + QueryCharacter | UserInfoCharacter, // 0x4e N + QueryCharacter | UserInfoCharacter, // 0x4f O + QueryCharacter | UserInfoCharacter, // 0x50 P + QueryCharacter | UserInfoCharacter, // 0x51 Q + QueryCharacter | UserInfoCharacter, // 0x52 R + QueryCharacter | UserInfoCharacter, // 0x53 S + QueryCharacter | UserInfoCharacter, // 0x54 T + QueryCharacter | UserInfoCharacter, // 0x55 U + QueryCharacter | UserInfoCharacter, // 0x56 V + QueryCharacter | UserInfoCharacter, // 0x57 W + QueryCharacter | UserInfoCharacter | IPv4Character, // 0x58 X + QueryCharacter | UserInfoCharacter, // 0x59 Y + QueryCharacter | UserInfoCharacter, // 0x5a Z + QueryCharacter, // 0x5b [ + QueryCharacter, // 0x5c '\' + QueryCharacter, // 0x5d ] + QueryCharacter, // 0x5e ^ + QueryCharacter | UserInfoCharacter, // 0x5f _ + QueryCharacter, // 0x60 ` + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x61 a + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x62 b + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x63 c + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x64 d + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x65 e + QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x66 f + QueryCharacter | UserInfoCharacter, // 0x67 g + QueryCharacter | UserInfoCharacter, // 0x68 h + QueryCharacter | UserInfoCharacter, // 0x69 i + QueryCharacter | UserInfoCharacter, // 0x6a j + QueryCharacter | UserInfoCharacter, // 0x6b k + QueryCharacter | UserInfoCharacter, // 0x6c l + QueryCharacter | UserInfoCharacter, // 0x6d m + QueryCharacter | UserInfoCharacter, // 0x6e n + QueryCharacter | UserInfoCharacter, // 0x6f o + QueryCharacter | UserInfoCharacter, // 0x70 p + QueryCharacter | UserInfoCharacter, // 0x71 q + QueryCharacter | UserInfoCharacter, // 0x72 r + QueryCharacter | UserInfoCharacter, // 0x73 s + QueryCharacter | UserInfoCharacter, // 0x74 t + QueryCharacter | UserInfoCharacter, // 0x75 u + QueryCharacter | UserInfoCharacter, // 0x76 v + QueryCharacter | UserInfoCharacter, // 0x77 w + QueryCharacter | UserInfoCharacter | IPv4Character, // 0x78 x + QueryCharacter | UserInfoCharacter, // 0x79 y + QueryCharacter | UserInfoCharacter, // 0x7a z + QueryCharacter, // 0x7b { + QueryCharacter, // 0x7c | + QueryCharacter, // 0x7d } + QueryCharacter | UserInfoCharacter, // 0x7e ~ + InvalidCharacter, // 0x7f + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x80 - 0x8f + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x90 - 0x9f + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xa0 - 0xaf + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xb0 - 0xbf + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xc0 - 0xcf + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xd0 - 0xdf + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xe0 - 0xef + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, + InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xf0 - 0xff +}; + +} diff --git a/JavaScriptCore/wtf/url/src/URLCharacterTypes.h b/JavaScriptCore/wtf/url/src/URLCharacterTypes.h new file mode 100644 index 0000000..194f6b0 --- /dev/null +++ b/JavaScriptCore/wtf/url/src/URLCharacterTypes.h @@ -0,0 +1,61 @@ +// Copyright 2010, Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef URLCharacterTypes_h +#define URLCharacterTypes_h + +namespace WTF { + +class URLCharacterTypes { +public: + static inline bool isQueryChar(unsigned char c) { return isCharOfType(c, QueryCharacter); } + static inline bool isIPv4Char(unsigned char c) { return isCharOfType(c, IPv4Character); } + static inline bool isHexChar(unsigned char c) { return isCharOfType(c, HexCharacter); } + +private: + enum CharTypes { + InvalidCharacter = 0, + QueryCharacter = 1 << 0, + UserInfoCharacter = 1 << 1, + IPv4Character = 1 << 2, + HexCharacter = 1 << 3, + DecimalCharacter = 1 << 4, + OctalCharacter = 1 << 5, + }; + + static const unsigned char characterTypeTable[0x100]; + + static inline bool isCharOfType(unsigned char c, CharTypes type) + { + return !!(characterTypeTable[c] & type); + } +}; + +} + +#endif diff --git a/JavaScriptCore/wtf/url/src/URLEscape.cpp b/JavaScriptCore/wtf/url/src/URLEscape.cpp new file mode 100644 index 0000000..2987343 --- /dev/null +++ b/JavaScriptCore/wtf/url/src/URLEscape.cpp @@ -0,0 +1,39 @@ +// Copyright 2010, Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "config.h" +#include "URLEscape.h" + +namespace WTF { + +const char hexCharacterTable[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', +}; + +} diff --git a/JavaScriptCore/wtf/url/src/URLEscape.h b/JavaScriptCore/wtf/url/src/URLEscape.h new file mode 100644 index 0000000..cc2b77f --- /dev/null +++ b/JavaScriptCore/wtf/url/src/URLEscape.h @@ -0,0 +1,49 @@ +// Copyright 2010, Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef URLEscape_h +#define URLEscape_h + +#include "URLBuffer.h" + +namespace WTF { + +extern const char hexCharacterTable[16]; + +template<typename InChar, typename OutChar> +inline void appendURLEscapedCharacter(InChar ch, URLBuffer<OutChar>& buffer) +{ + buffer.append('%'); + buffer.append(hexCharacterTable[ch >> 4]); + buffer.append(hexCharacterTable[ch & 0xf]); +} + +} + +#endif diff --git a/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h b/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h new file mode 100644 index 0000000..7740200 --- /dev/null +++ b/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h @@ -0,0 +1,107 @@ +// Copyright 2010, Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef URLQueryCanonicalizer_h +#define URLQueryCanonicalizer_h + +#include "RawURLBuffer.h" +#include "URLBuffer.h" +#include "URLCharacterTypes.h" +#include "URLComponent.h" +#include "URLEscape.h" + +namespace WTF { + +template<typename InChar, typename OutChar, void convertCharset(const InChar*, int length, URLBuffer<char>&)> +class URLQueryCanonicalizer { +public: + static void canonicalize(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer, URLComponent& resultQuery) + { + if (query.length() < 0) { + resultQuery = URLComponent(); + return; + } + + buffer->append('?'); + resultQuery.setBegin(buffer->length()); + convertToQueryEncoding(spec, query, buffer); + resultQuery.setLength(buffer->length() - resultQuery.begin()); + } + +private: + static bool isAllASCII(const InChar* spec, const URLComponent& query) + { + int end = query.end(); + for (int i = query.begin(); i < end; ++i) { + if (static_cast<unsigned>(spec[i]) >= 0x80) + return false; + } + return true; + } + +#ifndef NDEBUG + static bool isRaw8Bit(const InChar* source, int length) + { + for (int i = source; i < length; ++i) { + if (source[i] & 0xFF != source[i]) + return false; + } + return true; + } +#endif + + static void appendRaw8BitQueryString(const InChar* source, int length, URLBuffer<OutChar>* buffer) + { + ASSERT(isRaw8Bit(source, length)); + for (int i = 0; i < length; ++i) { + if (!URLCharacterTypes::isQueryChar(source[i])) + appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), buffer); + else + buffer->append(static_cast<char>(source[i])); + } + } + + static void convertToQueryEncoding(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer) + { + if (isAllASCII(spec, query)) { + appendRaw8BitQueryString(&spec[query.begin()], query.length(), buffer); + return; + } + + RawURLBuffer<char, 1024> convertedQuery; + convertCharset(spec, query, convertedQuery); + appendRaw8BitQueryString(convertedQuery.data(), convertedQuery.length(), buffer); + } +}; + +} + +#endif + + diff --git a/JavaScriptCore/wtf/wtf.pri b/JavaScriptCore/wtf/wtf.pri index 84ac20e..83e71d8 100644 --- a/JavaScriptCore/wtf/wtf.pri +++ b/JavaScriptCore/wtf/wtf.pri @@ -6,6 +6,7 @@ SOURCES += \ wtf/CurrentTime.cpp \ wtf/DateMath.cpp \ wtf/dtoa.cpp \ + wtf/DecimalNumber.cpp \ wtf/FastMalloc.cpp \ wtf/HashTable.cpp \ wtf/MD5.cpp \ @@ -22,6 +23,7 @@ SOURCES += \ wtf/WTFThreadData.cpp \ wtf/text/AtomicString.cpp \ wtf/text/CString.cpp \ + wtf/text/StringBuilder.cpp \ wtf/text/StringImpl.cpp \ wtf/text/StringStatics.cpp \ wtf/text/WTFString.cpp \ |