Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/i18n.cc

Issue 22266009: Move i18n's number-format C++ code to runtime (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/i18n.h ('k') | src/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11 matching lines...) Expand all
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/calendar.h" 31 #include "unicode/calendar.h"
32 #include "unicode/curramt.h"
33 #include "unicode/dcfmtsym.h"
34 #include "unicode/decimfmt.h"
32 #include "unicode/dtfmtsym.h" 35 #include "unicode/dtfmtsym.h"
33 #include "unicode/dtptngen.h" 36 #include "unicode/dtptngen.h"
34 #include "unicode/locid.h" 37 #include "unicode/locid.h"
38 #include "unicode/numfmt.h"
35 #include "unicode/numsys.h" 39 #include "unicode/numsys.h"
36 #include "unicode/smpdtfmt.h" 40 #include "unicode/smpdtfmt.h"
37 #include "unicode/timezone.h" 41 #include "unicode/timezone.h"
42 #include "unicode/uchar.h"
43 #include "unicode/ucurr.h"
44 #include "unicode/unum.h"
45 #include "unicode/uversion.h"
38 46
39 namespace v8 { 47 namespace v8 {
40 namespace internal { 48 namespace internal {
41 49
42 namespace { 50 namespace {
43 51
52 bool ExtractStringSetting(Isolate* isolate,
53 Handle<JSObject> options,
54 const char* key,
55 icu::UnicodeString* setting) {
56 MaybeObject* maybe_object = options->GetProperty(
57 *isolate->factory()->NewStringFromAscii(CStrVector(key)));
58 Object* object;
59 if (maybe_object->ToObject(&object) && object->IsString()) {
60 v8::String::Utf8Value utf8_string(
61 v8::Utils::ToLocal(Handle<String>(String::cast(object))));
62 *setting = icu::UnicodeString::fromUTF8(*utf8_string);
63 return true;
64 }
65 return false;
66 }
67
68
69 bool ExtractIntegerSetting(Isolate* isolate,
70 Handle<JSObject> options,
71 const char* key,
72 int32_t* value) {
73 MaybeObject* maybe_object = options->GetProperty(
74 *isolate->factory()->NewStringFromAscii(CStrVector(key)));
75 Object* object;
76 if (maybe_object->ToObject(&object) && object->IsNumber()) {
77 object->ToInt32(value);
78 return true;
79 }
80 return false;
81 }
82
83
84 bool ExtractBooleanSetting(Isolate* isolate,
85 Handle<JSObject> options,
86 const char* key,
87 bool* value) {
88 MaybeObject* maybe_object = options->GetProperty(
89 *isolate->factory()->NewStringFromAscii(CStrVector(key)));
90 Object* object;
91 if (maybe_object->ToObject(&object) && object->IsBoolean()) {
92 *value = object->BooleanValue();
93 return true;
94 }
95 return false;
96 }
97
98
44 icu::SimpleDateFormat* CreateICUDateFormat( 99 icu::SimpleDateFormat* CreateICUDateFormat(
45 Isolate* isolate, 100 Isolate* isolate,
46 const icu::Locale& icu_locale, 101 const icu::Locale& icu_locale,
47 Handle<Object> options) { 102 Handle<JSObject> options) {
48 // Create time zone as specified by the user. We have to re-create time zone 103 // Create time zone as specified by the user. We have to re-create time zone
49 // since calendar takes ownership. 104 // since calendar takes ownership.
50 icu::TimeZone* tz = NULL; 105 icu::TimeZone* tz = NULL;
51 MaybeObject* maybe_object = options->GetProperty( 106 icu::UnicodeString timezone;
52 *isolate->factory()->NewStringFromAscii(CStrVector("timeZone"))); 107 if (ExtractStringSetting(isolate, options, "timeZone", &timezone)) {
53 Object* timezone; 108 tz = icu::TimeZone::createTimeZone(timezone);
54 if (maybe_object->ToObject(&timezone) && timezone->IsString()) {
55 v8::String::Utf8Value utf8_timezone(
56 v8::Utils::ToLocal(Handle<String>(String::cast(timezone))));
57 icu::UnicodeString u_timezone(icu::UnicodeString::fromUTF8(*utf8_timezone));
58 tz = icu::TimeZone::createTimeZone(u_timezone);
59 } else { 109 } else {
60 tz = icu::TimeZone::createDefault(); 110 tz = icu::TimeZone::createDefault();
61 } 111 }
62 112
63 // Create a calendar using locale, and apply time zone to it. 113 // Create a calendar using locale, and apply time zone to it.
64 UErrorCode status = U_ZERO_ERROR; 114 UErrorCode status = U_ZERO_ERROR;
65 icu::Calendar* calendar = 115 icu::Calendar* calendar =
66 icu::Calendar::createInstance(tz, icu_locale, status); 116 icu::Calendar::createInstance(tz, icu_locale, status);
67 117
68 // Make formatter from skeleton. Calendar and numbering system are added 118 // Make formatter from skeleton. Calendar and numbering system are added
69 // to the locale as Unicode extension (if they were specified at all). 119 // to the locale as Unicode extension (if they were specified at all).
70 icu::SimpleDateFormat* date_format = NULL; 120 icu::SimpleDateFormat* date_format = NULL;
71 Object* skeleton; 121 icu::UnicodeString skeleton;
72 maybe_object = options->GetProperty( 122 if (ExtractStringSetting(isolate, options, "skeleton", &skeleton)) {
73 *isolate->factory()->NewStringFromAscii(CStrVector("skeleton")));
74 if (maybe_object->ToObject(&skeleton) && skeleton->IsString()) {
75 v8::String::Utf8Value utf8_skeleton(
76 v8::Utils::ToLocal(Handle<String>(String::cast(skeleton))));
77 icu::UnicodeString u_skeleton(icu::UnicodeString::fromUTF8(*utf8_skeleton));
78 icu::DateTimePatternGenerator* generator = 123 icu::DateTimePatternGenerator* generator =
79 icu::DateTimePatternGenerator::createInstance(icu_locale, status); 124 icu::DateTimePatternGenerator::createInstance(icu_locale, status);
80 icu::UnicodeString pattern; 125 icu::UnicodeString pattern;
81 if (U_SUCCESS(status)) { 126 if (U_SUCCESS(status)) {
82 pattern = generator->getBestPattern(u_skeleton, status); 127 pattern = generator->getBestPattern(skeleton, status);
83 delete generator; 128 delete generator;
84 } 129 }
85 130
86 date_format = new icu::SimpleDateFormat(pattern, icu_locale, status); 131 date_format = new icu::SimpleDateFormat(pattern, icu_locale, status);
87 if (U_SUCCESS(status)) { 132 if (U_SUCCESS(status)) {
88 date_format->adoptCalendar(calendar); 133 date_format->adoptCalendar(calendar);
89 } 134 }
90 } 135 }
91 136
92 if (U_FAILURE(status)) { 137 if (U_FAILURE(status)) {
93 delete calendar; 138 delete calendar;
94 delete date_format; 139 delete date_format;
95 date_format = NULL; 140 date_format = NULL;
96 } 141 }
97 142
98 return date_format; 143 return date_format;
99 } 144 }
100 145
101 146
102 void SetResolvedSettings(Isolate* isolate, 147 void SetResolvedDateSettings(Isolate* isolate,
103 const icu::Locale& icu_locale, 148 const icu::Locale& icu_locale,
104 icu::SimpleDateFormat* date_format, 149 icu::SimpleDateFormat* date_format,
105 Handle<JSObject> resolved) { 150 Handle<JSObject> resolved) {
106 UErrorCode status = U_ZERO_ERROR; 151 UErrorCode status = U_ZERO_ERROR;
107 icu::UnicodeString pattern; 152 icu::UnicodeString pattern;
108 date_format->toPattern(pattern); 153 date_format->toPattern(pattern);
109 JSObject::SetProperty( 154 JSObject::SetProperty(
110 resolved, 155 resolved,
111 isolate->factory()->NewStringFromAscii(CStrVector("pattern")), 156 isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
112 isolate->factory()->NewStringFromTwoByte( 157 isolate->factory()->NewStringFromTwoByte(
113 Vector<const uint16_t>( 158 Vector<const uint16_t>(
114 reinterpret_cast<const uint16_t*>(pattern.getBuffer()), 159 reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
115 pattern.length())), 160 pattern.length())),
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 255 }
211 v8::Local<v8::ObjectTemplate> raw_template(v8::ObjectTemplate::New()); 256 v8::Local<v8::ObjectTemplate> raw_template(v8::ObjectTemplate::New());
212 raw_template->SetInternalFieldCount(internal_fields); 257 raw_template->SetInternalFieldCount(internal_fields);
213 return Handle<ObjectTemplateInfo>::cast( 258 return Handle<ObjectTemplateInfo>::cast(
214 isolate->eternal_handles()->CreateSingleton( 259 isolate->eternal_handles()->CreateSingleton(
215 isolate, 260 isolate,
216 *v8::Utils::OpenHandle(*raw_template), 261 *v8::Utils::OpenHandle(*raw_template),
217 field)); 262 field));
218 } 263 }
219 264
265
266 icu::DecimalFormat* CreateICUNumberFormat(
267 Isolate* isolate,
268 const icu::Locale& icu_locale,
269 Handle<JSObject> options) {
270 // Make formatter from options. Numbering system is added
271 // to the locale as Unicode extension (if it was specified at all).
272 UErrorCode status = U_ZERO_ERROR;
273 icu::DecimalFormat* number_format = NULL;
274 icu::UnicodeString style;
275 icu::UnicodeString currency;
276 if (ExtractStringSetting(isolate, options, "style", &style)) {
277 if (style == UNICODE_STRING_SIMPLE("currency")) {
278 icu::UnicodeString display;
279 ExtractStringSetting(isolate, options, "currency", &currency);
280 ExtractStringSetting(isolate, options, "currencyDisplay", &display);
281
282 #if (U_ICU_VERSION_MAJOR_NUM == 4) && (U_ICU_VERSION_MINOR_NUM <= 6)
283 icu::NumberFormat::EStyles format_style;
284 if (display == UNICODE_STRING_SIMPLE("code")) {
285 format_style = icu::NumberFormat::kIsoCurrencyStyle;
286 } else if (display == UNICODE_STRING_SIMPLE("name")) {
287 format_style = icu::NumberFormat::kPluralCurrencyStyle;
288 } else {
289 format_style = icu::NumberFormat::kCurrencyStyle;
290 }
291 #else // ICU version is 4.8 or above (we ignore versions below 4.0).
292 UNumberFormatStyle format_style;
293 if (display == UNICODE_STRING_SIMPLE("code")) {
294 format_style = UNUM_CURRENCY_ISO;
295 } else if (display == UNICODE_STRING_SIMPLE("name")) {
296 format_style = UNUM_CURRENCY_PLURAL;
297 } else {
298 format_style = UNUM_CURRENCY;
299 }
300 #endif
301
302 number_format = static_cast<icu::DecimalFormat*>(
303 icu::NumberFormat::createInstance(icu_locale, format_style, status));
304 } else if (style == UNICODE_STRING_SIMPLE("percent")) {
305 number_format = static_cast<icu::DecimalFormat*>(
306 icu::NumberFormat::createPercentInstance(icu_locale, status));
307 if (U_FAILURE(status)) {
308 delete number_format;
309 return NULL;
310 }
311 // Make sure 1.1% doesn't go into 2%.
312 number_format->setMinimumFractionDigits(1);
313 } else {
314 // Make a decimal instance by default.
315 number_format = static_cast<icu::DecimalFormat*>(
316 icu::NumberFormat::createInstance(icu_locale, status));
317 }
318 }
319
320 if (U_FAILURE(status)) {
321 delete number_format;
322 return NULL;
323 }
324
325 // Set all options.
326 if (!currency.isEmpty()) {
327 number_format->setCurrency(currency.getBuffer(), status);
328 }
329
330 int32_t digits;
331 if (ExtractIntegerSetting(
332 isolate, options, "minimumIntegerDigits", &digits)) {
333 number_format->setMinimumIntegerDigits(digits);
334 }
335
336 if (ExtractIntegerSetting(
337 isolate, options, "minimumFractionDigits", &digits)) {
338 number_format->setMinimumFractionDigits(digits);
339 }
340
341 if (ExtractIntegerSetting(
342 isolate, options, "maximumFractionDigits", &digits)) {
343 number_format->setMaximumFractionDigits(digits);
344 }
345
346 bool significant_digits_used = false;
347 if (ExtractIntegerSetting(
348 isolate, options, "minimumSignificantDigits", &digits)) {
349 number_format->setMinimumSignificantDigits(digits);
350 significant_digits_used = true;
351 }
352
353 if (ExtractIntegerSetting(
354 isolate, options, "maximumSignificantDigits", &digits)) {
355 number_format->setMaximumSignificantDigits(digits);
356 significant_digits_used = true;
357 }
358
359 number_format->setSignificantDigitsUsed(significant_digits_used);
360
361 bool grouping;
362 if (ExtractBooleanSetting(isolate, options, "useGrouping", &grouping)) {
363 number_format->setGroupingUsed(grouping);
364 }
365
366 // Set rounding mode.
367 number_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp);
368
369 return number_format;
370 }
371
372
373 void SetResolvedNumberSettings(Isolate* isolate,
374 const icu::Locale& icu_locale,
375 icu::DecimalFormat* number_format,
376 Handle<JSObject> resolved) {
377 icu::UnicodeString pattern;
378 number_format->toPattern(pattern);
379 JSObject::SetProperty(
380 resolved,
381 isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
382 isolate->factory()->NewStringFromTwoByte(
383 Vector<const uint16_t>(
384 reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
385 pattern.length())),
386 NONE,
387 kNonStrictMode);
388
389 // Set resolved currency code in options.currency if not empty.
390 icu::UnicodeString currency(number_format->getCurrency());
391 if (!currency.isEmpty()) {
392 JSObject::SetProperty(
393 resolved,
394 isolate->factory()->NewStringFromAscii(CStrVector("currency")),
395 isolate->factory()->NewStringFromTwoByte(
396 Vector<const uint16_t>(
397 reinterpret_cast<const uint16_t*>(currency.getBuffer()),
398 currency.length())),
399 NONE,
400 kNonStrictMode);
401 }
402
403 // Ugly hack. ICU doesn't expose numbering system in any way, so we have
404 // to assume that for given locale NumberingSystem constructor produces the
405 // same digits as NumberFormat/Calendar would.
406 UErrorCode status = U_ZERO_ERROR;
407 icu::NumberingSystem* numbering_system =
408 icu::NumberingSystem::createInstance(icu_locale, status);
409 if (U_SUCCESS(status)) {
410 const char* ns = numbering_system->getName();
411 JSObject::SetProperty(
412 resolved,
413 isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
414 isolate->factory()->NewStringFromAscii(CStrVector(ns)),
415 NONE,
416 kNonStrictMode);
417 } else {
418 JSObject::SetProperty(
419 resolved,
420 isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
421 isolate->factory()->undefined_value(),
422 NONE,
423 kNonStrictMode);
424 }
425 delete numbering_system;
426
427 JSObject::SetProperty(
428 resolved,
429 isolate->factory()->NewStringFromAscii(CStrVector("useGrouping")),
430 isolate->factory()->ToBoolean(number_format->isGroupingUsed()),
431 NONE,
432 kNonStrictMode);
433
434 JSObject::SetProperty(
435 resolved,
436 isolate->factory()->NewStringFromAscii(
437 CStrVector("minimumIntegerDigits")),
438 isolate->factory()->NewNumberFromInt(
439 number_format->getMinimumIntegerDigits()),
440 NONE,
441 kNonStrictMode);
442
443 JSObject::SetProperty(
444 resolved,
445 isolate->factory()->NewStringFromAscii(
446 CStrVector("minimumFractionDigits")),
447 isolate->factory()->NewNumberFromInt(
448 number_format->getMinimumFractionDigits()),
449 NONE,
450 kNonStrictMode);
451
452 JSObject::SetProperty(
453 resolved,
454 isolate->factory()->NewStringFromAscii(
455 CStrVector("maximumFractionDigits")),
456 isolate->factory()->NewNumberFromInt(
457 number_format->getMaximumFractionDigits()),
458 NONE,
459 kNonStrictMode);
460
461 if (resolved->HasLocalProperty(*isolate->factory()->NewStringFromAscii(
462 CStrVector("minimumSignificantDigits")))) {
463 JSObject::SetProperty(
464 resolved,
465 isolate->factory()->NewStringFromAscii(
466 CStrVector("minimumSignificantDigits")),
467 isolate->factory()->NewNumberFromInt(
468 number_format->getMinimumSignificantDigits()),
469 NONE,
470 kNonStrictMode);
471 }
472
473 if (resolved->HasLocalProperty(*isolate->factory()->NewStringFromAscii(
474 CStrVector("maximumSignificantDigits")))) {
475 JSObject::SetProperty(
476 resolved,
477 isolate->factory()->NewStringFromAscii(
478 CStrVector("maximumSignificantDigits")),
479 isolate->factory()->NewNumberFromInt(
480 number_format->getMaximumSignificantDigits()),
481 NONE,
482 kNonStrictMode);
483 }
484
485 // Set the locale
486 char result[ULOC_FULLNAME_CAPACITY];
487 status = U_ZERO_ERROR;
488 uloc_toLanguageTag(
489 icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
490 if (U_SUCCESS(status)) {
491 JSObject::SetProperty(
492 resolved,
493 isolate->factory()->NewStringFromAscii(CStrVector("locale")),
494 isolate->factory()->NewStringFromAscii(CStrVector(result)),
495 NONE,
496 kNonStrictMode);
497 } else {
498 // This would never happen, since we got the locale from ICU.
499 JSObject::SetProperty(
500 resolved,
501 isolate->factory()->NewStringFromAscii(CStrVector("locale")),
502 isolate->factory()->NewStringFromAscii(CStrVector("und")),
503 NONE,
504 kNonStrictMode);
505 }
506 }
507
220 } // namespace 508 } // namespace
221 509
222 510
223 // static 511 // static
224 Handle<ObjectTemplateInfo> I18N::GetTemplate(Isolate* isolate) { 512 Handle<ObjectTemplateInfo> I18N::GetTemplate(Isolate* isolate) {
225 return GetEternal<1, i::EternalHandles::I18N_TEMPLATE_ONE>(isolate); 513 return GetEternal<1, i::EternalHandles::I18N_TEMPLATE_ONE>(isolate);
226 } 514 }
227 515
228 516
229 // static 517 // static
(...skipping 24 matching lines...) Expand all
254 } 542 }
255 543
256 icu::SimpleDateFormat* date_format = CreateICUDateFormat( 544 icu::SimpleDateFormat* date_format = CreateICUDateFormat(
257 isolate, icu_locale, options); 545 isolate, icu_locale, options);
258 if (!date_format) { 546 if (!date_format) {
259 // Remove extensions and try again. 547 // Remove extensions and try again.
260 icu::Locale no_extension_locale(icu_locale.getBaseName()); 548 icu::Locale no_extension_locale(icu_locale.getBaseName());
261 date_format = CreateICUDateFormat(isolate, no_extension_locale, options); 549 date_format = CreateICUDateFormat(isolate, no_extension_locale, options);
262 550
263 // Set resolved settings (pattern, numbering system, calendar). 551 // Set resolved settings (pattern, numbering system, calendar).
264 SetResolvedSettings(isolate, no_extension_locale, date_format, resolved); 552 SetResolvedDateSettings(
553 isolate, no_extension_locale, date_format, resolved);
265 } else { 554 } else {
266 SetResolvedSettings(isolate, icu_locale, date_format, resolved); 555 SetResolvedDateSettings(isolate, icu_locale, date_format, resolved);
267 } 556 }
268 557
269 return date_format; 558 return date_format;
270 } 559 }
271 560
272 561
273 icu::SimpleDateFormat* DateFormat::UnpackDateFormat( 562 icu::SimpleDateFormat* DateFormat::UnpackDateFormat(
274 Isolate* isolate, 563 Isolate* isolate,
275 Handle<JSObject> obj) { 564 Handle<JSObject> obj) {
276 if (obj->HasLocalProperty( 565 if (obj->HasLocalProperty(
(...skipping 10 matching lines...) Expand all
287 Persistent<v8::Object>* object, 576 Persistent<v8::Object>* object,
288 void* param) { 577 void* param) {
289 // First delete the hidden C++ object. 578 // First delete the hidden C++ object.
290 delete reinterpret_cast<icu::SimpleDateFormat*>(Handle<JSObject>::cast( 579 delete reinterpret_cast<icu::SimpleDateFormat*>(Handle<JSObject>::cast(
291 v8::Utils::OpenPersistent(object))->GetInternalField(0)); 580 v8::Utils::OpenPersistent(object))->GetInternalField(0));
292 581
293 // Then dispose of the persistent handle to JS object. 582 // Then dispose of the persistent handle to JS object.
294 object->Dispose(isolate); 583 object->Dispose(isolate);
295 } 584 }
296 585
586
587 icu::DecimalFormat* NumberFormat::InitializeNumberFormat(
588 Isolate* isolate,
589 Handle<String> locale,
590 Handle<JSObject> options,
591 Handle<JSObject> resolved) {
592 // Convert BCP47 into ICU locale format.
593 UErrorCode status = U_ZERO_ERROR;
594 icu::Locale icu_locale;
595 char icu_result[ULOC_FULLNAME_CAPACITY];
596 int icu_length = 0;
597 v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale));
598 if (bcp47_locale.length() != 0) {
599 uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY,
600 &icu_length, &status);
601 if (U_FAILURE(status) || icu_length == 0) {
602 return NULL;
603 }
604 icu_locale = icu::Locale(icu_result);
605 }
606
607 icu::DecimalFormat* number_format =
608 CreateICUNumberFormat(isolate, icu_locale, options);
609 if (!number_format) {
610 // Remove extensions and try again.
611 icu::Locale no_extension_locale(icu_locale.getBaseName());
612 number_format = CreateICUNumberFormat(
613 isolate, no_extension_locale, options);
614
615 // Set resolved settings (pattern, numbering system).
616 SetResolvedNumberSettings(
617 isolate, no_extension_locale, number_format, resolved);
618 } else {
619 SetResolvedNumberSettings(isolate, icu_locale, number_format, resolved);
620 }
621
622 return number_format;
623 }
624
625
626 icu::DecimalFormat* NumberFormat::UnpackNumberFormat(
627 Isolate* isolate,
628 Handle<JSObject> obj) {
629 if (obj->HasLocalProperty(*isolate->factory()->NewStringFromAscii(
630 CStrVector("numberFormat")))) {
631 return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0));
632 }
633
634 return NULL;
635 }
636
637
638 void NumberFormat::DeleteNumberFormat(v8::Isolate* isolate,
639 Persistent<v8::Object>* object,
640 void* param) {
641 // First delete the hidden C++ object.
642 delete reinterpret_cast<icu::DecimalFormat*>(Handle<JSObject>::cast(
643 v8::Utils::OpenPersistent(object))->GetInternalField(0));
644
645 // Then dispose of the persistent handle to JS object.
646 object->Dispose(isolate);
647 }
648
297 } } // namespace v8::internal 649 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/i18n.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698