OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 1997-2013, International Business Machines Corporation and | 3 * Copyright (C) 1997-2014, International Business Machines Corporation and |
4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
5 ******************************************************************************* | 5 ******************************************************************************* |
6 * | 6 * |
7 * File NUMFMT.CPP | 7 * File NUMFMT.CPP |
8 * | 8 * |
9 * Modification History: | 9 * Modification History: |
10 * | 10 * |
11 * Date Name Description | 11 * Date Name Description |
12 * 02/19/97 aliu Converted from java. | 12 * 02/19/97 aliu Converted from java. |
13 * 03/18/97 clhuang Implemented with C++ APIs. | 13 * 03/18/97 clhuang Implemented with C++ APIs. |
(...skipping 15 matching lines...) Expand all Loading... |
29 #include "unicode/numfmt.h" | 29 #include "unicode/numfmt.h" |
30 #include "unicode/locid.h" | 30 #include "unicode/locid.h" |
31 #include "unicode/dcfmtsym.h" | 31 #include "unicode/dcfmtsym.h" |
32 #include "unicode/decimfmt.h" | 32 #include "unicode/decimfmt.h" |
33 #include "unicode/ustring.h" | 33 #include "unicode/ustring.h" |
34 #include "unicode/ucurr.h" | 34 #include "unicode/ucurr.h" |
35 #include "unicode/curramt.h" | 35 #include "unicode/curramt.h" |
36 #include "unicode/numsys.h" | 36 #include "unicode/numsys.h" |
37 #include "unicode/rbnf.h" | 37 #include "unicode/rbnf.h" |
38 #include "unicode/localpointer.h" | 38 #include "unicode/localpointer.h" |
| 39 #include "unicode/udisplaycontext.h" |
39 #include "charstr.h" | 40 #include "charstr.h" |
40 #include "winnmfmt.h" | 41 #include "winnmfmt.h" |
41 #include "uresimp.h" | 42 #include "uresimp.h" |
42 #include "uhash.h" | 43 #include "uhash.h" |
43 #include "cmemory.h" | 44 #include "cmemory.h" |
44 #include "servloc.h" | 45 #include "servloc.h" |
45 #include "ucln_in.h" | 46 #include "ucln_in.h" |
46 #include "cstring.h" | 47 #include "cstring.h" |
47 #include "putilimp.h" | 48 #include "putilimp.h" |
48 #include "uassert.h" | 49 #include "uassert.h" |
49 #include "umutex.h" | 50 #include "umutex.h" |
50 #include "mutex.h" | 51 #include "mutex.h" |
51 #include "digitlst.h" | 52 #include "digitlst.h" |
52 #include <float.h> | 53 #include <float.h> |
| 54 #include "sharednumberformat.h" |
| 55 #include "unifiedcache.h" |
53 | 56 |
54 //#define FMT_DEBUG | 57 //#define FMT_DEBUG |
55 | 58 |
56 #ifdef FMT_DEBUG | 59 #ifdef FMT_DEBUG |
57 #include <stdio.h> | 60 #include <stdio.h> |
58 static inline void debugout(UnicodeString s) { | 61 static inline void debugout(UnicodeString s) { |
59 char buf[2000]; | 62 char buf[2000]; |
60 s.extract((int32_t) 0, s.length(), buf); | 63 s.extract((int32_t) 0, s.length(), buf); |
61 printf("%s", buf); | 64 printf("%s", buf); |
62 } | 65 } |
63 #define debug(x) printf("%s", x); | 66 #define debug(x) printf("%s", x); |
64 #else | 67 #else |
65 #define debugout(x) | 68 #define debugout(x) |
66 #define debug(x) | 69 #define debug(x) |
67 #endif | 70 #endif |
68 | 71 |
69 // If no number pattern can be located for a locale, this is the last | 72 // If no number pattern can be located for a locale, this is the last |
70 // resort. | 73 // resort. The patterns are same as the ones in root locale. |
71 static const UChar gLastResortDecimalPat[] = { | 74 static const UChar gLastResortDecimalPat[] = { |
72 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0x3B, 0x2D, 0x23, 0x30, 0x2E, 0x23, 0x23
, 0x23, 0 /* "#0.###;-#0.###" */ | 75 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0 /* "#,##0.###" */ |
73 }; | 76 }; |
74 static const UChar gLastResortCurrencyPat[] = { | 77 static const UChar gLastResortCurrencyPat[] = { |
75 0x24, 0x23, 0x30, 0x2E, 0x30, 0x30, 0x3B, 0x28, 0x24, 0x23, 0x30, 0x2E, 0x30
, 0x30, 0x29, 0 /* "$#0.00;($#0.00)" */ | 78 0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0 /* "\u00A4\u00
A0#,##0.00" */ |
76 }; | 79 }; |
77 static const UChar gLastResortPercentPat[] = { | 80 static const UChar gLastResortPercentPat[] = { |
78 0x23, 0x30, 0x25, 0 /* "#0%" */ | 81 0x23, 0x2C, 0x23, 0x23, 0x30, 0x25, 0 /* "#,##0%" */ |
79 }; | 82 }; |
80 static const UChar gLastResortScientificPat[] = { | 83 static const UChar gLastResortScientificPat[] = { |
81 0x23, 0x45, 0x30, 0 /* "#E0" */ | 84 0x23, 0x45, 0x30, 0 /* "#E0" */ |
82 }; | 85 }; |
83 static const UChar gLastResortIsoCurrencyPat[] = { | 86 static const UChar gLastResortIsoCurrencyPat[] = { |
84 0xA4, 0xA4, 0x23, 0x30, 0x2E, 0x30, 0x30, 0x3B, 0x28, 0xA4, 0xA4, 0x23, 0x30
, 0x2E, 0x30, 0x30, 0x29, 0 /* "\u00A4\u00A4#0.00;(\u00A4\u00A4#0.00)" */ | 87 0xA4, 0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0 /* "\u0
0A4\u00A4\u00A0#,##0.00" */ |
85 }; | 88 }; |
86 static const UChar gLastResortPluralCurrencyPat[] = { | 89 static const UChar gLastResortPluralCurrencyPat[] = { |
87 0x23, 0x30, 0x2E, 0x30, 0x30, 0xA0, 0xA4, 0xA4, 0xA4, 0 /* "#0.00\u00A0\u00A
4\u00A4\u00A4*/ | 90 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0x20, 0xA4, 0xA4, 0xA4
, 0 /* "#,##0.### \u00A4\u00A4\u00A4*/ |
| 91 }; |
| 92 static const UChar gLastResortAccountingCurrencyPat[] = { |
| 93 0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0 /* "\u00A4\u00
A0#,##0.00" */ |
88 }; | 94 }; |
89 | 95 |
90 static const UChar gSingleCurrencySign[] = {0xA4, 0}; | 96 static const UChar gSingleCurrencySign[] = {0xA4, 0}; |
91 static const UChar gDoubleCurrencySign[] = {0xA4, 0xA4, 0}; | 97 static const UChar gDoubleCurrencySign[] = {0xA4, 0xA4, 0}; |
92 | 98 |
93 static const UChar gSlash = 0x2f; | 99 static const UChar gSlash = 0x2f; |
94 | 100 |
95 // If the maximum base 10 exponent were 4, then the largest number would | 101 // If the maximum base 10 exponent were 4, then the largest number would |
96 // be 99,999 which has 5 digits. | 102 // be 99,999 which has 5 digits. |
97 // On IEEE754 systems gMaxIntegerDigits is 308 + possible denormalized 15 digits
+ rounding digit | 103 // On IEEE754 systems gMaxIntegerDigits is 308 + possible denormalized 15 digits
+ rounding digit |
98 // With big decimal, the max exponent is 999,999,999 and the max number of digit
s is the same, 999,999,999 | 104 // With big decimal, the max exponent is 999,999,999 and the max number of digit
s is the same, 999,999,999 |
99 const int32_t icu::NumberFormat::gDefaultMaxIntegerDigits = 2000000000; | 105 const int32_t icu::NumberFormat::gDefaultMaxIntegerDigits = 2000000000; |
100 const int32_t icu::NumberFormat::gDefaultMinIntegerDigits = 127; | 106 const int32_t icu::NumberFormat::gDefaultMinIntegerDigits = 127; |
101 | 107 |
102 static const UChar * const gLastResortNumberPatterns[UNUM_FORMAT_STYLE_COUNT] =
{ | 108 static const UChar * const gLastResortNumberPatterns[UNUM_FORMAT_STYLE_COUNT] =
{ |
103 NULL, // UNUM_PATTERN_DECIMAL | 109 NULL, // UNUM_PATTERN_DECIMAL |
104 gLastResortDecimalPat, // UNUM_DECIMAL | 110 gLastResortDecimalPat, // UNUM_DECIMAL |
105 gLastResortCurrencyPat, // UNUM_CURRENCY | 111 gLastResortCurrencyPat, // UNUM_CURRENCY |
106 gLastResortPercentPat, // UNUM_PERCENT | 112 gLastResortPercentPat, // UNUM_PERCENT |
107 gLastResortScientificPat, // UNUM_SCIENTIFIC | 113 gLastResortScientificPat, // UNUM_SCIENTIFIC |
108 NULL, // UNUM_SPELLOUT | 114 NULL, // UNUM_SPELLOUT |
109 NULL, // UNUM_ORDINAL | 115 NULL, // UNUM_ORDINAL |
110 NULL, // UNUM_DURATION | 116 NULL, // UNUM_DURATION |
111 NULL, // UNUM_NUMBERING_SYSTEM | 117 NULL, // UNUM_NUMBERING_SYSTEM |
112 NULL, // UNUM_PATTERN_RULEBASED | 118 NULL, // UNUM_PATTERN_RULEBASED |
113 gLastResortIsoCurrencyPat, // UNUM_CURRENCY_ISO | 119 gLastResortIsoCurrencyPat, // UNUM_CURRENCY_ISO |
114 gLastResortPluralCurrencyPat // UNUM_CURRENCY_PLURAL | 120 gLastResortPluralCurrencyPat, // UNUM_CURRENCY_PLURAL |
| 121 gLastResortAccountingCurrencyPat, // UNUM_CURRENCY_ACCOUNTING |
| 122 gLastResortCurrencyPat, // UNUM_CASH_CURRENCY |
115 }; | 123 }; |
116 | 124 |
117 // Keys used for accessing resource bundles | 125 // Keys used for accessing resource bundles |
118 | 126 |
119 static const char *gNumberElements = "NumberElements"; | 127 static const char *gNumberElements = "NumberElements"; |
120 static const char *gLatn = "latn"; | 128 static const char *gLatn = "latn"; |
121 static const char *gPatterns = "patterns"; | 129 static const char *gPatterns = "patterns"; |
122 static const char *gFormatKeys[UNUM_FORMAT_STYLE_COUNT] = { | 130 static const char *gFormatKeys[UNUM_FORMAT_STYLE_COUNT] = { |
123 NULL, // UNUM_PATTERN_DECIMAL | 131 NULL, // UNUM_PATTERN_DECIMAL |
124 "decimalFormat", // UNUM_DECIMAL | 132 "decimalFormat", // UNUM_DECIMAL |
125 "currencyFormat", // UNUM_CURRENCY | 133 "currencyFormat", // UNUM_CURRENCY |
126 "percentFormat", // UNUM_PERCENT | 134 "percentFormat", // UNUM_PERCENT |
127 "scientificFormat", // UNUM_SCIENTIFIC | 135 "scientificFormat", // UNUM_SCIENTIFIC |
128 NULL, // UNUM_SPELLOUT | 136 NULL, // UNUM_SPELLOUT |
129 NULL, // UNUM_ORDINAL | 137 NULL, // UNUM_ORDINAL |
130 NULL, // UNUM_DURATION | 138 NULL, // UNUM_DURATION |
131 NULL, // UNUM_NUMBERING_SYSTEM | 139 NULL, // UNUM_NUMBERING_SYSTEM |
132 NULL, // UNUM_PATTERN_RULEBASED | 140 NULL, // UNUM_PATTERN_RULEBASED |
133 // For UNUM_CURRENCY_ISO and UNUM_CURRENCY_PLURAL, | 141 // For UNUM_CURRENCY_ISO and UNUM_CURRENCY_PLURAL, |
134 // the pattern is the same as the pattern of UNUM_CURRENCY | 142 // the pattern is the same as the pattern of UNUM_CURRENCY |
135 // except for replacing the single currency sign with | 143 // except for replacing the single currency sign with |
136 // double currency sign or triple currency sign. | 144 // double currency sign or triple currency sign. |
137 "currencyFormat", // UNUM_CURRENCY_ISO | 145 "currencyFormat", // UNUM_CURRENCY_ISO |
138 "currencyFormat" // UNUM_CURRENCY_PLURAL | 146 "currencyFormat", // UNUM_CURRENCY_PLURAL |
| 147 "accountingFormat", // UNUM_CURRENCY_ACCOUNTING |
| 148 "currencyFormat" // UNUM_CASH_CURRENCY |
139 }; | 149 }; |
140 | 150 |
141 // Static hashtable cache of NumberingSystem objects used by NumberFormat | 151 // Static hashtable cache of NumberingSystem objects used by NumberFormat |
142 static UHashtable * NumberingSystem_cache = NULL; | 152 static UHashtable * NumberingSystem_cache = NULL; |
143 static UMutex nscacheMutex = U_MUTEX_INITIALIZER; | 153 static UMutex nscacheMutex = U_MUTEX_INITIALIZER; |
144 static icu::UInitOnce gNSCacheInitOnce = U_INITONCE_INITIALIZER; | 154 static icu::UInitOnce gNSCacheInitOnce = U_INITONCE_INITIALIZER; |
145 | 155 |
146 #if !UCONFIG_NO_SERVICE | 156 #if !UCONFIG_NO_SERVICE |
147 static icu::ICULocaleService* gService = NULL; | 157 static icu::ICULocaleService* gService = NULL; |
148 static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER; | 158 static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER; |
(...skipping 15 matching lines...) Expand all Loading... |
164 delete gService; | 174 delete gService; |
165 gService = NULL; | 175 gService = NULL; |
166 } | 176 } |
167 #endif | 177 #endif |
168 gNSCacheInitOnce.reset(); | 178 gNSCacheInitOnce.reset(); |
169 if (NumberingSystem_cache) { | 179 if (NumberingSystem_cache) { |
170 // delete NumberingSystem_cache; | 180 // delete NumberingSystem_cache; |
171 uhash_close(NumberingSystem_cache); | 181 uhash_close(NumberingSystem_cache); |
172 NumberingSystem_cache = NULL; | 182 NumberingSystem_cache = NULL; |
173 } | 183 } |
174 | |
175 return TRUE; | 184 return TRUE; |
176 } | 185 } |
177 U_CDECL_END | 186 U_CDECL_END |
178 | 187 |
179 // ***************************************************************************** | 188 // ***************************************************************************** |
180 // class NumberFormat | 189 // class NumberFormat |
181 // ***************************************************************************** | 190 // ***************************************************************************** |
182 | 191 |
183 U_NAMESPACE_BEGIN | 192 U_NAMESPACE_BEGIN |
184 | 193 |
(...skipping 29 matching lines...) Expand all Loading... |
214 | 223 |
215 // ------------------------------------- | 224 // ------------------------------------- |
216 // default constructor | 225 // default constructor |
217 NumberFormat::NumberFormat() | 226 NumberFormat::NumberFormat() |
218 : fGroupingUsed(TRUE), | 227 : fGroupingUsed(TRUE), |
219 fMaxIntegerDigits(gDefaultMaxIntegerDigits), | 228 fMaxIntegerDigits(gDefaultMaxIntegerDigits), |
220 fMinIntegerDigits(1), | 229 fMinIntegerDigits(1), |
221 fMaxFractionDigits(3), // invariant, >= minFractionDigits | 230 fMaxFractionDigits(3), // invariant, >= minFractionDigits |
222 fMinFractionDigits(0), | 231 fMinFractionDigits(0), |
223 fParseIntegerOnly(FALSE), | 232 fParseIntegerOnly(FALSE), |
224 fLenient(FALSE) | 233 fLenient(FALSE), |
| 234 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) |
225 { | 235 { |
226 fCurrency[0] = 0; | 236 fCurrency[0] = 0; |
227 } | 237 } |
228 | 238 |
229 // ------------------------------------- | 239 // ------------------------------------- |
230 | 240 |
231 NumberFormat::~NumberFormat() | 241 NumberFormat::~NumberFormat() |
232 { | 242 { |
233 } | 243 } |
234 | 244 |
| 245 SharedNumberFormat::~SharedNumberFormat() { |
| 246 delete ptr; |
| 247 } |
| 248 |
235 // ------------------------------------- | 249 // ------------------------------------- |
236 // copy constructor | 250 // copy constructor |
237 | 251 |
238 NumberFormat::NumberFormat(const NumberFormat &source) | 252 NumberFormat::NumberFormat(const NumberFormat &source) |
239 : Format(source) | 253 : Format(source) |
240 { | 254 { |
241 *this = source; | 255 *this = source; |
242 } | 256 } |
243 | 257 |
244 // ------------------------------------- | 258 // ------------------------------------- |
245 // assignment operator | 259 // assignment operator |
246 | 260 |
247 NumberFormat& | 261 NumberFormat& |
248 NumberFormat::operator=(const NumberFormat& rhs) | 262 NumberFormat::operator=(const NumberFormat& rhs) |
249 { | 263 { |
250 if (this != &rhs) | 264 if (this != &rhs) |
251 { | 265 { |
252 Format::operator=(rhs); | 266 Format::operator=(rhs); |
253 fGroupingUsed = rhs.fGroupingUsed; | 267 fGroupingUsed = rhs.fGroupingUsed; |
254 fMaxIntegerDigits = rhs.fMaxIntegerDigits; | 268 fMaxIntegerDigits = rhs.fMaxIntegerDigits; |
255 fMinIntegerDigits = rhs.fMinIntegerDigits; | 269 fMinIntegerDigits = rhs.fMinIntegerDigits; |
256 fMaxFractionDigits = rhs.fMaxFractionDigits; | 270 fMaxFractionDigits = rhs.fMaxFractionDigits; |
257 fMinFractionDigits = rhs.fMinFractionDigits; | 271 fMinFractionDigits = rhs.fMinFractionDigits; |
258 fParseIntegerOnly = rhs.fParseIntegerOnly; | 272 fParseIntegerOnly = rhs.fParseIntegerOnly; |
259 u_strncpy(fCurrency, rhs.fCurrency, 4); | 273 u_strncpy(fCurrency, rhs.fCurrency, 4); |
260 fLenient = rhs.fLenient; | 274 fLenient = rhs.fLenient; |
| 275 fCapitalizationContext = rhs.fCapitalizationContext; |
261 } | 276 } |
262 return *this; | 277 return *this; |
263 } | 278 } |
264 | 279 |
265 // ------------------------------------- | 280 // ------------------------------------- |
266 | 281 |
267 UBool | 282 UBool |
268 NumberFormat::operator==(const Format& that) const | 283 NumberFormat::operator==(const Format& that) const |
269 { | 284 { |
270 // Format::operator== guarantees this cast is safe | 285 // Format::operator== guarantees this cast is safe |
(...skipping 26 matching lines...) Expand all Loading... |
297 debug("fParseIntegerOnly != "); | 312 debug("fParseIntegerOnly != "); |
298 } | 313 } |
299 if (!(u_strcmp(fCurrency, other->fCurrency) == 0)) { | 314 if (!(u_strcmp(fCurrency, other->fCurrency) == 0)) { |
300 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | 315 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
301 debug("fCurrency !="); | 316 debug("fCurrency !="); |
302 } | 317 } |
303 if (!(fLenient == other->fLenient)) { | 318 if (!(fLenient == other->fLenient)) { |
304 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | 319 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
305 debug("fLenient != "); | 320 debug("fLenient != "); |
306 } | 321 } |
| 322 if (!(fCapitalizationContext == other->fCapitalizationContext)) { |
| 323 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
| 324 debug("fCapitalizationContext != "); |
| 325 } |
307 if (!first) { printf(" ]"); } | 326 if (!first) { printf(" ]"); } |
308 #endif | 327 #endif |
309 | 328 |
310 return ((this == &that) || | 329 return ((this == &that) || |
311 ((Format::operator==(that) && | 330 ((Format::operator==(that) && |
312 fMaxIntegerDigits == other->fMaxIntegerDigits && | 331 fMaxIntegerDigits == other->fMaxIntegerDigits && |
313 fMinIntegerDigits == other->fMinIntegerDigits && | 332 fMinIntegerDigits == other->fMinIntegerDigits && |
314 fMaxFractionDigits == other->fMaxFractionDigits && | 333 fMaxFractionDigits == other->fMaxFractionDigits && |
315 fMinFractionDigits == other->fMinFractionDigits && | 334 fMinFractionDigits == other->fMinFractionDigits && |
316 fGroupingUsed == other->fGroupingUsed && | 335 fGroupingUsed == other->fGroupingUsed && |
317 fParseIntegerOnly == other->fParseIntegerOnly && | 336 fParseIntegerOnly == other->fParseIntegerOnly && |
318 u_strcmp(fCurrency, other->fCurrency) == 0 && | 337 u_strcmp(fCurrency, other->fCurrency) == 0 && |
319 fLenient == other->fLenient))); | 338 fLenient == other->fLenient && |
| 339 fCapitalizationContext == other->fCapitalizationContext))); |
320 } | 340 } |
321 | 341 |
322 // ------------------------------------- | 342 // ------------------------------------- |
323 // Default implementation sets unsupported error; subclasses should | 343 // Default implementation sets unsupported error; subclasses should |
324 // override. | 344 // override. |
325 | 345 |
326 UnicodeString& | 346 UnicodeString& |
327 NumberFormat::format(double /* unused number */, | 347 NumberFormat::format(double /* unused number */, |
328 UnicodeString& toAppendTo, | 348 UnicodeString& toAppendTo, |
329 FieldPositionIterator* /* unused posIter */, | 349 FieldPositionIterator* /* unused posIter */, |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 { | 1013 { |
994 ICULocaleService *service = getNumberFormatService(); | 1014 ICULocaleService *service = getNumberFormatService(); |
995 if (service) { | 1015 if (service) { |
996 return service->getAvailableLocales(); | 1016 return service->getAvailableLocales(); |
997 } | 1017 } |
998 return NULL; // no way to return error condition | 1018 return NULL; // no way to return error condition |
999 } | 1019 } |
1000 #endif /* UCONFIG_NO_SERVICE */ | 1020 #endif /* UCONFIG_NO_SERVICE */ |
1001 // ------------------------------------- | 1021 // ------------------------------------- |
1002 | 1022 |
1003 NumberFormat* U_EXPORT2 | 1023 NumberFormat* |
1004 NumberFormat::createInstance(const Locale& loc, UNumberFormatStyle kind, UErrorC
ode& status) { | 1024 NumberFormat::internalCreateInstance(const Locale& loc, UNumberFormatStyle kind,
UErrorCode& status) { |
1005 #if !UCONFIG_NO_SERVICE | 1025 #if !UCONFIG_NO_SERVICE |
1006 if (haveService()) { | 1026 if (haveService()) { |
1007 return (NumberFormat*)gService->get(loc, kind, status); | 1027 return (NumberFormat*)gService->get(loc, kind, status); |
1008 } | 1028 } |
1009 #endif | 1029 #endif |
1010 return makeInstance(loc, kind, status); | 1030 return makeInstance(loc, kind, status); |
1011 } | 1031 } |
1012 | 1032 |
| 1033 NumberFormat* U_EXPORT2 |
| 1034 NumberFormat::createInstance(const Locale& loc, UNumberFormatStyle kind, UErrorC
ode& status) { |
| 1035 if (kind != UNUM_DECIMAL) { |
| 1036 return internalCreateInstance(loc, kind, status); |
| 1037 } |
| 1038 const SharedNumberFormat *shared = createSharedInstance(loc, kind, status); |
| 1039 if (U_FAILURE(status)) { |
| 1040 return NULL; |
| 1041 } |
| 1042 NumberFormat *result = static_cast<NumberFormat *>((*shared)->clone()); |
| 1043 shared->removeRef(); |
| 1044 if (result == NULL) { |
| 1045 status = U_MEMORY_ALLOCATION_ERROR; |
| 1046 } |
| 1047 return result; |
| 1048 } |
| 1049 |
1013 | 1050 |
1014 // ------------------------------------- | 1051 // ------------------------------------- |
1015 // Checks if the thousand/10 thousand grouping is used in the | 1052 // Checks if the thousand/10 thousand grouping is used in the |
1016 // NumberFormat instance. | 1053 // NumberFormat instance. |
1017 | 1054 |
1018 UBool | 1055 UBool |
1019 NumberFormat::isGroupingUsed() const | 1056 NumberFormat::isGroupingUsed() const |
1020 { | 1057 { |
1021 return fGroupingUsed; | 1058 return fGroupingUsed; |
1022 } | 1059 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 result[3] = 0; | 1180 result[3] = 0; |
1144 } else { | 1181 } else { |
1145 const char* loc = getLocaleID(ULOC_VALID_LOCALE, ec); | 1182 const char* loc = getLocaleID(ULOC_VALID_LOCALE, ec); |
1146 if (loc == NULL) { | 1183 if (loc == NULL) { |
1147 loc = uloc_getDefault(); | 1184 loc = uloc_getDefault(); |
1148 } | 1185 } |
1149 ucurr_forLocale(loc, result, 4, &ec); | 1186 ucurr_forLocale(loc, result, 4, &ec); |
1150 } | 1187 } |
1151 } | 1188 } |
1152 | 1189 |
| 1190 //---------------------------------------------------------------------- |
| 1191 |
| 1192 |
| 1193 void NumberFormat::setContext(UDisplayContext value, UErrorCode& status) |
| 1194 { |
| 1195 if (U_FAILURE(status)) |
| 1196 return; |
| 1197 if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZA
TION ) { |
| 1198 fCapitalizationContext = value; |
| 1199 } else { |
| 1200 status = U_ILLEGAL_ARGUMENT_ERROR; |
| 1201 } |
| 1202 } |
| 1203 |
| 1204 |
| 1205 UDisplayContext NumberFormat::getContext(UDisplayContextType type, UErrorCode& s
tatus) const |
| 1206 { |
| 1207 if (U_FAILURE(status)) |
| 1208 return (UDisplayContext)0; |
| 1209 if (type != UDISPCTX_TYPE_CAPITALIZATION) { |
| 1210 status = U_ILLEGAL_ARGUMENT_ERROR; |
| 1211 return (UDisplayContext)0; |
| 1212 } |
| 1213 return fCapitalizationContext; |
| 1214 } |
| 1215 |
| 1216 |
1153 // ------------------------------------- | 1217 // ------------------------------------- |
1154 // Creates the NumberFormat instance of the specified style (number, currency, | 1218 // Creates the NumberFormat instance of the specified style (number, currency, |
1155 // or percent) for the desired locale. | 1219 // or percent) for the desired locale. |
1156 | 1220 |
1157 static void U_CALLCONV nscacheInit() { | 1221 static void U_CALLCONV nscacheInit() { |
1158 U_ASSERT(NumberingSystem_cache == NULL); | 1222 U_ASSERT(NumberingSystem_cache == NULL); |
1159 ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup); | 1223 ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup); |
1160 UErrorCode status = U_ZERO_ERROR; | 1224 UErrorCode status = U_ZERO_ERROR; |
1161 NumberingSystem_cache = uhash_open(uhash_hashLong, | 1225 NumberingSystem_cache = uhash_open(uhash_hashLong, |
1162 uhash_compareLong, | 1226 uhash_compareLong, |
1163 NULL, | 1227 NULL, |
1164 &status); | 1228 &status); |
1165 if (U_FAILURE(status)) { | 1229 if (U_FAILURE(status)) { |
1166 // Number Format code will run with no cache if creation fails. | 1230 // Number Format code will run with no cache if creation fails. |
1167 NumberingSystem_cache = NULL; | 1231 NumberingSystem_cache = NULL; |
1168 return; | 1232 return; |
1169 } | 1233 } |
1170 uhash_setValueDeleter(NumberingSystem_cache, deleteNumberingSystem); | 1234 uhash_setValueDeleter(NumberingSystem_cache, deleteNumberingSystem); |
1171 } | 1235 } |
1172 | 1236 |
| 1237 template<> U_I18N_API |
| 1238 const SharedNumberFormat *LocaleCacheKey<SharedNumberFormat>::createObject( |
| 1239 const void * /*unused*/, UErrorCode &status) const { |
| 1240 const char *localeId = fLoc.getName(); |
| 1241 NumberFormat *nf = NumberFormat::internalCreateInstance( |
| 1242 localeId, UNUM_DECIMAL, status); |
| 1243 if (U_FAILURE(status)) { |
| 1244 return NULL; |
| 1245 } |
| 1246 SharedNumberFormat *result = new SharedNumberFormat(nf); |
| 1247 if (result == NULL) { |
| 1248 status = U_MEMORY_ALLOCATION_ERROR; |
| 1249 delete nf; |
| 1250 return NULL; |
| 1251 } |
| 1252 result->addRef(); |
| 1253 return result; |
| 1254 } |
| 1255 |
| 1256 const SharedNumberFormat* U_EXPORT2 |
| 1257 NumberFormat::createSharedInstance(const Locale& loc, UNumberFormatStyle kind, U
ErrorCode& status) { |
| 1258 if (U_FAILURE(status)) { |
| 1259 return NULL; |
| 1260 } |
| 1261 if (kind != UNUM_DECIMAL) { |
| 1262 status = U_UNSUPPORTED_ERROR; |
| 1263 return NULL; |
| 1264 } |
| 1265 const SharedNumberFormat *result = NULL; |
| 1266 UnifiedCache::getByLocale(loc, result, status); |
| 1267 return result; |
| 1268 } |
| 1269 |
1173 UBool | 1270 UBool |
1174 NumberFormat::isStyleSupported(UNumberFormatStyle style) { | 1271 NumberFormat::isStyleSupported(UNumberFormatStyle style) { |
1175 return gLastResortNumberPatterns[style] != NULL; | 1272 return gLastResortNumberPatterns[style] != NULL; |
1176 } | 1273 } |
1177 | 1274 |
1178 NumberFormat* | 1275 NumberFormat* |
1179 NumberFormat::makeInstance(const Locale& desiredLocale, | 1276 NumberFormat::makeInstance(const Locale& desiredLocale, |
1180 UNumberFormatStyle style, | 1277 UNumberFormatStyle style, |
1181 UErrorCode& status) { | 1278 UErrorCode& status) { |
1182 return makeInstance(desiredLocale, style, false, status); | 1279 return makeInstance(desiredLocale, style, false, status); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 UBool curr = TRUE; | 1313 UBool curr = TRUE; |
1217 | 1314 |
1218 switch (style) { | 1315 switch (style) { |
1219 case UNUM_DECIMAL: | 1316 case UNUM_DECIMAL: |
1220 curr = FALSE; | 1317 curr = FALSE; |
1221 // fall-through | 1318 // fall-through |
1222 | 1319 |
1223 case UNUM_CURRENCY: | 1320 case UNUM_CURRENCY: |
1224 case UNUM_CURRENCY_ISO: // do not support plural formatting here | 1321 case UNUM_CURRENCY_ISO: // do not support plural formatting here |
1225 case UNUM_CURRENCY_PLURAL: | 1322 case UNUM_CURRENCY_PLURAL: |
| 1323 case UNUM_CURRENCY_ACCOUNTING: |
| 1324 case UNUM_CASH_CURRENCY: |
1226 f = new Win32NumberFormat(desiredLocale, curr, status); | 1325 f = new Win32NumberFormat(desiredLocale, curr, status); |
1227 | 1326 |
1228 if (U_SUCCESS(status)) { | 1327 if (U_SUCCESS(status)) { |
1229 return f; | 1328 return f; |
1230 } | 1329 } |
1231 | 1330 |
1232 delete f; | 1331 delete f; |
1233 break; | 1332 break; |
1234 default: | 1333 default: |
1235 break; | 1334 break; |
(...skipping 29 matching lines...) Expand all Loading... |
1265 | 1364 |
1266 if (mustBeDecimalFormat && ns->isAlgorithmic()) { | 1365 if (mustBeDecimalFormat && ns->isAlgorithmic()) { |
1267 status = U_UNSUPPORTED_ERROR; | 1366 status = U_UNSUPPORTED_ERROR; |
1268 return NULL; | 1367 return NULL; |
1269 } | 1368 } |
1270 | 1369 |
1271 LocalPointer<DecimalFormatSymbols> symbolsToAdopt; | 1370 LocalPointer<DecimalFormatSymbols> symbolsToAdopt; |
1272 UnicodeString pattern; | 1371 UnicodeString pattern; |
1273 LocalUResourceBundlePointer ownedResource(ures_open(NULL, desiredLocale.getN
ame(), &status)); | 1372 LocalUResourceBundlePointer ownedResource(ures_open(NULL, desiredLocale.getN
ame(), &status)); |
1274 if (U_FAILURE(status)) { | 1373 if (U_FAILURE(status)) { |
1275 // We don't appear to have resource data available -- use the last-resor
t data | 1374 return NULL; |
1276 status = U_USING_FALLBACK_WARNING; | |
1277 // When the data is unavailable, and locale isn't passed in, last resort
data is used. | |
1278 symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(status)); | |
1279 if (symbolsToAdopt.isNull()) { | |
1280 status = U_MEMORY_ALLOCATION_ERROR; | |
1281 return NULL; | |
1282 } | |
1283 | |
1284 // Creates a DecimalFormat instance with the last resort number patterns
. | |
1285 pattern.setTo(TRUE, gLastResortNumberPatterns[style], -1); | |
1286 } | 1375 } |
1287 else { | 1376 else { |
1288 // Loads the decimal symbols of the desired locale. | 1377 // Loads the decimal symbols of the desired locale. |
1289 symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(desiredLocale, stat
us)); | 1378 symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(desiredLocale, stat
us)); |
1290 if (symbolsToAdopt.isNull()) { | 1379 if (symbolsToAdopt.isNull()) { |
1291 status = U_MEMORY_ALLOCATION_ERROR; | 1380 status = U_MEMORY_ALLOCATION_ERROR; |
1292 return NULL; | 1381 return NULL; |
1293 } | 1382 } |
1294 | 1383 |
1295 UResourceBundle *resource = ownedResource.orphan(); | 1384 UResourceBundle *resource = ownedResource.orphan(); |
(...skipping 14 matching lines...) Expand all Loading... |
1310 } | 1399 } |
1311 | 1400 |
1312 ures_close(numElements); | 1401 ures_close(numElements); |
1313 | 1402 |
1314 // Creates the specified decimal format style of the desired locale. | 1403 // Creates the specified decimal format style of the desired locale. |
1315 pattern.setTo(TRUE, patResStr, patLen); | 1404 pattern.setTo(TRUE, patResStr, patLen); |
1316 } | 1405 } |
1317 if (U_FAILURE(status)) { | 1406 if (U_FAILURE(status)) { |
1318 return NULL; | 1407 return NULL; |
1319 } | 1408 } |
1320 if(style==UNUM_CURRENCY || style == UNUM_CURRENCY_ISO){ | 1409 if(style==UNUM_CURRENCY || style == UNUM_CURRENCY_ISO || style == UNUM_CURRE
NCY_ACCOUNTING |
| 1410 || style == UNUM_CASH_CURRENCY){ |
1321 const UChar* currPattern = symbolsToAdopt->getCurrencyPattern(); | 1411 const UChar* currPattern = symbolsToAdopt->getCurrencyPattern(); |
1322 if(currPattern!=NULL){ | 1412 if(currPattern!=NULL){ |
1323 pattern.setTo(currPattern, u_strlen(currPattern)); | 1413 pattern.setTo(currPattern, u_strlen(currPattern)); |
1324 } | 1414 } |
1325 } | 1415 } |
1326 | 1416 |
1327 | 1417 |
1328 NumberFormat *f; | 1418 NumberFormat *f; |
1329 if (ns->isAlgorithmic()) { | 1419 if (ns->isAlgorithmic()) { |
1330 UnicodeString nsDesc; | 1420 UnicodeString nsDesc; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 } else { | 1454 } else { |
1365 // replace single currency sign in the pattern with double currency sign | 1455 // replace single currency sign in the pattern with double currency sign |
1366 // if the style is UNUM_CURRENCY_ISO | 1456 // if the style is UNUM_CURRENCY_ISO |
1367 if (style == UNUM_CURRENCY_ISO) { | 1457 if (style == UNUM_CURRENCY_ISO) { |
1368 pattern.findAndReplace(UnicodeString(TRUE, gSingleCurrencySign, 1), | 1458 pattern.findAndReplace(UnicodeString(TRUE, gSingleCurrencySign, 1), |
1369 UnicodeString(TRUE, gDoubleCurrencySign, 2)); | 1459 UnicodeString(TRUE, gDoubleCurrencySign, 2)); |
1370 } | 1460 } |
1371 | 1461 |
1372 // "new DecimalFormat()" does not adopt the symbols if its memory alloca
tion fails. | 1462 // "new DecimalFormat()" does not adopt the symbols if its memory alloca
tion fails. |
1373 DecimalFormatSymbols *syms = symbolsToAdopt.orphan(); | 1463 DecimalFormatSymbols *syms = symbolsToAdopt.orphan(); |
1374 f = new DecimalFormat(pattern, syms, style, status); | 1464 DecimalFormat* df = new DecimalFormat(pattern, syms, style, status); |
| 1465 |
| 1466 // if it is cash currency style, setCurrencyUsage with usage |
| 1467 if (style == UNUM_CASH_CURRENCY){ |
| 1468 df->setCurrencyUsage(UCURR_USAGE_CASH, &status); |
| 1469 } |
| 1470 |
| 1471 if (U_FAILURE(status)) { |
| 1472 delete df; |
| 1473 return NULL; |
| 1474 } |
| 1475 |
| 1476 f = df; |
1375 if (f == NULL) { | 1477 if (f == NULL) { |
1376 delete syms; | 1478 delete syms; |
1377 status = U_MEMORY_ALLOCATION_ERROR; | 1479 status = U_MEMORY_ALLOCATION_ERROR; |
1378 return NULL; | 1480 return NULL; |
1379 } | 1481 } |
1380 } | 1482 } |
1381 | 1483 |
1382 f->setLocaleIDs(ures_getLocaleByType(ownedResource.getAlias(), ULOC_VALID_LO
CALE, &status), | 1484 f->setLocaleIDs(ures_getLocaleByType(ownedResource.getAlias(), ULOC_VALID_LO
CALE, &status), |
1383 ures_getLocaleByType(ownedResource.getAlias(), ULOC_ACTUAL_L
OCALE, &status)); | 1485 ures_getLocaleByType(ownedResource.getAlias(), ULOC_ACTUAL_L
OCALE, &status)); |
1384 if (U_FAILURE(status)) { | 1486 if (U_FAILURE(status)) { |
1385 delete f; | 1487 delete f; |
1386 return NULL; | 1488 return NULL; |
1387 } | 1489 } |
1388 return f; | 1490 return f; |
1389 } | 1491 } |
1390 | 1492 |
1391 U_NAMESPACE_END | 1493 U_NAMESPACE_END |
1392 | 1494 |
1393 #endif /* #if !UCONFIG_NO_FORMATTING */ | 1495 #endif /* #if !UCONFIG_NO_FORMATTING */ |
1394 | 1496 |
1395 //eof | 1497 //eof |
OLD | NEW |