| 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 |