Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 #ifdef V8_I18N_SUPPORT | 6 #ifdef V8_I18N_SUPPORT |
| 7 #include "src/runtime/runtime-utils.h" | 7 #include "src/runtime/runtime-utils.h" |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "unicode/dcfmtsym.h" | 26 #include "unicode/dcfmtsym.h" |
| 27 #include "unicode/decimfmt.h" | 27 #include "unicode/decimfmt.h" |
| 28 #include "unicode/dtfmtsym.h" | 28 #include "unicode/dtfmtsym.h" |
| 29 #include "unicode/dtptngen.h" | 29 #include "unicode/dtptngen.h" |
| 30 #include "unicode/fieldpos.h" | 30 #include "unicode/fieldpos.h" |
| 31 #include "unicode/fpositer.h" | 31 #include "unicode/fpositer.h" |
| 32 #include "unicode/locid.h" | 32 #include "unicode/locid.h" |
| 33 #include "unicode/normalizer2.h" | 33 #include "unicode/normalizer2.h" |
| 34 #include "unicode/numfmt.h" | 34 #include "unicode/numfmt.h" |
| 35 #include "unicode/numsys.h" | 35 #include "unicode/numsys.h" |
| 36 #include "unicode/plurrule.h" | |
| 36 #include "unicode/rbbi.h" | 37 #include "unicode/rbbi.h" |
| 37 #include "unicode/smpdtfmt.h" | 38 #include "unicode/smpdtfmt.h" |
| 38 #include "unicode/timezone.h" | 39 #include "unicode/timezone.h" |
| 39 #include "unicode/translit.h" | 40 #include "unicode/translit.h" |
| 40 #include "unicode/uchar.h" | 41 #include "unicode/uchar.h" |
| 41 #include "unicode/ucol.h" | 42 #include "unicode/ucol.h" |
| 42 #include "unicode/ucurr.h" | 43 #include "unicode/ucurr.h" |
| 43 #include "unicode/uloc.h" | 44 #include "unicode/uloc.h" |
| 44 #include "unicode/unistr.h" | 45 #include "unicode/unistr.h" |
| 45 #include "unicode/unum.h" | 46 #include "unicode/unum.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 int32_t count = 0; | 117 int32_t count = 0; |
| 117 | 118 |
| 118 if (service->IsUtf8EqualTo(CStrVector("collator"))) { | 119 if (service->IsUtf8EqualTo(CStrVector("collator"))) { |
| 119 available_locales = icu::Collator::getAvailableLocales(count); | 120 available_locales = icu::Collator::getAvailableLocales(count); |
| 120 } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) { | 121 } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) { |
| 121 available_locales = icu::NumberFormat::getAvailableLocales(count); | 122 available_locales = icu::NumberFormat::getAvailableLocales(count); |
| 122 } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) { | 123 } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) { |
| 123 available_locales = icu::DateFormat::getAvailableLocales(count); | 124 available_locales = icu::DateFormat::getAvailableLocales(count); |
| 124 } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) { | 125 } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) { |
| 125 available_locales = icu::BreakIterator::getAvailableLocales(count); | 126 available_locales = icu::BreakIterator::getAvailableLocales(count); |
| 127 } else if (service->IsUtf8EqualTo(CStrVector("pluralrules"))) { | |
| 128 // TODO(littledan): For PluralRules, filter out locales that | |
| 129 // don't support PluralRules. | |
| 130 // PluralRules is missing an appropriate getAvailableLocales method, | |
| 131 // so we should filter from all locales, but it's not clear how; see | |
| 132 // https://ssl.icu-project.org/trac/ticket/12756 | |
| 133 available_locales = icu::Locale::getAvailableLocales(count); | |
| 134 } else { | |
| 135 UNREACHABLE(); | |
| 126 } | 136 } |
| 127 | 137 |
| 128 UErrorCode error = U_ZERO_ERROR; | 138 UErrorCode error = U_ZERO_ERROR; |
| 129 char result[ULOC_FULLNAME_CAPACITY]; | 139 char result[ULOC_FULLNAME_CAPACITY]; |
| 130 Handle<JSObject> locales = factory->NewJSObject(isolate->object_function()); | 140 Handle<JSObject> locales = factory->NewJSObject(isolate->object_function()); |
| 131 | 141 |
| 132 for (int32_t i = 0; i < count; ++i) { | 142 for (int32_t i = 0; i < count; ++i) { |
| 133 const char* icu_name = available_locales[i].getName(); | 143 const char* icu_name = available_locales[i].getName(); |
| 134 | 144 |
| 135 error = U_ZERO_ERROR; | 145 error = U_ZERO_ERROR; |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 const UChar* string_val1 = GetUCharBufferFromFlat(flat1, &sap1, length1); | 641 const UChar* string_val1 = GetUCharBufferFromFlat(flat1, &sap1, length1); |
| 632 const UChar* string_val2 = GetUCharBufferFromFlat(flat2, &sap2, length2); | 642 const UChar* string_val2 = GetUCharBufferFromFlat(flat2, &sap2, length2); |
| 633 result = | 643 result = |
| 634 collator->compare(string_val1, length1, string_val2, length2, status); | 644 collator->compare(string_val1, length1, string_val2, length2, status); |
| 635 } | 645 } |
| 636 if (U_FAILURE(status)) return isolate->ThrowIllegalOperation(); | 646 if (U_FAILURE(status)) return isolate->ThrowIllegalOperation(); |
| 637 | 647 |
| 638 return *isolate->factory()->NewNumberFromInt(result); | 648 return *isolate->factory()->NewNumberFromInt(result); |
| 639 } | 649 } |
| 640 | 650 |
| 651 RUNTIME_FUNCTION(Runtime_CreatePluralRules) { | |
| 652 HandleScope scope(isolate); | |
| 653 | |
| 654 DCHECK_EQ(3, args.length()); | |
| 655 | |
| 656 CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); | |
| 657 CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); | |
| 658 CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); | |
| 659 | |
| 660 Handle<JSFunction> constructor( | |
| 661 isolate->native_context()->intl_plural_rules_function()); | |
| 662 | |
| 663 Handle<JSObject> local_object; | |
| 664 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object, | |
| 665 JSObject::New(constructor, constructor)); | |
| 666 | |
| 667 // Set pluralRules as internal field of the resulting JS object. | |
| 668 icu::PluralRules* plural_rules; | |
| 669 icu::DecimalFormat* decimal_format; | |
| 670 bool success = PluralRules::InitializePluralRules( | |
| 671 isolate, locale, options, resolved, &plural_rules, &decimal_format); | |
| 672 | |
| 673 if (!success) return isolate->ThrowIllegalOperation(); | |
| 674 | |
| 675 local_object->SetInternalField(0, reinterpret_cast<Smi*>(plural_rules)); | |
| 676 local_object->SetInternalField(1, reinterpret_cast<Smi*>(decimal_format)); | |
| 677 | |
| 678 Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); | |
| 679 GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(), | |
| 680 PluralRules::DeletePluralRules, | |
| 681 WeakCallbackType::kInternalFields); | |
| 682 return *local_object; | |
| 683 } | |
| 684 | |
| 685 RUNTIME_FUNCTION(Runtime_PluralRulesSelect) { | |
| 686 HandleScope scope(isolate); | |
| 687 | |
| 688 DCHECK_EQ(2, args.length()); | |
| 689 | |
| 690 CONVERT_ARG_HANDLE_CHECKED(JSObject, plural_rules_holder, 0); | |
| 691 CONVERT_ARG_HANDLE_CHECKED(Object, number, 1); | |
| 692 | |
| 693 icu::PluralRules* plural_rules = | |
| 694 PluralRules::UnpackPluralRules(isolate, plural_rules_holder); | |
| 695 CHECK_NOT_NULL(plural_rules); | |
| 696 | |
| 697 icu::DecimalFormat* number_format = | |
| 698 PluralRules::UnpackNumberFormat(isolate, plural_rules_holder); | |
| 699 CHECK_NOT_NULL(number_format); | |
| 700 | |
| 701 // Currently, PluralRules doesn't implement all the options for rounding that | |
| 702 // the Intl spec provides; format and parse the number to round to the | |
| 703 // appropriate amount, then apply PluralRules. | |
| 704 // | |
| 705 // TODO(littledan): If a future ICU version supports an extended API to avoid | |
| 706 // this step, then switch to that API. Bug thread: | |
| 707 // http://bugs.icu-project.org/trac/ticket/12763 | |
|
jungshik at Google
2017/05/08 19:16:54
Fixed in ICU 59.1. Either wait for me to update Ch
Dan Ehrenberg
2017/07/14 08:31:50
Looks like that API is C-only. I posted a comment
| |
| 708 icu::UnicodeString rounded_string; | |
| 709 number_format->format(number->Number(), rounded_string); | |
| 710 | |
| 711 icu::Formattable formattable; | |
| 712 UErrorCode status = U_ZERO_ERROR; | |
| 713 number_format->parse(rounded_string, formattable, status); | |
| 714 if (!U_SUCCESS(status)) return isolate->ThrowIllegalOperation(); | |
|
jungshik at Google
2017/05/08 19:16:54
again, check at line 717 would suffice. If you wan
| |
| 715 | |
| 716 double rounded = formattable.getDouble(status); | |
| 717 if (!U_SUCCESS(status)) return isolate->ThrowIllegalOperation(); | |
| 718 | |
| 719 icu::UnicodeString result = plural_rules->select(rounded); | |
| 720 return *isolate->factory() | |
| 721 ->NewStringFromTwoByte(Vector<const uint16_t>( | |
| 722 reinterpret_cast<const uint16_t*>(result.getBuffer()), | |
| 723 result.length())) | |
| 724 .ToHandleChecked(); | |
| 725 } | |
| 641 | 726 |
| 642 RUNTIME_FUNCTION(Runtime_StringNormalize) { | 727 RUNTIME_FUNCTION(Runtime_StringNormalize) { |
| 643 HandleScope scope(isolate); | 728 HandleScope scope(isolate); |
| 644 static const struct { | 729 static const struct { |
| 645 const char* name; | 730 const char* name; |
| 646 UNormalization2Mode mode; | 731 UNormalization2Mode mode; |
| 647 } normalizationForms[] = { | 732 } normalizationForms[] = { |
| 648 {"nfc", UNORM2_COMPOSE}, | 733 {"nfc", UNORM2_COMPOSE}, |
| 649 {"nfc", UNORM2_DECOMPOSE}, | 734 {"nfc", UNORM2_DECOMPOSE}, |
| 650 {"nfkc", UNORM2_COMPOSE}, | 735 {"nfkc", UNORM2_COMPOSE}, |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1199 Handle<FixedArray> date_cache_version = | 1284 Handle<FixedArray> date_cache_version = |
| 1200 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton( | 1285 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton( |
| 1201 EternalHandles::DATE_CACHE_VERSION)); | 1286 EternalHandles::DATE_CACHE_VERSION)); |
| 1202 return date_cache_version->get(0); | 1287 return date_cache_version->get(0); |
| 1203 } | 1288 } |
| 1204 | 1289 |
| 1205 } // namespace internal | 1290 } // namespace internal |
| 1206 } // namespace v8 | 1291 } // namespace v8 |
| 1207 | 1292 |
| 1208 #endif // V8_I18N_SUPPORT | 1293 #endif // V8_I18N_SUPPORT |
| OLD | NEW |