OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 // limitations under the License. | 4 // limitations under the License. |
5 | 5 |
6 #include "src/i18n.h" | 6 #include "src/i18n.h" |
7 | 7 |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/api.h" | 10 #include "src/api.h" |
11 #include "src/factory.h" | 11 #include "src/factory.h" |
12 #include "src/isolate.h" | 12 #include "src/isolate.h" |
13 #include "src/objects-inl.h" | 13 #include "src/objects-inl.h" |
14 #include "src/property-descriptor.h" | |
14 #include "unicode/brkiter.h" | 15 #include "unicode/brkiter.h" |
15 #include "unicode/calendar.h" | 16 #include "unicode/calendar.h" |
16 #include "unicode/coll.h" | 17 #include "unicode/coll.h" |
17 #include "unicode/curramt.h" | 18 #include "unicode/curramt.h" |
18 #include "unicode/dcfmtsym.h" | 19 #include "unicode/dcfmtsym.h" |
19 #include "unicode/decimfmt.h" | 20 #include "unicode/decimfmt.h" |
20 #include "unicode/dtfmtsym.h" | 21 #include "unicode/dtfmtsym.h" |
21 #include "unicode/dtptngen.h" | 22 #include "unicode/dtptngen.h" |
22 #include "unicode/gregocal.h" | 23 #include "unicode/gregocal.h" |
23 #include "unicode/locid.h" | 24 #include "unicode/locid.h" |
24 #include "unicode/numfmt.h" | 25 #include "unicode/numfmt.h" |
25 #include "unicode/numsys.h" | 26 #include "unicode/numsys.h" |
27 #include "unicode/plurrule.h" | |
26 #include "unicode/rbbi.h" | 28 #include "unicode/rbbi.h" |
27 #include "unicode/smpdtfmt.h" | 29 #include "unicode/smpdtfmt.h" |
28 #include "unicode/timezone.h" | 30 #include "unicode/timezone.h" |
29 #include "unicode/uchar.h" | 31 #include "unicode/uchar.h" |
30 #include "unicode/ucol.h" | 32 #include "unicode/ucol.h" |
31 #include "unicode/ucurr.h" | 33 #include "unicode/ucurr.h" |
32 #include "unicode/unum.h" | 34 #include "unicode/unum.h" |
35 #include "unicode/upluralrules.h" | |
33 #include "unicode/uversion.h" | 36 #include "unicode/uversion.h" |
34 | 37 |
35 namespace v8 { | 38 namespace v8 { |
36 namespace internal { | 39 namespace internal { |
37 | 40 |
38 namespace { | 41 namespace { |
39 | 42 |
40 bool ExtractStringSetting(Isolate* isolate, | 43 bool ExtractStringSetting(Isolate* isolate, |
41 Handle<JSObject> options, | 44 Handle<JSObject> options, |
42 const char* key, | 45 const char* key, |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 factory->NewStringFromAsciiChecked(result), | 220 factory->NewStringFromAsciiChecked(result), |
218 SLOPPY).Assert(); | 221 SLOPPY).Assert(); |
219 } else { | 222 } else { |
220 // This would never happen, since we got the locale from ICU. | 223 // This would never happen, since we got the locale from ICU. |
221 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), | 224 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), |
222 factory->NewStringFromStaticChars("und"), | 225 factory->NewStringFromStaticChars("und"), |
223 SLOPPY).Assert(); | 226 SLOPPY).Assert(); |
224 } | 227 } |
225 } | 228 } |
226 | 229 |
230 void SetNumericSettings(Isolate* isolate, icu::DecimalFormat* number_format, | |
231 Handle<JSObject> options) { | |
232 int32_t digits; | |
233 if (ExtractIntegerSetting(isolate, options, "minimumIntegerDigits", | |
234 &digits)) { | |
235 number_format->setMinimumIntegerDigits(digits); | |
236 } | |
237 | |
238 if (ExtractIntegerSetting(isolate, options, "minimumFractionDigits", | |
239 &digits)) { | |
240 number_format->setMinimumFractionDigits(digits); | |
241 } | |
242 | |
243 if (ExtractIntegerSetting(isolate, options, "maximumFractionDigits", | |
244 &digits)) { | |
245 number_format->setMaximumFractionDigits(digits); | |
246 } | |
247 | |
248 bool significant_digits_used = false; | |
249 if (ExtractIntegerSetting(isolate, options, "minimumSignificantDigits", | |
250 &digits)) { | |
251 number_format->setMinimumSignificantDigits(digits); | |
252 significant_digits_used = true; | |
253 } | |
254 | |
255 if (ExtractIntegerSetting(isolate, options, "maximumSignificantDigits", | |
256 &digits)) { | |
257 number_format->setMaximumSignificantDigits(digits); | |
258 significant_digits_used = true; | |
259 } | |
260 | |
261 number_format->setSignificantDigitsUsed(significant_digits_used); | |
262 | |
263 number_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp); | |
264 } | |
227 | 265 |
228 icu::DecimalFormat* CreateICUNumberFormat( | 266 icu::DecimalFormat* CreateICUNumberFormat( |
229 Isolate* isolate, | 267 Isolate* isolate, |
230 const icu::Locale& icu_locale, | 268 const icu::Locale& icu_locale, |
231 Handle<JSObject> options) { | 269 Handle<JSObject> options) { |
232 // Make formatter from options. Numbering system is added | 270 // Make formatter from options. Numbering system is added |
233 // to the locale as Unicode extension (if it was specified at all). | 271 // to the locale as Unicode extension (if it was specified at all). |
234 UErrorCode status = U_ZERO_ERROR; | 272 UErrorCode status = U_ZERO_ERROR; |
235 icu::DecimalFormat* number_format = NULL; | 273 icu::DecimalFormat* number_format = NULL; |
236 icu::UnicodeString style; | 274 icu::UnicodeString style; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 if (U_FAILURE(status)) { | 325 if (U_FAILURE(status)) { |
288 delete number_format; | 326 delete number_format; |
289 return NULL; | 327 return NULL; |
290 } | 328 } |
291 | 329 |
292 // Set all options. | 330 // Set all options. |
293 if (!currency.isEmpty()) { | 331 if (!currency.isEmpty()) { |
294 number_format->setCurrency(currency.getBuffer(), status); | 332 number_format->setCurrency(currency.getBuffer(), status); |
295 } | 333 } |
296 | 334 |
297 int32_t digits; | 335 SetNumericSettings(isolate, number_format, options); |
298 if (ExtractIntegerSetting( | |
299 isolate, options, "minimumIntegerDigits", &digits)) { | |
300 number_format->setMinimumIntegerDigits(digits); | |
301 } | |
302 | |
303 if (ExtractIntegerSetting( | |
304 isolate, options, "minimumFractionDigits", &digits)) { | |
305 number_format->setMinimumFractionDigits(digits); | |
306 } | |
307 | |
308 if (ExtractIntegerSetting( | |
309 isolate, options, "maximumFractionDigits", &digits)) { | |
310 number_format->setMaximumFractionDigits(digits); | |
311 } | |
312 | |
313 bool significant_digits_used = false; | |
314 if (ExtractIntegerSetting( | |
315 isolate, options, "minimumSignificantDigits", &digits)) { | |
316 number_format->setMinimumSignificantDigits(digits); | |
317 significant_digits_used = true; | |
318 } | |
319 | |
320 if (ExtractIntegerSetting( | |
321 isolate, options, "maximumSignificantDigits", &digits)) { | |
322 number_format->setMaximumSignificantDigits(digits); | |
323 significant_digits_used = true; | |
324 } | |
325 | |
326 number_format->setSignificantDigitsUsed(significant_digits_used); | |
327 | 336 |
328 bool grouping; | 337 bool grouping; |
329 if (ExtractBooleanSetting(isolate, options, "useGrouping", &grouping)) { | 338 if (ExtractBooleanSetting(isolate, options, "useGrouping", &grouping)) { |
330 number_format->setGroupingUsed(grouping); | 339 number_format->setGroupingUsed(grouping); |
331 } | 340 } |
332 | 341 |
333 // Set rounding mode. | |
334 number_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp); | |
335 | |
336 return number_format; | 342 return number_format; |
337 } | 343 } |
338 | 344 |
345 void SetResolvedNumericSettings(Isolate* isolate, const icu::Locale& icu_locale, | |
346 icu::DecimalFormat* number_format, | |
347 Handle<JSObject> resolved) { | |
348 Factory* factory = isolate->factory(); | |
339 | 349 |
350 JSObject::SetProperty( | |
351 resolved, factory->NewStringFromStaticChars("minimumIntegerDigits"), | |
352 factory->NewNumberFromInt(number_format->getMinimumIntegerDigits()), | |
353 SLOPPY) | |
354 .Assert(); | |
355 | |
356 JSObject::SetProperty( | |
357 resolved, factory->NewStringFromStaticChars("minimumFractionDigits"), | |
358 factory->NewNumberFromInt(number_format->getMinimumFractionDigits()), | |
359 SLOPPY) | |
360 .Assert(); | |
361 | |
362 JSObject::SetProperty( | |
363 resolved, factory->NewStringFromStaticChars("maximumFractionDigits"), | |
364 factory->NewNumberFromInt(number_format->getMaximumFractionDigits()), | |
365 SLOPPY) | |
366 .Assert(); | |
367 | |
368 Handle<String> key = | |
369 factory->NewStringFromStaticChars("minimumSignificantDigits"); | |
370 Maybe<bool> maybe = JSReceiver::HasOwnProperty(resolved, key); | |
371 CHECK(maybe.IsJust()); | |
372 if (maybe.FromJust()) { | |
373 JSObject::SetProperty( | |
374 resolved, factory->NewStringFromStaticChars("minimumSignificantDigits"), | |
375 factory->NewNumberFromInt(number_format->getMinimumSignificantDigits()), | |
376 SLOPPY) | |
377 .Assert(); | |
378 } | |
379 | |
380 key = factory->NewStringFromStaticChars("maximumSignificantDigits"); | |
381 maybe = JSReceiver::HasOwnProperty(resolved, key); | |
382 CHECK(maybe.IsJust()); | |
383 if (maybe.FromJust()) { | |
384 JSObject::SetProperty( | |
385 resolved, factory->NewStringFromStaticChars("maximumSignificantDigits"), | |
386 factory->NewNumberFromInt(number_format->getMaximumSignificantDigits()), | |
387 SLOPPY) | |
388 .Assert(); | |
389 } | |
390 | |
391 // Set the locale | |
392 char result[ULOC_FULLNAME_CAPACITY]; | |
393 UErrorCode status = U_ZERO_ERROR; | |
394 uloc_toLanguageTag(icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, | |
395 FALSE, &status); | |
396 if (U_SUCCESS(status)) { | |
397 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), | |
398 factory->NewStringFromAsciiChecked(result), SLOPPY) | |
399 .Assert(); | |
400 } else { | |
401 // This would never happen, since we got the locale from ICU. | |
402 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), | |
403 factory->NewStringFromStaticChars("und"), SLOPPY) | |
404 .Assert(); | |
405 } | |
406 } | |
407 | |
408 | |
340 void SetResolvedNumberSettings(Isolate* isolate, | 409 void SetResolvedNumberSettings(Isolate* isolate, |
341 const icu::Locale& icu_locale, | 410 const icu::Locale& icu_locale, |
342 icu::DecimalFormat* number_format, | 411 icu::DecimalFormat* number_format, |
343 Handle<JSObject> resolved) { | 412 Handle<JSObject> resolved) { |
344 Factory* factory = isolate->factory(); | 413 Factory* factory = isolate->factory(); |
345 icu::UnicodeString pattern; | |
346 number_format->toPattern(pattern); | |
347 JSObject::SetProperty( | |
348 resolved, factory->intl_pattern_symbol(), | |
349 factory->NewStringFromTwoByte( | |
350 Vector<const uint16_t>( | |
351 reinterpret_cast<const uint16_t*>(pattern.getBuffer()), | |
352 pattern.length())).ToHandleChecked(), | |
353 SLOPPY).Assert(); | |
354 | 414 |
355 // Set resolved currency code in options.currency if not empty. | 415 // Set resolved currency code in options.currency if not empty. |
356 icu::UnicodeString currency(number_format->getCurrency()); | 416 icu::UnicodeString currency(number_format->getCurrency()); |
357 if (!currency.isEmpty()) { | 417 if (!currency.isEmpty()) { |
358 JSObject::SetProperty( | 418 JSObject::SetProperty( |
359 resolved, factory->NewStringFromStaticChars("currency"), | 419 resolved, factory->NewStringFromStaticChars("currency"), |
360 factory->NewStringFromTwoByte(Vector<const uint16_t>( | 420 factory->NewStringFromTwoByte(Vector<const uint16_t>( |
361 reinterpret_cast<const uint16_t*>( | 421 reinterpret_cast<const uint16_t*>( |
362 currency.getBuffer()), | 422 currency.getBuffer()), |
363 currency.length())).ToHandleChecked(), | 423 currency.length())).ToHandleChecked(), |
(...skipping 15 matching lines...) Expand all Loading... | |
379 JSObject::SetProperty(resolved, | 439 JSObject::SetProperty(resolved, |
380 factory->NewStringFromStaticChars("numberingSystem"), | 440 factory->NewStringFromStaticChars("numberingSystem"), |
381 factory->undefined_value(), SLOPPY).Assert(); | 441 factory->undefined_value(), SLOPPY).Assert(); |
382 } | 442 } |
383 delete numbering_system; | 443 delete numbering_system; |
384 | 444 |
385 JSObject::SetProperty( | 445 JSObject::SetProperty( |
386 resolved, factory->NewStringFromStaticChars("useGrouping"), | 446 resolved, factory->NewStringFromStaticChars("useGrouping"), |
387 factory->ToBoolean(number_format->isGroupingUsed()), SLOPPY).Assert(); | 447 factory->ToBoolean(number_format->isGroupingUsed()), SLOPPY).Assert(); |
388 | 448 |
389 JSObject::SetProperty( | 449 SetResolvedNumericSettings(isolate, icu_locale, number_format, resolved); |
390 resolved, factory->NewStringFromStaticChars("minimumIntegerDigits"), | |
391 factory->NewNumberFromInt(number_format->getMinimumIntegerDigits()), | |
392 SLOPPY).Assert(); | |
393 | |
394 JSObject::SetProperty( | |
395 resolved, factory->NewStringFromStaticChars("minimumFractionDigits"), | |
396 factory->NewNumberFromInt(number_format->getMinimumFractionDigits()), | |
397 SLOPPY).Assert(); | |
398 | |
399 JSObject::SetProperty( | |
400 resolved, factory->NewStringFromStaticChars("maximumFractionDigits"), | |
401 factory->NewNumberFromInt(number_format->getMaximumFractionDigits()), | |
402 SLOPPY).Assert(); | |
403 | |
404 Handle<String> key = | |
405 factory->NewStringFromStaticChars("minimumSignificantDigits"); | |
406 Maybe<bool> maybe = JSReceiver::HasOwnProperty(resolved, key); | |
407 CHECK(maybe.IsJust()); | |
408 if (maybe.FromJust()) { | |
409 JSObject::SetProperty( | |
410 resolved, factory->NewStringFromStaticChars("minimumSignificantDigits"), | |
411 factory->NewNumberFromInt(number_format->getMinimumSignificantDigits()), | |
412 SLOPPY).Assert(); | |
413 } | |
414 | |
415 key = factory->NewStringFromStaticChars("maximumSignificantDigits"); | |
416 maybe = JSReceiver::HasOwnProperty(resolved, key); | |
417 CHECK(maybe.IsJust()); | |
418 if (maybe.FromJust()) { | |
419 JSObject::SetProperty( | |
420 resolved, factory->NewStringFromStaticChars("maximumSignificantDigits"), | |
421 factory->NewNumberFromInt(number_format->getMaximumSignificantDigits()), | |
422 SLOPPY).Assert(); | |
423 } | |
424 | |
425 // Set the locale | |
426 char result[ULOC_FULLNAME_CAPACITY]; | |
427 status = U_ZERO_ERROR; | |
428 uloc_toLanguageTag( | |
429 icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); | |
430 if (U_SUCCESS(status)) { | |
431 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), | |
432 factory->NewStringFromAsciiChecked(result), | |
433 SLOPPY).Assert(); | |
434 } else { | |
435 // This would never happen, since we got the locale from ICU. | |
436 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), | |
437 factory->NewStringFromStaticChars("und"), | |
438 SLOPPY).Assert(); | |
439 } | |
440 } | 450 } |
441 | 451 |
442 | 452 |
443 icu::Collator* CreateICUCollator( | 453 icu::Collator* CreateICUCollator( |
444 Isolate* isolate, | 454 Isolate* isolate, |
445 const icu::Locale& icu_locale, | 455 const icu::Locale& icu_locale, |
446 Handle<JSObject> options) { | 456 Handle<JSObject> options) { |
447 // Make collator from options. | 457 // Make collator from options. |
448 icu::Collator* collator = NULL; | 458 icu::Collator* collator = NULL; |
449 UErrorCode status = U_ZERO_ERROR; | 459 UErrorCode status = U_ZERO_ERROR; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
603 factory->NewStringFromAsciiChecked(result), | 613 factory->NewStringFromAsciiChecked(result), |
604 SLOPPY).Assert(); | 614 SLOPPY).Assert(); |
605 } else { | 615 } else { |
606 // This would never happen, since we got the locale from ICU. | 616 // This would never happen, since we got the locale from ICU. |
607 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), | 617 JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), |
608 factory->NewStringFromStaticChars("und"), | 618 factory->NewStringFromStaticChars("und"), |
609 SLOPPY).Assert(); | 619 SLOPPY).Assert(); |
610 } | 620 } |
611 } | 621 } |
612 | 622 |
623 bool CreateICUPluralRules(Isolate* isolate, const icu::Locale& icu_locale, | |
624 Handle<JSObject> options, icu::PluralRules** pl, | |
625 icu::DecimalFormat** nf) { | |
626 // Make formatter from options. Numbering system is added | |
627 // to the locale as Unicode extension (if it was specified at all). | |
628 UErrorCode status = U_ZERO_ERROR; | |
629 | |
630 UPluralType type = UPLURAL_TYPE_CARDINAL; | |
631 | |
632 icu::UnicodeString type_string; | |
633 if (ExtractStringSetting(isolate, options, "type", &type_string)) { | |
634 if (type_string == UNICODE_STRING_SIMPLE("ordinal")) { | |
635 type = UPLURAL_TYPE_ORDINAL; | |
636 } else { | |
637 CHECK(type_string == UNICODE_STRING_SIMPLE("cardinal")); | |
638 } | |
639 } | |
640 | |
641 icu::PluralRules* plural_rules = | |
642 icu::PluralRules::forLocale(icu_locale, type, status); | |
643 | |
644 if (U_FAILURE(status)) { | |
645 delete plural_rules; | |
646 return false; | |
647 } | |
jungshik at Google
2017/05/08 19:16:54
nit:
NumberFormat::createInstance(....) will retu
| |
648 | |
649 icu::DecimalFormat* number_format = static_cast<icu::DecimalFormat*>( | |
650 icu::NumberFormat::createInstance(icu_locale, status)); | |
651 | |
652 if (U_FAILURE(status)) { | |
653 delete plural_rules; | |
654 delete number_format; | |
655 return false; | |
656 } | |
657 | |
658 *pl = plural_rules; | |
659 *nf = number_format; | |
660 | |
661 SetNumericSettings(isolate, number_format, options); | |
662 | |
663 // Set rounding mode. | |
664 | |
665 return true; | |
666 } | |
667 | |
668 bool SetResolvedPluralRulesSettings(Isolate* isolate, | |
669 const icu::Locale& icu_locale, | |
670 icu::PluralRules* plural_rules, | |
671 icu::DecimalFormat* number_format, | |
672 Handle<JSObject> resolved) { | |
673 SetResolvedNumericSettings(isolate, icu_locale, number_format, resolved); | |
674 | |
675 Factory* factory = isolate->factory(); | |
676 | |
677 Handle<JSObject> pluralCategories = Handle<JSObject>::cast( | |
678 JSObject::GetProperty( | |
679 resolved, factory->NewStringFromStaticChars("pluralCategories")) | |
680 .ToHandleChecked()); | |
681 | |
682 UErrorCode status = U_ZERO_ERROR; | |
683 std::unique_ptr<icu::StringEnumeration> categories( | |
684 plural_rules->getKeywords(status)); | |
685 if (!U_SUCCESS(status)) return false; | |
jungshik at Google
2017/05/08 19:16:54
nit: U_FAILURE(status) ?
Again, checking at line
| |
686 | |
687 int32_t count = categories->count(status); | |
688 if (!U_SUCCESS(status)) return false; | |
jungshik at Google
2017/05/08 19:16:54
nit: U_FAILURE(status)
| |
689 | |
690 for (int32_t i = 0; i < count; i++) { | |
691 const icu::UnicodeString* category = categories->snext(status); | |
692 if (!U_SUCCESS(status)) return false; | |
693 | |
694 Handle<String> value = | |
695 factory | |
696 ->NewStringFromTwoByte(Vector<const uint16_t>( | |
697 reinterpret_cast<const uint16_t*>(category->getBuffer()), | |
698 category->length())) | |
699 .ToHandleChecked(); | |
700 LookupIterator it(isolate, pluralCategories, i, LookupIterator::OWN); | |
701 JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, | |
702 PropertyAttributes::NONE) | |
703 .ToHandleChecked(); | |
704 } | |
705 | |
706 return true; | |
707 } | |
613 | 708 |
614 icu::BreakIterator* CreateICUBreakIterator( | 709 icu::BreakIterator* CreateICUBreakIterator( |
615 Isolate* isolate, | 710 Isolate* isolate, |
616 const icu::Locale& icu_locale, | 711 const icu::Locale& icu_locale, |
617 Handle<JSObject> options) { | 712 Handle<JSObject> options) { |
618 UErrorCode status = U_ZERO_ERROR; | 713 UErrorCode status = U_ZERO_ERROR; |
619 icu::BreakIterator* break_iterator = NULL; | 714 icu::BreakIterator* break_iterator = NULL; |
620 icu::UnicodeString type; | 715 icu::UnicodeString type; |
621 if (!ExtractStringSetting(isolate, options, "type", &type)) return NULL; | 716 if (!ExtractStringSetting(isolate, options, "type", &type)) return NULL; |
622 | 717 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
827 icu::Collator* Collator::UnpackCollator(Isolate* isolate, | 922 icu::Collator* Collator::UnpackCollator(Isolate* isolate, |
828 Handle<JSObject> obj) { | 923 Handle<JSObject> obj) { |
829 return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0)); | 924 return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0)); |
830 } | 925 } |
831 | 926 |
832 void Collator::DeleteCollator(const v8::WeakCallbackInfo<void>& data) { | 927 void Collator::DeleteCollator(const v8::WeakCallbackInfo<void>& data) { |
833 delete reinterpret_cast<icu::Collator*>(data.GetInternalField(0)); | 928 delete reinterpret_cast<icu::Collator*>(data.GetInternalField(0)); |
834 GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); | 929 GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); |
835 } | 930 } |
836 | 931 |
932 bool PluralRules::InitializePluralRules(Isolate* isolate, Handle<String> locale, | |
933 Handle<JSObject> options, | |
934 Handle<JSObject> resolved, | |
935 icu::PluralRules** plural_rules, | |
936 icu::DecimalFormat** number_format) { | |
937 // Convert BCP47 into ICU locale format. | |
jungshik at Google
2017/05/08 19:16:54
Need to refactor (may be in another CL if you want
| |
938 UErrorCode status = U_ZERO_ERROR; | |
939 icu::Locale icu_locale; | |
940 char icu_result[ULOC_FULLNAME_CAPACITY]; | |
941 int icu_length = 0; | |
942 v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); | |
943 if (bcp47_locale.length() != 0) { | |
944 uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, | |
945 &icu_length, &status); | |
946 if (U_FAILURE(status) || icu_length == 0) { | |
947 return false; | |
948 } | |
949 icu_locale = icu::Locale(icu_result); | |
950 } | |
951 | |
952 bool success = CreateICUPluralRules(isolate, icu_locale, options, | |
953 plural_rules, number_format); | |
954 if (!success) { | |
955 // Remove extensions and try again. | |
956 icu::Locale no_extension_locale(icu_locale.getBaseName()); | |
957 success = CreateICUPluralRules(isolate, no_extension_locale, options, | |
958 plural_rules, number_format); | |
959 | |
960 if (!success) { | |
961 FATAL("Failed to create ICU PluralRules, are ICU data files missing?"); | |
962 } | |
963 | |
964 // Set resolved settings (pattern, numbering system). | |
965 success = SetResolvedPluralRulesSettings( | |
966 isolate, no_extension_locale, *plural_rules, *number_format, resolved); | |
967 } else { | |
968 success = SetResolvedPluralRulesSettings(isolate, icu_locale, *plural_rules, | |
969 *number_format, resolved); | |
970 } | |
971 | |
972 return success; | |
973 } | |
974 | |
975 icu::PluralRules* PluralRules::UnpackPluralRules(Isolate* isolate, | |
976 Handle<JSObject> obj) { | |
977 return reinterpret_cast<icu::PluralRules*>(obj->GetInternalField(0)); | |
978 } | |
979 | |
980 icu::DecimalFormat* PluralRules::UnpackNumberFormat(Isolate* isolate, | |
981 Handle<JSObject> obj) { | |
982 return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(1)); | |
983 } | |
984 | |
985 void PluralRules::DeletePluralRules(const v8::WeakCallbackInfo<void>& data) { | |
986 delete reinterpret_cast<icu::PluralRules*>(data.GetInternalField(0)); | |
987 delete reinterpret_cast<icu::DecimalFormat*>(data.GetInternalField(1)); | |
988 GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); | |
989 } | |
990 | |
837 icu::BreakIterator* V8BreakIterator::InitializeBreakIterator( | 991 icu::BreakIterator* V8BreakIterator::InitializeBreakIterator( |
838 Isolate* isolate, Handle<String> locale, Handle<JSObject> options, | 992 Isolate* isolate, Handle<String> locale, Handle<JSObject> options, |
839 Handle<JSObject> resolved) { | 993 Handle<JSObject> resolved) { |
840 // Convert BCP47 into ICU locale format. | 994 // Convert BCP47 into ICU locale format. |
841 UErrorCode status = U_ZERO_ERROR; | 995 UErrorCode status = U_ZERO_ERROR; |
842 icu::Locale icu_locale; | 996 icu::Locale icu_locale; |
843 char icu_result[ULOC_FULLNAME_CAPACITY]; | 997 char icu_result[ULOC_FULLNAME_CAPACITY]; |
844 int icu_length = 0; | 998 int icu_length = 0; |
845 v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); | 999 v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); |
846 if (bcp47_locale.length() != 0) { | 1000 if (bcp47_locale.length() != 0) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
882 | 1036 |
883 void V8BreakIterator::DeleteBreakIterator( | 1037 void V8BreakIterator::DeleteBreakIterator( |
884 const v8::WeakCallbackInfo<void>& data) { | 1038 const v8::WeakCallbackInfo<void>& data) { |
885 delete reinterpret_cast<icu::BreakIterator*>(data.GetInternalField(0)); | 1039 delete reinterpret_cast<icu::BreakIterator*>(data.GetInternalField(0)); |
886 delete reinterpret_cast<icu::UnicodeString*>(data.GetInternalField(1)); | 1040 delete reinterpret_cast<icu::UnicodeString*>(data.GetInternalField(1)); |
887 GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); | 1041 GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); |
888 } | 1042 } |
889 | 1043 |
890 } // namespace internal | 1044 } // namespace internal |
891 } // namespace v8 | 1045 } // namespace v8 |
OLD | NEW |