Changeset 21371 in webkit for trunk/JavaScriptCore/wtf


Ignore:
Timestamp:
May 10, 2007, 7:36:58 AM (18 years ago)
Author:
lars
Message:

Reviewed by Zack

Fix our last three test failures in the JavaScript
tests.

Without change 21367 we would have been at 0 failures
in javascript and layout tests now... ;-)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h

    r19826 r21371  
    3030
    3131#include <stdint.h>
     32
     33#if QT_VERSION >= 0x040300
     34namespace QUnicodeTables {
     35    struct Properties {
     36        ushort category : 8;
     37        ushort line_break_class : 8;
     38        ushort direction : 8;
     39        ushort combiningClass :8;
     40        ushort joining : 2;
     41        signed short digitValue : 6; /* 5 needed */
     42        ushort unicodeVersion : 4;
     43        ushort lowerCaseSpecial : 1;
     44        ushort upperCaseSpecial : 1;
     45        ushort titleCaseSpecial : 1;
     46        ushort caseFoldSpecial : 1; /* currently unused */
     47        signed short mirrorDiff : 16;
     48        signed short lowerCaseDiff : 16;
     49        signed short upperCaseDiff : 16;
     50        signed short titleCaseDiff : 16;
     51        signed short caseFoldDiff : 16;
     52    };
     53    Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4);
     54    Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2);
     55}
     56#endif
    3257
    3358typedef uint16_t UChar;
     
    148173    inline int toLower(UChar* str, int strLength, UChar*& destIfNeeded)
    149174    {
    150       destIfNeeded = 0;
    151 
    152       // FIXME: handle special casing. Easiest with some low level API in Qt
    153       for (int i = 0; i < strLength; ++i)
    154         str[i] = QChar::toLower(str[i]);
    155 
    156       return strLength;
     175        destIfNeeded = 0;
     176       
     177        const UChar *e = str + strLength;
     178        UChar *s = str;
     179        while (s < e) {
     180            const QUnicodeTables::Properties *prop = QUnicodeTables::properties(*s);
     181            if (prop->lowerCaseSpecial || (((*s) & 0xf800) == 0xd800)) {
     182                QString qstring = QString(reinterpret_cast<QChar *>(str), strLength).toLower();
     183                strLength = qstring.length();
     184                destIfNeeded = static_cast<UChar*>(malloc(strLength * sizeof(UChar)));
     185                memcpy(destIfNeeded, qstring.constData(), strLength * sizeof(UChar));
     186                return strLength;
     187            }
     188            *s = *s + prop->lowerCaseDiff;
     189            ++s;
     190        }
     191
     192        return strLength;
    157193    }
    158194
     
    164200    inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength,  bool* error)
    165201    {
    166       // FIXME: handle special casing. Easiest with some low level API in Qt
    167       *error = false;
    168       if (resultLength < srcLength) {
    169         *error = true;
    170         return srcLength;
    171       }
    172       for (int i = 0; i < srcLength; ++i)
    173         result[i] = QChar::toLower(src[i]);
    174       return srcLength;
     202        const UChar *e = src + srcLength;
     203        const UChar *s = src;
     204        UChar *r = result;
     205        UChar *re = result + resultLength;
     206       
     207        // this avoids one out of bounds check in the loop
     208        if (QChar(*s).isLowSurrogate())
     209            *r++ = *s++;
     210
     211        int needed = 0;
     212        while (s < e && r < re) {
     213            uint c = *s;
     214            if (QChar(c).isLowSurrogate() && QChar(*(s - 1)).isHighSurrogate())
     215                c = QChar::surrogateToUcs4(*(s - 1), c);
     216            const QUnicodeTables::Properties *prop = QUnicodeTables::properties(c);
     217            if (prop->lowerCaseSpecial) {
     218                QString qstring;
     219                if (c > 0x10000) {
     220                    qstring += QChar(c);
     221                } else {
     222                    qstring += QChar(*(s-1));
     223                    qstring += QChar(*s);
     224                }
     225                qstring = qstring.toLower();
     226                for (int i = 0; i < qstring.length(); ++i) {
     227                    if (r == re) {
     228                        needed += qstring.length() - i;
     229                        break;
     230                    }
     231                    *r = qstring.at(i).unicode();
     232                    ++r;
     233                }
     234            } else {
     235                *r = *s + prop->lowerCaseDiff;
     236                ++r;
     237            }
     238            ++s;
     239        }
     240        if (s < e)
     241            needed += e - s;
     242        *error = (needed != 0);
     243        if (r < re)
     244            *r = 0;
     245        return (r - result) + needed;
    175246    }
    176247
    177248    inline int toUpper(UChar* str, int strLength, UChar*& destIfNeeded)
    178249    {
    179       // FIXME: handle special casing. Easiest with some low level API in Qt
    180       destIfNeeded = 0;
    181 
    182       for (int i = 0; i < strLength; ++i)
    183         str[i] = QChar::toUpper(str[i]);
    184 
    185       return strLength;
     250        destIfNeeded = 0;
     251       
     252        const UChar *e = str + strLength;
     253        UChar *s = str;
     254        while (s < e) {
     255            const QUnicodeTables::Properties *prop = QUnicodeTables::properties(*s);
     256            if (prop->upperCaseSpecial || (((*s) & 0xf800) == 0xd800)) {
     257                QString qstring = QString(reinterpret_cast<QChar *>(str), strLength).toUpper();
     258                strLength = qstring.length();
     259                destIfNeeded = static_cast<UChar*>(malloc(strLength * sizeof(UChar)));
     260                memcpy(destIfNeeded, qstring.constData(), strLength * sizeof(UChar));
     261                return strLength;
     262            }
     263            *s = *s + prop->upperCaseDiff;
     264            ++s;
     265        }
     266
     267        return strLength;
    186268    }
    187269
     
    193275    inline int toUpper(UChar* result, int resultLength, UChar* src, int srcLength,  bool* error)
    194276    {
    195       // FIXME: handle special casing. Easiest with some low level API in Qt
    196       *error = false;
    197       if (resultLength < srcLength) {
    198         *error = true;
    199         return srcLength;
    200       }
    201       for (int i = 0; i < srcLength; ++i)
    202         result[i] = QChar::toUpper(src[i]);
    203       return srcLength;
     277        const UChar *e = src + srcLength;
     278        const UChar *s = src;
     279        UChar *r = result;
     280        UChar *re = result + resultLength;
     281       
     282        // this avoids one out of bounds check in the loop
     283        if (QChar(*s).isLowSurrogate())
     284            *r++ = *s++;
     285
     286        int needed = 0;
     287        while (s < e && r < re) {
     288            uint c = *s;
     289            if (QChar(c).isLowSurrogate() && QChar(*(s - 1)).isHighSurrogate())
     290                c = QChar::surrogateToUcs4(*(s - 1), c);
     291            const QUnicodeTables::Properties *prop = QUnicodeTables::properties(c);
     292            if (prop->upperCaseSpecial) {
     293                QString qstring;
     294                if (c > 0x10000) {
     295                    qstring += QChar(c);
     296                } else {
     297                    qstring += QChar(*(s-1));
     298                    qstring += QChar(*s);
     299                }
     300                qstring = qstring.toUpper();
     301                for (int i = 0; i < qstring.length(); ++i) {
     302                    if (r == re) {
     303                        needed += qstring.length() - i;
     304                        break;
     305                    }
     306                    *r = qstring.at(i).unicode();
     307                    ++r;
     308                }
     309            } else {
     310                *r = *s + prop->upperCaseDiff;
     311                ++r;
     312            }
     313            ++s;
     314        }
     315        if (s < e)
     316            needed += e - s;
     317        *error = (needed != 0);
     318        if (r < re)
     319            *r = 0;
     320        return (r - result) + needed;
    204321    }
    205322
Note: See TracChangeset for help on using the changeset viewer.