OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 #include <string.h> | 30 #include <string.h> |
31 | 31 |
32 #include "src/extensions/experimental/i18n-utils.h" | 32 #include "src/extensions/experimental/i18n-utils.h" |
33 #include "unicode/dcfmtsym.h" | 33 #include "unicode/dcfmtsym.h" |
34 #include "unicode/decimfmt.h" | 34 #include "unicode/decimfmt.h" |
35 #include "unicode/locid.h" | 35 #include "unicode/locid.h" |
36 #include "unicode/numfmt.h" | 36 #include "unicode/numfmt.h" |
37 #include "unicode/uchar.h" | 37 #include "unicode/uchar.h" |
38 #include "unicode/ucurr.h" | 38 #include "unicode/ucurr.h" |
| 39 #include "unicode/unum.h" |
| 40 #include "unicode/uversion.h" |
39 | 41 |
40 namespace v8 { | 42 namespace v8 { |
41 namespace internal { | 43 namespace internal { |
42 | 44 |
43 const int NumberFormat::kCurrencyCodeLength = 4; | 45 const int NumberFormat::kCurrencyCodeLength = 4; |
44 | 46 |
45 v8::Persistent<v8::FunctionTemplate> NumberFormat::number_format_template_; | 47 v8::Persistent<v8::FunctionTemplate> NumberFormat::number_format_template_; |
46 | 48 |
47 static icu::DecimalFormat* CreateNumberFormat(v8::Handle<v8::String>, | 49 static icu::DecimalFormat* CreateNumberFormat(v8::Handle<v8::String>, |
48 v8::Handle<v8::String>, | 50 v8::Handle<v8::String>, |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 226 |
225 UChar currency_code[NumberFormat::kCurrencyCodeLength]; | 227 UChar currency_code[NumberFormat::kCurrencyCodeLength]; |
226 if (GetCurrencyCode(icu_locale, *ascii_region, settings, currency_code)) { | 228 if (GetCurrencyCode(icu_locale, *ascii_region, settings, currency_code)) { |
227 number_format->setCurrency(currency_code, status); | 229 number_format->setCurrency(currency_code, status); |
228 } | 230 } |
229 | 231 |
230 return number_format; | 232 return number_format; |
231 } | 233 } |
232 | 234 |
233 // Generates ICU number format pattern from given skeleton. | 235 // Generates ICU number format pattern from given skeleton. |
| 236 // TODO(cira): Remove once ICU includes equivalent method |
| 237 // (see http://bugs.icu-project.org/trac/ticket/8610). |
234 static icu::DecimalFormat* CreateFormatterFromSkeleton( | 238 static icu::DecimalFormat* CreateFormatterFromSkeleton( |
235 const icu::Locale& icu_locale, | 239 const icu::Locale& icu_locale, |
236 const icu::UnicodeString& skeleton, | 240 const icu::UnicodeString& skeleton, |
237 UErrorCode* status) { | 241 UErrorCode* status) { |
238 icu::DecimalFormat skeleton_format( | 242 icu::DecimalFormat skeleton_format( |
239 skeleton, GetFormatSymbols(icu_locale), *status); | 243 skeleton, GetFormatSymbols(icu_locale), *status); |
240 | 244 |
241 // Find out if skeleton contains currency or percent symbol and create | 245 // Find out if skeleton contains currency or percent symbol and create |
242 // proper instance to tweak. | 246 // proper instance to tweak. |
243 icu::DecimalFormat* base_format = NULL; | 247 icu::DecimalFormat* base_format = NULL; |
244 | 248 |
245 // UChar representation of U+00A4 currency symbol. | 249 // UChar representation of U+00A4 currency symbol. |
246 const UChar currency_symbol = 0xA4u; | 250 const UChar currency_symbol = 0xA4u; |
247 | 251 |
248 int32_t index = skeleton.indexOf(currency_symbol); | 252 int32_t index = skeleton.indexOf(currency_symbol); |
249 if (index != -1) { | 253 if (index != -1) { |
250 // Find how many U+00A4 are there. There is at least one. | 254 // Find how many U+00A4 are there. There is at least one. |
251 // Case of non-consecutive U+00A4 is taken care of in i18n.js. | 255 // Case of non-consecutive U+00A4 is taken care of in i18n.js. |
252 int32_t end_index = skeleton.lastIndexOf(currency_symbol, index); | 256 int32_t end_index = skeleton.lastIndexOf(currency_symbol, index); |
253 | 257 |
| 258 #if (U_ICU_VERSION_MAJOR_NUM == 4) && (U_ICU_VERSION_MINOR_NUM <= 6) |
254 icu::NumberFormat::EStyles style; | 259 icu::NumberFormat::EStyles style; |
255 switch (end_index - index) { | 260 switch (end_index - index) { |
256 case 0: | 261 case 0: |
257 style = icu::NumberFormat::kCurrencyStyle; | 262 style = icu::NumberFormat::kCurrencyStyle; |
258 break; | 263 break; |
259 case 1: | 264 case 1: |
260 style = icu::NumberFormat::kIsoCurrencyStyle; | 265 style = icu::NumberFormat::kIsoCurrencyStyle; |
261 break; | 266 break; |
262 default: | 267 default: |
263 style = icu::NumberFormat::kPluralCurrencyStyle; | 268 style = icu::NumberFormat::kPluralCurrencyStyle; |
264 } | 269 } |
| 270 #else // ICU version is 4.8 or above (we ignore versions below 4.0). |
| 271 UNumberFormatStyle style; |
| 272 switch (end_index - index) { |
| 273 case 0: |
| 274 style = UNUM_CURRENCY; |
| 275 break; |
| 276 case 1: |
| 277 style = UNUM_CURRENCY_ISO; |
| 278 break; |
| 279 default: |
| 280 style = UNUM_CURRENCY_PLURAL; |
| 281 } |
| 282 #endif |
265 | 283 |
266 base_format = static_cast<icu::DecimalFormat*>( | 284 base_format = static_cast<icu::DecimalFormat*>( |
267 icu::NumberFormat::createInstance(icu_locale, style, *status)); | 285 icu::NumberFormat::createInstance(icu_locale, style, *status)); |
268 } else if (skeleton.indexOf('%') != -1) { | 286 } else if (skeleton.indexOf('%') != -1) { |
269 base_format = static_cast<icu::DecimalFormat*>( | 287 base_format = static_cast<icu::DecimalFormat*>( |
270 icu::NumberFormat::createPercentInstance(icu_locale, *status)); | 288 icu::NumberFormat::createPercentInstance(icu_locale, *status)); |
271 } else { | 289 } else { |
272 // TODO(cira): Handle scientific skeleton. | 290 // TODO(cira): Handle scientific skeleton. |
273 base_format = static_cast<icu::DecimalFormat*>( | 291 base_format = static_cast<icu::DecimalFormat*>( |
274 icu::NumberFormat::createInstance(icu_locale, *status)); | 292 icu::NumberFormat::createInstance(icu_locale, *status)); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 | 365 |
348 // Throws a JavaScript exception. | 366 // Throws a JavaScript exception. |
349 static v8::Handle<v8::Value> ThrowUnexpectedObjectError() { | 367 static v8::Handle<v8::Value> ThrowUnexpectedObjectError() { |
350 // Returns undefined, and schedules an exception to be thrown. | 368 // Returns undefined, and schedules an exception to be thrown. |
351 return v8::ThrowException(v8::Exception::Error( | 369 return v8::ThrowException(v8::Exception::Error( |
352 v8::String::New("NumberFormat method called on an object " | 370 v8::String::New("NumberFormat method called on an object " |
353 "that is not a NumberFormat."))); | 371 "that is not a NumberFormat."))); |
354 } | 372 } |
355 | 373 |
356 } } // namespace v8::internal | 374 } } // namespace v8::internal |
OLD | NEW |