| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 // limitations under the License. | 27 // limitations under the License. |
| 28 | 28 |
| 29 #include "i18n.h" | 29 #include "i18n.h" |
| 30 | 30 |
| 31 #include "unicode/brkiter.h" |
| 31 #include "unicode/calendar.h" | 32 #include "unicode/calendar.h" |
| 33 #include "unicode/coll.h" |
| 32 #include "unicode/curramt.h" | 34 #include "unicode/curramt.h" |
| 33 #include "unicode/dcfmtsym.h" | 35 #include "unicode/dcfmtsym.h" |
| 34 #include "unicode/decimfmt.h" | 36 #include "unicode/decimfmt.h" |
| 35 #include "unicode/dtfmtsym.h" | 37 #include "unicode/dtfmtsym.h" |
| 36 #include "unicode/dtptngen.h" | 38 #include "unicode/dtptngen.h" |
| 37 #include "unicode/locid.h" | 39 #include "unicode/locid.h" |
| 38 #include "unicode/numfmt.h" | 40 #include "unicode/numfmt.h" |
| 39 #include "unicode/numsys.h" | 41 #include "unicode/numsys.h" |
| 42 #include "unicode/rbbi.h" |
| 40 #include "unicode/smpdtfmt.h" | 43 #include "unicode/smpdtfmt.h" |
| 41 #include "unicode/timezone.h" | 44 #include "unicode/timezone.h" |
| 42 #include "unicode/uchar.h" | 45 #include "unicode/uchar.h" |
| 46 #include "unicode/ucol.h" |
| 43 #include "unicode/ucurr.h" | 47 #include "unicode/ucurr.h" |
| 44 #include "unicode/unum.h" | 48 #include "unicode/unum.h" |
| 45 #include "unicode/uversion.h" | 49 #include "unicode/uversion.h" |
| 46 | 50 |
| 47 namespace v8 { | 51 namespace v8 { |
| 48 namespace internal { | 52 namespace internal { |
| 49 | 53 |
| 50 namespace { | 54 namespace { |
| 51 | 55 |
| 52 bool ExtractStringSetting(Isolate* isolate, | 56 bool ExtractStringSetting(Isolate* isolate, |
| 53 Handle<JSObject> options, | 57 Handle<JSObject> options, |
| 54 const char* key, | 58 const char* key, |
| 55 icu::UnicodeString* setting) { | 59 icu::UnicodeString* setting) { |
| 56 MaybeObject* maybe_object = options->GetProperty( | 60 Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key)); |
| 57 *isolate->factory()->NewStringFromAscii(CStrVector(key))); | 61 MaybeObject* maybe_object = options->GetProperty(*str); |
| 58 Object* object; | 62 Object* object; |
| 59 if (maybe_object->ToObject(&object) && object->IsString()) { | 63 if (maybe_object->ToObject(&object) && object->IsString()) { |
| 60 v8::String::Utf8Value utf8_string( | 64 v8::String::Utf8Value utf8_string( |
| 61 v8::Utils::ToLocal(Handle<String>(String::cast(object)))); | 65 v8::Utils::ToLocal(Handle<String>(String::cast(object)))); |
| 62 *setting = icu::UnicodeString::fromUTF8(*utf8_string); | 66 *setting = icu::UnicodeString::fromUTF8(*utf8_string); |
| 63 return true; | 67 return true; |
| 64 } | 68 } |
| 65 return false; | 69 return false; |
| 66 } | 70 } |
| 67 | 71 |
| 68 | 72 |
| 69 bool ExtractIntegerSetting(Isolate* isolate, | 73 bool ExtractIntegerSetting(Isolate* isolate, |
| 70 Handle<JSObject> options, | 74 Handle<JSObject> options, |
| 71 const char* key, | 75 const char* key, |
| 72 int32_t* value) { | 76 int32_t* value) { |
| 73 MaybeObject* maybe_object = options->GetProperty( | 77 Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key)); |
| 74 *isolate->factory()->NewStringFromAscii(CStrVector(key))); | 78 MaybeObject* maybe_object = options->GetProperty(*str); |
| 75 Object* object; | 79 Object* object; |
| 76 if (maybe_object->ToObject(&object) && object->IsNumber()) { | 80 if (maybe_object->ToObject(&object) && object->IsNumber()) { |
| 77 object->ToInt32(value); | 81 object->ToInt32(value); |
| 78 return true; | 82 return true; |
| 79 } | 83 } |
| 80 return false; | 84 return false; |
| 81 } | 85 } |
| 82 | 86 |
| 83 | 87 |
| 84 bool ExtractBooleanSetting(Isolate* isolate, | 88 bool ExtractBooleanSetting(Isolate* isolate, |
| 85 Handle<JSObject> options, | 89 Handle<JSObject> options, |
| 86 const char* key, | 90 const char* key, |
| 87 bool* value) { | 91 bool* value) { |
| 88 MaybeObject* maybe_object = options->GetProperty( | 92 Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key)); |
| 89 *isolate->factory()->NewStringFromAscii(CStrVector(key))); | 93 MaybeObject* maybe_object = options->GetProperty(*str); |
| 90 Object* object; | 94 Object* object; |
| 91 if (maybe_object->ToObject(&object) && object->IsBoolean()) { | 95 if (maybe_object->ToObject(&object) && object->IsBoolean()) { |
| 92 *value = object->BooleanValue(); | 96 *value = object->BooleanValue(); |
| 93 return true; | 97 return true; |
| 94 } | 98 } |
| 95 return false; | 99 return false; |
| 96 } | 100 } |
| 97 | 101 |
| 98 | 102 |
| 99 icu::SimpleDateFormat* CreateICUDateFormat( | 103 icu::SimpleDateFormat* CreateICUDateFormat( |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 | 455 |
| 452 JSObject::SetProperty( | 456 JSObject::SetProperty( |
| 453 resolved, | 457 resolved, |
| 454 isolate->factory()->NewStringFromAscii( | 458 isolate->factory()->NewStringFromAscii( |
| 455 CStrVector("maximumFractionDigits")), | 459 CStrVector("maximumFractionDigits")), |
| 456 isolate->factory()->NewNumberFromInt( | 460 isolate->factory()->NewNumberFromInt( |
| 457 number_format->getMaximumFractionDigits()), | 461 number_format->getMaximumFractionDigits()), |
| 458 NONE, | 462 NONE, |
| 459 kNonStrictMode); | 463 kNonStrictMode); |
| 460 | 464 |
| 461 if (resolved->HasLocalProperty(*isolate->factory()->NewStringFromAscii( | 465 Handle<String> key = isolate->factory()->NewStringFromAscii( |
| 462 CStrVector("minimumSignificantDigits")))) { | 466 CStrVector("minimumSignificantDigits")); |
| 467 if (resolved->HasLocalProperty(*key)) { |
| 463 JSObject::SetProperty( | 468 JSObject::SetProperty( |
| 464 resolved, | 469 resolved, |
| 465 isolate->factory()->NewStringFromAscii( | 470 isolate->factory()->NewStringFromAscii( |
| 466 CStrVector("minimumSignificantDigits")), | 471 CStrVector("minimumSignificantDigits")), |
| 467 isolate->factory()->NewNumberFromInt( | 472 isolate->factory()->NewNumberFromInt( |
| 468 number_format->getMinimumSignificantDigits()), | 473 number_format->getMinimumSignificantDigits()), |
| 469 NONE, | 474 NONE, |
| 470 kNonStrictMode); | 475 kNonStrictMode); |
| 471 } | 476 } |
| 472 | 477 |
| 473 if (resolved->HasLocalProperty(*isolate->factory()->NewStringFromAscii( | 478 key = isolate->factory()->NewStringFromAscii( |
| 474 CStrVector("maximumSignificantDigits")))) { | 479 CStrVector("maximumSignificantDigits")); |
| 480 if (resolved->HasLocalProperty(*key)) { |
| 475 JSObject::SetProperty( | 481 JSObject::SetProperty( |
| 476 resolved, | 482 resolved, |
| 477 isolate->factory()->NewStringFromAscii( | 483 isolate->factory()->NewStringFromAscii( |
| 478 CStrVector("maximumSignificantDigits")), | 484 CStrVector("maximumSignificantDigits")), |
| 479 isolate->factory()->NewNumberFromInt( | 485 isolate->factory()->NewNumberFromInt( |
| 480 number_format->getMaximumSignificantDigits()), | 486 number_format->getMaximumSignificantDigits()), |
| 481 NONE, | 487 NONE, |
| 482 kNonStrictMode); | 488 kNonStrictMode); |
| 483 } | 489 } |
| 484 | 490 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 498 // This would never happen, since we got the locale from ICU. | 504 // This would never happen, since we got the locale from ICU. |
| 499 JSObject::SetProperty( | 505 JSObject::SetProperty( |
| 500 resolved, | 506 resolved, |
| 501 isolate->factory()->NewStringFromAscii(CStrVector("locale")), | 507 isolate->factory()->NewStringFromAscii(CStrVector("locale")), |
| 502 isolate->factory()->NewStringFromAscii(CStrVector("und")), | 508 isolate->factory()->NewStringFromAscii(CStrVector("und")), |
| 503 NONE, | 509 NONE, |
| 504 kNonStrictMode); | 510 kNonStrictMode); |
| 505 } | 511 } |
| 506 } | 512 } |
| 507 | 513 |
| 514 |
| 515 icu::Collator* CreateICUCollator( |
| 516 Isolate* isolate, |
| 517 const icu::Locale& icu_locale, |
| 518 Handle<JSObject> options) { |
| 519 // Make collator from options. |
| 520 icu::Collator* collator = NULL; |
| 521 UErrorCode status = U_ZERO_ERROR; |
| 522 collator = icu::Collator::createInstance(icu_locale, status); |
| 523 |
| 524 if (U_FAILURE(status)) { |
| 525 delete collator; |
| 526 return NULL; |
| 527 } |
| 528 |
| 529 // Set flags first, and then override them with sensitivity if necessary. |
| 530 bool numeric; |
| 531 if (ExtractBooleanSetting(isolate, options, "numeric", &numeric)) { |
| 532 collator->setAttribute( |
| 533 UCOL_NUMERIC_COLLATION, numeric ? UCOL_ON : UCOL_OFF, status); |
| 534 } |
| 535 |
| 536 // Normalization is always on, by the spec. We are free to optimize |
| 537 // if the strings are already normalized (but we don't have a way to tell |
| 538 // that right now). |
| 539 collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); |
| 540 |
| 541 icu::UnicodeString case_first; |
| 542 if (ExtractStringSetting(isolate, options, "caseFirst", &case_first)) { |
| 543 if (case_first == UNICODE_STRING_SIMPLE("upper")) { |
| 544 collator->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status); |
| 545 } else if (case_first == UNICODE_STRING_SIMPLE("lower")) { |
| 546 collator->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status); |
| 547 } else { |
| 548 // Default (false/off). |
| 549 collator->setAttribute(UCOL_CASE_FIRST, UCOL_OFF, status); |
| 550 } |
| 551 } |
| 552 |
| 553 icu::UnicodeString sensitivity; |
| 554 if (ExtractStringSetting(isolate, options, "sensitivity", &sensitivity)) { |
| 555 if (sensitivity == UNICODE_STRING_SIMPLE("base")) { |
| 556 collator->setStrength(icu::Collator::PRIMARY); |
| 557 } else if (sensitivity == UNICODE_STRING_SIMPLE("accent")) { |
| 558 collator->setStrength(icu::Collator::SECONDARY); |
| 559 } else if (sensitivity == UNICODE_STRING_SIMPLE("case")) { |
| 560 collator->setStrength(icu::Collator::PRIMARY); |
| 561 collator->setAttribute(UCOL_CASE_LEVEL, UCOL_ON, status); |
| 562 } else { |
| 563 // variant (default) |
| 564 collator->setStrength(icu::Collator::TERTIARY); |
| 565 } |
| 566 } |
| 567 |
| 568 bool ignore; |
| 569 if (ExtractBooleanSetting(isolate, options, "ignorePunctuation", &ignore)) { |
| 570 if (ignore) { |
| 571 collator->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status); |
| 572 } |
| 573 } |
| 574 |
| 575 return collator; |
| 576 } |
| 577 |
| 578 |
| 579 void SetResolvedCollatorSettings(Isolate* isolate, |
| 580 const icu::Locale& icu_locale, |
| 581 icu::Collator* collator, |
| 582 Handle<JSObject> resolved) { |
| 583 UErrorCode status = U_ZERO_ERROR; |
| 584 |
| 585 JSObject::SetProperty( |
| 586 resolved, |
| 587 isolate->factory()->NewStringFromAscii(CStrVector("numeric")), |
| 588 isolate->factory()->ToBoolean( |
| 589 collator->getAttribute(UCOL_NUMERIC_COLLATION, status) == UCOL_ON), |
| 590 NONE, |
| 591 kNonStrictMode); |
| 592 |
| 593 switch (collator->getAttribute(UCOL_CASE_FIRST, status)) { |
| 594 case UCOL_LOWER_FIRST: |
| 595 JSObject::SetProperty( |
| 596 resolved, |
| 597 isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")), |
| 598 isolate->factory()->NewStringFromAscii(CStrVector("lower")), |
| 599 NONE, |
| 600 kNonStrictMode); |
| 601 break; |
| 602 case UCOL_UPPER_FIRST: |
| 603 JSObject::SetProperty( |
| 604 resolved, |
| 605 isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")), |
| 606 isolate->factory()->NewStringFromAscii(CStrVector("upper")), |
| 607 NONE, |
| 608 kNonStrictMode); |
| 609 break; |
| 610 default: |
| 611 JSObject::SetProperty( |
| 612 resolved, |
| 613 isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")), |
| 614 isolate->factory()->NewStringFromAscii(CStrVector("false")), |
| 615 NONE, |
| 616 kNonStrictMode); |
| 617 } |
| 618 |
| 619 switch (collator->getAttribute(UCOL_STRENGTH, status)) { |
| 620 case UCOL_PRIMARY: { |
| 621 JSObject::SetProperty( |
| 622 resolved, |
| 623 isolate->factory()->NewStringFromAscii(CStrVector("strength")), |
| 624 isolate->factory()->NewStringFromAscii(CStrVector("primary")), |
| 625 NONE, |
| 626 kNonStrictMode); |
| 627 |
| 628 // case level: true + s1 -> case, s1 -> base. |
| 629 if (UCOL_ON == collator->getAttribute(UCOL_CASE_LEVEL, status)) { |
| 630 JSObject::SetProperty( |
| 631 resolved, |
| 632 isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")), |
| 633 isolate->factory()->NewStringFromAscii(CStrVector("case")), |
| 634 NONE, |
| 635 kNonStrictMode); |
| 636 } else { |
| 637 JSObject::SetProperty( |
| 638 resolved, |
| 639 isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")), |
| 640 isolate->factory()->NewStringFromAscii(CStrVector("base")), |
| 641 NONE, |
| 642 kNonStrictMode); |
| 643 } |
| 644 break; |
| 645 } |
| 646 case UCOL_SECONDARY: |
| 647 JSObject::SetProperty( |
| 648 resolved, |
| 649 isolate->factory()->NewStringFromAscii(CStrVector("strength")), |
| 650 isolate->factory()->NewStringFromAscii(CStrVector("secondary")), |
| 651 NONE, |
| 652 kNonStrictMode); |
| 653 JSObject::SetProperty( |
| 654 resolved, |
| 655 isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")), |
| 656 isolate->factory()->NewStringFromAscii(CStrVector("accent")), |
| 657 NONE, |
| 658 kNonStrictMode); |
| 659 break; |
| 660 case UCOL_TERTIARY: |
| 661 JSObject::SetProperty( |
| 662 resolved, |
| 663 isolate->factory()->NewStringFromAscii(CStrVector("strength")), |
| 664 isolate->factory()->NewStringFromAscii(CStrVector("tertiary")), |
| 665 NONE, |
| 666 kNonStrictMode); |
| 667 JSObject::SetProperty( |
| 668 resolved, |
| 669 isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")), |
| 670 isolate->factory()->NewStringFromAscii(CStrVector("variant")), |
| 671 NONE, |
| 672 kNonStrictMode); |
| 673 break; |
| 674 case UCOL_QUATERNARY: |
| 675 // We shouldn't get quaternary and identical from ICU, but if we do |
| 676 // put them into variant. |
| 677 JSObject::SetProperty( |
| 678 resolved, |
| 679 isolate->factory()->NewStringFromAscii(CStrVector("strength")), |
| 680 isolate->factory()->NewStringFromAscii(CStrVector("quaternary")), |
| 681 NONE, |
| 682 kNonStrictMode); |
| 683 JSObject::SetProperty( |
| 684 resolved, |
| 685 isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")), |
| 686 isolate->factory()->NewStringFromAscii(CStrVector("variant")), |
| 687 NONE, |
| 688 kNonStrictMode); |
| 689 break; |
| 690 default: |
| 691 JSObject::SetProperty( |
| 692 resolved, |
| 693 isolate->factory()->NewStringFromAscii(CStrVector("strength")), |
| 694 isolate->factory()->NewStringFromAscii(CStrVector("identical")), |
| 695 NONE, |
| 696 kNonStrictMode); |
| 697 JSObject::SetProperty( |
| 698 resolved, |
| 699 isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")), |
| 700 isolate->factory()->NewStringFromAscii(CStrVector("variant")), |
| 701 NONE, |
| 702 kNonStrictMode); |
| 703 } |
| 704 |
| 705 JSObject::SetProperty( |
| 706 resolved, |
| 707 isolate->factory()->NewStringFromAscii(CStrVector("ignorePunctuation")), |
| 708 isolate->factory()->ToBoolean(collator->getAttribute( |
| 709 UCOL_ALTERNATE_HANDLING, status) == UCOL_SHIFTED), |
| 710 NONE, |
| 711 kNonStrictMode); |
| 712 |
| 713 // Set the locale |
| 714 char result[ULOC_FULLNAME_CAPACITY]; |
| 715 status = U_ZERO_ERROR; |
| 716 uloc_toLanguageTag( |
| 717 icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); |
| 718 if (U_SUCCESS(status)) { |
| 719 JSObject::SetProperty( |
| 720 resolved, |
| 721 isolate->factory()->NewStringFromAscii(CStrVector("locale")), |
| 722 isolate->factory()->NewStringFromAscii(CStrVector(result)), |
| 723 NONE, |
| 724 kNonStrictMode); |
| 725 } else { |
| 726 // This would never happen, since we got the locale from ICU. |
| 727 JSObject::SetProperty( |
| 728 resolved, |
| 729 isolate->factory()->NewStringFromAscii(CStrVector("locale")), |
| 730 isolate->factory()->NewStringFromAscii(CStrVector("und")), |
| 731 NONE, |
| 732 kNonStrictMode); |
| 733 } |
| 734 } |
| 735 |
| 736 |
| 737 icu::BreakIterator* CreateICUBreakIterator( |
| 738 Isolate* isolate, |
| 739 const icu::Locale& icu_locale, |
| 740 Handle<JSObject> options) { |
| 741 UErrorCode status = U_ZERO_ERROR; |
| 742 icu::BreakIterator* break_iterator = NULL; |
| 743 icu::UnicodeString type; |
| 744 if (!ExtractStringSetting(isolate, options, "type", &type)) return NULL; |
| 745 |
| 746 if (type == UNICODE_STRING_SIMPLE("character")) { |
| 747 break_iterator = |
| 748 icu::BreakIterator::createCharacterInstance(icu_locale, status); |
| 749 } else if (type == UNICODE_STRING_SIMPLE("sentence")) { |
| 750 break_iterator = |
| 751 icu::BreakIterator::createSentenceInstance(icu_locale, status); |
| 752 } else if (type == UNICODE_STRING_SIMPLE("line")) { |
| 753 break_iterator = |
| 754 icu::BreakIterator::createLineInstance(icu_locale, status); |
| 755 } else { |
| 756 // Defualt is word iterator. |
| 757 break_iterator = |
| 758 icu::BreakIterator::createWordInstance(icu_locale, status); |
| 759 } |
| 760 |
| 761 if (U_FAILURE(status)) { |
| 762 delete break_iterator; |
| 763 return NULL; |
| 764 } |
| 765 |
| 766 return break_iterator; |
| 767 } |
| 768 |
| 769 |
| 770 void SetResolvedBreakIteratorSettings(Isolate* isolate, |
| 771 const icu::Locale& icu_locale, |
| 772 icu::BreakIterator* break_iterator, |
| 773 Handle<JSObject> resolved) { |
| 774 UErrorCode status = U_ZERO_ERROR; |
| 775 |
| 776 // Set the locale |
| 777 char result[ULOC_FULLNAME_CAPACITY]; |
| 778 status = U_ZERO_ERROR; |
| 779 uloc_toLanguageTag( |
| 780 icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); |
| 781 if (U_SUCCESS(status)) { |
| 782 JSObject::SetProperty( |
| 783 resolved, |
| 784 isolate->factory()->NewStringFromAscii(CStrVector("locale")), |
| 785 isolate->factory()->NewStringFromAscii(CStrVector(result)), |
| 786 NONE, |
| 787 kNonStrictMode); |
| 788 } else { |
| 789 // This would never happen, since we got the locale from ICU. |
| 790 JSObject::SetProperty( |
| 791 resolved, |
| 792 isolate->factory()->NewStringFromAscii(CStrVector("locale")), |
| 793 isolate->factory()->NewStringFromAscii(CStrVector("und")), |
| 794 NONE, |
| 795 kNonStrictMode); |
| 796 } |
| 797 } |
| 798 |
| 508 } // namespace | 799 } // namespace |
| 509 | 800 |
| 510 | 801 |
| 511 // static | 802 // static |
| 512 Handle<ObjectTemplateInfo> I18N::GetTemplate(Isolate* isolate) { | 803 Handle<ObjectTemplateInfo> I18N::GetTemplate(Isolate* isolate) { |
| 513 return GetEternal<1, i::EternalHandles::I18N_TEMPLATE_ONE>(isolate); | 804 return GetEternal<1, i::EternalHandles::I18N_TEMPLATE_ONE>(isolate); |
| 514 } | 805 } |
| 515 | 806 |
| 516 | 807 |
| 517 // static | 808 // static |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 SetResolvedDateSettings(isolate, icu_locale, date_format, resolved); | 846 SetResolvedDateSettings(isolate, icu_locale, date_format, resolved); |
| 556 } | 847 } |
| 557 | 848 |
| 558 return date_format; | 849 return date_format; |
| 559 } | 850 } |
| 560 | 851 |
| 561 | 852 |
| 562 icu::SimpleDateFormat* DateFormat::UnpackDateFormat( | 853 icu::SimpleDateFormat* DateFormat::UnpackDateFormat( |
| 563 Isolate* isolate, | 854 Isolate* isolate, |
| 564 Handle<JSObject> obj) { | 855 Handle<JSObject> obj) { |
| 565 if (obj->HasLocalProperty( | 856 Handle<String> key = |
| 566 *isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")))) { | 857 isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")); |
| 858 if (obj->HasLocalProperty(*key)) { |
| 567 return reinterpret_cast<icu::SimpleDateFormat*>( | 859 return reinterpret_cast<icu::SimpleDateFormat*>( |
| 568 obj->GetInternalField(0)); | 860 obj->GetInternalField(0)); |
| 569 } | 861 } |
| 570 | 862 |
| 571 return NULL; | 863 return NULL; |
| 572 } | 864 } |
| 573 | 865 |
| 574 | 866 |
| 575 void DateFormat::DeleteDateFormat(v8::Isolate* isolate, | 867 void DateFormat::DeleteDateFormat(v8::Isolate* isolate, |
| 576 Persistent<v8::Object>* object, | 868 Persistent<v8::Value>* object, |
| 577 void* param) { | 869 void* param) { |
| 578 // First delete the hidden C++ object. | 870 // First delete the hidden C++ object. |
| 579 delete reinterpret_cast<icu::SimpleDateFormat*>(Handle<JSObject>::cast( | 871 delete reinterpret_cast<icu::SimpleDateFormat*>(Handle<JSObject>::cast( |
| 580 v8::Utils::OpenPersistent(object))->GetInternalField(0)); | 872 v8::Utils::OpenPersistent(object))->GetInternalField(0)); |
| 581 | 873 |
| 582 // Then dispose of the persistent handle to JS object. | 874 // Then dispose of the persistent handle to JS object. |
| 583 object->Dispose(isolate); | 875 object->Dispose(isolate); |
| 584 } | 876 } |
| 585 | 877 |
| 586 | 878 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 SetResolvedNumberSettings(isolate, icu_locale, number_format, resolved); | 911 SetResolvedNumberSettings(isolate, icu_locale, number_format, resolved); |
| 620 } | 912 } |
| 621 | 913 |
| 622 return number_format; | 914 return number_format; |
| 623 } | 915 } |
| 624 | 916 |
| 625 | 917 |
| 626 icu::DecimalFormat* NumberFormat::UnpackNumberFormat( | 918 icu::DecimalFormat* NumberFormat::UnpackNumberFormat( |
| 627 Isolate* isolate, | 919 Isolate* isolate, |
| 628 Handle<JSObject> obj) { | 920 Handle<JSObject> obj) { |
| 629 if (obj->HasLocalProperty(*isolate->factory()->NewStringFromAscii( | 921 Handle<String> key = |
| 630 CStrVector("numberFormat")))) { | 922 isolate->factory()->NewStringFromAscii(CStrVector("numberFormat")); |
| 923 if (obj->HasLocalProperty(*key)) { |
| 631 return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0)); | 924 return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0)); |
| 632 } | 925 } |
| 633 | 926 |
| 634 return NULL; | 927 return NULL; |
| 635 } | 928 } |
| 636 | 929 |
| 637 | 930 |
| 638 void NumberFormat::DeleteNumberFormat(v8::Isolate* isolate, | 931 void NumberFormat::DeleteNumberFormat(v8::Isolate* isolate, |
| 639 Persistent<v8::Object>* object, | 932 Persistent<v8::Value>* object, |
| 640 void* param) { | 933 void* param) { |
| 641 // First delete the hidden C++ object. | 934 // First delete the hidden C++ object. |
| 642 delete reinterpret_cast<icu::DecimalFormat*>(Handle<JSObject>::cast( | 935 delete reinterpret_cast<icu::DecimalFormat*>(Handle<JSObject>::cast( |
| 643 v8::Utils::OpenPersistent(object))->GetInternalField(0)); | 936 v8::Utils::OpenPersistent(object))->GetInternalField(0)); |
| 644 | 937 |
| 645 // Then dispose of the persistent handle to JS object. | 938 // Then dispose of the persistent handle to JS object. |
| 646 object->Dispose(isolate); | 939 object->Dispose(isolate); |
| 647 } | 940 } |
| 648 | 941 |
| 942 |
| 943 icu::Collator* Collator::InitializeCollator( |
| 944 Isolate* isolate, |
| 945 Handle<String> locale, |
| 946 Handle<JSObject> options, |
| 947 Handle<JSObject> resolved) { |
| 948 // Convert BCP47 into ICU locale format. |
| 949 UErrorCode status = U_ZERO_ERROR; |
| 950 icu::Locale icu_locale; |
| 951 char icu_result[ULOC_FULLNAME_CAPACITY]; |
| 952 int icu_length = 0; |
| 953 v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); |
| 954 if (bcp47_locale.length() != 0) { |
| 955 uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, |
| 956 &icu_length, &status); |
| 957 if (U_FAILURE(status) || icu_length == 0) { |
| 958 return NULL; |
| 959 } |
| 960 icu_locale = icu::Locale(icu_result); |
| 961 } |
| 962 |
| 963 icu::Collator* collator = CreateICUCollator(isolate, icu_locale, options); |
| 964 if (!collator) { |
| 965 // Remove extensions and try again. |
| 966 icu::Locale no_extension_locale(icu_locale.getBaseName()); |
| 967 collator = CreateICUCollator(isolate, no_extension_locale, options); |
| 968 |
| 969 // Set resolved settings (pattern, numbering system). |
| 970 SetResolvedCollatorSettings( |
| 971 isolate, no_extension_locale, collator, resolved); |
| 972 } else { |
| 973 SetResolvedCollatorSettings(isolate, icu_locale, collator, resolved); |
| 974 } |
| 975 |
| 976 return collator; |
| 977 } |
| 978 |
| 979 |
| 980 icu::Collator* Collator::UnpackCollator(Isolate* isolate, |
| 981 Handle<JSObject> obj) { |
| 982 Handle<String> key = |
| 983 isolate->factory()->NewStringFromAscii(CStrVector("collator")); |
| 984 if (obj->HasLocalProperty(*key)) { |
| 985 return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0)); |
| 986 } |
| 987 |
| 988 return NULL; |
| 989 } |
| 990 |
| 991 |
| 992 void Collator::DeleteCollator(v8::Isolate* isolate, |
| 993 Persistent<v8::Value>* object, |
| 994 void* param) { |
| 995 // First delete the hidden C++ object. |
| 996 delete reinterpret_cast<icu::Collator*>(Handle<JSObject>::cast( |
| 997 v8::Utils::OpenPersistent(object))->GetInternalField(0)); |
| 998 |
| 999 // Then dispose of the persistent handle to JS object. |
| 1000 object->Dispose(isolate); |
| 1001 } |
| 1002 |
| 1003 |
| 1004 icu::BreakIterator* BreakIterator::InitializeBreakIterator( |
| 1005 Isolate* isolate, |
| 1006 Handle<String> locale, |
| 1007 Handle<JSObject> options, |
| 1008 Handle<JSObject> resolved) { |
| 1009 // Convert BCP47 into ICU locale format. |
| 1010 UErrorCode status = U_ZERO_ERROR; |
| 1011 icu::Locale icu_locale; |
| 1012 char icu_result[ULOC_FULLNAME_CAPACITY]; |
| 1013 int icu_length = 0; |
| 1014 v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); |
| 1015 if (bcp47_locale.length() != 0) { |
| 1016 uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, |
| 1017 &icu_length, &status); |
| 1018 if (U_FAILURE(status) || icu_length == 0) { |
| 1019 return NULL; |
| 1020 } |
| 1021 icu_locale = icu::Locale(icu_result); |
| 1022 } |
| 1023 |
| 1024 icu::BreakIterator* break_iterator = CreateICUBreakIterator( |
| 1025 isolate, icu_locale, options); |
| 1026 if (!break_iterator) { |
| 1027 // Remove extensions and try again. |
| 1028 icu::Locale no_extension_locale(icu_locale.getBaseName()); |
| 1029 break_iterator = CreateICUBreakIterator( |
| 1030 isolate, no_extension_locale, options); |
| 1031 |
| 1032 // Set resolved settings (locale). |
| 1033 SetResolvedBreakIteratorSettings( |
| 1034 isolate, no_extension_locale, break_iterator, resolved); |
| 1035 } else { |
| 1036 SetResolvedBreakIteratorSettings( |
| 1037 isolate, icu_locale, break_iterator, resolved); |
| 1038 } |
| 1039 |
| 1040 return break_iterator; |
| 1041 } |
| 1042 |
| 1043 |
| 1044 icu::BreakIterator* BreakIterator::UnpackBreakIterator(Isolate* isolate, |
| 1045 Handle<JSObject> obj) { |
| 1046 Handle<String> key = |
| 1047 isolate->factory()->NewStringFromAscii(CStrVector("breakIterator")); |
| 1048 if (obj->HasLocalProperty(*key)) { |
| 1049 return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0)); |
| 1050 } |
| 1051 |
| 1052 return NULL; |
| 1053 } |
| 1054 |
| 1055 |
| 1056 void BreakIterator::DeleteBreakIterator(v8::Isolate* isolate, |
| 1057 Persistent<v8::Value>* object, |
| 1058 void* param) { |
| 1059 // First delete the hidden C++ object. |
| 1060 delete reinterpret_cast<icu::BreakIterator*>(Handle<JSObject>::cast( |
| 1061 v8::Utils::OpenPersistent(object))->GetInternalField(0)); |
| 1062 |
| 1063 delete reinterpret_cast<icu::UnicodeString*>(Handle<JSObject>::cast( |
| 1064 v8::Utils::OpenPersistent(object))->GetInternalField(1)); |
| 1065 |
| 1066 // Then dispose of the persistent handle to JS object. |
| 1067 object->Dispose(isolate); |
| 1068 } |
| 1069 |
| 649 } } // namespace v8::internal | 1070 } } // namespace v8::internal |
| OLD | NEW |