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 |