The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.
Please select the desired protocol below to get the URL.
This URL has Read-Only access.
main_repo / deps / v8 / src / i18n.cc @ f230a1cf
History | View | Annotate | Download (35.6 KB)
1 |
// Copyright 2013 the V8 project authors. All rights reserved.
|
---|---|
2 |
// Redistribution and use in source and binary forms, with or without
|
3 |
// modification, are permitted provided that the following conditions are
|
4 |
// met:
|
5 |
//
|
6 |
// * Redistributions of source code must retain the above copyright
|
7 |
// notice, this list of conditions and the following disclaimer.
|
8 |
// * Redistributions in binary form must reproduce the above
|
9 |
// copyright notice, this list of conditions and the following
|
10 |
// disclaimer in the documentation and/or other materials provided
|
11 |
// with the distribution.
|
12 |
// * Neither the name of Google Inc. nor the names of its
|
13 |
// contributors may be used to endorse or promote products derived
|
14 |
// from this software without specific prior written permission.
|
15 |
//
|
16 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
18 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
19 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
20 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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.
|
27 |
// limitations under the License.
|
28 |
|
29 |
#include "i18n.h" |
30 |
|
31 |
#include "unicode/brkiter.h" |
32 |
#include "unicode/calendar.h" |
33 |
#include "unicode/coll.h" |
34 |
#include "unicode/curramt.h" |
35 |
#include "unicode/dcfmtsym.h" |
36 |
#include "unicode/decimfmt.h" |
37 |
#include "unicode/dtfmtsym.h" |
38 |
#include "unicode/dtptngen.h" |
39 |
#include "unicode/locid.h" |
40 |
#include "unicode/numfmt.h" |
41 |
#include "unicode/numsys.h" |
42 |
#include "unicode/rbbi.h" |
43 |
#include "unicode/smpdtfmt.h" |
44 |
#include "unicode/timezone.h" |
45 |
#include "unicode/uchar.h" |
46 |
#include "unicode/ucol.h" |
47 |
#include "unicode/ucurr.h" |
48 |
#include "unicode/unum.h" |
49 |
#include "unicode/uversion.h" |
50 |
|
51 |
namespace v8 {
|
52 |
namespace internal {
|
53 |
|
54 |
namespace {
|
55 |
|
56 |
bool ExtractStringSetting(Isolate* isolate,
|
57 |
Handle<JSObject> options, |
58 |
const char* key, |
59 |
icu::UnicodeString* setting) { |
60 |
Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key)); |
61 |
MaybeObject* maybe_object = options->GetProperty(*str); |
62 |
Object* object; |
63 |
if (maybe_object->ToObject(&object) && object->IsString()) {
|
64 |
v8::String::Utf8Value utf8_string( |
65 |
v8::Utils::ToLocal(Handle<String>(String::cast(object)))); |
66 |
*setting = icu::UnicodeString::fromUTF8(*utf8_string); |
67 |
return true; |
68 |
} |
69 |
return false; |
70 |
} |
71 |
|
72 |
|
73 |
bool ExtractIntegerSetting(Isolate* isolate,
|
74 |
Handle<JSObject> options, |
75 |
const char* key, |
76 |
int32_t* value) { |
77 |
Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key)); |
78 |
MaybeObject* maybe_object = options->GetProperty(*str); |
79 |
Object* object; |
80 |
if (maybe_object->ToObject(&object) && object->IsNumber()) {
|
81 |
object->ToInt32(value); |
82 |
return true; |
83 |
} |
84 |
return false; |
85 |
} |
86 |
|
87 |
|
88 |
bool ExtractBooleanSetting(Isolate* isolate,
|
89 |
Handle<JSObject> options, |
90 |
const char* key, |
91 |
bool* value) {
|
92 |
Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key)); |
93 |
MaybeObject* maybe_object = options->GetProperty(*str); |
94 |
Object* object; |
95 |
if (maybe_object->ToObject(&object) && object->IsBoolean()) {
|
96 |
*value = object->BooleanValue(); |
97 |
return true; |
98 |
} |
99 |
return false; |
100 |
} |
101 |
|
102 |
|
103 |
icu::SimpleDateFormat* CreateICUDateFormat( |
104 |
Isolate* isolate, |
105 |
const icu::Locale& icu_locale,
|
106 |
Handle<JSObject> options) { |
107 |
// Create time zone as specified by the user. We have to re-create time zone
|
108 |
// since calendar takes ownership.
|
109 |
icu::TimeZone* tz = NULL;
|
110 |
icu::UnicodeString timezone; |
111 |
if (ExtractStringSetting(isolate, options, "timeZone", &timezone)) { |
112 |
tz = icu::TimeZone::createTimeZone(timezone); |
113 |
} else {
|
114 |
tz = icu::TimeZone::createDefault(); |
115 |
} |
116 |
|
117 |
// Create a calendar using locale, and apply time zone to it.
|
118 |
UErrorCode status = U_ZERO_ERROR; |
119 |
icu::Calendar* calendar = |
120 |
icu::Calendar::createInstance(tz, icu_locale, status); |
121 |
|
122 |
// Make formatter from skeleton. Calendar and numbering system are added
|
123 |
// to the locale as Unicode extension (if they were specified at all).
|
124 |
icu::SimpleDateFormat* date_format = NULL;
|
125 |
icu::UnicodeString skeleton; |
126 |
if (ExtractStringSetting(isolate, options, "skeleton", &skeleton)) { |
127 |
icu::DateTimePatternGenerator* generator = |
128 |
icu::DateTimePatternGenerator::createInstance(icu_locale, status); |
129 |
icu::UnicodeString pattern; |
130 |
if (U_SUCCESS(status)) {
|
131 |
pattern = generator->getBestPattern(skeleton, status); |
132 |
delete generator;
|
133 |
} |
134 |
|
135 |
date_format = new icu::SimpleDateFormat(pattern, icu_locale, status);
|
136 |
if (U_SUCCESS(status)) {
|
137 |
date_format->adoptCalendar(calendar); |
138 |
} |
139 |
} |
140 |
|
141 |
if (U_FAILURE(status)) {
|
142 |
delete calendar;
|
143 |
delete date_format;
|
144 |
date_format = NULL;
|
145 |
} |
146 |
|
147 |
return date_format;
|
148 |
} |
149 |
|
150 |
|
151 |
void SetResolvedDateSettings(Isolate* isolate,
|
152 |
const icu::Locale& icu_locale,
|
153 |
icu::SimpleDateFormat* date_format, |
154 |
Handle<JSObject> resolved) { |
155 |
UErrorCode status = U_ZERO_ERROR; |
156 |
icu::UnicodeString pattern; |
157 |
date_format->toPattern(pattern); |
158 |
JSObject::SetProperty( |
159 |
resolved, |
160 |
isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
|
161 |
isolate->factory()->NewStringFromTwoByte( |
162 |
Vector<const uint16_t>(
|
163 |
reinterpret_cast<const uint16_t*>(pattern.getBuffer()), |
164 |
pattern.length())), |
165 |
NONE, |
166 |
kNonStrictMode); |
167 |
|
168 |
// Set time zone and calendar.
|
169 |
const icu::Calendar* calendar = date_format->getCalendar();
|
170 |
const char* calendar_name = calendar->getType(); |
171 |
JSObject::SetProperty( |
172 |
resolved, |
173 |
isolate->factory()->NewStringFromAscii(CStrVector("calendar")),
|
174 |
isolate->factory()->NewStringFromAscii(CStrVector(calendar_name)), |
175 |
NONE, |
176 |
kNonStrictMode); |
177 |
|
178 |
const icu::TimeZone& tz = calendar->getTimeZone();
|
179 |
icu::UnicodeString time_zone; |
180 |
tz.getID(time_zone); |
181 |
|
182 |
icu::UnicodeString canonical_time_zone; |
183 |
icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, status); |
184 |
if (U_SUCCESS(status)) {
|
185 |
if (canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/GMT")) { |
186 |
JSObject::SetProperty( |
187 |
resolved, |
188 |
isolate->factory()->NewStringFromAscii(CStrVector("timeZone")),
|
189 |
isolate->factory()->NewStringFromAscii(CStrVector("UTC")),
|
190 |
NONE, |
191 |
kNonStrictMode); |
192 |
} else {
|
193 |
JSObject::SetProperty( |
194 |
resolved, |
195 |
isolate->factory()->NewStringFromAscii(CStrVector("timeZone")),
|
196 |
isolate->factory()->NewStringFromTwoByte( |
197 |
Vector<const uint16_t>(
|
198 |
reinterpret_cast<const uint16_t*>( |
199 |
canonical_time_zone.getBuffer()), |
200 |
canonical_time_zone.length())), |
201 |
NONE, |
202 |
kNonStrictMode); |
203 |
} |
204 |
} |
205 |
|
206 |
// Ugly hack. ICU doesn't expose numbering system in any way, so we have
|
207 |
// to assume that for given locale NumberingSystem constructor produces the
|
208 |
// same digits as NumberFormat/Calendar would.
|
209 |
status = U_ZERO_ERROR; |
210 |
icu::NumberingSystem* numbering_system = |
211 |
icu::NumberingSystem::createInstance(icu_locale, status); |
212 |
if (U_SUCCESS(status)) {
|
213 |
const char* ns = numbering_system->getName(); |
214 |
JSObject::SetProperty( |
215 |
resolved, |
216 |
isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
|
217 |
isolate->factory()->NewStringFromAscii(CStrVector(ns)), |
218 |
NONE, |
219 |
kNonStrictMode); |
220 |
} else {
|
221 |
JSObject::SetProperty( |
222 |
resolved, |
223 |
isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
|
224 |
isolate->factory()->undefined_value(), |
225 |
NONE, |
226 |
kNonStrictMode); |
227 |
} |
228 |
delete numbering_system;
|
229 |
|
230 |
// Set the locale
|
231 |
char result[ULOC_FULLNAME_CAPACITY];
|
232 |
status = U_ZERO_ERROR; |
233 |
uloc_toLanguageTag( |
234 |
icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); |
235 |
if (U_SUCCESS(status)) {
|
236 |
JSObject::SetProperty( |
237 |
resolved, |
238 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
239 |
isolate->factory()->NewStringFromAscii(CStrVector(result)), |
240 |
NONE, |
241 |
kNonStrictMode); |
242 |
} else {
|
243 |
// This would never happen, since we got the locale from ICU.
|
244 |
JSObject::SetProperty( |
245 |
resolved, |
246 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
247 |
isolate->factory()->NewStringFromAscii(CStrVector("und")),
|
248 |
NONE, |
249 |
kNonStrictMode); |
250 |
} |
251 |
} |
252 |
|
253 |
|
254 |
template<int internal_fields, EternalHandles::SingletonHandle field> |
255 |
Handle<ObjectTemplateInfo> GetEternal(Isolate* isolate) { |
256 |
if (isolate->eternal_handles()->Exists(field)) {
|
257 |
return Handle<ObjectTemplateInfo>::cast(
|
258 |
isolate->eternal_handles()->GetSingleton(field)); |
259 |
} |
260 |
v8::Local<v8::ObjectTemplate> raw_template(v8::ObjectTemplate::New()); |
261 |
raw_template->SetInternalFieldCount(internal_fields); |
262 |
return Handle<ObjectTemplateInfo>::cast(
|
263 |
isolate->eternal_handles()->CreateSingleton( |
264 |
isolate, |
265 |
*v8::Utils::OpenHandle(*raw_template), |
266 |
field)); |
267 |
} |
268 |
|
269 |
|
270 |
icu::DecimalFormat* CreateICUNumberFormat( |
271 |
Isolate* isolate, |
272 |
const icu::Locale& icu_locale,
|
273 |
Handle<JSObject> options) { |
274 |
// Make formatter from options. Numbering system is added
|
275 |
// to the locale as Unicode extension (if it was specified at all).
|
276 |
UErrorCode status = U_ZERO_ERROR; |
277 |
icu::DecimalFormat* number_format = NULL;
|
278 |
icu::UnicodeString style; |
279 |
icu::UnicodeString currency; |
280 |
if (ExtractStringSetting(isolate, options, "style", &style)) { |
281 |
if (style == UNICODE_STRING_SIMPLE("currency")) { |
282 |
icu::UnicodeString display; |
283 |
ExtractStringSetting(isolate, options, "currency", ¤cy);
|
284 |
ExtractStringSetting(isolate, options, "currencyDisplay", &display);
|
285 |
|
286 |
#if (U_ICU_VERSION_MAJOR_NUM == 4) && (U_ICU_VERSION_MINOR_NUM <= 6) |
287 |
icu::NumberFormat::EStyles format_style; |
288 |
if (display == UNICODE_STRING_SIMPLE("code")) { |
289 |
format_style = icu::NumberFormat::kIsoCurrencyStyle; |
290 |
} else if (display == UNICODE_STRING_SIMPLE("name")) { |
291 |
format_style = icu::NumberFormat::kPluralCurrencyStyle; |
292 |
} else {
|
293 |
format_style = icu::NumberFormat::kCurrencyStyle; |
294 |
} |
295 |
#else // ICU version is 4.8 or above (we ignore versions below 4.0). |
296 |
UNumberFormatStyle format_style; |
297 |
if (display == UNICODE_STRING_SIMPLE("code")) { |
298 |
format_style = UNUM_CURRENCY_ISO; |
299 |
} else if (display == UNICODE_STRING_SIMPLE("name")) { |
300 |
format_style = UNUM_CURRENCY_PLURAL; |
301 |
} else {
|
302 |
format_style = UNUM_CURRENCY; |
303 |
} |
304 |
#endif
|
305 |
|
306 |
number_format = static_cast<icu::DecimalFormat*>(
|
307 |
icu::NumberFormat::createInstance(icu_locale, format_style, status)); |
308 |
} else if (style == UNICODE_STRING_SIMPLE("percent")) { |
309 |
number_format = static_cast<icu::DecimalFormat*>(
|
310 |
icu::NumberFormat::createPercentInstance(icu_locale, status)); |
311 |
if (U_FAILURE(status)) {
|
312 |
delete number_format;
|
313 |
return NULL; |
314 |
} |
315 |
// Make sure 1.1% doesn't go into 2%.
|
316 |
number_format->setMinimumFractionDigits(1);
|
317 |
} else {
|
318 |
// Make a decimal instance by default.
|
319 |
number_format = static_cast<icu::DecimalFormat*>(
|
320 |
icu::NumberFormat::createInstance(icu_locale, status)); |
321 |
} |
322 |
} |
323 |
|
324 |
if (U_FAILURE(status)) {
|
325 |
delete number_format;
|
326 |
return NULL; |
327 |
} |
328 |
|
329 |
// Set all options.
|
330 |
if (!currency.isEmpty()) {
|
331 |
number_format->setCurrency(currency.getBuffer(), status); |
332 |
} |
333 |
|
334 |
int32_t digits; |
335 |
if (ExtractIntegerSetting(
|
336 |
isolate, options, "minimumIntegerDigits", &digits)) {
|
337 |
number_format->setMinimumIntegerDigits(digits); |
338 |
} |
339 |
|
340 |
if (ExtractIntegerSetting(
|
341 |
isolate, options, "minimumFractionDigits", &digits)) {
|
342 |
number_format->setMinimumFractionDigits(digits); |
343 |
} |
344 |
|
345 |
if (ExtractIntegerSetting(
|
346 |
isolate, options, "maximumFractionDigits", &digits)) {
|
347 |
number_format->setMaximumFractionDigits(digits); |
348 |
} |
349 |
|
350 |
bool significant_digits_used = false; |
351 |
if (ExtractIntegerSetting(
|
352 |
isolate, options, "minimumSignificantDigits", &digits)) {
|
353 |
number_format->setMinimumSignificantDigits(digits); |
354 |
significant_digits_used = true;
|
355 |
} |
356 |
|
357 |
if (ExtractIntegerSetting(
|
358 |
isolate, options, "maximumSignificantDigits", &digits)) {
|
359 |
number_format->setMaximumSignificantDigits(digits); |
360 |
significant_digits_used = true;
|
361 |
} |
362 |
|
363 |
number_format->setSignificantDigitsUsed(significant_digits_used); |
364 |
|
365 |
bool grouping;
|
366 |
if (ExtractBooleanSetting(isolate, options, "useGrouping", &grouping)) { |
367 |
number_format->setGroupingUsed(grouping); |
368 |
} |
369 |
|
370 |
// Set rounding mode.
|
371 |
number_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp); |
372 |
|
373 |
return number_format;
|
374 |
} |
375 |
|
376 |
|
377 |
void SetResolvedNumberSettings(Isolate* isolate,
|
378 |
const icu::Locale& icu_locale,
|
379 |
icu::DecimalFormat* number_format, |
380 |
Handle<JSObject> resolved) { |
381 |
icu::UnicodeString pattern; |
382 |
number_format->toPattern(pattern); |
383 |
JSObject::SetProperty( |
384 |
resolved, |
385 |
isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
|
386 |
isolate->factory()->NewStringFromTwoByte( |
387 |
Vector<const uint16_t>(
|
388 |
reinterpret_cast<const uint16_t*>(pattern.getBuffer()), |
389 |
pattern.length())), |
390 |
NONE, |
391 |
kNonStrictMode); |
392 |
|
393 |
// Set resolved currency code in options.currency if not empty.
|
394 |
icu::UnicodeString currency(number_format->getCurrency()); |
395 |
if (!currency.isEmpty()) {
|
396 |
JSObject::SetProperty( |
397 |
resolved, |
398 |
isolate->factory()->NewStringFromAscii(CStrVector("currency")),
|
399 |
isolate->factory()->NewStringFromTwoByte( |
400 |
Vector<const uint16_t>(
|
401 |
reinterpret_cast<const uint16_t*>(currency.getBuffer()), |
402 |
currency.length())), |
403 |
NONE, |
404 |
kNonStrictMode); |
405 |
} |
406 |
|
407 |
// Ugly hack. ICU doesn't expose numbering system in any way, so we have
|
408 |
// to assume that for given locale NumberingSystem constructor produces the
|
409 |
// same digits as NumberFormat/Calendar would.
|
410 |
UErrorCode status = U_ZERO_ERROR; |
411 |
icu::NumberingSystem* numbering_system = |
412 |
icu::NumberingSystem::createInstance(icu_locale, status); |
413 |
if (U_SUCCESS(status)) {
|
414 |
const char* ns = numbering_system->getName(); |
415 |
JSObject::SetProperty( |
416 |
resolved, |
417 |
isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
|
418 |
isolate->factory()->NewStringFromAscii(CStrVector(ns)), |
419 |
NONE, |
420 |
kNonStrictMode); |
421 |
} else {
|
422 |
JSObject::SetProperty( |
423 |
resolved, |
424 |
isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
|
425 |
isolate->factory()->undefined_value(), |
426 |
NONE, |
427 |
kNonStrictMode); |
428 |
} |
429 |
delete numbering_system;
|
430 |
|
431 |
JSObject::SetProperty( |
432 |
resolved, |
433 |
isolate->factory()->NewStringFromAscii(CStrVector("useGrouping")),
|
434 |
isolate->factory()->ToBoolean(number_format->isGroupingUsed()), |
435 |
NONE, |
436 |
kNonStrictMode); |
437 |
|
438 |
JSObject::SetProperty( |
439 |
resolved, |
440 |
isolate->factory()->NewStringFromAscii( |
441 |
CStrVector("minimumIntegerDigits")),
|
442 |
isolate->factory()->NewNumberFromInt( |
443 |
number_format->getMinimumIntegerDigits()), |
444 |
NONE, |
445 |
kNonStrictMode); |
446 |
|
447 |
JSObject::SetProperty( |
448 |
resolved, |
449 |
isolate->factory()->NewStringFromAscii( |
450 |
CStrVector("minimumFractionDigits")),
|
451 |
isolate->factory()->NewNumberFromInt( |
452 |
number_format->getMinimumFractionDigits()), |
453 |
NONE, |
454 |
kNonStrictMode); |
455 |
|
456 |
JSObject::SetProperty( |
457 |
resolved, |
458 |
isolate->factory()->NewStringFromAscii( |
459 |
CStrVector("maximumFractionDigits")),
|
460 |
isolate->factory()->NewNumberFromInt( |
461 |
number_format->getMaximumFractionDigits()), |
462 |
NONE, |
463 |
kNonStrictMode); |
464 |
|
465 |
Handle<String> key = isolate->factory()->NewStringFromAscii( |
466 |
CStrVector("minimumSignificantDigits"));
|
467 |
if (JSReceiver::HasLocalProperty(resolved, key)) {
|
468 |
JSObject::SetProperty( |
469 |
resolved, |
470 |
isolate->factory()->NewStringFromAscii( |
471 |
CStrVector("minimumSignificantDigits")),
|
472 |
isolate->factory()->NewNumberFromInt( |
473 |
number_format->getMinimumSignificantDigits()), |
474 |
NONE, |
475 |
kNonStrictMode); |
476 |
} |
477 |
|
478 |
key = isolate->factory()->NewStringFromAscii( |
479 |
CStrVector("maximumSignificantDigits"));
|
480 |
if (JSReceiver::HasLocalProperty(resolved, key)) {
|
481 |
JSObject::SetProperty( |
482 |
resolved, |
483 |
isolate->factory()->NewStringFromAscii( |
484 |
CStrVector("maximumSignificantDigits")),
|
485 |
isolate->factory()->NewNumberFromInt( |
486 |
number_format->getMaximumSignificantDigits()), |
487 |
NONE, |
488 |
kNonStrictMode); |
489 |
} |
490 |
|
491 |
// Set the locale
|
492 |
char result[ULOC_FULLNAME_CAPACITY];
|
493 |
status = U_ZERO_ERROR; |
494 |
uloc_toLanguageTag( |
495 |
icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); |
496 |
if (U_SUCCESS(status)) {
|
497 |
JSObject::SetProperty( |
498 |
resolved, |
499 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
500 |
isolate->factory()->NewStringFromAscii(CStrVector(result)), |
501 |
NONE, |
502 |
kNonStrictMode); |
503 |
} else {
|
504 |
// This would never happen, since we got the locale from ICU.
|
505 |
JSObject::SetProperty( |
506 |
resolved, |
507 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
508 |
isolate->factory()->NewStringFromAscii(CStrVector("und")),
|
509 |
NONE, |
510 |
kNonStrictMode); |
511 |
} |
512 |
} |
513 |
|
514 |
|
515 |
icu::Collator* CreateICUCollator( |
516 |
Isolate* isolate, |
517 |
const icu::Locale& icu_locale,
|
518 |
Handle<JSObject> options) { |
519 |
// Make collator from options.
|
520 |
icu::Collator* collator = NULL;
|
521 |
UErrorCode status = U_ZERO_ERROR; |
522 |
collator = icu::Collator::createInstance(icu_locale, status); |
523 |
|
524 |
if (U_FAILURE(status)) {
|
525 |
delete collator;
|
526 |
return NULL; |
527 |
} |
528 |
|
529 |
// Set flags first, and then override them with sensitivity if necessary.
|
530 |
bool numeric;
|
531 |
if (ExtractBooleanSetting(isolate, options, "numeric", &numeric)) { |
532 |
collator->setAttribute( |
533 |
UCOL_NUMERIC_COLLATION, numeric ? UCOL_ON : UCOL_OFF, status); |
534 |
} |
535 |
|
536 |
// Normalization is always on, by the spec. We are free to optimize
|
537 |
// if the strings are already normalized (but we don't have a way to tell
|
538 |
// that right now).
|
539 |
collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); |
540 |
|
541 |
icu::UnicodeString case_first; |
542 |
if (ExtractStringSetting(isolate, options, "caseFirst", &case_first)) { |
543 |
if (case_first == UNICODE_STRING_SIMPLE("upper")) { |
544 |
collator->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status); |
545 |
} else if (case_first == UNICODE_STRING_SIMPLE("lower")) { |
546 |
collator->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status); |
547 |
} else {
|
548 |
// Default (false/off).
|
549 |
collator->setAttribute(UCOL_CASE_FIRST, UCOL_OFF, status); |
550 |
} |
551 |
} |
552 |
|
553 |
icu::UnicodeString sensitivity; |
554 |
if (ExtractStringSetting(isolate, options, "sensitivity", &sensitivity)) { |
555 |
if (sensitivity == UNICODE_STRING_SIMPLE("base")) { |
556 |
collator->setStrength(icu::Collator::PRIMARY); |
557 |
} else if (sensitivity == UNICODE_STRING_SIMPLE("accent")) { |
558 |
collator->setStrength(icu::Collator::SECONDARY); |
559 |
} else if (sensitivity == UNICODE_STRING_SIMPLE("case")) { |
560 |
collator->setStrength(icu::Collator::PRIMARY); |
561 |
collator->setAttribute(UCOL_CASE_LEVEL, UCOL_ON, status); |
562 |
} else {
|
563 |
// variant (default)
|
564 |
collator->setStrength(icu::Collator::TERTIARY); |
565 |
} |
566 |
} |
567 |
|
568 |
bool ignore;
|
569 |
if (ExtractBooleanSetting(isolate, options, "ignorePunctuation", &ignore)) { |
570 |
if (ignore) {
|
571 |
collator->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status); |
572 |
} |
573 |
} |
574 |
|
575 |
return collator;
|
576 |
} |
577 |
|
578 |
|
579 |
void SetResolvedCollatorSettings(Isolate* isolate,
|
580 |
const icu::Locale& icu_locale,
|
581 |
icu::Collator* collator, |
582 |
Handle<JSObject> resolved) { |
583 |
UErrorCode status = U_ZERO_ERROR; |
584 |
|
585 |
JSObject::SetProperty( |
586 |
resolved, |
587 |
isolate->factory()->NewStringFromAscii(CStrVector("numeric")),
|
588 |
isolate->factory()->ToBoolean( |
589 |
collator->getAttribute(UCOL_NUMERIC_COLLATION, status) == UCOL_ON), |
590 |
NONE, |
591 |
kNonStrictMode); |
592 |
|
593 |
switch (collator->getAttribute(UCOL_CASE_FIRST, status)) {
|
594 |
case UCOL_LOWER_FIRST:
|
595 |
JSObject::SetProperty( |
596 |
resolved, |
597 |
isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
|
598 |
isolate->factory()->NewStringFromAscii(CStrVector("lower")),
|
599 |
NONE, |
600 |
kNonStrictMode); |
601 |
break;
|
602 |
case UCOL_UPPER_FIRST:
|
603 |
JSObject::SetProperty( |
604 |
resolved, |
605 |
isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
|
606 |
isolate->factory()->NewStringFromAscii(CStrVector("upper")),
|
607 |
NONE, |
608 |
kNonStrictMode); |
609 |
break;
|
610 |
default:
|
611 |
JSObject::SetProperty( |
612 |
resolved, |
613 |
isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
|
614 |
isolate->factory()->NewStringFromAscii(CStrVector("false")),
|
615 |
NONE, |
616 |
kNonStrictMode); |
617 |
} |
618 |
|
619 |
switch (collator->getAttribute(UCOL_STRENGTH, status)) {
|
620 |
case UCOL_PRIMARY: {
|
621 |
JSObject::SetProperty( |
622 |
resolved, |
623 |
isolate->factory()->NewStringFromAscii(CStrVector("strength")),
|
624 |
isolate->factory()->NewStringFromAscii(CStrVector("primary")),
|
625 |
NONE, |
626 |
kNonStrictMode); |
627 |
|
628 |
// case level: true + s1 -> case, s1 -> base.
|
629 |
if (UCOL_ON == collator->getAttribute(UCOL_CASE_LEVEL, status)) {
|
630 |
JSObject::SetProperty( |
631 |
resolved, |
632 |
isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
|
633 |
isolate->factory()->NewStringFromAscii(CStrVector("case")),
|
634 |
NONE, |
635 |
kNonStrictMode); |
636 |
} else {
|
637 |
JSObject::SetProperty( |
638 |
resolved, |
639 |
isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
|
640 |
isolate->factory()->NewStringFromAscii(CStrVector("base")),
|
641 |
NONE, |
642 |
kNonStrictMode); |
643 |
} |
644 |
break;
|
645 |
} |
646 |
case UCOL_SECONDARY:
|
647 |
JSObject::SetProperty( |
648 |
resolved, |
649 |
isolate->factory()->NewStringFromAscii(CStrVector("strength")),
|
650 |
isolate->factory()->NewStringFromAscii(CStrVector("secondary")),
|
651 |
NONE, |
652 |
kNonStrictMode); |
653 |
JSObject::SetProperty( |
654 |
resolved, |
655 |
isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
|
656 |
isolate->factory()->NewStringFromAscii(CStrVector("accent")),
|
657 |
NONE, |
658 |
kNonStrictMode); |
659 |
break;
|
660 |
case UCOL_TERTIARY:
|
661 |
JSObject::SetProperty( |
662 |
resolved, |
663 |
isolate->factory()->NewStringFromAscii(CStrVector("strength")),
|
664 |
isolate->factory()->NewStringFromAscii(CStrVector("tertiary")),
|
665 |
NONE, |
666 |
kNonStrictMode); |
667 |
JSObject::SetProperty( |
668 |
resolved, |
669 |
isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
|
670 |
isolate->factory()->NewStringFromAscii(CStrVector("variant")),
|
671 |
NONE, |
672 |
kNonStrictMode); |
673 |
break;
|
674 |
case UCOL_QUATERNARY:
|
675 |
// We shouldn't get quaternary and identical from ICU, but if we do
|
676 |
// put them into variant.
|
677 |
JSObject::SetProperty( |
678 |
resolved, |
679 |
isolate->factory()->NewStringFromAscii(CStrVector("strength")),
|
680 |
isolate->factory()->NewStringFromAscii(CStrVector("quaternary")),
|
681 |
NONE, |
682 |
kNonStrictMode); |
683 |
JSObject::SetProperty( |
684 |
resolved, |
685 |
isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
|
686 |
isolate->factory()->NewStringFromAscii(CStrVector("variant")),
|
687 |
NONE, |
688 |
kNonStrictMode); |
689 |
break;
|
690 |
default:
|
691 |
JSObject::SetProperty( |
692 |
resolved, |
693 |
isolate->factory()->NewStringFromAscii(CStrVector("strength")),
|
694 |
isolate->factory()->NewStringFromAscii(CStrVector("identical")),
|
695 |
NONE, |
696 |
kNonStrictMode); |
697 |
JSObject::SetProperty( |
698 |
resolved, |
699 |
isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
|
700 |
isolate->factory()->NewStringFromAscii(CStrVector("variant")),
|
701 |
NONE, |
702 |
kNonStrictMode); |
703 |
} |
704 |
|
705 |
JSObject::SetProperty( |
706 |
resolved, |
707 |
isolate->factory()->NewStringFromAscii(CStrVector("ignorePunctuation")),
|
708 |
isolate->factory()->ToBoolean(collator->getAttribute( |
709 |
UCOL_ALTERNATE_HANDLING, status) == UCOL_SHIFTED), |
710 |
NONE, |
711 |
kNonStrictMode); |
712 |
|
713 |
// Set the locale
|
714 |
char result[ULOC_FULLNAME_CAPACITY];
|
715 |
status = U_ZERO_ERROR; |
716 |
uloc_toLanguageTag( |
717 |
icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); |
718 |
if (U_SUCCESS(status)) {
|
719 |
JSObject::SetProperty( |
720 |
resolved, |
721 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
722 |
isolate->factory()->NewStringFromAscii(CStrVector(result)), |
723 |
NONE, |
724 |
kNonStrictMode); |
725 |
} else {
|
726 |
// This would never happen, since we got the locale from ICU.
|
727 |
JSObject::SetProperty( |
728 |
resolved, |
729 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
730 |
isolate->factory()->NewStringFromAscii(CStrVector("und")),
|
731 |
NONE, |
732 |
kNonStrictMode); |
733 |
} |
734 |
} |
735 |
|
736 |
|
737 |
icu::BreakIterator* CreateICUBreakIterator( |
738 |
Isolate* isolate, |
739 |
const icu::Locale& icu_locale,
|
740 |
Handle<JSObject> options) { |
741 |
UErrorCode status = U_ZERO_ERROR; |
742 |
icu::BreakIterator* break_iterator = NULL;
|
743 |
icu::UnicodeString type; |
744 |
if (!ExtractStringSetting(isolate, options, "type", &type)) return NULL; |
745 |
|
746 |
if (type == UNICODE_STRING_SIMPLE("character")) { |
747 |
break_iterator = |
748 |
icu::BreakIterator::createCharacterInstance(icu_locale, status); |
749 |
} else if (type == UNICODE_STRING_SIMPLE("sentence")) { |
750 |
break_iterator = |
751 |
icu::BreakIterator::createSentenceInstance(icu_locale, status); |
752 |
} else if (type == UNICODE_STRING_SIMPLE("line")) { |
753 |
break_iterator = |
754 |
icu::BreakIterator::createLineInstance(icu_locale, status); |
755 |
} else {
|
756 |
// Defualt is word iterator.
|
757 |
break_iterator = |
758 |
icu::BreakIterator::createWordInstance(icu_locale, status); |
759 |
} |
760 |
|
761 |
if (U_FAILURE(status)) {
|
762 |
delete break_iterator;
|
763 |
return NULL; |
764 |
} |
765 |
|
766 |
return break_iterator;
|
767 |
} |
768 |
|
769 |
|
770 |
void SetResolvedBreakIteratorSettings(Isolate* isolate,
|
771 |
const icu::Locale& icu_locale,
|
772 |
icu::BreakIterator* break_iterator, |
773 |
Handle<JSObject> resolved) { |
774 |
UErrorCode status = U_ZERO_ERROR; |
775 |
|
776 |
// Set the locale
|
777 |
char result[ULOC_FULLNAME_CAPACITY];
|
778 |
status = U_ZERO_ERROR; |
779 |
uloc_toLanguageTag( |
780 |
icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); |
781 |
if (U_SUCCESS(status)) {
|
782 |
JSObject::SetProperty( |
783 |
resolved, |
784 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
785 |
isolate->factory()->NewStringFromAscii(CStrVector(result)), |
786 |
NONE, |
787 |
kNonStrictMode); |
788 |
} else {
|
789 |
// This would never happen, since we got the locale from ICU.
|
790 |
JSObject::SetProperty( |
791 |
resolved, |
792 |
isolate->factory()->NewStringFromAscii(CStrVector("locale")),
|
793 |
isolate->factory()->NewStringFromAscii(CStrVector("und")),
|
794 |
NONE, |
795 |
kNonStrictMode); |
796 |
} |
797 |
} |
798 |
|
799 |
} // namespace
|
800 |
|
801 |
|
802 |
// static
|
803 |
Handle<ObjectTemplateInfo> I18N::GetTemplate(Isolate* isolate) { |
804 |
return GetEternal<1, i::EternalHandles::I18N_TEMPLATE_ONE>(isolate); |
805 |
} |
806 |
|
807 |
|
808 |
// static
|
809 |
Handle<ObjectTemplateInfo> I18N::GetTemplate2(Isolate* isolate) { |
810 |
return GetEternal<2, i::EternalHandles::I18N_TEMPLATE_TWO>(isolate); |
811 |
} |
812 |
|
813 |
|
814 |
// static
|
815 |
icu::SimpleDateFormat* DateFormat::InitializeDateTimeFormat( |
816 |
Isolate* isolate, |
817 |
Handle<String> locale, |
818 |
Handle<JSObject> options, |
819 |
Handle<JSObject> resolved) { |
820 |
// Convert BCP47 into ICU locale format.
|
821 |
UErrorCode status = U_ZERO_ERROR; |
822 |
icu::Locale icu_locale; |
823 |
char icu_result[ULOC_FULLNAME_CAPACITY];
|
824 |
int icu_length = 0; |
825 |
v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); |
826 |
if (bcp47_locale.length() != 0) { |
827 |
uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, |
828 |
&icu_length, &status); |
829 |
if (U_FAILURE(status) || icu_length == 0) { |
830 |
return NULL; |
831 |
} |
832 |
icu_locale = icu::Locale(icu_result); |
833 |
} |
834 |
|
835 |
icu::SimpleDateFormat* date_format = CreateICUDateFormat( |
836 |
isolate, icu_locale, options); |
837 |
if (!date_format) {
|
838 |
// Remove extensions and try again.
|
839 |
icu::Locale no_extension_locale(icu_locale.getBaseName()); |
840 |
date_format = CreateICUDateFormat(isolate, no_extension_locale, options); |
841 |
|
842 |
// Set resolved settings (pattern, numbering system, calendar).
|
843 |
SetResolvedDateSettings( |
844 |
isolate, no_extension_locale, date_format, resolved); |
845 |
} else {
|
846 |
SetResolvedDateSettings(isolate, icu_locale, date_format, resolved); |
847 |
} |
848 |
|
849 |
return date_format;
|
850 |
} |
851 |
|
852 |
|
853 |
icu::SimpleDateFormat* DateFormat::UnpackDateFormat( |
854 |
Isolate* isolate, |
855 |
Handle<JSObject> obj) { |
856 |
Handle<String> key = |
857 |
isolate->factory()->NewStringFromAscii(CStrVector("dateFormat"));
|
858 |
if (JSReceiver::HasLocalProperty(obj, key)) {
|
859 |
return reinterpret_cast<icu::SimpleDateFormat*>( |
860 |
obj->GetInternalField(0));
|
861 |
} |
862 |
|
863 |
return NULL; |
864 |
} |
865 |
|
866 |
|
867 |
void DateFormat::DeleteDateFormat(v8::Isolate* isolate,
|
868 |
Persistent<v8::Value>* object, |
869 |
void* param) {
|
870 |
// First delete the hidden C++ object.
|
871 |
delete reinterpret_cast<icu::SimpleDateFormat*>(Handle<JSObject>::cast( |
872 |
v8::Utils::OpenPersistent(object))->GetInternalField(0));
|
873 |
|
874 |
// Then dispose of the persistent handle to JS object.
|
875 |
object->Dispose(); |
876 |
} |
877 |
|
878 |
|
879 |
icu::DecimalFormat* NumberFormat::InitializeNumberFormat( |
880 |
Isolate* isolate, |
881 |
Handle<String> locale, |
882 |
Handle<JSObject> options, |
883 |
Handle<JSObject> resolved) { |
884 |
// Convert BCP47 into ICU locale format.
|
885 |
UErrorCode status = U_ZERO_ERROR; |
886 |
icu::Locale icu_locale; |
887 |
char icu_result[ULOC_FULLNAME_CAPACITY];
|
888 |
int icu_length = 0; |
889 |
v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); |
890 |
if (bcp47_locale.length() != 0) { |
891 |
uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, |
892 |
&icu_length, &status); |
893 |
if (U_FAILURE(status) || icu_length == 0) { |
894 |
return NULL; |
895 |
} |
896 |
icu_locale = icu::Locale(icu_result); |
897 |
} |
898 |
|
899 |
icu::DecimalFormat* number_format = |
900 |
CreateICUNumberFormat(isolate, icu_locale, options); |
901 |
if (!number_format) {
|
902 |
// Remove extensions and try again.
|
903 |
icu::Locale no_extension_locale(icu_locale.getBaseName()); |
904 |
number_format = CreateICUNumberFormat( |
905 |
isolate, no_extension_locale, options); |
906 |
|
907 |
// Set resolved settings (pattern, numbering system).
|
908 |
SetResolvedNumberSettings( |
909 |
isolate, no_extension_locale, number_format, resolved); |
910 |
} else {
|
911 |
SetResolvedNumberSettings(isolate, icu_locale, number_format, resolved); |
912 |
} |
913 |
|
914 |
return number_format;
|
915 |
} |
916 |
|
917 |
|
918 |
icu::DecimalFormat* NumberFormat::UnpackNumberFormat( |
919 |
Isolate* isolate, |
920 |
Handle<JSObject> obj) { |
921 |
Handle<String> key = |
922 |
isolate->factory()->NewStringFromAscii(CStrVector("numberFormat"));
|
923 |
if (JSReceiver::HasLocalProperty(obj, key)) {
|
924 |
return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0)); |
925 |
} |
926 |
|
927 |
return NULL; |
928 |
} |
929 |
|
930 |
|
931 |
void NumberFormat::DeleteNumberFormat(v8::Isolate* isolate,
|
932 |
Persistent<v8::Value>* object, |
933 |
void* param) {
|
934 |
// First delete the hidden C++ object.
|
935 |
delete reinterpret_cast<icu::DecimalFormat*>(Handle<JSObject>::cast( |
936 |
v8::Utils::OpenPersistent(object))->GetInternalField(0));
|
937 |
|
938 |
// Then dispose of the persistent handle to JS object.
|
939 |
object->Dispose(); |
940 |
} |
941 |
|
942 |
|
943 |
icu::Collator* Collator::InitializeCollator( |
944 |
Isolate* isolate, |
945 |
Handle<String> locale, |
946 |
Handle<JSObject> options, |
947 |
Handle<JSObject> resolved) { |
948 |
// Convert BCP47 into ICU locale format.
|
949 |
UErrorCode status = U_ZERO_ERROR; |
950 |
icu::Locale icu_locale; |
951 |
char icu_result[ULOC_FULLNAME_CAPACITY];
|
952 |
int icu_length = 0; |
953 |
v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); |
954 |
if (bcp47_locale.length() != 0) { |
955 |
uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, |
956 |
&icu_length, &status); |
957 |
if (U_FAILURE(status) || icu_length == 0) { |
958 |
return NULL; |
959 |
} |
960 |
icu_locale = icu::Locale(icu_result); |
961 |
} |
962 |
|
963 |
icu::Collator* collator = CreateICUCollator(isolate, icu_locale, options); |
964 |
if (!collator) {
|
965 |
// Remove extensions and try again.
|
966 |
icu::Locale no_extension_locale(icu_locale.getBaseName()); |
967 |
collator = CreateICUCollator(isolate, no_extension_locale, options); |
968 |
|
969 |
// Set resolved settings (pattern, numbering system).
|
970 |
SetResolvedCollatorSettings( |
971 |
isolate, no_extension_locale, collator, resolved); |
972 |
} else {
|
973 |
SetResolvedCollatorSettings(isolate, icu_locale, collator, resolved); |
974 |
} |
975 |
|
976 |
return collator;
|
977 |
} |
978 |
|
979 |
|
980 |
icu::Collator* Collator::UnpackCollator(Isolate* isolate, |
981 |
Handle<JSObject> obj) { |
982 |
Handle<String> key = |
983 |
isolate->factory()->NewStringFromAscii(CStrVector("collator"));
|
984 |
if (JSReceiver::HasLocalProperty(obj, key)) {
|
985 |
return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0)); |
986 |
} |
987 |
|
988 |
return NULL; |
989 |
} |
990 |
|
991 |
|
992 |
void Collator::DeleteCollator(v8::Isolate* isolate,
|
993 |
Persistent<v8::Value>* object, |
994 |
void* param) {
|
995 |
// First delete the hidden C++ object.
|
996 |
delete reinterpret_cast<icu::Collator*>(Handle<JSObject>::cast( |
997 |
v8::Utils::OpenPersistent(object))->GetInternalField(0));
|
998 |
|
999 |
// Then dispose of the persistent handle to JS object.
|
1000 |
object->Dispose(); |
1001 |
} |
1002 |
|
1003 |
|
1004 |
icu::BreakIterator* BreakIterator::InitializeBreakIterator( |
1005 |
Isolate* isolate, |
1006 |
Handle<String> locale, |
1007 |
Handle<JSObject> options, |
1008 |
Handle<JSObject> resolved) { |
1009 |
// Convert BCP47 into ICU locale format.
|
1010 |
UErrorCode status = U_ZERO_ERROR; |
1011 |
icu::Locale icu_locale; |
1012 |
char icu_result[ULOC_FULLNAME_CAPACITY];
|
1013 |
int icu_length = 0; |
1014 |
v8::String::Utf8Value bcp47_locale(v8::Utils::ToLocal(locale)); |
1015 |
if (bcp47_locale.length() != 0) { |
1016 |
uloc_forLanguageTag(*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, |
1017 |
&icu_length, &status); |
1018 |
if (U_FAILURE(status) || icu_length == 0) { |
1019 |
return NULL; |
1020 |
} |
1021 |
icu_locale = icu::Locale(icu_result); |
1022 |
} |
1023 |
|
1024 |
icu::BreakIterator* break_iterator = CreateICUBreakIterator( |
1025 |
isolate, icu_locale, options); |
1026 |
if (!break_iterator) {
|
1027 |
// Remove extensions and try again.
|
1028 |
icu::Locale no_extension_locale(icu_locale.getBaseName()); |
1029 |
break_iterator = CreateICUBreakIterator( |
1030 |
isolate, no_extension_locale, options); |
1031 |
|
1032 |
// Set resolved settings (locale).
|
1033 |
SetResolvedBreakIteratorSettings( |
1034 |
isolate, no_extension_locale, break_iterator, resolved); |
1035 |
} else {
|
1036 |
SetResolvedBreakIteratorSettings( |
1037 |
isolate, icu_locale, break_iterator, resolved); |
1038 |
} |
1039 |
|
1040 |
return break_iterator;
|
1041 |
} |
1042 |
|
1043 |
|
1044 |
icu::BreakIterator* BreakIterator::UnpackBreakIterator(Isolate* isolate, |
1045 |
Handle<JSObject> obj) { |
1046 |
Handle<String> key = |
1047 |
isolate->factory()->NewStringFromAscii(CStrVector("breakIterator"));
|
1048 |
if (JSReceiver::HasLocalProperty(obj, key)) {
|
1049 |
return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0)); |
1050 |
} |
1051 |
|
1052 |
return NULL; |
1053 |
} |
1054 |
|
1055 |
|
1056 |
void BreakIterator::DeleteBreakIterator(v8::Isolate* isolate,
|
1057 |
Persistent<v8::Value>* object, |
1058 |
void* param) {
|
1059 |
// First delete the hidden C++ object.
|
1060 |
delete reinterpret_cast<icu::BreakIterator*>(Handle<JSObject>::cast( |
1061 |
v8::Utils::OpenPersistent(object))->GetInternalField(0));
|
1062 |
|
1063 |
delete reinterpret_cast<icu::UnicodeString*>(Handle<JSObject>::cast( |
1064 |
v8::Utils::OpenPersistent(object))->GetInternalField(1));
|
1065 |
|
1066 |
// Then dispose of the persistent handle to JS object.
|
1067 |
object->Dispose(); |
1068 |
} |
1069 |
|
1070 |
} } // namespace v8::internal
|