OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 #include "wtf/ArrayBufferContents.h" | 60 #include "wtf/ArrayBufferContents.h" |
61 #include "wtf/MainThread.h" | 61 #include "wtf/MainThread.h" |
62 #include "wtf/MathExtras.h" | 62 #include "wtf/MathExtras.h" |
63 #include "wtf/StdLibExtras.h" | 63 #include "wtf/StdLibExtras.h" |
64 #include "wtf/Threading.h" | 64 #include "wtf/Threading.h" |
65 #include "wtf/text/AtomicString.h" | 65 #include "wtf/text/AtomicString.h" |
66 #include "wtf/text/CString.h" | 66 #include "wtf/text/CString.h" |
67 #include "wtf/text/StringBuffer.h" | 67 #include "wtf/text/StringBuffer.h" |
68 #include "wtf/text/StringHash.h" | 68 #include "wtf/text/StringHash.h" |
69 #include "wtf/text/WTFString.h" | 69 #include "wtf/text/WTFString.h" |
| 70 #include "wtf/unicode/CharacterNames.h" |
| 71 #include "wtf/unicode/Unicode.h" |
70 | 72 |
71 namespace WebCore { | 73 namespace WebCore { |
72 | 74 |
73 v8::Handle<v8::Value> throwError(V8ErrorType errorType, const String& message, v
8::Isolate* isolate) | 75 v8::Handle<v8::Value> throwError(V8ErrorType errorType, const String& message, v
8::Isolate* isolate) |
74 { | 76 { |
75 return V8ThrowException::throwError(errorType, message, isolate); | 77 return V8ThrowException::throwError(errorType, message, isolate); |
76 } | 78 } |
77 | 79 |
78 v8::Handle<v8::Value> throwError(v8::Handle<v8::Value> exception, v8::Isolate* i
solate) | 80 v8::Handle<v8::Value> throwError(v8::Handle<v8::Value> exception, v8::Isolate* i
solate) |
79 { | 81 { |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 return numberObject->NumberValue(); | 494 return numberObject->NumberValue(); |
493 } | 495 } |
494 | 496 |
495 String toByteString(v8::Handle<v8::Value> value, ExceptionState& exceptionState) | 497 String toByteString(v8::Handle<v8::Value> value, ExceptionState& exceptionState) |
496 { | 498 { |
497 // Handle null default value. | 499 // Handle null default value. |
498 if (value.IsEmpty()) | 500 if (value.IsEmpty()) |
499 return String(); | 501 return String(); |
500 | 502 |
501 // From the Web IDL spec: http://heycam.github.io/webidl/#es-ByteString | 503 // From the Web IDL spec: http://heycam.github.io/webidl/#es-ByteString |
| 504 if (value.IsEmpty()) |
| 505 return String(); |
502 | 506 |
503 // 1. Let x be ToString(v) | 507 // 1. Let x be ToString(v) |
504 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value->
ToString(), exceptionState, String()); | 508 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value->
ToString(), exceptionState, String()); |
505 String x = toCoreString(stringObject); | 509 String x = toCoreString(stringObject); |
506 | 510 |
507 // 2. If the value of any element of x is greater than 255, then throw a Typ
eError. | 511 // 2. If the value of any element of x is greater than 255, then throw a Typ
eError. |
508 if (!x.containsOnlyLatin1()) { | 512 if (!x.containsOnlyLatin1()) { |
509 exceptionState.throwTypeError("Value is not a valid ByteString."); | 513 exceptionState.throwTypeError("Value is not a valid ByteString."); |
510 return String(); | 514 return String(); |
511 } | 515 } |
512 | 516 |
513 // 3. Return an IDL ByteString value whose length is the length of x, and wh
ere the | 517 // 3. Return an IDL ByteString value whose length is the length of x, and wh
ere the |
514 // value of each element is the value of the corresponding element of x. | 518 // value of each element is the value of the corresponding element of x. |
515 // Blink: A ByteString is simply a String with a range constrained per the a
bove, so | 519 // Blink: A ByteString is simply a String with a range constrained per the a
bove, so |
516 // this is the identity operation. | 520 // this is the identity operation. |
517 return x; | 521 return x; |
518 } | 522 } |
519 | 523 |
| 524 static bool hasUnmatchedSurrogates(const String& string) |
| 525 { |
| 526 // By definition, 8-bit strings are confined to the Latin-1 code page and |
| 527 // have no surrogates, matched or otherwise. |
| 528 if (string.is8Bit()) |
| 529 return false; |
| 530 |
| 531 const UChar* characters = string.characters16(); |
| 532 const unsigned length = string.length(); |
| 533 |
| 534 for (unsigned i = 0; i < length; ++i) { |
| 535 UChar c = characters[i]; |
| 536 if (U16_IS_SINGLE(c)) |
| 537 continue; |
| 538 if (U16_IS_TRAIL(c)) |
| 539 return true; |
| 540 ASSERT(U16_IS_LEAD(c)); |
| 541 if (i == length - 1) |
| 542 return true; |
| 543 UChar d = characters[i + 1]; |
| 544 if (!U16_IS_TRAIL(d)) |
| 545 return true; |
| 546 ++i; |
| 547 } |
| 548 return false; |
| 549 } |
| 550 |
| 551 // Replace unmatched surrogates with REPLACEMENT CHARACTER U+FFFD. |
| 552 static String replaceUnmatchedSurrogates(const String& string) |
| 553 { |
| 554 // This roughly implements http://heycam.github.io/webidl/#dfn-obtain-unicod
e |
| 555 // but since Blink strings are 16-bits internally, the output is simply |
| 556 // re-encoded to UTF-16. |
| 557 |
| 558 // The concept of surrogate pairs is explained at: |
| 559 // http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G2630 |
| 560 |
| 561 // Blink-specific optimization to avoid making an unnecessary copy. |
| 562 if (!hasUnmatchedSurrogates(string)) |
| 563 return string; |
| 564 ASSERT(!string.is8Bit()); |
| 565 |
| 566 // 1. Let S be the DOMString value. |
| 567 const UChar* s = string.characters16(); |
| 568 |
| 569 // 2. Let n be the length of S. |
| 570 const unsigned n = string.length(); |
| 571 |
| 572 // 3. Initialize i to 0. |
| 573 unsigned i = 0; |
| 574 |
| 575 // 4. Initialize U to be an empty sequence of Unicode characters. |
| 576 StringBuilder u; |
| 577 u.reserveCapacity(n); |
| 578 |
| 579 // 5. While i < n: |
| 580 while (i < n) { |
| 581 // 1. Let c be the code unit in S at index i. |
| 582 UChar c = s[i]; |
| 583 // 2. Depending on the value of c: |
| 584 if (U16_IS_SINGLE(c)) { |
| 585 // c < 0xD800 or c > 0xDFFF |
| 586 // Append to U the Unicode character with code point c. |
| 587 u.append(c); |
| 588 } else if (U16_IS_TRAIL(c)) { |
| 589 // 0xDC00 <= c <= 0xDFFF |
| 590 // Append to U a U+FFFD REPLACEMENT CHARACTER. |
| 591 u.append(WTF::Unicode::replacementCharacter); |
| 592 } else { |
| 593 // 0xD800 <= c <= 0xDBFF |
| 594 ASSERT(U16_IS_LEAD(c)); |
| 595 if (i == n - 1) { |
| 596 // 1. If i = n−1, then append to U a U+FFFD REPLACEMENT CHARACTE
R. |
| 597 u.append(WTF::Unicode::replacementCharacter); |
| 598 } else { |
| 599 // 2. Otherwise, i < n−1: |
| 600 ASSERT(i < n - 1); |
| 601 // ....1. Let d be the code unit in S at index i+1. |
| 602 UChar d = s[i + 1]; |
| 603 if (U16_IS_TRAIL(d)) { |
| 604 // 2. If 0xDC00 <= d <= 0xDFFF, then: |
| 605 // ..1. Let a be c & 0x3FF. |
| 606 // ..2. Let b be d & 0x3FF. |
| 607 // ..3. Append to U the Unicode character with code point 2^
16+2^10*a+b. |
| 608 u.append(U16_GET_SUPPLEMENTARY(c, d)); |
| 609 // Blink: This is equivalent to u.append(c); u.append(d); |
| 610 ++i; |
| 611 } else { |
| 612 // 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a U+F
FFD REPLACEMENT CHARACTER. |
| 613 u.append(WTF::Unicode::replacementCharacter); |
| 614 } |
| 615 } |
| 616 } |
| 617 // 3. Set i to i+1. |
| 618 ++i; |
| 619 } |
| 620 |
| 621 // 6. Return U. |
| 622 ASSERT(u.length() == string.length()); |
| 623 return u.toString(); |
| 624 } |
| 625 |
| 626 String toScalarValueString(v8::Handle<v8::Value> value, ExceptionState& exceptio
nState) |
| 627 { |
| 628 // From the Encoding standard (with a TODO to move to Web IDL): |
| 629 // http://encoding.spec.whatwg.org/#type-scalarvaluestring |
| 630 if (value.IsEmpty()) |
| 631 return String(); |
| 632 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value->
ToString(), exceptionState, String()); |
| 633 |
| 634 // ScalarValueString is identical to DOMString except that "convert a |
| 635 // DOMString to a sequence of Unicode characters" is used subsequently |
| 636 // when converting to an IDL value |
| 637 String x = toCoreString(stringObject); |
| 638 return replaceUnmatchedSurrogates(x); |
| 639 } |
| 640 |
520 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>
value, v8::Isolate* isolate) | 641 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>
value, v8::Isolate* isolate) |
521 { | 642 { |
522 RefPtrWillBeRawPtr<XPathNSResolver> resolver = nullptr; | 643 RefPtrWillBeRawPtr<XPathNSResolver> resolver = nullptr; |
523 if (V8XPathNSResolver::hasInstance(value, isolate)) | 644 if (V8XPathNSResolver::hasInstance(value, isolate)) |
524 resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(valu
e)); | 645 resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(valu
e)); |
525 else if (value->IsObject()) | 646 else if (value->IsObject()) |
526 resolver = V8CustomXPathNSResolver::create(value->ToObject(), isolate); | 647 resolver = V8CustomXPathNSResolver::create(value->ToObject(), isolate); |
527 return resolver; | 648 return resolver; |
528 } | 649 } |
529 | 650 |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 PassRefPtr<TraceEvent::ConvertableToTraceFormat> devToolsTraceEventData(Executio
nContext* context, v8::Handle<v8::Function> function, v8::Isolate* isolate) | 931 PassRefPtr<TraceEvent::ConvertableToTraceFormat> devToolsTraceEventData(Executio
nContext* context, v8::Handle<v8::Function> function, v8::Isolate* isolate) |
811 { | 932 { |
812 int scriptId = 0; | 933 int scriptId = 0; |
813 String resourceName; | 934 String resourceName; |
814 int lineNumber = 1; | 935 int lineNumber = 1; |
815 GetDevToolsFunctionInfo(function, isolate, scriptId, resourceName, lineNumbe
r); | 936 GetDevToolsFunctionInfo(function, isolate, scriptId, resourceName, lineNumbe
r); |
816 return InspectorFunctionCallEvent::data(context, scriptId, resourceName, lin
eNumber); | 937 return InspectorFunctionCallEvent::data(context, scriptId, resourceName, lin
eNumber); |
817 } | 938 } |
818 | 939 |
819 } // namespace WebCore | 940 } // namespace WebCore |
OLD | NEW |