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 static String convertDOMStringToSequenceOfUnicodeCharacters(const String& string ) | |
Nils Barth (inactive)
2014/06/18 03:25:26
I admire your adherence to spec, but you're right,
haraken
2014/06/18 04:57:33
I don't have a strong opinion here, since this met
jsbell
2014/06/18 17:25:19
I'll go back to 'replaceUnmatchedSurrogates' and a
| |
552 { | |
553 // This roughly implements http://heycam.github.io/webidl/#dfn-obtain-unicod e | |
554 // but the output is still a sequence of 16-bit code units, effectively | |
Nils Barth (inactive)
2014/06/18 03:25:26
Is this still true, now that you're using StringBu
jsbell
2014/06/18 17:25:19
Yes. Blink strings are 16-bit internally, this jus
Nils Barth (inactive)
2014/06/20 00:57:54
Thanks for explanation!
On 2014/06/18 17:25:19, j
| |
555 // re-encoding to UTF-16 after performing the replacements. | |
556 | |
557 // The concepts of surrogate pairs are explained at: | |
558 // http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G2630 | |
559 | |
560 // Blink-specific optimization to avoid making an unnecessary copy. | |
561 if (!hasUnmatchedSurrogates(string)) | |
562 return string; | |
563 ASSERT(!string.is8Bit()); | |
564 | |
565 // 1. Let S be the DOMString value. | |
566 const UChar* s = string.characters16(); | |
567 | |
568 // 2. Let n be the length of S. | |
569 const unsigned n = string.length(); | |
570 | |
571 // 3. Initialize i to 0. | |
572 unsigned i = 0; | |
573 | |
574 // 4. Initialize U to be an empty sequence of Unicode characters. | |
575 StringBuilder u; | |
576 u.reserveCapacity(n); | |
577 | |
578 // 5. While i < n: | |
579 while (i < n) { | |
580 // 1. Let c be the code unit in S at index i. | |
581 UChar c = s[i]; | |
582 // 2. Depending on the value of c: | |
583 if (U16_IS_SINGLE(c)) { | |
584 // c < 0xD800 or c > 0xDFFF | |
585 // Append to U the Unicode character with code point c. | |
586 u.append(c); | |
587 } else if (U16_IS_TRAIL(c)) { | |
588 // 0xDC00 <= c <= 0xDFFF | |
589 // Append to U a U+FFFD REPLACEMENT CHARACTER. | |
590 u.append(WTF::Unicode::replacementCharacter); | |
591 } else { | |
592 // 0xD800 <= c <= 0xDBFF | |
593 ASSERT(U16_IS_LEAD(c)); | |
594 if (i == n - 1) { | |
595 // 1. If i = n−1, then append to U a U+FFFD REPLACEMENT CHARACTE R. | |
596 u.append(WTF::Unicode::replacementCharacter); | |
597 } else { | |
598 // 2. Otherwise, i < n−1: | |
599 ASSERT(i < n - 1); | |
600 // ....1. Let d be the code unit in S at index i+1. | |
601 UChar d = s[i + 1]; | |
602 if (U16_IS_TRAIL(d)) { | |
603 // 2. If 0xDC00 <= d <= 0xDFFF, then: | |
604 // ..1. Let a be c & 0x3FF. | |
605 unsigned a = c & 0x3FF; | |
606 // ..2. Let b be d & 0x3FF. | |
607 unsigned b = d & 0x3FF; | |
608 // ..3. Append to U the Unicode character with code point 2^ 16+2^10*a+b. | |
609 u.append(static_cast<UChar32>((1 << 16) + (a << 10) + b)); | |
jsbell
2014/06/17 21:39:50
Since this is using StringBuilder, it's now "per s
tkent
2014/06/17 23:38:54
U16_GET_SUPPLEMENTARY(c, d) ?
Nils Barth (inactive)
2014/06/18 03:25:26
+1!
jsbell
2014/06/18 17:25:19
Will do!
| |
610 // Blink: This is equivalent to u.append(c); u.append(d); | |
611 ++i; | |
612 } else { | |
613 // 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a U+F FFD REPLACEMENT CHARACTER. | |
614 u.append(WTF::Unicode::replacementCharacter); | |
615 } | |
616 } | |
617 } | |
618 // 3. Set i to i+1. | |
619 ++i; | |
620 } | |
621 | |
622 // 6. Return U. | |
623 ASSERT(u.length() == string.length()); | |
624 return u.toString(); | |
625 } | |
626 | |
627 String toScalarValueString(v8::Handle<v8::Value> value, ExceptionState& exceptio nState) | |
628 { | |
629 // From the Encoding standard (with a TODO to move to Web IDL): | |
630 // http://encoding.spec.whatwg.org/#type-scalarvaluestring | |
631 if (value.IsEmpty()) | |
632 return String(); | |
633 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value-> ToString(), exceptionState, String()); | |
634 | |
635 // ScalarValueString is identical to DOMString except that "convert a | |
636 // DOMString to a sequence of Unicode characters" is used subsequently | |
637 // when converting to an IDL value | |
638 String x = toCoreString(stringObject); | |
639 return convertDOMStringToSequenceOfUnicodeCharacters(x); | |
640 } | |
641 | |
520 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value> value, v8::Isolate* isolate) | 642 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value> value, v8::Isolate* isolate) |
521 { | 643 { |
522 RefPtrWillBeRawPtr<XPathNSResolver> resolver = nullptr; | 644 RefPtrWillBeRawPtr<XPathNSResolver> resolver = nullptr; |
523 if (V8XPathNSResolver::hasInstance(value, isolate)) | 645 if (V8XPathNSResolver::hasInstance(value, isolate)) |
524 resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(valu e)); | 646 resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(valu e)); |
525 else if (value->IsObject()) | 647 else if (value->IsObject()) |
526 resolver = V8CustomXPathNSResolver::create(value->ToObject(), isolate); | 648 resolver = V8CustomXPathNSResolver::create(value->ToObject(), isolate); |
527 return resolver; | 649 return resolver; |
528 } | 650 } |
529 | 651 |
(...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) | 932 PassRefPtr<TraceEvent::ConvertableToTraceFormat> devToolsTraceEventData(Executio nContext* context, v8::Handle<v8::Function> function, v8::Isolate* isolate) |
811 { | 933 { |
812 int scriptId = 0; | 934 int scriptId = 0; |
813 String resourceName; | 935 String resourceName; |
814 int lineNumber = 1; | 936 int lineNumber = 1; |
815 GetDevToolsFunctionInfo(function, isolate, scriptId, resourceName, lineNumbe r); | 937 GetDevToolsFunctionInfo(function, isolate, scriptId, resourceName, lineNumbe r); |
816 return InspectorFunctionCallEvent::data(context, scriptId, resourceName, lin eNumber); | 938 return InspectorFunctionCallEvent::data(context, scriptId, resourceName, lin eNumber); |
817 } | 939 } |
818 | 940 |
819 } // namespace WebCore | 941 } // namespace WebCore |
OLD | NEW |