1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// limitations under the License. 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/i18n.h" 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include <memory> 9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/api.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/factory.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate.h" 1362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/brkiter.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/calendar.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/coll.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/curramt.h" 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/dcfmtsym.h" 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/decimfmt.h" 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/dtfmtsym.h" 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/dtptngen.h" 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "unicode/gregocal.h" 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/locid.h" 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/numfmt.h" 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/numsys.h" 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/rbbi.h" 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/smpdtfmt.h" 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/timezone.h" 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/uchar.h" 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/ucol.h" 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/ucurr.h" 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/unum.h" 3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "unicode/uvernum.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "unicode/uversion.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#if U_ICU_VERSION_MAJOR_NUM >= 59 3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "unicode/char16ptr.h" 3862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif 3962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace { 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool ExtractStringSetting(Isolate* isolate, 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options, 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* key, 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString* setting) { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key); 503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> object = 513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSReceiver::GetProperty(options, str).ToHandleChecked(); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsString()) { 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value utf8_string( 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Utils::ToLocal(Handle<String>::cast(object))); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *setting = icu::UnicodeString::fromUTF8(*utf8_string); 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool ExtractIntegerSetting(Isolate* isolate, 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options, 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* key, 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t* value) { 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key); 673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> object = 683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSReceiver::GetProperty(options, str).ToHandleChecked(); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsNumber()) { 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->ToInt32(value); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool ExtractBooleanSetting(Isolate* isolate, 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options, 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* key, 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool* value) { 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key); 823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> object = 833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSReceiver::GetProperty(options, str).ToHandleChecked(); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsBoolean()) { 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *value = object->BooleanValue(); 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::SimpleDateFormat* CreateICUDateFormat( 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options) { 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create time zone as specified by the user. We have to re-create time zone 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // since calendar takes ownership. 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::TimeZone* tz = NULL; 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString timezone; 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractStringSetting(isolate, options, "timeZone", &timezone)) { 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tz = icu::TimeZone::createTimeZone(timezone); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tz = icu::TimeZone::createDefault(); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a calendar using locale, and apply time zone to it. 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Calendar* calendar = 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Calendar::createInstance(tz, icu_locale, status); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (calendar->getDynamicClassID() == 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch icu::GregorianCalendar::getStaticClassID()) { 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch icu::GregorianCalendar* gc = (icu::GregorianCalendar*)calendar; 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UErrorCode status = U_ZERO_ERROR; 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The beginning of ECMAScript time, namely -(2**53) 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const double start_of_time = -9007199254740992; 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch gc->setGregorianChange(start_of_time, status); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(U_SUCCESS(status)); 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make formatter from skeleton. Calendar and numbering system are added 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the locale as Unicode extension (if they were specified at all). 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::SimpleDateFormat* date_format = NULL; 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString skeleton; 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractStringSetting(isolate, options, "skeleton", &skeleton)) { 126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<icu::DateTimePatternGenerator> generator( 127f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch icu::DateTimePatternGenerator::createInstance(icu_locale, status)); 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString pattern; 129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (U_SUCCESS(status)) 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pattern = generator->getBestPattern(skeleton, status); 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch date_format = new icu::SimpleDateFormat(pattern, icu_locale, status); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch date_format->adoptCalendar(calendar); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status)) { 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete calendar; 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete date_format; 141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch date_format = nullptr; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return date_format; 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SetResolvedDateSettings(Isolate* isolate, 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::SimpleDateFormat* date_format, 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString pattern; 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch date_format->toPattern(pattern); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch resolved, factory->intl_pattern_symbol(), 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromTwoByte( 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint16_t>( 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const uint16_t*>(pattern.getBuffer()), 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pattern.length())).ToHandleChecked(), 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set time zone and calendar. 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Calendar* calendar = date_format->getCalendar(); 166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // getType() returns legacy calendar type name instead of LDML/BCP47 calendar 167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // key values. i18n.js maps them to BCP47 values for key "ca". 168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(jshin): Consider doing it here, instead. 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* calendar_name = calendar->getType(); 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("calendar"), 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromAsciiChecked(calendar_name), 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::TimeZone& tz = calendar->getTimeZone(); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString time_zone; 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tz.getID(time_zone); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString canonical_time_zone; 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, status); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/GMT")) { 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("timeZone"), 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("UTC"), SLOPPY).Assert(); 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("timeZone"), 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromTwoByte( 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint16_t>( 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const uint16_t*>( 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch canonical_time_zone.getBuffer()), 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch canonical_time_zone.length())).ToHandleChecked(), 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ugly hack. ICU doesn't expose numbering system in any way, so we have 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to assume that for given locale NumberingSystem constructor produces the 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // same digits as NumberFormat/Calendar would. 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = U_ZERO_ERROR; 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::NumberingSystem* numbering_system = 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::NumberingSystem::createInstance(icu_locale, status); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* ns = numbering_system->getName(); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("numberingSystem"), 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromAsciiChecked(ns), SLOPPY).Assert(); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("numberingSystem"), 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->undefined_value(), SLOPPY).Assert(); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete numbering_system; 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the locale 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char result[ULOC_FULLNAME_CAPACITY]; 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = U_ZERO_ERROR; 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_toLanguageTag( 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromAsciiChecked(result), 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This would never happen, since we got the locale from ICU. 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("und"), 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::DecimalFormat* CreateICUNumberFormat( 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options) { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make formatter from options. Numbering system is added 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the locale as Unicode extension (if it was specified at all). 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::DecimalFormat* number_format = NULL; 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString style; 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString currency; 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractStringSetting(isolate, options, "style", &style)) { 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (style == UNICODE_STRING_SIMPLE("currency")) { 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString display; 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExtractStringSetting(isolate, options, "currency", ¤cy); 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExtractStringSetting(isolate, options, "currencyDisplay", &display); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if (U_ICU_VERSION_MAJOR_NUM == 4) && (U_ICU_VERSION_MINOR_NUM <= 6) 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::NumberFormat::EStyles format_style; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (display == UNICODE_STRING_SIMPLE("code")) { 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch format_style = icu::NumberFormat::kIsoCurrencyStyle; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (display == UNICODE_STRING_SIMPLE("name")) { 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch format_style = icu::NumberFormat::kPluralCurrencyStyle; 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch format_style = icu::NumberFormat::kCurrencyStyle; 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else // ICU version is 4.8 or above (we ignore versions below 4.0). 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNumberFormatStyle format_style; 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (display == UNICODE_STRING_SIMPLE("code")) { 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch format_style = UNUM_CURRENCY_ISO; 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (display == UNICODE_STRING_SIMPLE("name")) { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch format_style = UNUM_CURRENCY_PLURAL; 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch format_style = UNUM_CURRENCY; 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format = static_cast<icu::DecimalFormat*>( 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch icu::NumberFormat::createInstance(icu_locale, format_style, status)); 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (U_FAILURE(status)) { 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch delete number_format; 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NULL; 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UErrorCode status_digits = U_ZERO_ERROR; 27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#if U_ICU_VERSION_MAJOR_NUM >= 59 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t fraction_digits = ucurr_getDefaultFractionDigits( 28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch icu::toUCharPtr(currency.getTerminatedBuffer()), &status_digits); 28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#else 28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t fraction_digits = ucurr_getDefaultFractionDigits( 28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch currency.getTerminatedBuffer(), &status_digits); 28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (U_SUCCESS(status_digits)) { 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch number_format->setMinimumFractionDigits(fraction_digits); 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch number_format->setMaximumFractionDigits(fraction_digits); 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set min & max to default values (previously in i18n.js) 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch number_format->setMinimumFractionDigits(0); 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch number_format->setMaximumFractionDigits(3); 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (style == UNICODE_STRING_SIMPLE("percent")) { 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format = static_cast<icu::DecimalFormat*>( 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::NumberFormat::createPercentInstance(icu_locale, status)); 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status)) { 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete number_format; 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure 1.1% doesn't go into 2%. 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setMinimumFractionDigits(1); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make a decimal instance by default. 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format = static_cast<icu::DecimalFormat*>( 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::NumberFormat::createInstance(icu_locale, status)); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status)) { 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete number_format; 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set all options. 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!currency.isEmpty()) { 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setCurrency(currency.getBuffer(), status); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t digits; 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractIntegerSetting( 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, options, "minimumIntegerDigits", &digits)) { 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setMinimumIntegerDigits(digits); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractIntegerSetting( 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, options, "minimumFractionDigits", &digits)) { 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setMinimumFractionDigits(digits); 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractIntegerSetting( 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, options, "maximumFractionDigits", &digits)) { 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setMaximumFractionDigits(digits); 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool significant_digits_used = false; 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractIntegerSetting( 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, options, "minimumSignificantDigits", &digits)) { 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setMinimumSignificantDigits(digits); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch significant_digits_used = true; 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractIntegerSetting( 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, options, "maximumSignificantDigits", &digits)) { 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setMaximumSignificantDigits(digits); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch significant_digits_used = true; 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setSignificantDigitsUsed(significant_digits_used); 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool grouping; 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractBooleanSetting(isolate, options, "useGrouping", &grouping)) { 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setGroupingUsed(grouping); 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set rounding mode. 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return number_format; 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SetResolvedNumberSettings(Isolate* isolate, 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::DecimalFormat* number_format, 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString pattern; 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format->toPattern(pattern); 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch resolved, factory->intl_pattern_symbol(), 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromTwoByte( 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<const uint16_t>( 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const uint16_t*>(pattern.getBuffer()), 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pattern.length())).ToHandleChecked(), 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set resolved currency code in options.currency if not empty. 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString currency(number_format->getCurrency()); 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!currency.isEmpty()) { 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("currency"), 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromTwoByte(Vector<const uint16_t>( 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const uint16_t*>( 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch currency.getBuffer()), 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch currency.length())).ToHandleChecked(), 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ugly hack. ICU doesn't expose numbering system in any way, so we have 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to assume that for given locale NumberingSystem constructor produces the 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // same digits as NumberFormat/Calendar would. 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::NumberingSystem* numbering_system = 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::NumberingSystem::createInstance(icu_locale, status); 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* ns = numbering_system->getName(); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("numberingSystem"), 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromAsciiChecked(ns), SLOPPY).Assert(); 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("numberingSystem"), 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->undefined_value(), SLOPPY).Assert(); 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete numbering_system; 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("useGrouping"), 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->ToBoolean(number_format->isGroupingUsed()), SLOPPY).Assert(); 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("minimumIntegerDigits"), 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewNumberFromInt(number_format->getMinimumIntegerDigits()), 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("minimumFractionDigits"), 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewNumberFromInt(number_format->getMinimumFractionDigits()), 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("maximumFractionDigits"), 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewNumberFromInt(number_format->getMaximumFractionDigits()), 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> key = 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("minimumSignificantDigits"); 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Maybe<bool> maybe = JSReceiver::HasOwnProperty(resolved, key); 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(maybe.IsJust()); 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (maybe.FromJust()) { 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("minimumSignificantDigits"), 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewNumberFromInt(number_format->getMinimumSignificantDigits()), 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = factory->NewStringFromStaticChars("maximumSignificantDigits"); 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maybe = JSReceiver::HasOwnProperty(resolved, key); 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(maybe.IsJust()); 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (maybe.FromJust()) { 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("maximumSignificantDigits"), 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewNumberFromInt(number_format->getMaximumSignificantDigits()), 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the locale 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char result[ULOC_FULLNAME_CAPACITY]; 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = U_ZERO_ERROR; 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_toLanguageTag( 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromAsciiChecked(result), 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This would never happen, since we got the locale from ICU. 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("und"), 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::Collator* CreateICUCollator( 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options) { 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make collator from options. 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Collator* collator = NULL; 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator = icu::Collator::createInstance(icu_locale, status); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status)) { 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete collator; 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set flags first, and then override them with sensitivity if necessary. 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool numeric; 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractBooleanSetting(isolate, options, "numeric", &numeric)) { 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setAttribute( 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UCOL_NUMERIC_COLLATION, numeric ? UCOL_ON : UCOL_OFF, status); 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Normalization is always on, by the spec. We are free to optimize 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if the strings are already normalized (but we don't have a way to tell 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that right now). 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString case_first; 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractStringSetting(isolate, options, "caseFirst", &case_first)) { 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (case_first == UNICODE_STRING_SIMPLE("upper")) { 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status); 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (case_first == UNICODE_STRING_SIMPLE("lower")) { 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status); 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Default (false/off). 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setAttribute(UCOL_CASE_FIRST, UCOL_OFF, status); 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString sensitivity; 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractStringSetting(isolate, options, "sensitivity", &sensitivity)) { 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (sensitivity == UNICODE_STRING_SIMPLE("base")) { 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setStrength(icu::Collator::PRIMARY); 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (sensitivity == UNICODE_STRING_SIMPLE("accent")) { 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setStrength(icu::Collator::SECONDARY); 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (sensitivity == UNICODE_STRING_SIMPLE("case")) { 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setStrength(icu::Collator::PRIMARY); 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setAttribute(UCOL_CASE_LEVEL, UCOL_ON, status); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // variant (default) 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setStrength(icu::Collator::TERTIARY); 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ignore; 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ExtractBooleanSetting(isolate, options, "ignorePunctuation", &ignore)) { 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ignore) { 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status); 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return collator; 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SetResolvedCollatorSettings(Isolate* isolate, 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Collator* collator, 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("numeric"), 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->ToBoolean( 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator->getAttribute(UCOL_NUMERIC_COLLATION, status) == UCOL_ON), 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (collator->getAttribute(UCOL_CASE_FIRST, status)) { 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UCOL_LOWER_FIRST: 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("caseFirst"), 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("lower"), SLOPPY).Assert(); 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UCOL_UPPER_FIRST: 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("caseFirst"), 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("upper"), SLOPPY).Assert(); 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("caseFirst"), 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("false"), SLOPPY).Assert(); 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (collator->getAttribute(UCOL_STRENGTH, status)) { 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UCOL_PRIMARY: { 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("strength"), 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("primary"), SLOPPY).Assert(); 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // case level: true + s1 -> case, s1 -> base. 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (UCOL_ON == collator->getAttribute(UCOL_CASE_LEVEL, status)) { 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("sensitivity"), 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("case"), SLOPPY).Assert(); 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("sensitivity"), 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("base"), SLOPPY).Assert(); 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UCOL_SECONDARY: 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("strength"), 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("secondary"), SLOPPY).Assert(); 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("sensitivity"), 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("accent"), SLOPPY).Assert(); 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UCOL_TERTIARY: 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("strength"), 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("tertiary"), SLOPPY).Assert(); 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("sensitivity"), 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("variant"), SLOPPY).Assert(); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UCOL_QUATERNARY: 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We shouldn't get quaternary and identical from ICU, but if we do 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // put them into variant. 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("strength"), 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("quaternary"), SLOPPY).Assert(); 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("sensitivity"), 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("variant"), SLOPPY).Assert(); 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("strength"), 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("identical"), SLOPPY).Assert(); 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("sensitivity"), 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("variant"), SLOPPY).Assert(); 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty( 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolved, factory->NewStringFromStaticChars("ignorePunctuation"), 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->ToBoolean(collator->getAttribute(UCOL_ALTERNATE_HANDLING, 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status) == UCOL_SHIFTED), 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the locale 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char result[ULOC_FULLNAME_CAPACITY]; 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = U_ZERO_ERROR; 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_toLanguageTag( 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromAsciiChecked(result), 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This would never happen, since we got the locale from ICU. 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("und"), 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::BreakIterator* CreateICUBreakIterator( 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options) { 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::BreakIterator* break_iterator = NULL; 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::UnicodeString type; 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ExtractStringSetting(isolate, options, "type", &type)) return NULL; 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == UNICODE_STRING_SIMPLE("character")) { 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_iterator = 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::BreakIterator::createCharacterInstance(icu_locale, status); 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (type == UNICODE_STRING_SIMPLE("sentence")) { 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_iterator = 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::BreakIterator::createSentenceInstance(icu_locale, status); 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (type == UNICODE_STRING_SIMPLE("line")) { 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_iterator = 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::BreakIterator::createLineInstance(icu_locale, status); 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Defualt is word iterator. 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_iterator = 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::BreakIterator::createWordInstance(icu_locale, status); 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status)) { 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete break_iterator; 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->CountUsage(v8::Isolate::UseCounterFeature::kBreakIterator); 666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return break_iterator; 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SetResolvedBreakIteratorSettings(Isolate* isolate, 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const icu::Locale& icu_locale, 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::BreakIterator* break_iterator, 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the locale 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char result[ULOC_FULLNAME_CAPACITY]; 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = U_ZERO_ERROR; 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_toLanguageTag( 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_SUCCESS(status)) { 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromAsciiChecked(result), 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This would never happen, since we got the locale from ICU. 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::SetProperty(resolved, factory->NewStringFromStaticChars("locale"), 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewStringFromStaticChars("und"), 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SLOPPY).Assert(); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// static 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::SimpleDateFormat* DateFormat::InitializeDateTimeFormat( 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> locale, 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options, 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert BCP47 into ICU locale format. 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale icu_locale; 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char icu_result[ULOC_FULLNAME_CAPACITY]; 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int icu_length = 0; 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bcp47_locale.length() != 0) { 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &icu_length, &status); 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status) || icu_length == 0) { 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale = icu::Locale(icu_result); 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::SimpleDateFormat* date_format = CreateICUDateFormat( 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, icu_locale, options); 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!date_format) { 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove extensions and try again. 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale no_extension_locale(icu_locale.getBaseName()); 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch date_format = CreateICUDateFormat(isolate, no_extension_locale, options); 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!date_format) { 727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FATAL("Failed to create ICU date format, are ICU data files missing?"); 728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set resolved settings (pattern, numbering system, calendar). 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedDateSettings( 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, no_extension_locale, date_format, resolved); 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedDateSettings(isolate, icu_locale, date_format, resolved); 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return date_format; 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::SimpleDateFormat* DateFormat::UnpackDateFormat( 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> obj) { 74462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return reinterpret_cast<icu::SimpleDateFormat*>(obj->GetInternalField(0)); 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 747bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid DateFormat::DeleteDateFormat(const v8::WeakCallbackInfo<void>& data) { 748bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch delete reinterpret_cast<icu::SimpleDateFormat*>(data.GetInternalField(0)); 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::DecimalFormat* NumberFormat::InitializeNumberFormat( 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> locale, 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options, 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert BCP47 into ICU locale format. 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale icu_locale; 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char icu_result[ULOC_FULLNAME_CAPACITY]; 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int icu_length = 0; 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bcp47_locale.length() != 0) { 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &icu_length, &status); 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status) || icu_length == 0) { 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale = icu::Locale(icu_result); 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::DecimalFormat* number_format = 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateICUNumberFormat(isolate, icu_locale, options); 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!number_format) { 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove extensions and try again. 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale no_extension_locale(icu_locale.getBaseName()); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_format = CreateICUNumberFormat( 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, no_extension_locale, options); 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!number_format) { 782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FATAL("Failed to create ICU number format, are ICU data files missing?"); 783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set resolved settings (pattern, numbering system). 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedNumberSettings( 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, no_extension_locale, number_format, resolved); 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedNumberSettings(isolate, icu_locale, number_format, resolved); 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return number_format; 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::DecimalFormat* NumberFormat::UnpackNumberFormat( 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> obj) { 79962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0)); 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 802bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid NumberFormat::DeleteNumberFormat(const v8::WeakCallbackInfo<void>& data) { 803bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch delete reinterpret_cast<icu::DecimalFormat*>(data.GetInternalField(0)); 804bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::Collator* Collator::InitializeCollator( 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate, 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> locale, 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> options, 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert BCP47 into ICU locale format. 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale icu_locale; 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char icu_result[ULOC_FULLNAME_CAPACITY]; 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int icu_length = 0; 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bcp47_locale.length() != 0) { 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &icu_length, &status); 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status) || icu_length == 0) { 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale = icu::Locale(icu_result); 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Collator* collator = CreateICUCollator(isolate, icu_locale, options); 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!collator) { 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove extensions and try again. 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale no_extension_locale(icu_locale.getBaseName()); 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch collator = CreateICUCollator(isolate, no_extension_locale, options); 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!collator) { 835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FATAL("Failed to create ICU collator, are ICU data files missing?"); 836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set resolved settings (pattern, numbering system). 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedCollatorSettings( 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, no_extension_locale, collator, resolved); 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedCollatorSettings(isolate, icu_locale, collator, resolved); 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return collator; 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochicu::Collator* Collator::UnpackCollator(Isolate* isolate, 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> obj) { 85162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0)); 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 854bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Collator::DeleteCollator(const v8::WeakCallbackInfo<void>& data) { 855bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch delete reinterpret_cast<icu::Collator*>(data.GetInternalField(0)); 856bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 85962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochicu::BreakIterator* V8BreakIterator::InitializeBreakIterator( 86062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate, Handle<String> locale, Handle<JSObject> options, 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> resolved) { 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert BCP47 into ICU locale format. 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UErrorCode status = U_ZERO_ERROR; 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale icu_locale; 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char icu_result[ULOC_FULLNAME_CAPACITY]; 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int icu_length = 0; 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bcp47_locale.length() != 0) { 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &icu_length, &status); 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (U_FAILURE(status) || icu_length == 0) { 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu_locale = icu::Locale(icu_result); 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::BreakIterator* break_iterator = CreateICUBreakIterator( 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, icu_locale, options); 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!break_iterator) { 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove extensions and try again. 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch icu::Locale no_extension_locale(icu_locale.getBaseName()); 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_iterator = CreateICUBreakIterator( 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, no_extension_locale, options); 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!break_iterator) { 886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FATAL("Failed to create ICU break iterator, are ICU data files missing?"); 887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set resolved settings (locale). 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedBreakIteratorSettings( 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, no_extension_locale, break_iterator, resolved); 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetResolvedBreakIteratorSettings( 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, icu_locale, break_iterator, resolved); 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return break_iterator; 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochicu::BreakIterator* V8BreakIterator::UnpackBreakIterator(Isolate* isolate, 90162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> obj) { 90262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0)); 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 90562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8BreakIterator::DeleteBreakIterator( 906bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const v8::WeakCallbackInfo<void>& data) { 907bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch delete reinterpret_cast<icu::BreakIterator*>(data.GetInternalField(0)); 908bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch delete reinterpret_cast<icu::UnicodeString*>(data.GetInternalField(1)); 909bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 914