Changeset 63120 in webkit for trunk/JavaScriptCore/runtime/UString.cpp
- Timestamp:
- Jul 12, 2010, 2:32:34 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/UString.cpp
r62457 r63120 243 243 } 244 244 245 static inline bool isInfinity(double number) 246 { 247 return number == Inf || number == -Inf; 248 } 249 250 static bool isInfinity(const UChar* data, const UChar* end) 251 { 252 return data + 7 < end 253 && data[0] == 'I' 254 && data[1] == 'n' 255 && data[2] == 'f' 256 && data[3] == 'i' 257 && data[4] == 'n' 258 && data[5] == 'i' 259 && data[6] == 't' 260 && data[7] == 'y'; 261 } 262 245 263 double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const 246 264 { 247 if (size() == 1) { 265 unsigned size = this->size(); 266 267 if (size == 1) { 248 268 UChar c = data()[0]; 249 269 if (isASCIIDigit(c)) 250 270 return c - '0'; 251 if (is ASCIISpace(c) && tolerateEmptyString)271 if (isStrWhiteSpace(c) && tolerateEmptyString) 252 272 return 0; 253 273 return NaN; … … 265 285 // right thing but requires UChar, not char, for its argument. 266 286 267 CString s = UTF8String();268 if (s.isNull())269 return NaN; 270 const char* c = s.data();271 272 // skip leading white space273 while (isASCIISpace(*c))274 c++;275 276 // empty string ?277 if ( *c == '\0')287 const UChar* data = this->data(); 288 const UChar* end = data + size; 289 290 // Skip leading white space. 291 for (; data < end; ++data) { 292 if (!isStrWhiteSpace(*data)) 293 break; 294 } 295 296 // Empty string. 297 if (data == end) 278 298 return tolerateEmptyString ? 0.0 : NaN; 279 299 280 double d; 281 282 // hex number ? 283 if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) { 284 const char* firstDigitPosition = c + 2; 285 c++; 286 d = 0.0; 287 while (*(++c)) { 288 if (*c >= '0' && *c <= '9') 289 d = d * 16.0 + *c - '0'; 290 else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f')) 291 d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0; 292 else 300 double number; 301 302 if (data[0] == '0' && data + 2 < end && (data[1] | 0x20) == 'x' && isASCIIHexDigit(data[2])) { 303 // Hex number. 304 data += 2; 305 const UChar* firstDigitPosition = data; 306 number = 0; 307 while (true) { 308 number = number * 16 + toASCIIHexValue(*data); 309 ++data; 310 if (data == end) 293 311 break; 294 } 295 296 if (d >= mantissaOverflowLowerBound) 297 d = parseIntOverflow(firstDigitPosition, c - firstDigitPosition, 16); 312 if (!isASCIIHexDigit(*data)) 313 break; 314 } 315 if (number >= mantissaOverflowLowerBound) 316 number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 16); 298 317 } else { 299 // regular number ? 300 char* end; 301 d = WTF::strtod(c, &end); 302 if ((d != 0.0 || end != c) && d != Inf && d != -Inf) { 303 c = end; 304 } else { 305 double sign = 1.0; 306 307 if (*c == '+') 308 c++; 309 else if (*c == '-') { 310 sign = -1.0; 311 c++; 312 } 313 318 // Decimal number. 319 320 // Put into a null-terminated byte buffer. 321 Vector<char, 32> byteBuffer; 322 for (const UChar* characters = data; characters < end; ++characters) { 323 UChar character = *characters; 324 byteBuffer.append(isASCII(character) ? character : 0); 325 } 326 byteBuffer.append(0); 327 328 char* byteBufferEnd; 329 number = WTF::strtod(byteBuffer.data(), &byteBufferEnd); 330 const UChar* pastNumber = data + (byteBufferEnd - byteBuffer.data()); 331 332 if ((number || pastNumber != data) && !isInfinity(number)) 333 data = pastNumber; 334 else { 314 335 // We used strtod() to do the conversion. However, strtod() handles 315 336 // infinite values slightly differently than JavaScript in that it … … 317 338 // whereas the ECMA spec requires that it be converted to NaN. 318 339 319 if (c[0] == 'I' && c[1] == 'n' && c[2] == 'f' && c[3] == 'i' && c[4] == 'n' && c[5] == 'i' && c[6] == 't' && c[7] == 'y') { 320 d = sign * Inf; 321 c += 8; 322 } else if ((d == Inf || d == -Inf) && *c != 'I' && *c != 'i') 323 c = end; 340 double signedInfinity = Inf; 341 if (data < end) { 342 if (*data == '+') 343 data++; 344 else if (*data == '-') { 345 signedInfinity = -Inf; 346 data++; 347 } 348 } 349 if (isInfinity(data, end)) { 350 number = signedInfinity; 351 data += 8; 352 } else if (isInfinity(number) && data < end && (*data | 0x20) != 'i') 353 data = pastNumber; 324 354 else 325 355 return NaN; … … 327 357 } 328 358 359 // Look for trailing junk. 329 360 if (!tolerateTrailingJunk) { 330 // allow trailing white space 331 while (isASCIISpace(*c)) 332 c++; 333 if (c != s.data() + s.length()) 334 d = NaN; 335 } 336 337 return d; 361 // Allow trailing white space. 362 for (; data < end; ++data) { 363 if (!isStrWhiteSpace(*data)) 364 break; 365 } 366 if (data != end) 367 return NaN; 368 } 369 370 return number; 338 371 } 339 372
Note:
See TracChangeset
for help on using the changeset viewer.