Changeset 21371 in webkit for trunk/JavaScriptCore/wtf
- Timestamp:
- May 10, 2007, 7:36:58 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
r19826 r21371 30 30 31 31 #include <stdint.h> 32 33 #if QT_VERSION >= 0x040300 34 namespace 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 32 57 33 58 typedef uint16_t UChar; … … 148 173 inline int toLower(UChar* str, int strLength, UChar*& destIfNeeded) 149 174 { 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; 157 193 } 158 194 … … 164 200 inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) 165 201 { 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; 175 246 } 176 247 177 248 inline int toUpper(UChar* str, int strLength, UChar*& destIfNeeded) 178 249 { 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; 186 268 } 187 269 … … 193 275 inline int toUpper(UChar* result, int resultLength, UChar* src, int srcLength, bool* error) 194 276 { 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; 204 321 } 205 322
Note:
See TracChangeset
for help on using the changeset viewer.