1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* Copyright (C) 1997-2014, International Business Machines Corporation and
459d709d503bab6e2b61931737e662dd293b40578ccornelius* others. All Rights Reserved.
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File NUMFMT.CPP
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History:
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Date        Name        Description
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   02/19/97    aliu        Converted from java.
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   03/18/97    clhuang     Implemented with C++ APIs.
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/17/97    aliu        Enlarged MAX_INTEGER_DIGITS to fully accomodate the
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           largest double, by default.
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           Changed DigitCount to int per code review.
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*    07/20/98    stephen        Changed operator== to check for grouping
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            Changed setMaxIntegerDigits per Java implementation.
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            Changed setMinIntegerDigits per Java implementation.
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            Changed setMinFractionDigits per Java implementation.
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            Changed setMaxFractionDigits per Java implementation.
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************************
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/numfmt.h"
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/locid.h"
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/dcfmtsym.h"
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/decimfmt.h"
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h"
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ucurr.h"
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/curramt.h"
36b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/numsys.h"
37b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/rbnf.h"
38103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/localpointer.h"
39fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/udisplaycontext.h"
40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "charstr.h"
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "winnmfmt.h"
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresimp.h"
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uhash.h"
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "servloc.h"
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_in.h"
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h"
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h"
4959d709d503bab6e2b61931737e662dd293b40578ccornelius#include "uassert.h"
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "umutex.h"
51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "mutex.h"
5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "digitlst.h"
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <float.h>
54fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "sharednumberformat.h"
55fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "lrucache.h"
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//#define FMT_DEBUG
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef FMT_DEBUG
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h>
61103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline void debugout(UnicodeString s) {
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char buf[2000];
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    s.extract((int32_t) 0, s.length(), buf);
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    printf("%s", buf);
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define debug(x) printf("%s", x);
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define debugout(x)
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define debug(x)
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// If no number pattern can be located for a locale, this is the last
73fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// resort. The patterns are same as the ones in root locale.
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar gLastResortDecimalPat[] = {
75fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0 /* "#,##0.###" */
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar gLastResortCurrencyPat[] = {
78fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0 /* "\u00A4\u00A0#,##0.00" */
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar gLastResortPercentPat[] = {
81fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    0x23, 0x2C, 0x23, 0x23, 0x30, 0x25, 0 /* "#,##0%" */
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar gLastResortScientificPat[] = {
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    0x23, 0x45, 0x30, 0 /* "#E0" */
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
86b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gLastResortIsoCurrencyPat[] = {
87fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    0xA4, 0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0  /* "\u00A4\u00A4\u00A0#,##0.00" */
88b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru};
89b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gLastResortPluralCurrencyPat[] = {
90fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0x20, 0xA4, 0xA4, 0xA4, 0 /* "#,##0.### \u00A4\u00A4\u00A4*/
91fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius};
92fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic const UChar gLastResortAccountingCurrencyPat[] =  {
93fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0 /* "\u00A4\u00A0#,##0.00" */
94b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru};
95b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
96b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gSingleCurrencySign[] = {0xA4, 0};
97b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gDoubleCurrencySign[] = {0xA4, 0xA4, 0};
98b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
99b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gSlash = 0x2f;
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// If the maximum base 10 exponent were 4, then the largest number would
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// be 99,999 which has 5 digits.
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// On IEEE754 systems gMaxIntegerDigits is 308 + possible denormalized 15 digits + rounding digit
10459d709d503bab6e2b61931737e662dd293b40578ccornelius// With big decimal, the max exponent is 999,999,999 and the max number of digits is the same, 999,999,999
10559d709d503bab6e2b61931737e662dd293b40578ccorneliusconst int32_t icu::NumberFormat::gDefaultMaxIntegerDigits = 2000000000;
10659d709d503bab6e2b61931737e662dd293b40578ccorneliusconst int32_t icu::NumberFormat::gDefaultMinIntegerDigits = 127;
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar * const gLastResortNumberPatterns[UNUM_FORMAT_STYLE_COUNT] = {
109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_PATTERN_DECIMAL
110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    gLastResortDecimalPat,  // UNUM_DECIMAL
111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    gLastResortCurrencyPat,  // UNUM_CURRENCY
112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    gLastResortPercentPat,  // UNUM_PERCENT
113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    gLastResortScientificPat,  // UNUM_SCIENTIFIC
114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_SPELLOUT
115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_ORDINAL
116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_DURATION
117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_NUMBERING_SYSTEM
118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_PATTERN_RULEBASED
119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    gLastResortIsoCurrencyPat,  // UNUM_CURRENCY_ISO
120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    gLastResortPluralCurrencyPat,  // UNUM_CURRENCY_PLURAL
121fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    gLastResortAccountingCurrencyPat // UNUM_CURRENCY_ACCOUNTING
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
12427f654740f2a26ad62a5c155af9199af9e69b889claireho// Keys used for accessing resource bundles
12527f654740f2a26ad62a5c155af9199af9e69b889claireho
12627f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char *gNumberElements = "NumberElements";
12727f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char *gLatn = "latn";
12827f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char *gPatterns = "patterns";
129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char *gFormatKeys[UNUM_FORMAT_STYLE_COUNT] = {
130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_PATTERN_DECIMAL
131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    "decimalFormat",  // UNUM_DECIMAL
132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    "currencyFormat",  // UNUM_CURRENCY
133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    "percentFormat",  // UNUM_PERCENT
134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    "scientificFormat",  // UNUM_SCIENTIFIC
135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_SPELLOUT
136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_ORDINAL
137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_DURATION
138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_NUMBERING_SYSTEM
139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NULL,  // UNUM_PATTERN_RULEBASED
140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // For UNUM_CURRENCY_ISO and UNUM_CURRENCY_PLURAL,
141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // the pattern is the same as the pattern of UNUM_CURRENCY
142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // except for replacing the single currency sign with
143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // double currency sign or triple currency sign.
144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    "currencyFormat",  // UNUM_CURRENCY_ISO
145fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    "currencyFormat",  // UNUM_CURRENCY_PLURAL
146fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    "accountingFormat"  // UNUM_CURRENCY_ACCOUNTING
147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho};
14827f654740f2a26ad62a5c155af9199af9e69b889claireho
149fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic icu::LRUCache *gNumberFormatCache = NULL;
150fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UMutex gNumberFormatCacheMutex = U_MUTEX_INITIALIZER;
151fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic icu::UInitOnce gNumberFormatCacheInitOnce = U_INITONCE_INITIALIZER;
152fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Static hashtable cache of NumberingSystem objects used by NumberFormat
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UHashtable * NumberingSystem_cache = NULL;
15554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex nscacheMutex = U_MUTEX_INITIALIZER;
15659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gNSCacheInitOnce = U_INITONCE_INITIALIZER;
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCONFIG_NO_SERVICE
159103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic icu::ICULocaleService* gService = NULL;
16059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER;
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Release all static memory held by Number Format.
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_BEGIN
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void U_CALLCONV
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehodeleteNumberingSystem(void *obj) {
169103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete (icu::NumberingSystem *)obj;
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV numfmt_cleanup(void) {
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCONFIG_NO_SERVICE
17459d709d503bab6e2b61931737e662dd293b40578ccornelius    gServiceInitOnce.reset();
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (gService) {
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete gService;
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        gService = NULL;
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
18059d709d503bab6e2b61931737e662dd293b40578ccornelius    gNSCacheInitOnce.reset();
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (NumberingSystem_cache) {
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // delete NumberingSystem_cache;
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uhash_close(NumberingSystem_cache);
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        NumberingSystem_cache = NULL;
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
186fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    gNumberFormatCacheInitOnce.reset();
187fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (gNumberFormatCache) {
188fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        delete gNumberFormatCache;
189fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        gNumberFormatCache = NULL;
190fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return TRUE;
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_END
19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// *****************************************************************************
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// class NumberFormat
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// *****************************************************************************
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(NumberFormat)
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// SimpleNumberFormatFactory implementation
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormatFactory::~NumberFormatFactory() {}
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSimpleNumberFormatFactory::SimpleNumberFormatFactory(const Locale& locale, UBool visible)
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    : _visible(visible)
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    LocaleUtility::initNameFromLocale(locale, _id);
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSimpleNumberFormatFactory::~SimpleNumberFormatFactory() {}
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool SimpleNumberFormatFactory::visible(void) const {
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return _visible;
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UnicodeString *
22050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleNumberFormatFactory::getSupportedIDs(int32_t &count, UErrorCode& status) const
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count = 1;
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return &_id;
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    count = 0;
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return NULL;
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_SERVICE */
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// default constructor
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::NumberFormat()
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru:   fGroupingUsed(TRUE),
23559d709d503bab6e2b61931737e662dd293b40578ccornelius    fMaxIntegerDigits(gDefaultMaxIntegerDigits),
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMinIntegerDigits(1),
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMaxFractionDigits(3), // invariant, >= minFractionDigits
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMinFractionDigits(0),
239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fParseIntegerOnly(FALSE),
240fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fLenient(FALSE),
241fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fCurrency[0] = 0;
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::~NumberFormat()
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
252fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusSharedNumberFormat::~SharedNumberFormat() {
253fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    delete ptr;
254fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
255fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// copy constructor
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::NumberFormat(const NumberFormat &source)
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru:   Format(source)
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *this = source;
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// assignment operator
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat&
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::operator=(const NumberFormat& rhs)
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (this != &rhs)
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        Format::operator=(rhs);
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fGroupingUsed = rhs.fGroupingUsed;
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMaxIntegerDigits = rhs.fMaxIntegerDigits;
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMinIntegerDigits = rhs.fMinIntegerDigits;
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMaxFractionDigits = rhs.fMaxFractionDigits;
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMinFractionDigits = rhs.fMinFractionDigits;
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fParseIntegerOnly = rhs.fParseIntegerOnly;
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        u_strncpy(fCurrency, rhs.fCurrency, 4);
281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fLenient = rhs.fLenient;
282fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        fCapitalizationContext = rhs.fCapitalizationContext;
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return *this;
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::operator==(const Format& that) const
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Format::operator== guarantees this cast is safe
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormat* other = (NumberFormat*)&that;
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef FMT_DEBUG
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // This code makes it easy to determine why two format objects that should
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // be equal aren't.
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool first = TRUE;
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!Format::operator==(that)) {
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Format::!=");
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(fMaxIntegerDigits == other->fMaxIntegerDigits &&
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          fMinIntegerDigits == other->fMinIntegerDigits)) {
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Integer digits !=");
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(fMaxFractionDigits == other->fMaxFractionDigits &&
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          fMinFractionDigits == other->fMinFractionDigits)) {
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Fraction digits !=");
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(fGroupingUsed == other->fGroupingUsed)) {
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("fGroupingUsed != ");
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(fParseIntegerOnly == other->fParseIntegerOnly)) {
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("fParseIntegerOnly != ");
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(u_strcmp(fCurrency, other->fCurrency) == 0)) {
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("fCurrency !=");
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (!(fLenient == other->fLenient)) {
326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        debug("fLenient != ");
328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
329fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (!(fCapitalizationContext == other->fCapitalizationContext)) {
330fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
331fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        debug("fCapitalizationContext != ");
332fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!first) { printf(" ]"); }
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ((this == &that) ||
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ((Format::operator==(that) &&
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fMaxIntegerDigits == other->fMaxIntegerDigits &&
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fMinIntegerDigits == other->fMinIntegerDigits &&
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fMaxFractionDigits == other->fMaxFractionDigits &&
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fMinFractionDigits == other->fMinFractionDigits &&
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fGroupingUsed == other->fGroupingUsed &&
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fParseIntegerOnly == other->fParseIntegerOnly &&
344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho              u_strcmp(fCurrency, other->fCurrency) == 0 &&
345fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius              fLenient == other->fLenient &&
346fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius              fCapitalizationContext == other->fCapitalizationContext)));
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Default implementation sets unsupported error; subclasses should
35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// override.
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
35450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNumberFormat::format(double /* unused number */,
35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UnicodeString& toAppendTo,
35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     FieldPositionIterator* /* unused posIter */,
35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UErrorCode& status) const
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(status)) {
36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_UNSUPPORTED_ERROR;
36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return toAppendTo;
36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Default implementation sets unsupported error; subclasses should
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// override.
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
37050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNumberFormat::format(int32_t /* unused number */,
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UnicodeString& toAppendTo,
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     FieldPositionIterator* /* unused posIter */,
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UErrorCode& status) const
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(status)) {
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_UNSUPPORTED_ERROR;
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return toAppendTo;
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Default implementation sets unsupported error; subclasses should
38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// override.
38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
38550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
38650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNumberFormat::format(int64_t /* unused number */,
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UnicodeString& toAppendTo,
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     FieldPositionIterator* /* unused posIter */,
38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UErrorCode& status) const
39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(status)) {
39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_UNSUPPORTED_ERROR;
39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return toAppendTo;
39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
39754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// ------------------------------------------
39854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// These functions add the status code, just fall back to the non-status versions
39954dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString&
40054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusNumberFormat::format(double number,
40154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     UnicodeString& appendTo,
40254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     FieldPosition& pos,
40354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     UErrorCode &status) const {
40454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if(U_SUCCESS(status)) {
40554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return format(number,appendTo,pos);
40654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    } else {
40754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return appendTo;
40854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
40954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
41054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
41154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString&
41254dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusNumberFormat::format(int32_t number,
41354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     UnicodeString& appendTo,
41454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     FieldPosition& pos,
41554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     UErrorCode &status) const {
41654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if(U_SUCCESS(status)) {
41754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return format(number,appendTo,pos);
41854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    } else {
41954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return appendTo;
42054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
42154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
42254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
42354dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString&
42454dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusNumberFormat::format(int64_t number,
42554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     UnicodeString& appendTo,
42654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     FieldPosition& pos,
42754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                     UErrorCode &status) const {
42854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if(U_SUCCESS(status)) {
42954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return format(number,appendTo,pos);
43054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    } else {
43154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return appendTo;
43254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
43354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
43454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
43554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
43654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Decimal Number format() default implementation
43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Subclasses do not normally override this function, but rather the DigitList
44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// formatting functions..
44150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//   The expected call chain from here is
44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//      this function ->
44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//      NumberFormat::format(Formattable  ->
44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//      DecimalFormat::format(DigitList
44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//   Or, for subclasses of Formattable that do not know about DigitList,
44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//       this Function ->
44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//       NumberFormat::format(Formattable  ->
44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//       NumberFormat::format(DigitList  ->
45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//       XXXFormat::format(double
45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
45250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
45350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNumberFormat::format(const StringPiece &decimalNum,
45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UnicodeString& toAppendTo,
45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     FieldPositionIterator* fpi,
45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UErrorCode& status) const
45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    Formattable f;
45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    f.setDecimalNumber(decimalNum, status);
46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    format(f, toAppendTo, fpi, status);
46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return toAppendTo;
46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
46459d709d503bab6e2b61931737e662dd293b40578ccornelius/**
46559d709d503bab6e2b61931737e662dd293b40578ccornelius *
46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Formats the number object and save the format
46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// result in the toAppendTo string buffer.
46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// utility to save/restore state, used in two overloads
47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// of format(const Formattable&...) below.
47159d709d503bab6e2b61931737e662dd293b40578ccornelius*
47259d709d503bab6e2b61931737e662dd293b40578ccornelius* Old purpose of ArgExtractor was to avoid const. Not thread safe!
47359d709d503bab6e2b61931737e662dd293b40578ccornelius*
47459d709d503bab6e2b61931737e662dd293b40578ccornelius* keeping it around as a shim.
47559d709d503bab6e2b61931737e662dd293b40578ccornelius*/
47650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass ArgExtractor {
47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  const Formattable* num;
47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  UChar save[4];
47959d709d503bab6e2b61931737e662dd293b40578ccornelius  UBool fWasCurrency;
48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho public:
48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  ArgExtractor(const NumberFormat& nf, const Formattable& obj, UErrorCode& status);
48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  ~ArgExtractor();
48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  const Formattable* number(void) const;
48659d709d503bab6e2b61931737e662dd293b40578ccornelius  const UChar *iso(void) const;
48759d709d503bab6e2b61931737e662dd293b40578ccornelius  UBool wasCurrency(void) const;
48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoinline const Formattable*
49150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoArgExtractor::number(void) const {
49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  return num;
49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
49559d709d503bab6e2b61931737e662dd293b40578ccorneliusinline UBool
49659d709d503bab6e2b61931737e662dd293b40578ccorneliusArgExtractor::wasCurrency(void) const {
49759d709d503bab6e2b61931737e662dd293b40578ccornelius  return fWasCurrency;
49859d709d503bab6e2b61931737e662dd293b40578ccornelius}
49959d709d503bab6e2b61931737e662dd293b40578ccornelius
50059d709d503bab6e2b61931737e662dd293b40578ccorneliusinline const UChar *
50159d709d503bab6e2b61931737e662dd293b40578ccorneliusArgExtractor::iso(void) const {
50259d709d503bab6e2b61931737e662dd293b40578ccornelius  return save;
50359d709d503bab6e2b61931737e662dd293b40578ccornelius}
50459d709d503bab6e2b61931737e662dd293b40578ccornelius
50559d709d503bab6e2b61931737e662dd293b40578ccorneliusArgExtractor::ArgExtractor(const NumberFormat& /*nf*/, const Formattable& obj, UErrorCode& /*status*/)
50659d709d503bab6e2b61931737e662dd293b40578ccornelius  : num(&obj), fWasCurrency(FALSE) {
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UObject* o = obj.getObject(); // most commonly o==NULL
50927f654740f2a26ad62a5c155af9199af9e69b889claireho    const CurrencyAmount* amt;
51027f654740f2a26ad62a5c155af9199af9e69b889claireho    if (o != NULL && (amt = dynamic_cast<const CurrencyAmount*>(o)) != NULL) {
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // getISOCurrency() returns a pointer to internal storage, so we
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // copy it to retain it across the call to setCurrency().
51359d709d503bab6e2b61931737e662dd293b40578ccornelius        //const UChar* curr = amt->getISOCurrency();
51459d709d503bab6e2b61931737e662dd293b40578ccornelius        u_strcpy(save, amt->getISOCurrency());
51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        num = &amt->getNumber();
51659d709d503bab6e2b61931737e662dd293b40578ccornelius        fWasCurrency=TRUE;
51759d709d503bab6e2b61931737e662dd293b40578ccornelius    } else {
51859d709d503bab6e2b61931737e662dd293b40578ccornelius      save[0]=0;
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
52050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
52250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoArgExtractor::~ArgExtractor() {
52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString& NumberFormat::format(const DigitList &number,
52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UnicodeString& appendTo,
52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      FieldPositionIterator* posIter,
52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UErrorCode& status) const {
52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // DecimalFormat overrides this function, and handles DigitList based big decimals.
53050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Other subclasses (ChoiceFormat, RuleBasedNumberFormat) do not (yet) handle DigitLists,
53150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // so this default implementation falls back to formatting decimal numbers as doubles.
53250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
53350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return appendTo;
53450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    double dnum = number.getDouble();
53650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    format(dnum, appendTo, posIter, status);
53750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return appendTo;
53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
53950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
54150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
54250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
54350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNumberFormat::format(const DigitList &number,
54450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UnicodeString& appendTo,
54550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     FieldPosition& pos,
54650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UErrorCode &status) const {
54750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // DecimalFormat overrides this function, and handles DigitList based big decimals.
54850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Other subclasses (ChoiceFormat, RuleBasedNumberFormat) do not (yet) handle DigitLists,
54950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // so this default implementation falls back to formatting decimal numbers as doubles.
55050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return appendTo;
55250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
55350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    double dnum = number.getDouble();
55450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    format(dnum, appendTo, pos, status);
55550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return appendTo;
55650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
55850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
55950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNumberFormat::format(const Formattable& obj,
56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UnicodeString& appendTo,
56150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        FieldPosition& pos,
56250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UErrorCode& status) const
56350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) return appendTo;
56550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
56650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ArgExtractor arg(*this, obj, status);
56750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const Formattable *n = arg.number();
56859d709d503bab6e2b61931737e662dd293b40578ccornelius    const UChar *iso = arg.iso();
56959d709d503bab6e2b61931737e662dd293b40578ccornelius
57059d709d503bab6e2b61931737e662dd293b40578ccornelius    if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) {
57159d709d503bab6e2b61931737e662dd293b40578ccornelius      // trying to format a different currency.
57259d709d503bab6e2b61931737e662dd293b40578ccornelius      // Right now, we clone.
57359d709d503bab6e2b61931737e662dd293b40578ccornelius      LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone());
57459d709d503bab6e2b61931737e662dd293b40578ccornelius      cloneFmt->setCurrency(iso, status);
57559d709d503bab6e2b61931737e662dd293b40578ccornelius      // next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount.
57659d709d503bab6e2b61931737e662dd293b40578ccornelius      return cloneFmt->format(*n, appendTo, pos, status);
57759d709d503bab6e2b61931737e662dd293b40578ccornelius    }
57850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (n->isNumeric() && n->getDigitList() != NULL) {
58050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Decimal Number.  We will have a DigitList available if the value was
58150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //   set to a decimal number, or if the value originated with a parse.
58250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
58350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // The default implementation for formatting a DigitList converts it
58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // to a double, and formats that, allowing formatting classes that don't
58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // know about DigitList to continue to operate as they had.
58650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
58750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // DecimalFormat overrides the DigitList formatting functions.
58850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        format(*n->getDigitList(), appendTo, pos, status);
58950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
59050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        switch (n->getType()) {
59150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case Formattable::kDouble:
59250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            format(n->getDouble(), appendTo, pos);
59350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
59450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case Formattable::kLong:
59550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            format(n->getLong(), appendTo, pos);
59650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
59750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case Formattable::kInt64:
59850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            format(n->getInt64(), appendTo, pos);
59950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
60050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        default:
60150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            status = U_INVALID_FORMAT_ERROR;
60250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
60350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
60450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
60550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
60650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return appendTo;
60750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
60850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
60950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------x
61050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Formats the number object and save the format
61150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// result in the toAppendTo string buffer.
61250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
61350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
61450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNumberFormat::format(const Formattable& obj,
61550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UnicodeString& appendTo,
61650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        FieldPositionIterator* posIter,
61750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UErrorCode& status) const
61850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
61950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) return appendTo;
62050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
62150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ArgExtractor arg(*this, obj, status);
62250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const Formattable *n = arg.number();
62359d709d503bab6e2b61931737e662dd293b40578ccornelius    const UChar *iso = arg.iso();
62459d709d503bab6e2b61931737e662dd293b40578ccornelius
62559d709d503bab6e2b61931737e662dd293b40578ccornelius    if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) {
62659d709d503bab6e2b61931737e662dd293b40578ccornelius      // trying to format a different currency.
62759d709d503bab6e2b61931737e662dd293b40578ccornelius      // Right now, we clone.
62859d709d503bab6e2b61931737e662dd293b40578ccornelius      LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone());
62959d709d503bab6e2b61931737e662dd293b40578ccornelius      cloneFmt->setCurrency(iso, status);
63059d709d503bab6e2b61931737e662dd293b40578ccornelius      // next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount.
63159d709d503bab6e2b61931737e662dd293b40578ccornelius      return cloneFmt->format(*n, appendTo, posIter, status);
63259d709d503bab6e2b61931737e662dd293b40578ccornelius    }
63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
63450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (n->isNumeric() && n->getDigitList() != NULL) {
63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Decimal Number
63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        format(*n->getDigitList(), appendTo, posIter, status);
63750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
63850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        switch (n->getType()) {
63950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case Formattable::kDouble:
64050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            format(n->getDouble(), appendTo, posIter, status);
64150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
64250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case Formattable::kLong:
64350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            format(n->getLong(), appendTo, posIter, status);
64450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
64550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case Formattable::kInt64:
64650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            format(n->getInt64(), appendTo, posIter, status);
64750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
64850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        default:
64950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            status = U_INVALID_FORMAT_ERROR;
65050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
65150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
65350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return appendTo;
655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
65950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::format(int64_t number,
661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     UnicodeString& appendTo,
662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     FieldPosition& pos) const
663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // default so we don't introduce a new abstract method
665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return format((int32_t)number, appendTo, pos);
666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Parses the string and save the result object as well
670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// as the final parsed position.
671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::parseObject(const UnicodeString& source,
674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             Formattable& result,
675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             ParsePosition& parse_pos) const
676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    parse(source, result, parse_pos);
678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Formats a double number and save the result in a string.
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::format(double number, UnicodeString& appendTo) const
685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    FieldPosition pos(0);
687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return format(number, appendTo, pos);
688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Formats a long number and save the result in a string.
692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::format(int32_t number, UnicodeString& appendTo) const
695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    FieldPosition pos(0);
697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return format(number, appendTo, pos);
698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Formats a long number and save the result in a string.
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::format(int64_t number, UnicodeString& appendTo) const
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    FieldPosition pos(0);
707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return format(number, appendTo, pos);
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Parses the text and save the result object.  If the returned
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// parse position is 0, that means the parsing failed, the status
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// code needs to be set to failure.  Ignores the returned parse
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// position, otherwise.
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::parse(const UnicodeString& text,
718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        Formattable& result,
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UErrorCode& status) const
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) return;
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ParsePosition parsePosition(0);
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    parse(text, result, parsePosition);
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (parsePosition.getIndex() == 0) {
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status = U_INVALID_FORMAT_ERROR;
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
730103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusCurrencyAmount* NumberFormat::parseCurrency(const UnicodeString& text,
731103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                                            ParsePosition& pos) const {
732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Default implementation only -- subclasses should override
733103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Formattable parseResult;
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t start = pos.getIndex();
735103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    parse(text, parseResult, pos);
736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (pos.getIndex() != start) {
737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar curr[4];
738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UErrorCode ec = U_ZERO_ERROR;
739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getEffectiveCurrency(curr, ec);
740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_SUCCESS(ec)) {
741103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, curr, ec));
742103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (U_FAILURE(ec)) {
743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                pos.setIndex(start); // indicate failure
744c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            } else {
745103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return currAmt.orphan();
746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
749103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return NULL;
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets to only parse integers.
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::setParseIntegerOnly(UBool value)
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fParseIntegerOnly = value;
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Sets whether lenient parse is enabled.
763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
764b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid
765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoNumberFormat::setLenient(UBool enable)
766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{
767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fLenient = enable;
768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
769b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// -------------------------------------
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a number style NumberFormat instance with the default locale.
772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createInstance(UErrorCode& status)
775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return createInstance(Locale::getDefault(), UNUM_DECIMAL, status);
777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a number style NumberFormat instance with the inLocale locale.
781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createInstance(const Locale& inLocale, UErrorCode& status)
784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
785b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return createInstance(inLocale, UNUM_DECIMAL, status);
786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a currency style NumberFormat instance with the default locale.
790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createCurrencyInstance(UErrorCode& status)
793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return createCurrencyInstance(Locale::getDefault(),  status);
795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a currency style NumberFormat instance with the inLocale locale.
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createCurrencyInstance(const Locale& inLocale, UErrorCode& status)
80250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
803b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return createInstance(inLocale, UNUM_CURRENCY, status);
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a percent style NumberFormat instance with the default locale.
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createPercentInstance(UErrorCode& status)
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
812b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return createInstance(Locale::getDefault(), UNUM_PERCENT, status);
813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a percent style NumberFormat instance with the inLocale locale.
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createPercentInstance(const Locale& inLocale, UErrorCode& status)
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
821b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return createInstance(inLocale, UNUM_PERCENT, status);
822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a scientific style NumberFormat instance with the default locale.
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createScientificInstance(UErrorCode& status)
829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
830b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return createInstance(Locale::getDefault(), UNUM_SCIENTIFIC, status);
831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Create a scientific style NumberFormat instance with the inLocale locale.
835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat* U_EXPORT2
837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::createScientificInstance(const Locale& inLocale, UErrorCode& status)
838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
839b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return createInstance(inLocale, UNUM_SCIENTIFIC, status);
840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale* U_EXPORT2
845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::getAvailableLocales(int32_t& count)
846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return Locale::getAvailableLocales(count);
848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------------
851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Registration
853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//-------------------------------------------
855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE
857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass ICUNumberFormatFactory : public ICUResourceBundleFactory {
861103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliuspublic:
862103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    virtual ~ICUNumberFormatFactory();
863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprotected:
864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* /* service */, UErrorCode& status) const {
865b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NumberFormat::makeInstance(loc, (UNumberFormatStyle)kind, status);
866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
869103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusICUNumberFormatFactory::~ICUNumberFormatFactory() {}
870103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass NFFactory : public LocaleKeyFactory {
874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate:
875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormatFactory* _delegate;
876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Hashtable* _ids;
877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
87950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    NFFactory(NumberFormatFactory* delegate)
880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        : LocaleKeyFactory(delegate->visible() ? VISIBLE : INVISIBLE)
881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        , _delegate(delegate)
882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        , _ids(NULL)
883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
886103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    virtual ~NFFactory();
887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const
889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (handlesKey(key, status)) {
891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const LocaleKey& lkey = (const LocaleKey&)key;
892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            Locale loc;
893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            lkey.canonicalLocale(loc);
894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t kind = lkey.kind();
895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
896b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UObject* result = _delegate->createFormat(loc, (UNumberFormatStyle)kind);
897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (result == NULL) {
898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result = service->getKey((ICUServiceKey&)key /* cast away const */, NULL, this, status);
899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return result;
901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprotected:
906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Return the set of ids that this factory supports (visible or
908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * otherwise).  This can be called often and might need to be
909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * cached if it is expensive to create.
910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual const Hashtable* getSupportedIDs(UErrorCode& status) const
912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_SUCCESS(status)) {
914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (!_ids) {
915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                int32_t count = 0;
916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                const UnicodeString * const idlist = _delegate->getSupportedIDs(count, status);
917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ((NFFactory*)this)->_ids = new Hashtable(status); /* cast away const */
918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (_ids) {
919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    for (int i = 0; i < count; ++i) {
920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        _ids->put(idlist[i], (void*)this, status);
921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return _ids;
925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
930103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusNFFactory::~NFFactory()
931103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
932103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete _delegate;
933103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete _ids;
934103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
935103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass ICUNumberFormatService : public ICULocaleService {
937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ICUNumberFormatService()
939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        : ICULocaleService(UNICODE_STRING_SIMPLE("Number Format"))
940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        registerFactory(new ICUNumberFormatFactory(), status);
943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
945103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    virtual ~ICUNumberFormatService();
946103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UObject* cloneInstance(UObject* instance) const {
948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return ((NumberFormat*)instance)->clone();
949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* /* actualID */, UErrorCode& status) const {
952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        LocaleKey& lkey = (LocaleKey&)key;
953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t kind = lkey.kind();
954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Locale loc;
955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        lkey.currentLocale(loc);
956b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NumberFormat::makeInstance(loc, (UNumberFormatStyle)kind, status);
957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UBool isDefault() const {
960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return countFactories() == 1;
961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
964103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusICUNumberFormatService::~ICUNumberFormatService() {}
965103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
96859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initNumberFormatService() {
96959d709d503bab6e2b61931737e662dd293b40578ccornelius    U_ASSERT(gService == NULL);
97059d709d503bab6e2b61931737e662dd293b40578ccornelius    ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup);
97159d709d503bab6e2b61931737e662dd293b40578ccornelius    gService = new ICUNumberFormatService();
97259d709d503bab6e2b61931737e662dd293b40578ccornelius}
97359d709d503bab6e2b61931737e662dd293b40578ccornelius
97450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic ICULocaleService*
975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetNumberFormatService(void)
976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
97759d709d503bab6e2b61931737e662dd293b40578ccornelius    umtx_initOnce(gServiceInitOnce, &initNumberFormatService);
978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return gService;
979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
98159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UBool haveService() {
98259d709d503bab6e2b61931737e662dd293b40578ccornelius    return !gServiceInitOnce.isReset() && (getNumberFormatService() != NULL);
98359d709d503bab6e2b61931737e662dd293b40578ccornelius}
98459d709d503bab6e2b61931737e662dd293b40578ccornelius
985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruURegistryKey U_EXPORT2
988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::registerFactory(NumberFormatFactory* toAdopt, UErrorCode& status)
989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  ICULocaleService *service = getNumberFormatService();
991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (service) {
992c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  NFFactory *tempnnf = new NFFactory(toAdopt);
993c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  if (tempnnf != NULL) {
994c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru		  return service->registerFactory(tempnnf, status);
995c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  }
996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  status = U_MEMORY_ALLOCATION_ERROR;
998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return NULL;
999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool U_EXPORT2
1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::unregister(URegistryKey key, UErrorCode& status)
1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
100659d709d503bab6e2b61931737e662dd293b40578ccornelius    if (U_FAILURE(status)) {
100759d709d503bab6e2b61931737e662dd293b40578ccornelius        return FALSE;
100859d709d503bab6e2b61931737e662dd293b40578ccornelius    }
100959d709d503bab6e2b61931737e662dd293b40578ccornelius    if (haveService()) {
101059d709d503bab6e2b61931737e662dd293b40578ccornelius        return gService->unregister(key, status);
101159d709d503bab6e2b61931737e662dd293b40578ccornelius    } else {
1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
101359d709d503bab6e2b61931737e662dd293b40578ccornelius        return FALSE;
1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruStringEnumeration* U_EXPORT2
1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::getAvailableLocales(void)
1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  ICULocaleService *service = getNumberFormatService();
1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (service) {
102359d709d503bab6e2b61931737e662dd293b40578ccornelius      return service->getAvailableLocales();
1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return NULL; // no way to return error condition
1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* UCONFIG_NO_SERVICE */
1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1030fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusNumberFormat*
1031fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusNumberFormat::internalCreateInstance(const Locale& loc, UNumberFormatStyle kind, UErrorCode& status) {
1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE
103359d709d503bab6e2b61931737e662dd293b40578ccornelius    if (haveService()) {
1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return (NumberFormat*)gService->get(loc, kind, status);
1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
103759d709d503bab6e2b61931737e662dd293b40578ccornelius    return makeInstance(loc, kind, status);
1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1040fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusNumberFormat* U_EXPORT2
1041fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusNumberFormat::createInstance(const Locale& loc, UNumberFormatStyle kind, UErrorCode& status) {
1042fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (kind != UNUM_DECIMAL) {
1043fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return internalCreateInstance(loc, kind, status);
1044fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1045fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    const SharedNumberFormat *shared = createSharedInstance(loc, kind, status);
1046fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status)) {
1047fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return NULL;
1048fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1049fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    NumberFormat *result = static_cast<NumberFormat *>((*shared)->clone());
1050fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    shared->removeRef();
1051fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (result == NULL) {
1052fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        status = U_MEMORY_ALLOCATION_ERROR;
1053fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1054fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    return result;
1055fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
1056fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Checks if the thousand/10 thousand grouping is used in the
1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// NumberFormat instance.
1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool
1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::isGroupingUsed() const
1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fGroupingUsed;
1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets to use the thousand/10 thousand grouping in the
1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// NumberFormat instance.
1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::setGroupingUsed(UBool newValue)
1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fGroupingUsed = newValue;
1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the maximum number of digits for the integral part for
1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t NumberFormat::getMaximumIntegerDigits() const
1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fMaxIntegerDigits;
1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the maximum number of digits for the integral part for
1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::setMaximumIntegerDigits(int32_t newValue)
1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
109459d709d503bab6e2b61931737e662dd293b40578ccornelius    fMaxIntegerDigits = uprv_max(0, uprv_min(newValue, gDefaultMaxIntegerDigits));
1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(fMinIntegerDigits > fMaxIntegerDigits)
1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMinIntegerDigits = fMaxIntegerDigits;
1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the minimum number of digits for the integral part for
1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::getMinimumIntegerDigits() const
1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fMinIntegerDigits;
1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the minimum number of digits for the integral part for
1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::setMinimumIntegerDigits(int32_t newValue)
1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
111659d709d503bab6e2b61931737e662dd293b40578ccornelius    fMinIntegerDigits = uprv_max(0, uprv_min(newValue, gDefaultMinIntegerDigits));
1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(fMinIntegerDigits > fMaxIntegerDigits)
1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMaxIntegerDigits = fMinIntegerDigits;
1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the maximum number of digits for the fractional part for
1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::getMaximumFractionDigits() const
1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fMaxFractionDigits;
1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the maximum number of digits for the fractional part for
1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::setMaximumFractionDigits(int32_t newValue)
1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
113859d709d503bab6e2b61931737e662dd293b40578ccornelius    fMaxFractionDigits = uprv_max(0, uprv_min(newValue, gDefaultMaxIntegerDigits));
1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(fMaxFractionDigits < fMinFractionDigits)
1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMinFractionDigits = fMaxFractionDigits;
1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the minimum number of digits for the fractional part for
1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::getMinimumFractionDigits() const
1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fMinFractionDigits;
1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the minimum number of digits for the fractional part for
1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// this NumberFormat instance.
1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::setMinimumFractionDigits(int32_t newValue)
1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
116059d709d503bab6e2b61931737e662dd293b40578ccornelius    fMinFractionDigits = uprv_max(0, uprv_min(newValue, gDefaultMinIntegerDigits));
1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fMaxFractionDigits < fMinFractionDigits)
1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMaxFractionDigits = fMinFractionDigits;
1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid NumberFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(ec)) {
1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (theCurrency) {
1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        u_strncpy(fCurrency, theCurrency, 3);
1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fCurrency[3] = 0;
1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fCurrency[0] = 0;
1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UChar* NumberFormat::getCurrency() const {
1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fCurrency;
1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid NumberFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UChar* c = getCurrency();
1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*c != 0) {
1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        u_strncpy(result, c, 3);
1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result[3] = 0;
1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const char* loc = getLocaleID(ULOC_VALID_LOCALE, ec);
1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (loc == NULL) {
1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            loc = uloc_getDefault();
1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ucurr_forLocale(loc, result, 4, &ec);
1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1197fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius//----------------------------------------------------------------------
1198fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1199fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1200fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid NumberFormat::setContext(UDisplayContext value, UErrorCode& status)
1201fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{
1202fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status))
1203fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return;
1204fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) {
1205fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        fCapitalizationContext = value;
1206fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    } else {
1207fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        status = U_ILLEGAL_ARGUMENT_ERROR;
1208fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius   }
1209fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
1210fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1211fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1212fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusUDisplayContext NumberFormat::getContext(UDisplayContextType type, UErrorCode& status) const
1213fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{
1214fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status))
1215fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return (UDisplayContext)0;
1216fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (type != UDISPCTX_TYPE_CAPITALIZATION) {
1217fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        status = U_ILLEGAL_ARGUMENT_ERROR;
1218fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return (UDisplayContext)0;
1219fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1220fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    return fCapitalizationContext;
1221fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
1222fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1223fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Creates the NumberFormat instance of the specified style (number, currency,
1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// or percent) for the desired locale.
1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
122859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV nscacheInit() {
122959d709d503bab6e2b61931737e662dd293b40578ccornelius    U_ASSERT(NumberingSystem_cache == NULL);
123059d709d503bab6e2b61931737e662dd293b40578ccornelius    ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup);
123159d709d503bab6e2b61931737e662dd293b40578ccornelius    UErrorCode status = U_ZERO_ERROR;
123259d709d503bab6e2b61931737e662dd293b40578ccornelius    NumberingSystem_cache = uhash_open(uhash_hashLong,
123359d709d503bab6e2b61931737e662dd293b40578ccornelius                                       uhash_compareLong,
123459d709d503bab6e2b61931737e662dd293b40578ccornelius                                       NULL,
123559d709d503bab6e2b61931737e662dd293b40578ccornelius                                       &status);
123659d709d503bab6e2b61931737e662dd293b40578ccornelius    if (U_FAILURE(status)) {
123759d709d503bab6e2b61931737e662dd293b40578ccornelius        // Number Format code will run with no cache if creation fails.
123859d709d503bab6e2b61931737e662dd293b40578ccornelius        NumberingSystem_cache = NULL;
123959d709d503bab6e2b61931737e662dd293b40578ccornelius        return;
124059d709d503bab6e2b61931737e662dd293b40578ccornelius    }
124159d709d503bab6e2b61931737e662dd293b40578ccornelius    uhash_setValueDeleter(NumberingSystem_cache, deleteNumberingSystem);
124259d709d503bab6e2b61931737e662dd293b40578ccornelius}
124359d709d503bab6e2b61931737e662dd293b40578ccornelius
1244fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic SharedObject *U_CALLCONV createSharedNumberFormat(
1245fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        const char *localeId, UErrorCode &status) {
1246fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status)) {
1247fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return NULL;
1248fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1249fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    NumberFormat *nf = NumberFormat::internalCreateInstance(
1250fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            localeId, UNUM_DECIMAL, status);
1251fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status)) {
1252fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return NULL;
1253fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1254fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    SharedObject *result = new SharedNumberFormat(nf);
1255fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (result == NULL) {
1256fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        status = U_MEMORY_ALLOCATION_ERROR;
1257fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        delete nf;
1258fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return NULL;
1259fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1260fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    return result;
1261fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
1262fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1263fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void U_CALLCONV numberFormatCacheInit(UErrorCode &status) {
1264fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    U_ASSERT(gNumberFormatCache == NULL);
1265fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup);
1266fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    gNumberFormatCache = new SimpleLRUCache(100, &createSharedNumberFormat, status);
1267fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status)) {
1268fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        delete gNumberFormatCache;
1269fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        gNumberFormatCache = NULL;
1270fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1271fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
1272fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1273fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void getSharedNumberFormatFromCache(
1274fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        const char *locale,
1275fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        const SharedNumberFormat *&ptr,
1276fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        UErrorCode &status) {
1277fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    umtx_initOnce(gNumberFormatCacheInitOnce, &numberFormatCacheInit, status);
1278fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status)) {
1279fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return;
1280fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1281fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    Mutex lock(&gNumberFormatCacheMutex);
1282fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    gNumberFormatCache->get(locale, ptr, status);
1283fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
1284fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1285fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusconst SharedNumberFormat* U_EXPORT2
1286fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusNumberFormat::createSharedInstance(const Locale& loc, UNumberFormatStyle kind, UErrorCode& status) {
1287fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status)) {
1288fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return NULL;
1289fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1290fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (kind != UNUM_DECIMAL) {
1291fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        status = U_UNSUPPORTED_ERROR;
1292fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        return NULL;
1293fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
1294fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    const SharedNumberFormat *result = NULL;
1295fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    getSharedNumberFormatFromCache(loc.getName(), result, status);
1296fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    return result;
1297fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
1298fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
1299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool
1300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoNumberFormat::isStyleSupported(UNumberFormatStyle style) {
1301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return gLastResortNumberPatterns[style] != NULL;
1302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
1303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat*
1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNumberFormat::makeInstance(const Locale& desiredLocale,
1306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           UNumberFormatStyle style,
13078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                           UErrorCode& status) {
13088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius  return makeInstance(desiredLocale, style, false, status);
13098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
13108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
13118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusNumberFormat*
13128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusNumberFormat::makeInstance(const Locale& desiredLocale,
13138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                           UNumberFormatStyle style,
13148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                           UBool mustBeDecimalFormat,
13158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                           UErrorCode& status) {
1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) return NULL;
1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (style < 0 || style >= UNUM_FORMAT_STYLE_COUNT) {
1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Some styles are not supported. This is a result of merging
1324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // the @draft ICU 4.2 NumberFormat::EStyles into the long-existing UNumberFormatStyle.
1325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Ticket #8503 is for reviewing/fixing/merging the two relevant implementations:
1326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // this one and unum_open().
1327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // The UNUM_PATTERN_ styles are not supported here
1328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // because this method does not take a pattern string.
1329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (!isStyleSupported(style)) {
1330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_UNSUPPORTED_ERROR;
1331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
1332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
1333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1334103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
13358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (!mustBeDecimalFormat) {
13368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        char buffer[8];
13378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        int32_t count = desiredLocale.getKeywordValue("compat", buffer, sizeof(buffer), status);
13388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
13398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        // if the locale has "@compat=host", create a host-specific NumberFormat
13408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (U_SUCCESS(status) && count > 0 && uprv_strcmp(buffer, "host") == 0) {
13418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            Win32NumberFormat *f = NULL;
13428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UBool curr = TRUE;
13438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
13448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            switch (style) {
13458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case UNUM_DECIMAL:
13468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                curr = FALSE;
13478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                // fall-through
13488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
13498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case UNUM_CURRENCY:
13508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case UNUM_CURRENCY_ISO: // do not support plural formatting here
13518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case UNUM_CURRENCY_PLURAL:
1352fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            case UNUM_CURRENCY_ACCOUNTING:
13538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                f = new Win32NumberFormat(desiredLocale, curr, status);
13548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
13558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                if (U_SUCCESS(status)) {
13568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    return f;
13578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
135850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
13598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                delete f;
13608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
13618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            default:
13628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
13638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
136750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Use numbering system cache hashtable
136859d709d503bab6e2b61931737e662dd293b40578ccornelius    umtx_initOnce(gNSCacheInitOnce, &nscacheInit);
136950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
137050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Get cached numbering system
1371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    LocalPointer<NumberingSystem> ownedNs;
1372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NumberingSystem *ns = NULL;
137359d709d503bab6e2b61931737e662dd293b40578ccornelius    if (NumberingSystem_cache != NULL) {
1374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // TODO: Bad hash key usage, see ticket #8504.
1375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t hashKey = desiredLocale.hashCode();
137650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        Mutex lock(&nscacheMutex);
137859d709d503bab6e2b61931737e662dd293b40578ccornelius        ns = (NumberingSystem *)uhash_iget(NumberingSystem_cache, hashKey);
137950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (ns == NULL) {
138050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            ns = NumberingSystem::createInstance(desiredLocale,status);
138159d709d503bab6e2b61931737e662dd293b40578ccornelius            uhash_iput(NumberingSystem_cache, hashKey, (void*)ns, &status);
138250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
1383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
1384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        ownedNs.adoptInstead(NumberingSystem::createInstance(desiredLocale,status));
1385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        ns = ownedNs.getAlias();
138650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
138750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
138850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // check results of getting a numbering system
1389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(status)) {
1390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
13938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (mustBeDecimalFormat && ns->isAlgorithmic()) {
13948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        status = U_UNSUPPORTED_ERROR;
13958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return NULL;
13968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
13978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1398103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    LocalPointer<DecimalFormatSymbols> symbolsToAdopt;
1399103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UnicodeString pattern;
1400103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    LocalUResourceBundlePointer ownedResource(ures_open(NULL, desiredLocale.getName(), &status));
1401103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (U_FAILURE(status)) {
1402103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // We don't appear to have resource data available -- use the last-resort data
1403103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        status = U_USING_FALLBACK_WARNING;
1404103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // When the data is unavailable, and locale isn't passed in, last resort data is used.
1405103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(status));
1406103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (symbolsToAdopt.isNull()) {
1407103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_MEMORY_ALLOCATION_ERROR;
1408103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return NULL;
1409103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1410103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1411103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Creates a DecimalFormat instance with the last resort number patterns.
1412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        pattern.setTo(TRUE, gLastResortNumberPatterns[style], -1);
1413103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1414103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    else {
1415103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Loads the decimal symbols of the desired locale.
1416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(desiredLocale, status));
1417103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (symbolsToAdopt.isNull()) {
1418103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_MEMORY_ALLOCATION_ERROR;
1419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return NULL;
1420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1421103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1422103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UResourceBundle *resource = ownedResource.orphan();
1423103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UResourceBundle *numElements = ures_getByKeyWithFallback(resource, gNumberElements, NULL, &status);
1424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &status);
1425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status);
1426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        ownedResource.adoptInstead(resource);
1427103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1428103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        int32_t patLen = 0;
1429103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        const UChar *patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status);
1430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1431103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Didn't find a pattern specific to the numbering system, so fall back to "latn"
1432103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(gLatn,ns->getName())) {
1433103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_ZERO_ERROR;
1434103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            resource = ures_getByKeyWithFallback(numElements, gLatn, resource, &status);
1435103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status);
1436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status);
1437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1438103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1439103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        ures_close(numElements);
1440103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1441103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Creates the specified decimal format style of the desired locale.
1442103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        pattern.setTo(TRUE, patResStr, patLen);
1443103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1444103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (U_FAILURE(status)) {
1445103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return NULL;
1446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1447fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if(style==UNUM_CURRENCY || style == UNUM_CURRENCY_ISO || style == UNUM_CURRENCY_ACCOUNTING){
1448103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        const UChar* currPattern = symbolsToAdopt->getCurrencyPattern();
1449103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if(currPattern!=NULL){
1450103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            pattern.setTo(currPattern, u_strlen(currPattern));
1451103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1452103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1453103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1454103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NumberFormat *f;
1456b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (ns->isAlgorithmic()) {
1457b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UnicodeString nsDesc;
1458b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UnicodeString nsRuleSetGroup;
1459b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UnicodeString nsRuleSetName;
1460b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        Locale nsLoc;
1461b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        URBNFRuleSetTag desiredRulesType = URBNF_NUMBERING_SYSTEM;
146250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1463b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        nsDesc.setTo(ns->getDescription());
1464b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        int32_t firstSlash = nsDesc.indexOf(gSlash);
1465b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        int32_t lastSlash = nsDesc.lastIndexOf(gSlash);
1466b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if ( lastSlash > firstSlash ) {
1467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            CharString nsLocID;
1468b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
1469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            nsLocID.appendInvariantChars(nsDesc.tempSubString(0, firstSlash), status);
1470b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            nsRuleSetGroup.setTo(nsDesc,firstSlash+1,lastSlash-firstSlash-1);
1471b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            nsRuleSetName.setTo(nsDesc,lastSlash+1);
147250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            nsLoc = Locale::createFromName(nsLocID.data());
1474b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
1475b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UnicodeString SpelloutRules = UNICODE_STRING_SIMPLE("SpelloutRules");
1476b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( nsRuleSetGroup.compare(SpelloutRules) == 0 ) {
1477b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                desiredRulesType = URBNF_SPELLOUT;
1478b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
1479b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
1480b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            nsLoc = desiredLocale;
1481b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            nsRuleSetName.setTo(nsDesc);
1482b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
1483b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
1484b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        RuleBasedNumberFormat *r = new RuleBasedNumberFormat(desiredRulesType,nsLoc,status);
1485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (r == NULL) {
1486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            status = U_MEMORY_ALLOCATION_ERROR;
1487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return NULL;
1488b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
1489b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        r->setDefaultRuleSet(nsRuleSetName,status);
1490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        f = r;
1491b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
1492b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // replace single currency sign in the pattern with double currency sign
1493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // if the style is UNUM_CURRENCY_ISO
1494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (style == UNUM_CURRENCY_ISO) {
1495103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            pattern.findAndReplace(UnicodeString(TRUE, gSingleCurrencySign, 1),
1496103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                                   UnicodeString(TRUE, gDoubleCurrencySign, 2));
1497b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
1498b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
1499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // "new DecimalFormat()" does not adopt the symbols if its memory allocation fails.
1500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        DecimalFormatSymbols *syms = symbolsToAdopt.orphan();
1501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        f = new DecimalFormat(pattern, syms, style, status);
1502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (f == NULL) {
1503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            delete syms;
1504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            status = U_MEMORY_ALLOCATION_ERROR;
1505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return NULL;
1506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
1507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
150850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    f->setLocaleIDs(ures_getLocaleByType(ownedResource.getAlias(), ULOC_VALID_LOCALE, &status),
1510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    ures_getLocaleByType(ownedResource.getAlias(), ULOC_ACTUAL_LOCALE, &status));
1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete f;
1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return f;
1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof
1523