1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
38393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* Copyright (C) 1997-2013, International Business Machines Corporation and    *
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* others. All Rights Reserved.                                                *
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File DECIMFMT.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/20/97    clhuang     Implemented with new APIs.
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   03/31/97    aliu        Moved isLONG_MIN to DigitList, and fixed it.
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/3/97     aliu        Rewrote parsing and formatting completely, and
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           cleaned up and debugged.  Actually works now.
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           Implemented NAN and INF handling, for both parsing
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           and formatting.  Extensive testing & debugging.
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/10/97    aliu        Modified to compile on AIX.
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/16/97    aliu        Rewrote to use DigitList, which has been resurrected.
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           Changed DigitCount to int per code review.
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   07/09/97    helena      Made ParsePosition into a class.
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/26/97    aliu        Extensive changes to applyPattern; completely
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           rewritten from the Java.
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   09/09/97    aliu        Ported over support for exponential formats.
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   07/20/98    stephen     JDK 1.2 sync up.
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                             Various instances of '0' replaced with 'NULL'
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                             Check for grouping size in subFormat()
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                             Brought subParse() in line with Java 1.2
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                             Added method appendAffix()
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/24/1998  srl         Removed Mutex calls. This is not a thread safe class!
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   02/22/99    stephen     Removed character literals for EBCDIC safety
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   06/28/99    stephen     Fixed bugs in toPattern().
3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   06/29/99    stephen     Fixed operator= to copy fFormatWidth, fPad,
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                             fPadPosition
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************************
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "fphdlimp.h"
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/decimfmt.h"
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/choicfmt.h"
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ucurr.h"
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h"
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/dcfmtsym.h"
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ures.h"
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uchar.h"
52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/uniset.h"
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/curramt.h"
54b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/currpinf.h"
55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/plurrule.h"
56103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf16.h"
57103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/numsys.h"
58103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/localpointer.h"
59b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uresimp.h"
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucurrimp.h"
6127f654740f2a26ad62a5c155af9199af9e69b889claireho#include "charstr.h"
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h"
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "digitlst.h"
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h"
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h"
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h"
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h"
69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include <math.h>
70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "hash.h"
71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "decfmtst.h"
72103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "dcfmtimp.h"
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/*
758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * On certain platforms, round is a macro defined in math.h
768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * This undefine is to avoid conflict between the macro and
778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * the function defined below.
788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius */
798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#ifdef round
808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#undef round
818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#endif
828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
86103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/* == Fastpath calculation. ==
87103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius */
88103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
89103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusinline DecimalFormatInternal& internalData(uint8_t *reserved) {
90103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  return *reinterpret_cast<DecimalFormatInternal*>(reserved);
91103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
92103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusinline const DecimalFormatInternal& internalData(const uint8_t *reserved) {
93103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  return *reinterpret_cast<const DecimalFormatInternal*>(reserved);
94103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
95103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#else
96103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
97103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* For currency parsing purose,
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Need to remember all prefix patterns and suffix patterns of
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * every currency format pattern,
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * including the pattern of default currecny style
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and plural currency style. And the patterns are set through applyPattern.
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct AffixPatternsForCurrency : public UMemory {
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// negative prefix pattern
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString negPrefixPatternForCurrency;
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// negative suffix pattern
10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString negSuffixPatternForCurrency;
10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// positive prefix pattern
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString posPrefixPatternForCurrency;
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// positive suffix pattern
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString posSuffixPatternForCurrency;
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	int8_t patternType;
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	AffixPatternsForCurrency(const UnicodeString& negPrefix,
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho							 const UnicodeString& negSuffix,
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho							 const UnicodeString& posPrefix,
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho							 const UnicodeString& posSuffix,
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho							 int8_t type) {
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		negPrefixPatternForCurrency = negPrefix;
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		negSuffixPatternForCurrency = negSuffix;
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		posPrefixPatternForCurrency = posPrefix;
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		posSuffixPatternForCurrency = posSuffix;
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		patternType = type;
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	}
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* affix for currency formatting when the currency sign in the pattern
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * equals to 3, such as the pattern contains 3 currency sign or
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the formatter style is currency plural format style.
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct AffixesForCurrency : public UMemory {
13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// negative prefix
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString negPrefixForCurrency;
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// negative suffix
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString negSuffixForCurrency;
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// positive prefix
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString posPrefixForCurrency;
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	// positive suffix
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	UnicodeString posSuffixForCurrency;
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	int32_t formatWidth;
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	AffixesForCurrency(const UnicodeString& negPrefix,
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho					   const UnicodeString& negSuffix,
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho					   const UnicodeString& posPrefix,
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho					   const UnicodeString& posSuffix) {
14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		negPrefixForCurrency = negPrefix;
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		negSuffixForCurrency = negSuffix;
15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		posPrefixForCurrency = posPrefix;
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		posSuffixForCurrency = posSuffix;
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	}
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CDECL_BEGIN
156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/**
158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @internal ICU 4.2
159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2);
161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/**
163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @internal ICU 4.2
164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2);
166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool
169b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2) {
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const AffixesForCurrency* affix_1 =
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        (AffixesForCurrency*)val1.pointer;
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const AffixesForCurrency* affix_2 =
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        (AffixesForCurrency*)val2.pointer;
174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return affix_1->negPrefixForCurrency == affix_2->negPrefixForCurrency &&
175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_1->negSuffixForCurrency == affix_2->negSuffixForCurrency &&
176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_1->posPrefixForCurrency == affix_2->posPrefixForCurrency &&
177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_1->posSuffixForCurrency == affix_2->posSuffixForCurrency;
178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool
182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) {
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const AffixPatternsForCurrency* affix_1 =
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        (AffixPatternsForCurrency*)val1.pointer;
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const AffixPatternsForCurrency* affix_2 =
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        (AffixPatternsForCurrency*)val2.pointer;
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return affix_1->negPrefixPatternForCurrency ==
188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_2->negPrefixPatternForCurrency &&
18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           affix_1->negSuffixPatternForCurrency ==
190b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_2->negSuffixPatternForCurrency &&
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           affix_1->posPrefixPatternForCurrency ==
192b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_2->posPrefixPatternForCurrency &&
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           affix_1->posSuffixPatternForCurrency ==
194b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_2->posSuffixPatternForCurrency &&
195b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           affix_1->patternType == affix_2->patternType;
196b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
197b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_END
19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef FMT_DEBUG
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h>
202103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic void _debugout(const char *f, int l, const UnicodeString& s) {
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char buf[2000];
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    s.extract((int32_t) 0, s.length(), buf);
205103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    printf("%s:%d: %s\n", f,l, buf);
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
207103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define debugout(x) _debugout(__FILE__,__LINE__,x)
208103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define debug(x) printf("%s:%d: %s\n", __FILE__,__LINE__, x);
209103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UnicodeString dbg_null("<NULL>","");
210103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define DEREFSTR(x)   ((x!=NULL)?(*x):(dbg_null))
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define debugout(x)
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define debug(x)
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// *****************************************************************************
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// class DecimalFormat
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// *****************************************************************************
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat)
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constants for characters used in programmatic (unlocalized) patterns.
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternZeroDigit            ((UChar)0x0030) /*'0'*/
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternSignificantDigit     ((UChar)0x0040) /*'@'*/
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternGroupingSeparator    ((UChar)0x002C) /*','*/
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternDecimalSeparator     ((UChar)0x002E) /*'.'*/
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternPerMill              ((UChar)0x2030)
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternPercent              ((UChar)0x0025) /*'%'*/
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternDigit                ((UChar)0x0023) /*'#'*/
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternSeparator            ((UChar)0x003B) /*';'*/
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternExponent             ((UChar)0x0045) /*'E'*/
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternPlus                 ((UChar)0x002B) /*'+'*/
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternMinus                ((UChar)0x002D) /*'-'*/
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kPatternPadEscape            ((UChar)0x002A) /*'*'*/
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kQuote                       ((UChar)0x0027) /*'\''*/
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is used in patterns and substitued with either the currency symbol,
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * or if it is doubled, with the international currency symbol.  If the
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * replaced with the monetary decimal separator.
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kCurrencySign                ((UChar)0x00A4)
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kDefaultPad                  ((UChar)0x0020) /* */
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int32_t DecimalFormat::kDoubleIntegerDigits  = 309;
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int32_t DecimalFormat::kDoubleFractionDigits = 340;
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int32_t DecimalFormat::kMaxScientificIntegerDigits = 8;
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * These are the tags we expect to see in normal resource bundle files associated
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with a locale.
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
25727f654740f2a26ad62a5c155af9199af9e69b889clairehoconst char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - not used
25827f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char fgNumberElements[]="NumberElements";
25927f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char fgLatn[]="latn";
26027f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char fgPatterns[]="patterns";
26127f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char fgDecimalFormat[]="decimalFormat";
26227f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char fgCurrencyFormat[]="currencyFormat";
263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; }
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constructs a DecimalFormat instance in the default locale.
27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::DecimalFormat(UErrorCode& status) {
272103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    init(status);
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UParseError parseError;
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    construct(status, parseError);
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constructs a DecimalFormat instance with the specified number format
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// pattern in the default locale.
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::DecimalFormat(const UnicodeString& pattern,
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             UErrorCode& status) {
283103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    init(status);
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UParseError parseError;
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    construct(status, parseError, &pattern);
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constructs a DecimalFormat instance with the specified number format
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// pattern and the number format symbols in the default locale.  The
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// created instance owns the symbols.
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::DecimalFormat(const UnicodeString& pattern,
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             DecimalFormatSymbols* symbolsToAdopt,
29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             UErrorCode& status) {
296103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    init(status);
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UParseError parseError;
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (symbolsToAdopt == NULL)
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    construct(status, parseError, &pattern, symbolsToAdopt);
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::DecimalFormat(  const UnicodeString& pattern,
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    DecimalFormatSymbols* symbolsToAdopt,
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    UParseError& parseErr,
30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    UErrorCode& status) {
307103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    init(status);
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (symbolsToAdopt == NULL)
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    construct(status,parseErr, &pattern, symbolsToAdopt);
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constructs a DecimalFormat instance with the specified number format
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// pattern and the number format symbols in the default locale.  The
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// created instance owns the clone of the symbols.
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::DecimalFormat(const UnicodeString& pattern,
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             const DecimalFormatSymbols& symbols,
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             UErrorCode& status) {
321103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    init(status);
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UParseError parseError;
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constructs a DecimalFormat instance with the specified number format
328b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// pattern, the number format symbols, and the number format style.
329b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// The created instance owns the clone of the symbols.
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
331b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::DecimalFormat(const UnicodeString& pattern,
332b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                             DecimalFormatSymbols* symbolsToAdopt,
333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                             UNumberFormatStyle style,
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             UErrorCode& status) {
335103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    init(status);
33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fStyle = style;
337b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UParseError parseError;
338b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    construct(status, parseError, &pattern, symbolsToAdopt);
339b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
340b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//-----------------------------------------------------------------------------
34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Common DecimalFormat initialization.
34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    Put all fields of an uninitialized object into a known state.
34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    Common code, shared by all constructors.
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
346103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusDecimalFormat::init(UErrorCode &status) {
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fPosPrefixPattern = 0;
34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fPosSuffixPattern = 0;
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fNegPrefixPattern = 0;
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fNegSuffixPattern = 0;
35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fCurrencyChoice = 0;
35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fMultiplier = NULL;
3538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    fScale = 0;
35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fGroupingSize = 0;
35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fGroupingSize2 = 0;
35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fDecimalSeparatorAlwaysShown = FALSE;
35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fSymbols = NULL;
35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fUseSignificantDigits = FALSE;
35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fMinSignificantDigits = 1;
36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fMaxSignificantDigits = 6;
36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fUseExponentialNotation = FALSE;
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fMinExponentDigits = 0;
36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fExponentSignAlwaysShown = FALSE;
36454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    fBoolFlags.clear();
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fRoundingIncrement = 0;
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fRoundingMode = kRoundHalfEven;
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fPad = 0;
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fFormatWidth = 0;
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fPadPosition = kPadBeforePrefix;
370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fStyle = UNUM_DECIMAL;
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fCurrencySignCount = 0;
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fAffixPatternsForCurrency = NULL;
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fAffixesForCurrency = NULL;
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fPluralAffixesForCurrency = NULL;
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fCurrencyPluralInfo = NULL;
376103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_HAVE_PARSEALLINPUT
377103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fParseAllInput = UNUM_MAYBE;
378103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
379103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
380103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
381103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DecimalFormatInternal &data = internalData(fReserved);
38254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    data.fFastFormatStatus=kFastpathUNKNOWN; // don't try to calculate the fastpath until later.
38354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    data.fFastParseStatus=kFastpathUNKNOWN; // don't try to calculate the fastpath until later.
384103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
385103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // only do this once per obj.
386103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DecimalFormatStaticSets::initSets(&status);
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//------------------------------------------------------------------------------
390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Constructs a DecimalFormat instance with the specified number format
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// pattern and the number format symbols in the desired locale.  The
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// created instance owns the symbols.
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::construct(UErrorCode&             status,
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         UParseError&           parseErr,
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         const UnicodeString*   pattern,
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         DecimalFormatSymbols*  symbolsToAdopt)
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!!
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fRoundingIncrement = NULL;
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fRoundingMode = kRoundHalfEven;
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPad = kPatternPadEscape;
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPadPosition = kPadBeforePrefix;
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status))
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPosPrefixPattern = fPosSuffixPattern = NULL;
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fNegPrefixPattern = fNegSuffixPattern = NULL;
41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    setMultiplier(1);
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fGroupingSize = 3;
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fGroupingSize2 = 0;
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fDecimalSeparatorAlwaysShown = FALSE;
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fUseExponentialNotation = FALSE;
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMinExponentDigits = 0;
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fSymbols == NULL)
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status);
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* test for NULL */
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fSymbols == 0) {
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_MEMORY_ALLOCATION_ERROR;
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return;
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UErrorCode nsStatus = U_ZERO_ERROR;
427103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    NumberingSystem *ns = NumberingSystem::createInstance(nsStatus);
428103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (U_FAILURE(nsStatus)) {
429103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        status = nsStatus;
430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return;
431103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString str;
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Uses the default locale's number format pattern if there isn't
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // one specified.
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (pattern == NULL)
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t len = 0;
439103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UResourceBundle *top = ures_open(NULL, Locale::getDefault().getName(), &status);
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
441103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UResourceBundle *resource = ures_getByKeyWithFallback(top, fgNumberElements, NULL, &status);
442103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        resource = ures_getByKeyWithFallback(resource, ns->getName(), resource, &status);
443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status);
444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status);
445103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(fgLatn,ns->getName())) {
446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_ZERO_ERROR;
447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            resource = ures_getByKeyWithFallback(top, fgNumberElements, resource, &status);
448103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &status);
449103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status);
450103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status);
451103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        str.setTo(TRUE, resStr, len);
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pattern = &str;
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ures_close(resource);
455103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        ures_close(top);
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
458103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete ns;
459103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status))
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (pattern->indexOf((UChar)kCurrencySign) >= 0) {
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // If it looks like we are going to use a currency pattern
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // then do the time consuming lookup.
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setCurrencyForSymbols();
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
470b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        setCurrencyInternally(NULL, status);
471b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
472b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
473b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UnicodeString* patternUsed;
474b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UnicodeString currencyPluralPatternForOther;
475b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // apply pattern
476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fStyle == UNUM_CURRENCY_PLURAL) {
477b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
478b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_FAILURE(status)) {
479b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            return;
480b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
481b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
482b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // the pattern used in format is not fixed until formatting,
48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // in which, the number is known and
484b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // will be used to pick the right pattern based on plural count.
485b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // Here, set the pattern as the pattern of plural count == "other".
486b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // For most locale, the patterns are probably the same for all
487b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // plural count. If not, the right pattern need to be re-applied
488b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // during format.
489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5), currencyPluralPatternForOther);
490b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        patternUsed = &currencyPluralPatternForOther;
491b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // TODO: not needed?
492b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        setCurrencyForSymbols();
49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
494b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
495b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        patternUsed = pattern;
496b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
497b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
498b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (patternUsed->indexOf(kCurrencySign) != -1) {
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // initialize for currency, not only for plural format,
500b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // but also for mix parsing
501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (fCurrencyPluralInfo == NULL) {
502b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           if (U_FAILURE(status)) {
504b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru               return;
505b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           }
506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // need it for mix parsing
508b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        setupCurrencyAffixPatterns(status);
509b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // expanded affixes for plural names
510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (patternUsed->indexOf(fgTripleCurrencySign, 3, 0) != -1) {
511b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            setupCurrencyAffixes(*patternUsed, TRUE, TRUE, status);
512b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
514b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
515b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    applyPatternWithoutExpandAffix(*patternUsed,FALSE, parseErr, status);
516b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
517b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // expand affixes
518b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencySignCount != fgCurrencySignCountInPluralFormat) {
519b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        expandAffixAdjustWidth(NULL);
520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // If it was a currency format, apply the appropriate rounding by
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // resetting the currency. NOTE: this copies fCurrency on top of itself.
524b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencySignCount > fgCurrencySignCountZero) {
525b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        setCurrencyInternally(getCurrency(), status);
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
527103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
528103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DecimalFormatInternal &data = internalData(fReserved);
52954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    data.fFastFormatStatus = kFastpathNO; // allow it to be calculated
53054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    data.fFastParseStatus = kFastpathNO; // allow it to be calculated
531103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
532103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
535b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
536b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
537b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) {
538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
539b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
541b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UParseError parseErr;
542b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fAffixPatternsForCurrency = initHashForAffixPattern(status);
543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
544b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
545b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
546b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
547103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    NumberingSystem *ns = NumberingSystem::createInstance(fSymbols->getLocale(),status);
548103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (U_FAILURE(status)) {
549103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return;
550103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
551103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
552b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // Save the default currency patterns of this locale.
553b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // Here, chose onlyApplyPatternWithoutExpandAffix without
554b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // expanding the affix patterns into affixes.
555b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UnicodeString currencyPattern;
55627f654740f2a26ad62a5c155af9199af9e69b889claireho    UErrorCode error = U_ZERO_ERROR;
55727f654740f2a26ad62a5c155af9199af9e69b889claireho
55827f654740f2a26ad62a5c155af9199af9e69b889claireho    UResourceBundle *resource = ures_open(NULL, fSymbols->getLocale().getName(), &error);
559103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UResourceBundle *numElements = ures_getByKeyWithFallback(resource, fgNumberElements, NULL, &error);
560103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &error);
561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error);
562b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t patLen = 0;
563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat,  &patLen, &error);
564103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if ( error == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),fgLatn)) {
565103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        error = U_ZERO_ERROR;
566103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        resource = ures_getByKeyWithFallback(numElements, fgLatn, resource, &error);
567103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error);
568103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat,  &patLen, &error);
569103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
570103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    ures_close(numElements);
571b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ures_close(resource);
572103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete ns;
573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_SUCCESS(error)) {
575b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        applyPatternWithoutExpandAffix(UnicodeString(patResStr, patLen), false,
576b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                       parseErr, status);
577b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
578b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fNegPrefixPattern,
579b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fNegSuffixPattern,
580b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fPosPrefixPattern,
581b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fPosSuffixPattern,
582b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    UCURR_SYMBOL_NAME);
583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, status);
584b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
586b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // save the unique currency plural patterns of this locale.
587b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPattern;
588b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
589b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
590b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    Hashtable pluralPatternSet;
591b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    while ((element = pluralPtn->nextElement(pos)) != NULL) {
592b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UHashTok valueTok = element->value;
593b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UnicodeString* value = (UnicodeString*)valueTok.pointer;
594b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UHashTok keyTok = element->key;
595b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UnicodeString* key = (UnicodeString*)keyTok.pointer;
596b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (pluralPatternSet.geti(*value) != 1) {
597b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            pluralPatternSet.puti(*value, 1, status);
598b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            applyPatternWithoutExpandAffix(*value, false, parseErr, status);
599b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
600b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fNegPrefixPattern,
601b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fNegSuffixPattern,
602b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fPosPrefixPattern,
603b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    *fPosSuffixPattern,
604b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                    UCURR_LONG_NAME);
605b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            fAffixPatternsForCurrency->put(*key, affixPtn, status);
606b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
607b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
608b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
609b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
610b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
611b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
61250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::setupCurrencyAffixes(const UnicodeString& pattern,
613b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                    UBool setupForCurrentPattern,
614b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                    UBool setupForPluralPattern,
615b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                    UErrorCode& status) {
616b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
617b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
618b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
619b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UParseError parseErr;
620b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (setupForCurrentPattern) {
621b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (fAffixesForCurrency) {
622b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            deleteHashForAffix(fAffixesForCurrency);
623b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
624b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fAffixesForCurrency = initHashForAffix(status);
625b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_SUCCESS(status)) {
626b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            applyPatternWithoutExpandAffix(pattern, false, parseErr, status);
627b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules();
628b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            StringEnumeration* keywords = pluralRules->getKeywords(status);
629b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (U_SUCCESS(status)) {
630b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                const UnicodeString* pluralCount;
631b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                while ((pluralCount = keywords->snext(status)) != NULL) {
632b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if ( U_SUCCESS(status) ) {
633b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        expandAffixAdjustWidth(pluralCount);
634b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        AffixesForCurrency* affix = new AffixesForCurrency(
635b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix);
636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        fAffixesForCurrency->put(*pluralCount, affix, status);
637b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
638b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
639b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
64050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            delete keywords;
641b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
642b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
643b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
644b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
645b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
646b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
647b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
648b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (setupForPluralPattern) {
649b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (fPluralAffixesForCurrency) {
650b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            deleteHashForAffix(fPluralAffixesForCurrency);
651b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
652b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fPluralAffixesForCurrency = initHashForAffix(status);
653b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_SUCCESS(status)) {
654b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules();
655b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            StringEnumeration* keywords = pluralRules->getKeywords(status);
656b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (U_SUCCESS(status)) {
657b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                const UnicodeString* pluralCount;
658b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                while ((pluralCount = keywords->snext(status)) != NULL) {
659b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if ( U_SUCCESS(status) ) {
660b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        UnicodeString ptn;
661b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        fCurrencyPluralInfo->getCurrencyPluralPattern(*pluralCount, ptn);
662b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        applyPatternInternally(*pluralCount, ptn, false, parseErr, status);
663b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        AffixesForCurrency* affix = new AffixesForCurrency(
664b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix);
665b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        fPluralAffixesForCurrency->put(*pluralCount, affix, status);
666b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
667b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
668b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
66950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            delete keywords;
670b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
671b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
672b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
673b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
674b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::~DecimalFormat()
678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fPosPrefixPattern;
680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fPosSuffixPattern;
681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fNegPrefixPattern;
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fNegSuffixPattern;
683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fCurrencyChoice;
68450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    delete fMultiplier;
685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fSymbols;
686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fRoundingIncrement;
687b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    deleteHashForAffixPattern();
688b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    deleteHashForAffix(fAffixesForCurrency);
689b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    deleteHashForAffix(fPluralAffixesForCurrency);
690b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete fCurrencyPluralInfo;
691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// copy constructor
695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
69650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::DecimalFormat(const DecimalFormat &source) :
69750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    NumberFormat(source) {
698103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UErrorCode status = U_ZERO_ERROR;
699103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    init(status); // if this fails, 'source' isn't initialized properly either.
700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *this = source;
701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// assignment operator
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
70654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliustemplate <class T>
70754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void _copy_ptr(T** pdest, const T* source) {
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (source == NULL) {
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete *pdest;
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pdest = NULL;
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else if (*pdest == NULL) {
71254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        *pdest = new T(*source);
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
71454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        **pdest = *source;
71554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
71654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
71754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
71854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliustemplate <class T>
71954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void _clone_ptr(T** pdest, const T* source) {
72054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    delete *pdest;
72154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (source == NULL) {
72254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        *pdest = NULL;
72354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    } else {
72454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        *pdest = static_cast<T*>(source->clone());
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat&
729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::operator=(const DecimalFormat& rhs)
730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(this != &rhs) {
732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        NumberFormat::operator=(rhs);
733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fPositivePrefix = rhs.fPositivePrefix;
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fPositiveSuffix = rhs.fPositiveSuffix;
735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fNegativePrefix = rhs.fNegativePrefix;
736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fNegativeSuffix = rhs.fNegativeSuffix;
73754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _copy_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
73854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _copy_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
73954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _copy_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
74054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _copy_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
74154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _clone_ptr(&fCurrencyChoice, rhs.fCurrencyChoice);
74250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        setRoundingIncrement(rhs.getRoundingIncrement());
743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fRoundingMode = rhs.fRoundingMode;
74450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        setMultiplier(rhs.getMultiplier());
745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fGroupingSize = rhs.fGroupingSize;
746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fGroupingSize2 = rhs.fGroupingSize2;
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
74854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _copy_ptr(&fSymbols, rhs.fSymbols);
749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fUseExponentialNotation = rhs.fUseExponentialNotation;
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
75154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        fBoolFlags = rhs.fBoolFlags;
752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*Bertrand A. D. Update 98.03.17*/
753b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencySignCount = rhs.fCurrencySignCount;
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*end of Update*/
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMinExponentDigits = rhs.fMinExponentDigits;
75650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* sfb 990629 */
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fFormatWidth = rhs.fFormatWidth;
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fPad = rhs.fPad;
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fPadPosition = rhs.fPadPosition;
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* end sfb */
762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMinSignificantDigits = rhs.fMinSignificantDigits;
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fMaxSignificantDigits = rhs.fMaxSignificantDigits;
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fUseSignificantDigits = rhs.fUseSignificantDigits;
765b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fFormatPattern = rhs.fFormatPattern;
766b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fStyle = rhs.fStyle;
767b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencySignCount = rhs.fCurrencySignCount;
76854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo);
76954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        deleteHashForAffixPattern();
770b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (rhs.fAffixPatternsForCurrency) {
771b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UErrorCode status = U_ZERO_ERROR;
772b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            fAffixPatternsForCurrency = initHashForAffixPattern(status);
77350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            copyHashForAffixPattern(rhs.fAffixPatternsForCurrency,
774b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                    fAffixPatternsForCurrency, status);
775b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
77654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        deleteHashForAffix(fAffixesForCurrency);
777b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (rhs.fAffixesForCurrency) {
778b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UErrorCode status = U_ZERO_ERROR;
779b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            fAffixesForCurrency = initHashForAffixPattern(status);
780b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, status);
781b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
78254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        deleteHashForAffix(fPluralAffixesForCurrency);
783b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (rhs.fPluralAffixesForCurrency) {
784b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UErrorCode status = U_ZERO_ERROR;
785b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            fPluralAffixesForCurrency = initHashForAffixPattern(status);
786b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCurrency, status);
787b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
789103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
790103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
791103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return *this;
793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::operator==(const Format& that) const
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (this == &that)
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return TRUE;
802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // NumberFormat::operator== guarantees this cast is safe
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const DecimalFormat* other = (DecimalFormat*)&that;
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef FMT_DEBUG
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // This code makes it easy to determine why two format objects that should
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // be equal aren't.
809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool first = TRUE;
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!NumberFormat::operator==(that)) {
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("NumberFormat::!=");
813b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null
815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fPositivePrefix == other->fPositivePrefix)
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               *fPosPrefixPattern  == *other->fPosPrefixPattern))) {
818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Pos Prefix !=");
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null
822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           fPositiveSuffix == other->fPositiveSuffix)
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              *fPosSuffixPattern  == *other->fPosSuffixPattern))) {
825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Pos Suffix !=");
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null
829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           fNegativePrefix == other->fNegativePrefix)
830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              *fNegPrefixPattern  == *other->fNegPrefixPattern))) {
832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Neg Prefix ");
834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fNegPrefixPattern == NULL) {
835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug("NULL(");
836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(fNegativePrefix);
837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug(")");
838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(*fNegPrefixPattern);
840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug(" != ");
842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (other->fNegPrefixPattern == NULL) {
843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug("NULL(");
844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(other->fNegativePrefix);
845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug(")");
846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(*other->fNegPrefixPattern);
848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null
851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           fNegativeSuffix == other->fNegativeSuffix)
852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              *fNegSuffixPattern  == *other->fNegSuffixPattern))) {
854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Neg Suffix ");
856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fNegSuffixPattern == NULL) {
857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug("NULL(");
858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(fNegativeSuffix);
859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug(")");
860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(*fNegSuffixPattern);
862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug(" != ");
864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (other->fNegSuffixPattern == NULL) {
865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug("NULL(");
866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(other->fNegativeSuffix);
867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug(")");
868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debugout(*other->fNegSuffixPattern);
870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!((fRoundingIncrement == other->fRoundingIncrement) // both null
873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          || (fRoundingIncrement != NULL &&
874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              other->fRoundingIncrement != NULL &&
875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              *fRoundingIncrement == *other->fRoundingIncrement))) {
876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Rounding Increment !=");
878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              }
87950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (getMultiplier() != other->getMultiplier()) {
880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; }
88150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier());
882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fGroupingSize != other->fGroupingSize) {
884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize);
886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fGroupingSize2 != other->fGroupingSize2) {
888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2);
890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) {
892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown);
894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fUseExponentialNotation != other->fUseExponentialNotation) {
896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Use Exp !=");
898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(!fUseExponentialNotation ||
900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          fMinExponentDigits != other->fMinExponentDigits)) {
901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Exp Digits !=");
903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*fSymbols != *(other->fSymbols)) {
905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        debug("Symbols !=");
907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TODO Add debug stuff for significant digits here
909b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fUseSignificantDigits != other->fUseSignificantDigits) {
910b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fUseSignificantDigits !=");
911b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
912b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fUseSignificantDigits &&
913b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fMinSignificantDigits != other->fMinSignificantDigits) {
914b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fMinSignificantDigits !=");
915b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
916b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fUseSignificantDigits &&
917b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fMaxSignificantDigits != other->fMaxSignificantDigits) {
918b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fMaxSignificantDigits !=");
919b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
920b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!first) { printf(" ]"); }
922b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencySignCount != other->fCurrencySignCount) {
923b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fCurrencySignCount !=");
924b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
925b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) {
926b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fCurrencyPluralInfo == ");
927b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (fCurrencyPluralInfo == NULL) {
928b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            debug("fCurrencyPluralInfo == NULL");
929b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
930b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
931b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
932b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) {
933b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fCurrencyPluralInfo !=");
934b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
935b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL ||
936b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) {
937b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fCurrencyPluralInfo one NULL, the other not");
938b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
939b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) {
940b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        debug("fCurrencyPluralInfo == ");
941b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
942b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (NumberFormat::operator==(that) &&
94650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ?
947b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency)) :
948b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            (((fPosPrefixPattern == other->fPosPrefixPattern && // both null
949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fPositivePrefix == other->fPositivePrefix)
950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 *fPosPrefixPattern  == *other->fPosPrefixPattern)) &&
952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ((fPosSuffixPattern == other->fPosSuffixPattern && // both null
953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fPositiveSuffix == other->fPositiveSuffix)
954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 *fPosSuffixPattern  == *other->fPosSuffixPattern)) &&
956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ((fNegPrefixPattern == other->fNegPrefixPattern && // both null
957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fNegativePrefix == other->fNegativePrefix)
958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 *fNegPrefixPattern  == *other->fNegPrefixPattern)) &&
960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ((fNegSuffixPattern == other->fNegSuffixPattern && // both null
961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              fNegativeSuffix == other->fNegativeSuffix)
962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
963b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                 *fNegSuffixPattern  == *other->fNegSuffixPattern)))) &&
964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ((fRoundingIncrement == other->fRoundingIncrement) // both null
965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (fRoundingIncrement != NULL &&
966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 other->fRoundingIncrement != NULL &&
967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 *fRoundingIncrement == *other->fRoundingIncrement)) &&
96850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        getMultiplier() == other->getMultiplier() &&
969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fGroupingSize == other->fGroupingSize &&
970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fGroupingSize2 == other->fGroupingSize2 &&
971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown &&
972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fUseExponentialNotation == other->fUseExponentialNotation &&
973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (!fUseExponentialNotation ||
974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         fMinExponentDigits == other->fMinExponentDigits) &&
975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *fSymbols == *(other->fSymbols) &&
976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fUseSignificantDigits == other->fUseSignificantDigits &&
977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (!fUseSignificantDigits ||
978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         (fMinSignificantDigits == other->fMinSignificantDigits &&
979b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru          fMaxSignificantDigits == other->fMaxSignificantDigits)) &&
980b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencySignCount == other->fCurrencySignCount &&
981b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ((fCurrencyPluralInfo == other->fCurrencyPluralInfo &&
982b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru          fCurrencyPluralInfo == NULL) ||
983b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
984b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         *fCurrencyPluralInfo == *(other->fCurrencyPluralInfo))));
985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruFormat*
990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::clone() const
991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return new DecimalFormat(*this);
993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
99650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::format(int32_t number,
999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                      UnicodeString& appendTo,
1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                      FieldPosition& fieldPosition) const
1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return format((int64_t)number, appendTo, fieldPosition);
1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
100550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
100650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::format(int32_t number,
100750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UnicodeString& appendTo,
100854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                      FieldPosition& fieldPosition,
100954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                      UErrorCode& status) const
101054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{
101154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return format((int64_t)number, appendTo, fieldPosition, status);
101254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
101354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
101454dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString&
101554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusDecimalFormat::format(int32_t number,
101654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                      UnicodeString& appendTo,
101750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      FieldPositionIterator* posIter,
101850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UErrorCode& status) const
101950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
102050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return format((int64_t)number, appendTo, posIter, status);
102150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
102250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1023103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1024103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
1025103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid DecimalFormat::handleChanged() {
1026103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  DecimalFormatInternal &data = internalData(fReserved);
1027103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
102854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  if(data.fFastFormatStatus == kFastpathUNKNOWN || data.fFastParseStatus == kFastpathUNKNOWN) {
1029103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return; // still constructing. Wait.
1030103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  }
1031103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
103254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  data.fFastParseStatus = data.fFastFormatStatus = kFastpathNO;
1033103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
103454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if UCONFIG_HAVE_PARSEALLINPUT
103554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  if(fParseAllInput == UNUM_NO) {
103654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No Parse fastpath: fParseAllInput==UNUM_NO");
103754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else
103854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
103954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  if (fFormatWidth!=0) {
104054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      debug("No Parse fastpath: fFormatWidth");
104154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else if(fPositivePrefix.length()>0) {
104254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No Parse fastpath: positive prefix");
104354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else if(fPositiveSuffix.length()>0) {
104454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No Parse fastpath: positive suffix");
104554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else if(fNegativePrefix.length()>1
104654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            || ((fNegativePrefix.length()==1) && (fNegativePrefix.charAt(0)!=0x002D))) {
104754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No Parse fastpath: negative prefix that isn't '-'");
104854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else if(fNegativeSuffix.length()>0) {
104954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No Parse fastpath: negative suffix");
105054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else {
105154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    data.fFastParseStatus = kFastpathYES;
105254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("parse fastpath: YES");
105354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  }
105454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
105554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  if (fGroupingSize!=0 && isGroupingUsed()) {
105654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fGroupingSize!=0 and grouping is used");
105754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#ifdef FMT_DEBUG
105854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    printf("groupingsize=%d\n", fGroupingSize);
105954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
106054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else if(fGroupingSize2!=0 && isGroupingUsed()) {
106154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fGroupingSize2!=0");
1062103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(fUseExponentialNotation) {
106354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fUseExponentialNotation");
1064103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(fFormatWidth!=0) {
106554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fFormatWidth!=0");
1066103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(fMinSignificantDigits!=1) {
106754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fMinSignificantDigits!=1");
1068103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(fMultiplier!=NULL) {
106954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fMultiplier!=NULL");
10708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius  } else if(fScale!=0) {
10718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    debug("No format fastpath: fScale!=0");
1072103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(0x0030 != getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0)) {
107354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: 0x0030 != getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0)");
1074103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(fDecimalSeparatorAlwaysShown) {
107554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fDecimalSeparatorAlwaysShown");
1076103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(getMinimumFractionDigits()>0) {
107754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fMinFractionDigits>0");
1078103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else if(fCurrencySignCount > fgCurrencySignCountZero) {
107954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fCurrencySignCount > fgCurrencySignCountZero");
108054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  } else if(fRoundingIncrement!=0) {
108154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("No format fastpath: fRoundingIncrement!=0");
1082103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } else {
108354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    data.fFastFormatStatus = kFastpathYES;
108454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    debug("format:kFastpathYES!");
1085103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  }
108654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
108754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
1088103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
1089103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
109150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::format(int64_t number,
1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                      UnicodeString& appendTo,
1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                      FieldPosition& fieldPosition) const
1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
109754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UErrorCode status = U_ZERO_ERROR; /* ignored */
109854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    FieldPositionOnlyHandler handler(fieldPosition);
109954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return _format(number, appendTo, handler, status);
110054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
110154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
110254dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString&
110354dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusDecimalFormat::format(int64_t number,
110454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                      UnicodeString& appendTo,
110554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                      FieldPosition& fieldPosition,
110654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                      UErrorCode& status) const
110754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{
110854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    FieldPositionOnlyHandler handler(fieldPosition);
110954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return _format(number, appendTo, handler, status);
111050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
111250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
111350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::format(int64_t number,
111450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UnicodeString& appendTo,
111550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      FieldPositionIterator* posIter,
111650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UErrorCode& status) const
111750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
111850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FieldPositionIteratorHandler handler(posIter, status);
111954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return _format(number, appendTo, handler, status);
112050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
112250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
112350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::_format(int64_t number,
112450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UnicodeString& appendTo,
112554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                       FieldPositionHandler& handler,
112654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                       UErrorCode &status) const
112750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
1128103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // Bottleneck function for formatting int64_t
112954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (U_FAILURE(status)) {
113054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return appendTo;
113154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
1132103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1133103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
1134103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  // const UnicodeString *posPrefix = fPosPrefixPattern;
1135103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  // const UnicodeString *posSuffix = fPosSuffixPattern;
1136103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  // const UnicodeString *negSuffix = fNegSuffixPattern;
1137103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1138103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  const DecimalFormatInternal &data = internalData(fReserved);
1139103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1140103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
1141103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  data.dump();
1142103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  printf("fastpath? [%d]\n", number);
1143103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1144103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
114554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  if( data.fFastFormatStatus==kFastpathYES) {
1146103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1147103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define kZero 0x0030
1148103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    const int32_t MAX_IDX = MAX_DIGITS+2;
1149103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UChar outputStr[MAX_IDX];
1150103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t destIdx = MAX_IDX;
1151103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    outputStr[--destIdx] = 0;  // term
1152103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1153103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int64_t  n = number;
1154103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (number < 1) {
1155103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      // Negative numbers are slightly larger than positive
1156103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      // output the first digit (or the leading zero)
1157103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      outputStr[--destIdx] = (-(n % 10) + kZero);
1158103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      n /= -10;
1159103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1160103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // get any remaining digits
1161103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    while (n > 0) {
1162103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      outputStr[--destIdx] = (n % 10) + kZero;
1163103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      n /= 10;
1164103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1165103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1166103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1167103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Slide the number to the start of the output str
1168103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    U_ASSERT(destIdx >= 0);
1169103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t length = MAX_IDX - destIdx -1;
117054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*int32_t prefixLen = */ appendAffix(appendTo, number, handler, number<0, TRUE);
1171103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t maxIntDig = getMaximumIntegerDigits();
117254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinned to max int digits
117354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
117454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if(length>maxIntDig && fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS)) {
117554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      status = U_ILLEGAL_ARGUMENT_ERROR;
117654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
117754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
117854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t prependZero = getMinimumIntegerDigits() - destlength;
1179103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1180103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
118154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    printf("prependZero=%d, length=%d, minintdig=%d maxintdig=%d destlength=%d skip=%d\n", prependZero, length, getMinimumIntegerDigits(), maxIntDig, destlength, length-destlength);
1182103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1183103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t intBegin = appendTo.length();
1184103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1185103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    while((prependZero--)>0) {
118654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      appendTo.append((UChar)0x0030); // '0'
1187103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1188103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
118954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    appendTo.append(outputStr+destIdx+
119054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    (length-destlength), // skip any leading digits
119154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    destlength);
1192103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handler.addAttribute(kIntegerField, intBegin, appendTo.length());
1193103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
119454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /*int32_t suffixLen =*/ appendAffix(appendTo, number, handler, number<0, FALSE);
1195103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1196103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    //outputStr[length]=0;
1197103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1198103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
1199103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        printf("Writing [%s] length [%d] max %d for [%d]\n", outputStr+destIdx, length, MAX_IDX, number);
1200103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1201103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1202103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#undef kZero
1203103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1204103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return appendTo;
1205103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } // end fastpath
1206103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1207103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1208103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  // Else the slow way - via DigitList
120950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DigitList digits;
121050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    digits.set(number);
121150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return _format(digits, appendTo, handler, status);
1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
121350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::format(  double number,
1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UnicodeString& appendTo,
1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        FieldPosition& fieldPosition) const
1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
122154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UErrorCode status = U_ZERO_ERROR; /* ignored */
122254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    FieldPositionOnlyHandler handler(fieldPosition);
122354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return _format(number, appendTo, handler, status);
122454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
122554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
122654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString&
122754dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusDecimalFormat::format(  double number,
122854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        UnicodeString& appendTo,
122954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        FieldPosition& fieldPosition,
123054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        UErrorCode& status) const
123154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{
123250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FieldPositionOnlyHandler handler(fieldPosition);
123354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return _format(number, appendTo, handler, status);
123450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
123650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
123750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::format(  double number,
123850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UnicodeString& appendTo,
123950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        FieldPositionIterator* posIter,
124050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UErrorCode& status) const
124150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
124250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  FieldPositionIteratorHandler handler(posIter, status);
124354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  return _format(number, appendTo, handler, status);
124450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
124550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
124650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
124750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::_format( double number,
124850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UnicodeString& appendTo,
124954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        FieldPositionHandler& handler,
125054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        UErrorCode &status) const
125150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
125254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (U_FAILURE(status)) {
125354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return appendTo;
125454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Special case for NaN, sets the begin and end index to be the
1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // the string length of localized name of NaN.
125750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // TODO:  let NaNs go through DigitList.
1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (uprv_isNaN(number))
1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
126050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int begin = appendTo.length();
126150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
126250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
126350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kIntegerField, begin, appendTo.length());
126450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
126550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        addPadding(appendTo, handler, 0, 0);
126650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return appendTo;
126750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
126850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
126950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DigitList digits;
127050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    digits.set(number);
127150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    _format(digits, appendTo, handler, status);
127250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // No way to return status from here.
127350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return appendTo;
127450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
127550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
127650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//------------------------------------------------------------------------------
127750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
127950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
128050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::format(const StringPiece &number,
128150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UnicodeString &toAppendTo,
128250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      FieldPositionIterator *posIter,
128350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UErrorCode &status) const
128450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
1285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
1286103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  // don't bother if the int64 path is not optimized
1287103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  int32_t len    = number.length();
1288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  if(len>0&&len<10) { /* 10 or more digits may not be an int64 */
1290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    const char *data = number.data();
1291103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int64_t num = 0;
1292103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UBool neg = FALSE;
1293103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UBool ok = TRUE;
1294103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1295103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t start  = 0;
1296103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1297103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(data[start]=='+') {
1298103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      start++;
1299103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    } else if(data[start]=='-') {
1300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      neg=TRUE;
1301103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      start++;
1302103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1303103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1304103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t place = 1; /* 1, 10, ... */
1305103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    for(int32_t i=len-1;i>=start;i--) {
1306103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      if(data[i]>='0'&&data[i]<='9') {
1307103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        num+=place*(int64_t)(data[i]-'0');
1308103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      } else {
1309103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        ok=FALSE;
1310103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        break;
1311103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      }
1312103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      place *= 10;
1313103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1315103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(ok) {
1316103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      if(neg) {
1317103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        num = -num;// add minus bit
1318103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      }
1319103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      // format as int64_t
1320103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      return format(num, toAppendTo, posIter, status);
1321103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1322103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // else fall through
1323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  }
1324103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1325103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
132650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DigitList   dnum;
132750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    dnum.set(number, status);
132850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
132950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return toAppendTo;
133050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
133150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FieldPositionIteratorHandler handler(posIter, status);
133250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    _format(dnum, toAppendTo, handler, status);
133350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return toAppendTo;
133450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
133550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
133650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
133750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
133850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::format(const DigitList &number,
133950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UnicodeString &appendTo,
134050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      FieldPositionIterator *posIter,
134150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UErrorCode &status) const {
134250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FieldPositionIteratorHandler handler(posIter, status);
134350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    _format(number, appendTo, handler, status);
134450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return appendTo;
134550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
134650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
134750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
134850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
134950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
135050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::format(const DigitList &number,
135150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UnicodeString& appendTo,
135250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     FieldPosition& pos,
135350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                     UErrorCode &status) const {
135450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FieldPositionOnlyHandler handler(pos);
135550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    _format(number, appendTo, handler, status);
135650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return appendTo;
135750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
135850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
13598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusDigitList&
13608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusDecimalFormat::_round(const DigitList &number, DigitList &adjustedNum, UBool& isNegative, UErrorCode &status) const {
13618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_FAILURE(status)) {
13628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return adjustedNum;
13638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
13648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    adjustedNum = number;
13658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    isNegative = false;
13668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (number.isNaN()) {
13678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return adjustedNum;
1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1370c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // Do this BEFORE checking to see if value is infinite or negative! Sets the
1371c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // begin and end index to be length of the string composed of
1372c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // localized name of Infinite and the positive/negative localized
1373c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // signs.
1374c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
137550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    adjustedNum.setRoundingMode(fRoundingMode);
137650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fMultiplier != NULL) {
137750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        adjustedNum.mult(*fMultiplier, status);
13788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (U_FAILURE(status)) {
13798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return adjustedNum;
13808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
138150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
1382c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
13838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (fScale != 0) {
13848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        DigitList ten;
13858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        ten.set(10);
13868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (fScale > 0) {
13878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            for (int32_t i = fScale ; i > 0 ; i--) {
13888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                adjustedNum.mult(ten, status);
13898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                if (U_FAILURE(status)) {
13908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    return adjustedNum;
13918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
13928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
13938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        } else {
13948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            for (int32_t i = fScale ; i < 0 ; i++) {
13958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                adjustedNum.div(ten, status);
13968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                if (U_FAILURE(status)) {
13978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    return adjustedNum;
13988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
13998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
14008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
14018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
14028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*
140450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Note: sign is important for zero as well as non-zero numbers.
140550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Proper detection of -0.0 is needed to deal with the
1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
14088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    isNegative = !adjustedNum.isPositive();
1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Apply rounding after multiplier
14118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    adjustedNum.fContext.status &= ~DEC_Inexact;
1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fRoundingIncrement != NULL) {
141450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        adjustedNum.div(*fRoundingIncrement, status);
141550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        adjustedNum.toIntegralValue();
141650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        adjustedNum.mult(*fRoundingIncrement, status);
141750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        adjustedNum.trim();
14188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (U_FAILURE(status)) {
14198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return adjustedNum;
14208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) {
1423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_FORMAT_INEXACT_ERROR;
14248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return adjustedNum;
1425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
142750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (adjustedNum.isInfinite()) {
14288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return adjustedNum;
1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
143127f654740f2a26ad62a5c155af9199af9e69b889claireho    if (fUseExponentialNotation || areSignificantDigitsUsed()) {
143227f654740f2a26ad62a5c155af9199af9e69b889claireho        int32_t sigDigits = precision();
143327f654740f2a26ad62a5c155af9199af9e69b889claireho        if (sigDigits > 0) {
143427f654740f2a26ad62a5c155af9199af9e69b889claireho            adjustedNum.round(sigDigits);
1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
143627f654740f2a26ad62a5c155af9199af9e69b889claireho    } else {
143727f654740f2a26ad62a5c155af9199af9e69b889claireho        // Fixed point format.  Round to a set number of fraction digits.
143827f654740f2a26ad62a5c155af9199af9e69b889claireho        int32_t numFractionDigits = precision();
143927f654740f2a26ad62a5c155af9199af9e69b889claireho        adjustedNum.roundFixedPoint(numFractionDigits);
1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) {
1442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_FORMAT_INEXACT_ERROR;
14438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return adjustedNum;
14448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
14458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    return adjustedNum;
14468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}
14478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString&
14498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusDecimalFormat::_format(const DigitList &number,
14508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        UnicodeString& appendTo,
14518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        FieldPositionHandler& handler,
14528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        UErrorCode &status) const
14538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{
14548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_FAILURE(status)) {
14558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return appendTo;
14568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
14578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // Special case for NaN, sets the begin and end index to be the
14598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // the string length of localized name of NaN.
14608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (number.isNaN())
14618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    {
14628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        int begin = appendTo.length();
14638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
14648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        handler.addAttribute(kIntegerField, begin, appendTo.length());
14668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        addPadding(appendTo, handler, 0, 0);
14688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return appendTo;
14698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
14708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    DigitList adjustedNum;
14728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UBool isNegative;
14738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    _round(number, adjustedNum, isNegative, status);
14748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (U_FAILURE(status)) {
14758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return appendTo;
14768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    }
14778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // Special case for INFINITE,
14798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (adjustedNum.isInfinite()) {
14808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        int32_t prefixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, TRUE);
14818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        int begin = appendTo.length();
14838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
14848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        handler.addAttribute(kIntegerField, begin, appendTo.length());
14868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        int32_t suffixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, FALSE);
14888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
14898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        addPadding(appendTo, handler, prefixLen, suffixLen);
1490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return appendTo;
1491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
149254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return subformat(appendTo, handler, adjustedNum, FALSE, status);
1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::format(  const Formattable& obj,
1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UnicodeString& appendTo,
1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        FieldPosition& fieldPosition,
1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UErrorCode& status) const
1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return NumberFormat::format(obj, appendTo, fieldPosition, status);
1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return true if a grouping separator belongs at the given
1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * position, based on whether grouping is in use and the values of
1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the primary and secondary grouping interval.
1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param pos the number of integer digits to the right of
1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the current position.  Zero indicates the position after the
1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rightmost integer digit.
1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return true if a grouping character belongs at the current
1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * position.
1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool DecimalFormat::isGroupingPosition(int32_t pos) const {
1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool result = FALSE;
1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) {
1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) {
1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result = ((pos - fGroupingSize) % fGroupingSize2) == 0;
1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result = pos % fGroupingSize == 0;
1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return result;
1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
152950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Complete the formatting of a finite number.  On entry, the DigitList must
1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * be filled in with the correct digits.
1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::subformat(UnicodeString& appendTo,
153450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         FieldPositionHandler& handler,
1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         DigitList&     digits,
153654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                         UBool          isInteger,
153754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                         UErrorCode& status) const
1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
153927f654740f2a26ad62a5c155af9199af9e69b889claireho    // char zero = '0';
154027f654740f2a26ad62a5c155af9199af9e69b889claireho    // DigitList returns digits as '0' thru '9', so we will need to
154127f654740f2a26ad62a5c155af9199af9e69b889claireho    // always need to subtract the character 0 to get the numeric value to use for indexing.
154227f654740f2a26ad62a5c155af9199af9e69b889claireho
154327f654740f2a26ad62a5c155af9199af9e69b889claireho    UChar32 localizedDigits[10];
154427f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[0] = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
154527f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[1] = getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol).char32At(0);
154627f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[2] = getConstSymbol(DecimalFormatSymbols::kTwoDigitSymbol).char32At(0);
154727f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[3] = getConstSymbol(DecimalFormatSymbols::kThreeDigitSymbol).char32At(0);
154827f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[4] = getConstSymbol(DecimalFormatSymbols::kFourDigitSymbol).char32At(0);
154927f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[5] = getConstSymbol(DecimalFormatSymbols::kFiveDigitSymbol).char32At(0);
155027f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[6] = getConstSymbol(DecimalFormatSymbols::kSixDigitSymbol).char32At(0);
155127f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[7] = getConstSymbol(DecimalFormatSymbols::kSevenDigitSymbol).char32At(0);
155227f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[8] = getConstSymbol(DecimalFormatSymbols::kEightDigitSymbol).char32At(0);
155327f654740f2a26ad62a5c155af9199af9e69b889claireho    localizedDigits[9] = getConstSymbol(DecimalFormatSymbols::kNineDigitSymbol).char32At(0);
155427f654740f2a26ad62a5c155af9199af9e69b889claireho
1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString *grouping ;
1556b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if(fCurrencySignCount > fgCurrencySignCountZero) {
1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }else{
1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString *decimal;
1562b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if(fCurrencySignCount > fgCurrencySignCountZero) {
1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool useSigDig = areSignificantDigitsUsed();
1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t maxIntDig = getMaximumIntegerDigits();
1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t minIntDig = getMinimumIntegerDigits();
1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Appends the prefix.
1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    double doubleValue = digits.getDouble();
157350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t prefixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), TRUE);
1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fUseExponentialNotation)
1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
157750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int currentLength = appendTo.length();
157850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int intBegin = currentLength;
157950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int intEnd = -1;
158050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int fracBegin = -1;
1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t minFracDig = 0;
1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (useSigDig) {
1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            maxIntDig = minIntDig = 1;
1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            minFracDig = getMinimumSignificantDigits() - 1;
1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            minFracDig = getMinimumFractionDigits();
1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (maxIntDig > kMaxScientificIntegerDigits) {
1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                maxIntDig = 1;
1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (maxIntDig < minIntDig) {
1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    maxIntDig = minIntDig;
1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (maxIntDig > minIntDig) {
1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                minIntDig = 1;
1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Minimum integer digits are handled in exponential format by
1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // adjusting the exponent.  For example, 0.01234 with 3 minimum
1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // integer digits is "123.4E-4".
1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Maximum integer digits are interpreted as indicating the
1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // repeating range.  This is useful for engineering notation, in
1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // which the exponent is restricted to a multiple of 3.  For
1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // If maximum integer digits are defined and are larger than
1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // minimum integer digits, then minimum integer digits are
1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // ignored.
161050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        digits.reduce();   // Removes trailing zero digits.
161150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t exponent = digits.getDecimalAt();
1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (maxIntDig > 1 && maxIntDig != minIntDig) {
1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // A exponent increment is defined; adjust to it.
1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            exponent = (exponent > 0) ? (exponent - 1) / maxIntDig
1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                      : (exponent / maxIntDig) - 1;
1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            exponent *= maxIntDig;
1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // No exponent increment is defined; use minimum integer digits.
1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // If none is specified, as in "#E0", generate 1 integer digit.
1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            exponent -= (minIntDig > 0 || minFracDig > 0)
1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ? minIntDig : 1;
1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // We now output a minimum number of digits, and more if there
1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // are more digits, up to the maximum number of digits.  We
1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // place the decimal point after the "integer" digits, which
1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // are the first (decimalAt - exponent) digits.
1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t minimumDigits =  minIntDig + minFracDig;
1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // The number of integer digits is handled specially if the number
1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // is zero, since then there may be no digits.
1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t integerDigits = digits.isZero() ? minIntDig :
163250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            digits.getDecimalAt() - exponent;
163350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t totalDigits = digits.getCount();
1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (minimumDigits > totalDigits)
1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            totalDigits = minimumDigits;
1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (integerDigits > totalDigits)
1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            totalDigits = integerDigits;
1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // totalDigits records total number of digits needs to be processed
1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t i;
1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (i=0; i<totalDigits; ++i)
1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (i == integerDigits)
1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
164550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                intEnd = appendTo.length();
164650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.addAttribute(kIntegerField, intBegin, intEnd);
1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo += *decimal;
1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
165050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                fracBegin = appendTo.length();
165150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.addAttribute(kDecimalSeparatorField, fracBegin - 1, fracBegin);
1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Restores the digit character or pads the buffer with zeros.
165450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            UChar32 c = (UChar32)((i < digits.getCount()) ?
165527f654740f2a26ad62a5c155af9199af9e69b889claireho                          localizedDigits[digits.getDigitValue(i)] :
165627f654740f2a26ad62a5c155af9199af9e69b889claireho                          localizedDigits[0]);
1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendTo += c;
1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
166050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        currentLength = appendTo.length();
166150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
166250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (intEnd < 0) {
166350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            handler.addAttribute(kIntegerField, intBegin, currentLength);
1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
166550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (fracBegin > 0) {
166650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            handler.addAttribute(kFractionField, fracBegin, currentLength);
1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // The exponent is output using the pattern-specified minimum
1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // exponent digits.  There is no maximum limit to the exponent
1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // digits, since truncating the exponent would appendTo in an
1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // unacceptable inaccuracy.
1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
167550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kExponentSymbolField, currentLength, appendTo.length());
167650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        currentLength = appendTo.length();
167750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // For zero values, we force the exponent to zero.  We
1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // must do this here, and not earlier, because the value
1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // is used to determine integer digit count above.
1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (digits.isZero())
1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            exponent = 0;
1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (exponent < 0) {
1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
168650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            handler.addAttribute(kExponentSignField, currentLength, appendTo.length());
1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if (fExponentSignAlwaysShown) {
1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
168950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            handler.addAttribute(kExponentSignField, currentLength, appendTo.length());
1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
169250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        currentLength = appendTo.length();
169350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        DigitList expDigits;
1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        expDigits.set(exponent);
1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int expDig = fMinExponentDigits;
1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fUseExponentialNotation && expDig < 1) {
1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                expDig = 1;
1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
170150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            for (i=expDigits.getDecimalAt(); i<expDig; ++i)
170227f654740f2a26ad62a5c155af9199af9e69b889claireho                appendTo += (localizedDigits[0]);
1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
170450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        for (i=0; i<expDigits.getDecimalAt(); ++i)
1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
170650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            UChar32 c = (UChar32)((i < expDigits.getCount()) ?
170727f654740f2a26ad62a5c155af9199af9e69b889claireho                          localizedDigits[expDigits.getDigitValue(i)] :
170827f654740f2a26ad62a5c155af9199af9e69b889claireho                          localizedDigits[0]);
1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendTo += c;
1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
171150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
171250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kExponentField, currentLength, appendTo.length());
1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else  // Not using exponential notation
1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
171650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int currentLength = appendTo.length();
171750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int intBegin = currentLength;
1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t sigCount = 0;
1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t minSigDig = getMinimumSignificantDigits();
1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t maxSigDig = getMaximumSignificantDigits();
1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!useSigDig) {
1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            minSigDig = 0;
1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            maxSigDig = INT32_MAX;
1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Output the integer portion.  Here 'count' is the total
1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // number of integer digits we will display, including both
1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // leading zeros required to satisfy getMinimumIntegerDigits,
1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // and actual digits present in the number.
1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t count = useSigDig ?
173250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            _max(1, digits.getDecimalAt()) : minIntDig;
173350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (digits.getDecimalAt() > 0 && count < digits.getDecimalAt()) {
173450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            count = digits.getDecimalAt();
1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Handle the case where getMaximumIntegerDigits() is smaller
1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // than the real number of integer digits.  If this is so, we
1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // output the least significant max integer digits.  For example,
1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // the value 1997 printed with 2 max integer digits is just "97".
1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t digitIndex = 0; // Index into digitList.fDigits[]
1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (count > maxIntDig && maxIntDig >= 0) {
1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            count = maxIntDig;
174550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            digitIndex = digits.getDecimalAt() - count;
174654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if(fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS)) {
174754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                status = U_ILLEGAL_ARGUMENT_ERROR;
174854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            }
1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t sizeBeforeIntegerPart = appendTo.length();
1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t i;
1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (i=count-1; i>=0; --i)
1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
175650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (i < digits.getDecimalAt() && digitIndex < digits.getCount() &&
1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                sigCount < maxSigDig) {
1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Output a real digit
175927f654740f2a26ad62a5c155af9199af9e69b889claireho                appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)];
1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ++sigCount;
1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            else
1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Output a zero (leading or trailing)
176527f654740f2a26ad62a5c155af9199af9e69b889claireho                appendTo += localizedDigits[0];
1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (sigCount > 0) {
1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ++sigCount;
1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Output grouping separator if necessary.
1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (isGroupingPosition(i)) {
177350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                currentLength = appendTo.length();
1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo.append(*grouping);
177550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.addAttribute(kGroupingSeparatorField, currentLength, appendTo.length());
1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
177950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // TODO(dlf): this looks like it was a bug, we marked the int field as ending
178050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // before the zero was generated.
1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Record field information for caller.
178250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // if (fieldPosition.getField() == NumberFormat::kIntegerField)
178350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //     fieldPosition.setEndIndex(appendTo.length());
1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Determine whether or not there are any printable fractional
1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // digits.  If we've used up the digits we know there aren't.
178750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UBool fractionPresent = (!isInteger && digitIndex < digits.getCount()) ||
1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0));
1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // If there is no fraction present, and we haven't printed any
1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // integer digits, then print a zero.  Otherwise we won't print
1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // _any_ digits, and we won't be able to parse this string.
1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart)
179427f654740f2a26ad62a5c155af9199af9e69b889claireho            appendTo += localizedDigits[0];
1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
179650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        currentLength = appendTo.length();
179750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kIntegerField, intBegin, currentLength);
179850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Output the decimal separator if we always do so.
180050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (fDecimalSeparatorAlwaysShown || fractionPresent) {
1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendTo += *decimal;
180250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            handler.addAttribute(kDecimalSeparatorField, currentLength, appendTo.length());
180350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            currentLength = appendTo.length();
180450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
180650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int fracBegin = currentLength;
1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count = useSigDig ? INT32_MAX : getMaximumFractionDigits();
1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (useSigDig && (sigCount == maxSigDig ||
181050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          (sigCount >= minSigDig && digitIndex == digits.getCount()))) {
1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            count = 0;
1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (i=0; i < count; ++i) {
1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Here is where we escape from the loop.  We escape
1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // if we've output the maximum fraction digits
1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // (specified in the for expression above).  We also
1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // stop when we've output the minimum digits and
1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // either: we have an integer, so there is no
1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // fractional stuff to display, or we're out of
1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // significant digits.
1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (!useSigDig && i >= getMinimumFractionDigits() &&
182350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                (isInteger || digitIndex >= digits.getCount())) {
1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Output leading fractional zeros.  These are zeros
1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // that come after the decimal but before any
1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // significant digits.  These are only output if
1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // abs(number being formatted) < 1.0.
183150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (-1-i > (digits.getDecimalAt()-1)) {
183227f654740f2a26ad62a5c155af9199af9e69b889claireho                appendTo += localizedDigits[0];
1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                continue;
1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Output a digit, if we have any precision left, or a
1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // zero if we don't.  We don't want to output noise digits.
183850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (!isInteger && digitIndex < digits.getCount()) {
183927f654740f2a26ad62a5c155af9199af9e69b889claireho                appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)];
1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
184127f654740f2a26ad62a5c155af9199af9e69b889claireho                appendTo += localizedDigits[0];
1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // If we reach the maximum number of significant
1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // digits, or if we output all the real digits and
1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // reach the minimum, then we are done.
1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ++sigCount;
1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (useSigDig &&
1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (sigCount == maxSigDig ||
185050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 (digitIndex == digits.getCount() && sigCount >= minSigDig))) {
1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
185550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kFractionField, fracBegin, appendTo.length());
1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
185850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t suffixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), FALSE);
1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
186050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    addPadding(appendTo, handler, prefixLen, suffixLen);
1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return appendTo;
1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Inserts the character fPad as needed to expand result to fFormatWidth.
1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param result the string to be padded
1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::addPadding(UnicodeString& appendTo,
186950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               FieldPositionHandler& handler,
1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               int32_t prefixLen,
1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               int32_t suffixLen) const
1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0) {
1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t len = fFormatWidth - appendTo.length();
1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (len > 0) {
1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UnicodeString padding;
1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            for (int32_t i=0; i<len; ++i) {
1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                padding += fPad;
1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            switch (fPadPosition) {
1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPadAfterPrefix:
1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo.insert(prefixLen, padding);
1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPadBeforePrefix:
1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo.insert(0, padding);
1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPadBeforeSuffix:
1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo.insert(appendTo.length() - suffixLen, padding);
1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPadAfterSuffix:
1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo += padding;
1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
189450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (fPadPosition == kPadBeforePrefix || fPadPosition == kPadAfterPrefix) {
189550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.shiftLast(len);
1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
190250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::parse(const UnicodeString& text,
1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     Formattable& result,
1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     UErrorCode& status) const
1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormat::parse(text, result, status);
1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::parse(const UnicodeString& text,
1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     Formattable& result,
1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     ParsePosition& parsePosition) const {
1915103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    parse(text, result, parsePosition, NULL);
1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1918103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusCurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text,
1919103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                                             ParsePosition& pos) const {
1920103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Formattable parseResult;
1921103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t start = pos.getIndex();
19228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UChar curbuf[4] = {};
1923103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    parse(text, parseResult, pos, curbuf);
1924103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (pos.getIndex() != start) {
1925103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UErrorCode ec = U_ZERO_ERROR;
1926103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, curbuf, ec));
1927103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (U_FAILURE(ec)) {
1928103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            pos.setIndex(start); // indicate failure
1929103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1930103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return currAmt.orphan();
1931103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1932103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1933103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return NULL;
1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
1937103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Parses the given text as a number, optionally providing a currency amount.
1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param text the string to parse
1939103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * @param result output parameter for the numeric result.
1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param parsePosition input-output position; on input, the
1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * position within text to match; must have 0 <= pos.getIndex() <
1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * text.length(); on output, the position after the last matched
1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * character. If the parse fails, the position in unchanged upon
1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * output.
1945103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * @param currency if non-NULL, it should point to a 4-UChar buffer.
1946103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * In this case the text is parsed as a currency format, and the
1947103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * ISO 4217 code for the parsed currency is put into the buffer.
1948103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Otherwise the text is parsed as a non-currency format.
1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::parse(const UnicodeString& text,
1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                          Formattable& result,
1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                          ParsePosition& parsePosition,
1953103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                          UChar* currency) const {
1954103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t startIdx, backup;
1955103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t i = startIdx = backup = parsePosition.getIndex();
1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
195750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // clear any old contents in the result.  In particular, clears any DigitList
195850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //   that it may be holding.
195950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    result.setLong(0);
196050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Handle NaN as a special case:
196250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Skip padding characters, if around prefix
1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix ||
1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             fPadPosition == kPadAfterPrefix)) {
1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i = skipPadding(text, i);
1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1968b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1969b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (isLenient()) {
1970b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // skip any leading whitespace
1971b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        i = backup = skipUWhiteSpace(text, i);
1972b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
1973b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // If the text is composed of the representation of NaN, returns NaN.length
1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t nanLen = (text.compare(i, nan->length(), *nan)
1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                      ? 0 : nan->length());
1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (nanLen) {
1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i += nanLen;
1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix ||
1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 fPadPosition == kPadAfterSuffix)) {
1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            i = skipPadding(text, i);
1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        parsePosition.setIndex(i);
1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result.setDouble(uprv_getNaN());
1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
198850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // NaN parse failed; start over
1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    i = backup;
1991b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    parsePosition.setIndex(i);
1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // status is used to record whether a number is infinite.
1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool status[fgStatusLength];
1995103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1996103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DigitList *digits = result.getInternalDigitList(); // get one from the stack buffer
199750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (digits == NULL) {
199850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;    // no way to report error from here.
199950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2001b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencySignCount > fgCurrencySignCountZero) {
200250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (!parseForCurrency(text, parsePosition, *digits,
2003b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              status, currency)) {
2004103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          return;
2005b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
2006b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
200750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (!subparse(text,
2008b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                      fNegPrefixPattern, fNegSuffixPattern,
2009b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                      fPosPrefixPattern, fPosSuffixPattern,
2010b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                      FALSE, UCURR_SYMBOL_NAME,
201150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      parsePosition, *digits, status, currency)) {
2012103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            debug("!subparse(...) - rewind");
2013103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            parsePosition.setIndex(startIdx);
2014b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            return;
2015b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Handle infinity
2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (status[fgStatusInfinite]) {
2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        double inf = uprv_getInfinity();
202150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.setDouble(digits->isPositive() ? inf : -inf);
2022103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // TODO:  set the dl to infinity, and let it fall into the code below.
2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
202750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (fMultiplier != NULL) {
202850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            UErrorCode ec = U_ZERO_ERROR;
202950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            digits->div(*fMultiplier, ec);
2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
203150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        if (fScale != 0) {
20338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            DigitList ten;
20348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            ten.set(10);
20358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (fScale > 0) {
20368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                for (int32_t i = fScale; i > 0; i--) {
20378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    UErrorCode ec = U_ZERO_ERROR;
20388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    digits->div(ten,ec);
20398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
20408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            } else {
20418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                for (int32_t i = fScale; i < 0; i++) {
20428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    UErrorCode ec = U_ZERO_ERROR;
20438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    digits->mult(ten,ec);
20448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
20458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
20468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
20478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
204850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Negative zero special case:
204950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //    if parsing integerOnly, change to +0, which goes into an int32 in a Formattable.
205050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //    if not parsing integerOnly, leave as -0, which a double can represent.
205150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) {
205250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            digits->setPositive(TRUE);
2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
205450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.adoptDigitList(digits);
2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2059b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
2060b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUBool
2061b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::parseForCurrency(const UnicodeString& text,
2062b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                ParsePosition& parsePosition,
2063b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                DigitList& digits,
2064b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                UBool* status,
2065b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                UChar* currency) const {
2066b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int origPos = parsePosition.getIndex();
2067b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int maxPosIndex = origPos;
2068b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int maxErrorPos = -1;
2069b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // First, parse against current pattern.
2070b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // Since current pattern could be set by applyPattern(),
2071b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // it could be an arbitrary pattern, and it may not be the one
2072b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // defined in current locale.
2073b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UBool tmpStatus[fgStatusLength];
2074b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ParsePosition tmpPos(origPos);
2075b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    DigitList tmpDigitList;
2076b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UBool found;
2077b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fStyle == UNUM_CURRENCY_PLURAL) {
207850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        found = subparse(text,
2079b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         fNegPrefixPattern, fNegSuffixPattern,
2080b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         fPosPrefixPattern, fPosSuffixPattern,
2081b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         TRUE, UCURR_LONG_NAME,
2082b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         tmpPos, tmpDigitList, tmpStatus, currency);
2083b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
208450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        found = subparse(text,
2085b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         fNegPrefixPattern, fNegSuffixPattern,
2086b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         fPosPrefixPattern, fPosSuffixPattern,
2087b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         TRUE, UCURR_SYMBOL_NAME,
2088b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         tmpPos, tmpDigitList, tmpStatus, currency);
2089b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
2090b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (found) {
2091b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (tmpPos.getIndex() > maxPosIndex) {
2092b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            maxPosIndex = tmpPos.getIndex();
2093b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            for (int32_t i = 0; i < fgStatusLength; ++i) {
2094b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                status[i] = tmpStatus[i];
2095b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
2096b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            digits = tmpDigitList;
2097b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
2098b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
2099b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        maxErrorPos = tmpPos.getErrorIndex();
2100b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
2101b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // Then, parse against affix patterns.
2102b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // Those are currency patterns and currency plural patterns.
2103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
2104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
2105b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
2106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UHashTok valueTok = element->value;
2107b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)valueTok.pointer;
2108b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UBool tmpStatus[fgStatusLength];
2109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ParsePosition tmpPos(origPos);
2110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        DigitList tmpDigitList;
211150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UBool result = subparse(text,
2112b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                &affixPtn->negPrefixPatternForCurrency,
211350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                &affixPtn->negSuffixPatternForCurrency,
211450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                &affixPtn->posPrefixPatternForCurrency,
2115b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                &affixPtn->posSuffixPatternForCurrency,
2116b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                TRUE, affixPtn->patternType,
2117b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                tmpPos, tmpDigitList, tmpStatus, currency);
2118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (result) {
2119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            found = true;
2120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (tmpPos.getIndex() > maxPosIndex) {
2121b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                maxPosIndex = tmpPos.getIndex();
2122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                for (int32_t i = 0; i < fgStatusLength; ++i) {
2123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    status[i] = tmpStatus[i];
2124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
2125b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                digits = tmpDigitList;
2126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
2127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
2128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?
2129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                          tmpPos.getErrorIndex() : maxErrorPos;
2130b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
2131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
2132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // Finally, parse against simple affix to find the match.
2133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // For example, in TestMonster suite,
2134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // if the to-be-parsed text is "-\u00A40,00".
2135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // complexAffixCompare will not find match,
2136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // since there is no ISO code matches "\u00A4",
2137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // and the parse stops at "\u00A4".
2138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // We will just use simple affix comparison (look for exact match)
2139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // to pass it.
2140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UBool tmpStatus_2[fgStatusLength];
2141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ParsePosition tmpPos_2(origPos);
2142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    DigitList tmpDigitList_2;
2143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // set currencySignCount to 0 so that compareAffix function will
2144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // fall to compareSimpleAffix path, not compareComplexAffix path.
2145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // ?? TODO: is it right? need "false"?
214650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UBool result = subparse(text,
2147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            &fNegativePrefix, &fNegativeSuffix,
2148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            &fPositivePrefix, &fPositiveSuffix,
2149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            FALSE, UCURR_SYMBOL_NAME,
215050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            tmpPos_2, tmpDigitList_2, tmpStatus_2,
2151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            currency);
2152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (result) {
2153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (tmpPos_2.getIndex() > maxPosIndex) {
2154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            maxPosIndex = tmpPos_2.getIndex();
2155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            for (int32_t i = 0; i < fgStatusLength; ++i) {
2156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                status[i] = tmpStatus_2[i];
2157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
2158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            digits = tmpDigitList_2;
2159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
2160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        found = true;
2161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
2162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            maxErrorPos = (tmpPos_2.getErrorIndex() > maxErrorPos) ?
2163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                          tmpPos_2.getErrorIndex() : maxErrorPos;
2164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
2165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
2166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (!found) {
2167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        //parsePosition.setIndex(origPos);
2168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        parsePosition.setErrorIndex(maxErrorPos);
2169b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
2170b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        parsePosition.setIndex(maxPosIndex);
2171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        parsePosition.setErrorIndex(-1);
2172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
2173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return found;
2174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
2175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
2176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
2177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Parse the given text into a number.  The text is parsed beginning at
2179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * parsePosition, until an unparseable character is seen.
2180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param text the string to parse.
2181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param negPrefix negative prefix.
2182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param negSuffix negative suffix.
2183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param posPrefix positive prefix.
2184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param posSuffix positive suffix.
2185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param currencyParsing whether it is currency parsing or not.
2186b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param type the currency type to parse against, LONG_NAME only or not.
2187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param parsePosition The position at which to being parsing.  Upon
2188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * return, the first unparsed character.
2189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param digits the DigitList to set to the parsed value.
2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param status output param containing boolean status flags indicating
2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * whether the value was infinite and whether it was positive.
2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param currency return value for parsed currency, for generic
2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency parsing mode, or NULL for normal parsing. In generic
2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency parsing mode, any currency is parsed, not just the
2195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency that this formatter is set to.
2196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
219750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUBool DecimalFormat::subparse(const UnicodeString& text,
2198b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              const UnicodeString* negPrefix,
2199b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              const UnicodeString* negSuffix,
2200b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              const UnicodeString* posPrefix,
2201b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              const UnicodeString* posSuffix,
2202b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              UBool currencyParsing,
2203b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              int8_t type,
2204b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                              ParsePosition& parsePosition,
2205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                              DigitList& digits, UBool* status,
2206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                              UChar* currency) const
2207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
220850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  The parsing process builds up the number as char string, in the neutral format that
220950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  will be acceptable to the decNumber library, then at the end passes that string
221050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  off for conversion to a decNumber.
221150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode err = U_ZERO_ERROR;
221227f654740f2a26ad62a5c155af9199af9e69b889claireho    CharString parsedNum;
221350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    digits.setToZero();
221450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t position = parsePosition.getIndex();
2216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t oldStart = position;
2217103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t textLength = text.length(); // One less pointer to follow
2218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool strictParse = !isLenient();
2219103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
222054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    const UnicodeString *groupingString = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
222154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UChar32 groupingChar = groupingString->char32At(0);
222254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t groupingStringLength = groupingString->length();
222354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t groupingCharLength   = U16_LENGTH(groupingChar);
222454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UBool   groupingUsed = isGroupingUsed();
2225103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2226103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UChar dbgbuf[300];
2227103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UnicodeString s(dbgbuf,0,300);;
2228103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    s.append((UnicodeString)"PARSE \"").append(text.tempSubString(position)).append((UnicodeString)"\" " );
222954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define DBGAPPD(x) if(x) { s.append(UnicodeString(#x "="));  if(x->isEmpty()) { s.append(UnicodeString("<empty>")); } else { s.append(*x); } s.append(UnicodeString(" ")); } else { s.append(UnicodeString(#x "=NULL ")); }
2230103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DBGAPPD(negPrefix);
2231103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DBGAPPD(negSuffix);
2232103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DBGAPPD(posPrefix);
2233103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DBGAPPD(posSuffix);
2234103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    debugout(s);
223554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    printf("currencyParsing=%d, fFormatWidth=%d, isParseIntegerOnly=%c text.length=%d negPrefLen=%d\n", currencyParsing, fFormatWidth, (isParseIntegerOnly())?'Y':'N', text.length(),  negPrefix!=NULL?negPrefix->length():-1);
2236103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2238103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UBool fastParseOk = false; /* TRUE iff fast parse is OK */
22398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // UBool fastParseHadDecimal = FALSE; /* true if fast parse saw a decimal point. */
224054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    const DecimalFormatInternal &data = internalData(fReserved);
224154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if((data.fFastParseStatus==kFastpathYES) &&
224254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       !currencyParsing &&
224354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       //       (negPrefix!=NULL&&negPrefix->isEmpty()) ||
224454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       text.length()>0 &&
224554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       text.length()<32 &&
224654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       (posPrefix==NULL||posPrefix->isEmpty()) &&
224754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       (posSuffix==NULL||posSuffix->isEmpty()) &&
224854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       //            (negPrefix==NULL||negPrefix->isEmpty()) &&
224954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       //            (negSuffix==NULL||(negSuffix->isEmpty()) ) &&
225054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       TRUE) {  // optimized path
2251103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      int j=position;
2252103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      int l=text.length();
2253103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      int digitCount=0;
2254103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      UChar32 ch = text.char32At(j);
2255103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      const UnicodeString *decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
2256103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      UChar32 decimalChar = 0;
225754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      UBool intOnly = FALSE;
225854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      UChar32 lookForGroup = (groupingUsed&&intOnly&&strictParse)?groupingChar:0;
225954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2260103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      int32_t decimalCount = decimalString->countChar32(0,3);
2261103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      if(isParseIntegerOnly()) {
2262103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        decimalChar = 0; // not allowed
226354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        intOnly = TRUE; // Don't look for decimals.
2264103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      } else if(decimalCount==1) {
226554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        decimalChar = decimalString->char32At(0); // Look for this decimal
2266103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      } else if(decimalCount==0) {
226754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        decimalChar=0; // NO decimal set
2268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      } else {
226954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        j=l+1;//Set counter to end of line, so that we break. Unknown decimal situation.
2270103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      }
2271103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
227254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#ifdef FMT_DEBUG
227354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      printf("Preparing to do fastpath parse: decimalChar=U+%04X, groupingChar=U+%04X, first ch=U+%04X intOnly=%c strictParse=%c\n",
227454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        decimalChar, groupingChar, ch,
227554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        (intOnly)?'y':'n',
227654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        (strictParse)?'y':'n');
227754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
227854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      if(ch==0x002D) { // '-'
227954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        j=l+1;//=break - negative number.
2280103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2281103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        /*
2282103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          parsedNum.append('-',err);
2283103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          j+=U16_LENGTH(ch);
2284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          if(j<l) ch = text.char32At(j);
2285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        */
2286103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      } else {
2287103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        parsedNum.append('+',err);
2288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      }
2289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      while(j<l) {
2290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        int32_t digit = ch - zero;
2291103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if(digit >=0 && digit <= 9) {
2292103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          parsedNum.append((char)(digit + '0'), err);
2293103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          if((digitCount>0) || digit!=0 || j==(l-1)) {
2294103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            digitCount++;
2295103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          }
229654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if(ch == 0) { // break out
229754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          digitCount=-1;
229854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          break;
2299103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if(ch == decimalChar) {
2300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          parsedNum.append((char)('.'), err);
2301103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          decimalChar=0; // no more decimals.
23028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius          // fastParseHadDecimal=TRUE;
230354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if(ch == lookForGroup) {
230454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          // ignore grouping char. No decimals, so it has to be an ignorable grouping sep
230554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if(intOnly && (lookForGroup!=0) && !u_isdigit(ch)) {
230654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          // parsing integer only and can fall through
2307103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
230854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          digitCount=-1; // fail - fall through to slow parse
2309103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          break;
2310103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2311103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        j+=U16_LENGTH(ch);
2312103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        ch = text.char32At(j); // for next
2313103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      }
231454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      if(
231554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         ((j==l)||intOnly) // end OR only parsing integer
231654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius         && (digitCount>0)) { // and have at least one digit
2317103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2318103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        printf("PP -> %d, good = [%s]  digitcount=%d, fGroupingSize=%d fGroupingSize2=%d!\n", j, parsedNum.data(), digitCount, fGroupingSize, fGroupingSize2);
2319103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2320103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        fastParseOk=true; // Fast parse OK!
2321103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2322103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef SKIP_OPT
2323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        debug("SKIP_OPT");
2324103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        /* for testing, try it the slow way. also */
2325103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        fastParseOk=false;
2326103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        parsedNum.clear();
2327103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#else
2328103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        parsePosition.setIndex(position=j);
2329103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        status[fgStatusInfinite]=false;
2330103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2331103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      } else {
2332103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // was not OK. reset, retry
2333103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2334103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        printf("Fall through: j=%d, l=%d, digitCount=%d\n", j, l, digitCount);
2335103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2336103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        parsedNum.clear();
2337103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      }
233854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    } else {
233954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#ifdef FMT_DEBUG
234054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      printf("Could not fastpath parse. ");
234154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      printf("fFormatWidth=%d ", fFormatWidth);
234254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      printf("text.length()=%d ", text.length());
234354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix);
234454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
234554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      printf("\n");
234654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
2347103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
2348103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2349103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  if(!fastParseOk
2350103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_HAVE_PARSEALLINPUT
2351103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     && fParseAllInput!=UNUM_YES
2352103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2353103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     )
2354103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  {
2355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Match padding before prefix
2356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) {
2357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        position = skipPadding(text, position);
2358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Match positive and negative prefixes; prefer longest match.
2361b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, currencyParsing, type, currency);
2362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t negMatch = compareAffix(text, position, TRUE,  TRUE, negPrefix, currencyParsing, type, currency);
2363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (posMatch >= 0 && negMatch >= 0) {
2364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (posMatch > negMatch) {
2365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            negMatch = -1;
2366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if (negMatch > posMatch) {
2367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            posMatch = -1;
236850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
2369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (posMatch >= 0) {
2371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        position += posMatch;
237250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        parsedNum.append('+', err);
2373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else if (negMatch >= 0) {
2374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        position += negMatch;
237550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        parsedNum.append('-', err);
2376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else if (strictParse){
2377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        parsePosition.setErrorIndex(position);
2378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return FALSE;
2379103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    } else {
2380103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // Temporary set positive. This might be changed after checking suffix
2381103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        parsedNum.append('+', err);
2382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Match padding before prefix
2385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) {
2386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        position = skipPadding(text, position);
2387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (! strictParse) {
2390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        position = skipUWhiteSpace(text, position);
2391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // process digits or Inf, find decimal position
2394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
2395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t infLen = (text.compare(position, inf->length(), *inf)
2396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ? 0 : inf->length());
2397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    position += infLen; // infLen is non-zero when it does equal to infinity
2398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status[fgStatusInfinite] = infLen != 0;
2399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (infLen != 0) {
240150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        parsedNum.append("Infinity", err);
240250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
2403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // We now have a string of digits, possibly with grouping symbols,
2404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // and decimal points.  We want to process these into a DigitList.
2405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // We don't want to put a bunch of leading zeros into the DigitList
2406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // though, so we keep track of the location of the decimal point,
2407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // put only significant digits into the DigitList, and adjust the
2408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // exponent as needed.
2409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UBool strictFail = FALSE; // did we exit with a strict parse failure?
2412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t lastGroup = -1; // where did we last see a grouping separator?
2413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t digitStart = position;
2414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t gs2 = fGroupingSize2 == 0 ? fGroupingSize : fGroupingSize2;
2415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UnicodeString *decimalString;
2417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (fCurrencySignCount > fgCurrencySignCountZero) {
2418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            decimalString = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
2419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
2420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
2421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2422103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UChar32 decimalChar = decimalString->char32At(0);
2423103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        int32_t decimalStringLength = decimalString->length();
2424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        int32_t decimalCharLength   = U16_LENGTH(decimalChar);
2425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UBool sawDecimal = FALSE;
2427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UChar32 sawDecimalChar = 0xFFFF;
2428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UBool sawGrouping = FALSE;
2429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UChar32 sawGroupingChar = 0xFFFF;
2430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UBool sawDigit = FALSE;
2431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t backup = -1;
2432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t digit;
2433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // equivalent grouping and decimal support
2435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UnicodeSet *decimalSet = NULL;
2436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UnicodeSet *groupingSet = NULL;
2437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (decimalCharLength == decimalStringLength) {
2439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            decimalSet = DecimalFormatStaticSets::getSimilarDecimals(decimalChar, strictParse);
2440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (groupingCharLength == groupingStringLength) {
2443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (strictParse) {
2444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                groupingSet = DecimalFormatStaticSets::gStaticSets->fStrictDefaultGroupingSeparators;
2445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
2446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                groupingSet = DecimalFormatStaticSets::gStaticSets->fDefaultGroupingSeparators;
2447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // We need to test groupingChar and decimalChar separately from groupingSet and decimalSet, if the sets are even initialized.
2451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // If sawDecimal is TRUE, only consider sawDecimalChar and NOT decimalSet
2452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // If a character matches decimalSet, don't consider it to be a member of the groupingSet.
2453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // We have to track digitCount ourselves, because digits.fCount will
2455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // pin when the maximum allowable digits is reached.
2456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t digitCount = 0;
2457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t integerDigitCount = 0;
2458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (; position < textLength; )
2460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
2461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UChar32 ch = text.char32At(position);
2462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* We recognize all digit ranges, not only the Latin digit range
2464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             * '0'..'9'.  We do so by using the Character.digit() method,
2465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             * which converts a valid Unicode digit to the range 0..9.
2466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             *
2467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             * The character 'ch' may be a digit.  If so, place its value
2468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             * from 0 to 9 in 'digit'.  First try using the locale digit,
2469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             * which may or MAY NOT be a standard Unicode digit range.  If
2470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             * this fails, try using the standard Unicode digit ranges by
247150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * calling Character.digit().  If this also fails, digit will
2472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             * have a value outside the range 0..9.
2473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             */
2474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            digit = ch - zero;
2475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (digit < 0 || digit > 9)
2476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
2477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                digit = u_charDigitValue(ch);
2478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
247927f654740f2a26ad62a5c155af9199af9e69b889claireho
248027f654740f2a26ad62a5c155af9199af9e69b889claireho            // As a last resort, look through the localized digits if the zero digit
248127f654740f2a26ad62a5c155af9199af9e69b889claireho            // is not a "standard" Unicode digit.
248227f654740f2a26ad62a5c155af9199af9e69b889claireho            if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) {
248327f654740f2a26ad62a5c155af9199af9e69b889claireho                digit = 0;
248427f654740f2a26ad62a5c155af9199af9e69b889claireho                if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) {
248527f654740f2a26ad62a5c155af9199af9e69b889claireho                    break;
248627f654740f2a26ad62a5c155af9199af9e69b889claireho                }
248727f654740f2a26ad62a5c155af9199af9e69b889claireho                for (digit = 1 ; digit < 10 ; digit++ ) {
248827f654740f2a26ad62a5c155af9199af9e69b889claireho                    if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) {
248927f654740f2a26ad62a5c155af9199af9e69b889claireho                        break;
249027f654740f2a26ad62a5c155af9199af9e69b889claireho                    }
249127f654740f2a26ad62a5c155af9199af9e69b889claireho                }
249227f654740f2a26ad62a5c155af9199af9e69b889claireho            }
2493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
249450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (digit >= 0 && digit <= 9)
2495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
2496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (strictParse && backup != -1) {
2497b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // comma followed by digit, so group before comma is a
2498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // secondary group.  If there was a group separator
2499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // before that, the group must == the secondary group
2500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // length, else it can be <= the the secondary group
2501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // length.
2502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||
2503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        (lastGroup == -1 && position - digitStart - 1 > gs2)) {
2504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        strictFail = TRUE;
2505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        break;
2506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
2507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    lastGroup = backup;
2509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Cancel out backup setting (see grouping handler below)
2512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                backup = -1;
2513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                sawDigit = TRUE;
2514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Note: this will append leading zeros
251627f654740f2a26ad62a5c155af9199af9e69b889claireho                parsedNum.append((char)(digit + '0'), err);
2517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // count any digit that's not a leading zero
2519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (digit > 0 || digitCount > 0 || sawDecimal) {
2520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    digitCount += 1;
2521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // count any integer digit that's not a leading zero
2523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if (! sawDecimal) {
2524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        integerDigitCount += 1;
2525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
2526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                position += U16_LENGTH(ch);
2529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            else if (groupingStringLength > 0 &&
2531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                matchGrouping(groupingChar, sawGrouping, sawGroupingChar, groupingSet,
2532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            decimalChar, decimalSet,
253354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            ch) && groupingUsed)
2534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
2535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (sawDecimal) {
2536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    break;
2537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (strictParse) {
2540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if ((!sawDigit || backup != -1)) {
2541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // leading group, or two group separators in a row
2542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        strictFail = TRUE;
2543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        break;
2544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
2545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Ignore grouping characters, if we are using them, but require
2548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // that they be followed by a digit.  Otherwise we backup and
2549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // reprocess them.
2550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                backup = position;
2551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                position += groupingStringLength;
2552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                sawGrouping=TRUE;
2553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Once we see a grouping character, we only accept that grouping character from then on.
2554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                sawGroupingChar=ch;
2555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            else if (matchDecimal(decimalChar,sawDecimal,sawDecimalChar, decimalSet, ch))
2557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
2558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (strictParse) {
2559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if (backup != -1 ||
2560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        (lastGroup != -1 && position - lastGroup != fGroupingSize + 1)) {
2561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        strictFail = TRUE;
2562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        break;
2563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
2564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // If we're only parsing integers, or if we ALREADY saw the
2567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // decimal, then don't parse this one.
2568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (isParseIntegerOnly() || sawDecimal) {
2569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    break;
2570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
257250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                parsedNum.append('.', err);
2573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                position += decimalStringLength;
2574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                sawDecimal = TRUE;
2575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Once we see a decimal character, we only accept that decimal character from then on.
2576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                sawDecimalChar=ch;
2577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // decimalSet is considered to consist of (ch,ch)
2578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            else {
2580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
258154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                if(!fBoolFlags.contains(UNUM_PARSE_NO_EXPONENT) || // don't parse if this is set unless..
258254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    fUseExponentialNotation /* should be:  isScientificNotation() but it is not const (?!) see bug #9619 */) { // .. it's an exponent format - ignore setting and parse anyways
258354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    const UnicodeString *tmp;
258454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
258554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // TODO: CASE
258654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT))    // error code is set below if !sawDigit
2587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    {
258854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        // Parse sign, if present
258954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        int32_t pos = position + tmp->length();
259054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        char exponentSign = '+';
259154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
259254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        if (pos < textLength)
2593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        {
259454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (!text.compare(pos, tmp->length(), *tmp))
2596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            {
2597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                pos += tmp->length();
2598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
259954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            else {
260054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
260154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                if (!text.compare(pos, tmp->length(), *tmp))
260254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                {
260354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                    exponentSign = '-';
260454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                    pos += tmp->length();
260554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                }
260654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            }
2607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
260954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        UBool sawExponentDigit = FALSE;
261054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        while (pos < textLength) {
261154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            ch = text[(int32_t)pos];
261254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            digit = ch - zero;
2613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
261454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            if (digit < 0 || digit > 9) {
261554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                digit = u_charDigitValue(ch);
261654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            }
261754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            if (0 <= digit && digit <= 9) {
261854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                if (!sawExponentDigit) {
261954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                    parsedNum.append('E', err);
262054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                    parsedNum.append(exponentSign, err);
262154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                    sawExponentDigit = TRUE;
262254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                }
262354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                ++pos;
262454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                parsedNum.append((char)(digit + '0'), err);
262554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            } else {
262654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                break;
262750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            }
2628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
263054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        if (sawExponentDigit) {
263154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            position = pos; // Advance past the exponent
263254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        }
2633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
263454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        break; // Whether we fail or succeed, we exit this loop
263554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    } else {
263654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        break;
263754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    }
263854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                } else { // not parsing exponent
2639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
264054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius              }
2641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (backup != -1)
2645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
2646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            position = backup;
2647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2649b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (strictParse && !sawDecimal) {
2650b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) {
2651b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                strictFail = TRUE;
2652b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2653b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2654b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2655b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (strictFail) {
2656b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // only set with strictParse and a grouping separator error
2657b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2658b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            parsePosition.setIndex(oldStart);
2659b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            parsePosition.setErrorIndex(position);
2660103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            debug("strictFail!");
2661b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return FALSE;
2662b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2663b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // If there was no decimal point we have an integer
2665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // If none of the text string was recognized.  For example, parse
2667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // "x" with pattern "#0.00" (return index and error index both 0)
2668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // parse "$" with pattern "$#0.00". (return index 0 and error index
2669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // 1).
2670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!sawDigit && digitCount == 0) {
2671103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2672103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            debug("none of text rec");
2673103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            printf("position=%d\n",position);
2674103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            parsePosition.setIndex(oldStart);
2676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            parsePosition.setErrorIndex(oldStart);
2677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return FALSE;
2678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Match padding before suffix
2682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) {
2683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        position = skipPadding(text, position);
2684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2686b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t posSuffixMatch = -1, negSuffixMatch = -1;
2687b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Match positive and negative suffixes; prefer longest match.
2689b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (posMatch >= 0 || (!strictParse && negMatch < 0)) {
2690b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, currencyParsing, type, currency);
2691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (negMatch >= 0) {
2693b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        negSuffixMatch = compareAffix(text, position, TRUE, FALSE, negSuffix, currencyParsing, type, currency);
2694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (posSuffixMatch >= 0 && negSuffixMatch >= 0) {
2696b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (posSuffixMatch > negSuffixMatch) {
2697b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            negSuffixMatch = -1;
2698b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (negSuffixMatch > posSuffixMatch) {
2699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            posSuffixMatch = -1;
270050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
2701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Fail if neither or both
2704b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) {
2705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        parsePosition.setErrorIndex(position);
2706103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        debug("neither or both");
2707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return FALSE;
2708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? negSuffixMatch : 0));
2711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Match padding before suffix
2713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) {
2714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        position = skipPadding(text, position);
2715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    parsePosition.setIndex(position);
2718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0 && negSuffixMatch < 0)) ? '+' : '-';
2720103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2721103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusprintf("PP -> %d, SLOW = [%s]!    pp=%d, os=%d, err=%s\n", position, parsedNum.data(), parsePosition.getIndex(),oldStart,u_errorName(err));
2722103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2723103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } /* end SLOW parse */
2724103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  if(parsePosition.getIndex() == oldStart)
2725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
2726103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2727103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      printf(" PP didnt move, err\n");
2728103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2729103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        parsePosition.setErrorIndex(position);
2730103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return FALSE;
2731103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
2732103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_HAVE_PARSEALLINPUT
2733103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  else if (fParseAllInput==UNUM_YES&&parsePosition.getIndex()!=textLength)
2734103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    {
2735103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2736103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      printf(" PP didnt consume all (UNUM_YES), err\n");
2737103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
2738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        parsePosition.setErrorIndex(position);
2739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return FALSE;
2740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2741103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
274254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    // uint32_t bits = (fastParseOk?kFastpathOk:0) |
274354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    //   (fastParseHadDecimal?0:kNoDecimal);
274454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    //printf("FPOK=%d, FPHD=%d, bits=%08X\n", fastParseOk, fastParseHadDecimal, bits);
274554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    digits.set(parsedNum.toStringPiece(),
274654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius               err,
274754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius               0//bits
274854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius               );
274950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
275050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(err)) {
2751103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef FMT_DEBUG
2752103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      printf(" err setting %s\n", u_errorName(err));
2753103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
275450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        parsePosition.setErrorIndex(position);
275550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
275650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
2757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return TRUE;
2758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Starting at position, advance past a run of pad characters, if any.
2762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the index of the first character after position that is not a pad
2763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * character.  Result is >= position.
2764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const {
2766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t padLen = U16_LENGTH(fPad);
2767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (position < text.length() &&
2768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           text.char32At(position) == fPad) {
2769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        position += padLen;
2770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return position;
2772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the length matched by the given affix, or -1 if none.
2776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Runs of white space in the affix, match runs of white space in
2777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the input.  Pattern white space and input white space are
2778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * determined differently; see code.
2779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param text input text
2780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param pos offset into input at which to begin matching
2781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param isNegative
2782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param isPrefix
2783b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param affixPat affix pattern used for currency affix comparison.
2784b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param currencyParsing whether it is currency parsing or not
2785b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param type the currency type to parse against, LONG_NAME only or not.
2786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param currency return value for parsed currency, for generic
2787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency parsing mode, or null for normal parsing. In generic
2788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency parsing mode, any currency is parsed, not just the
2789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency that this formatter is set to.
2790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return length of input that matches, or -1 if match failure
2791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::compareAffix(const UnicodeString& text,
2793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    int32_t pos,
2794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    UBool isNegative,
2795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    UBool isPrefix,
2796b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                    const UnicodeString* affixPat,
2797b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                    UBool currencyParsing,
2798b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                    int8_t type,
2799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    UChar* currency) const
2800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
2801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString *patternToCompare;
2802b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencyChoice != NULL || currency != NULL ||
2803b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        (fCurrencySignCount > fgCurrencySignCountZero && currencyParsing)) {
280450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2805b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (affixPat != NULL) {
2806b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            return compareComplexAffix(*affixPat, text, pos, type, currency);
2807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
280950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (isNegative) {
2811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (isPrefix) {
2812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            patternToCompare = &fNegativePrefix;
2813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
2815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            patternToCompare = &fNegativeSuffix;
2816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
2819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (isPrefix) {
2820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            patternToCompare = &fPositivePrefix;
2821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
2823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            patternToCompare = &fPositiveSuffix;
2824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2826b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return compareSimpleAffix(*patternToCompare, text, pos, isLenient());
2827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the length matched by the given affix, or -1 if none.
2831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Runs of white space in the affix, match runs of white space in
2832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the input.  Pattern white space and input white space are
2833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * determined differently; see code.
2834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param affix pattern string, taken as a literal
2835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param input input text
2836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param pos offset into input at which to begin matching
2837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return length of input that matches, or -1 if match failure
2838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix,
2840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                          const UnicodeString& input,
2841b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                          int32_t pos,
2842b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                          UBool lenient) {
2843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t start = pos;
2844b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UChar32 affixChar = affix.char32At(0);
2845b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t affixLength = affix.length();
2846b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t inputLength = input.length();
2847b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t affixCharLength = U16_LENGTH(affixChar);
2848b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeSet *affixSet;
2849b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2850b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (!lenient) {
2851b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        affixSet = DecimalFormatStaticSets::gStaticSets->fStrictDashEquivalents;
2852b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2853b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // If the affix is exactly one character long and that character
2854b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // is in the dash set and the very next input character is also
2855b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // in the dash set, return a match.
2856b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (affixCharLength == affixLength && affixSet->contains(affixChar))  {
2857b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (affixSet->contains(input.char32At(pos))) {
2858b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return 1;
2859b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2860b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2861b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2862b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        for (int32_t i = 0; i < affixLength; ) {
2863b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UChar32 c = affix.char32At(i);
2864b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t len = U16_LENGTH(c);
2865b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (PatternProps::isWhiteSpace(c)) {
2866b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // We may have a pattern like: \u200F \u0020
2867b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                //        and input text like: \u200F \u0020
2868b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Note that U+200F and U+0020 are Pattern_White_Space but only
2869b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // U+0020 is UWhiteSpace.  So we have to first do a direct
2870b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // match of the run of Pattern_White_Space in the pattern,
2871b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // then match any extra characters.
2872b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UBool literalMatch = FALSE;
2873b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                while (pos < inputLength &&
2874b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       input.char32At(pos) == c) {
2875b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    literalMatch = TRUE;
2876b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    i += len;
2877b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    pos += len;
2878b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if (i == affixLength) {
2879b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        break;
2880b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
2881b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    c = affix.char32At(i);
2882b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    len = U16_LENGTH(c);
2883b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if (!PatternProps::isWhiteSpace(c)) {
2884b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        break;
2885b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
2886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
2887b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2888b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Advance over run in pattern
2889b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                i = skipPatternWhiteSpace(affix, i);
2890b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2891b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Advance over run in input text
2892b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Must see at least one white space char in input,
2893b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // unless we've already matched some characters literally.
2894b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                int32_t s = pos;
2895b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                pos = skipUWhiteSpace(input, pos);
2896b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (pos == s && !literalMatch) {
2897b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    return -1;
2898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
2899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2900b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
2901b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
2902b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // is also in the affix.
2903b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                i = skipUWhiteSpace(affix, i);
2904b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
2905b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (pos < inputLength &&
2906b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    input.char32At(pos) == c) {
2907b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    i += len;
2908b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    pos += len;
2909b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                } else {
2910b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    return -1;
2911b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2912b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2913b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2914b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
2915b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UBool match = FALSE;
2916b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2917b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        affixSet = DecimalFormatStaticSets::gStaticSets->fDashEquivalents;
2918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2919b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (affixCharLength == affixLength && affixSet->contains(affixChar))  {
2920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pos = skipUWhiteSpace(input, pos);
2921b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2922b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (affixSet->contains(input.char32At(pos))) {
2923b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return pos - start + 1;
2924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2925b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2926c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
2927b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        for (int32_t i = 0; i < affixLength; )
2928b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        {
2929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            //i = skipRuleWhiteSpace(affix, i);
2930c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            i = skipUWhiteSpace(affix, i);
2931b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pos = skipUWhiteSpace(input, pos);
2932b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2933b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (i >= affixLength || pos >= inputLength) {
2934b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
2935b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2936b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2937b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UChar32 c = affix.char32At(i);
2938b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t len = U16_LENGTH(c);
2939b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2940b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (input.char32At(pos) != c) {
2941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return -1;
2942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2943b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2944b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            match = TRUE;
2945b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            i += len;
2946b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pos += len;
2947b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2948b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2949b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (affixLength > 0 && ! match) {
2950b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return -1;
2951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return pos - start;
2954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2957b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Skip over a run of zero or more Pattern_White_Space characters at
2958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * pos in text.
2959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2960b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t DecimalFormat::skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) {
2961b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UChar* s = text.getBuffer();
2962b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return (int32_t)(PatternProps::skipWhiteSpace(s + pos, text.length() - pos) - s);
2963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Skip over a run of zero or more isUWhiteSpace() characters at pos
2967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in text.
2968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) {
2970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (pos < text.length()) {
2971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar32 c = text.char32At(pos);
2972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!u_isUWhiteSpace(c)) {
2973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pos += U16_LENGTH(c);
2976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return pos;
2978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the length matched by the given affix, or -1 if none.
2982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param affixPat pattern string
2983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param input input text
2984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param pos offset into input at which to begin matching
2985b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param type the currency type to parse against, LONG_NAME only or not.
2986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param currency return value for parsed currency, for generic
2987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency parsing mode, or null for normal parsing. In generic
2988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency parsing mode, any currency is parsed, not just the
2989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency that this formatter is set to.
2990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return length of input that matches, or -1 if match failure
2991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat,
2993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                           const UnicodeString& text,
2994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                           int32_t pos,
2995b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                           int8_t type,
2996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                           UChar* currency) const
2997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
2998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t start = pos;
2999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_ASSERT(currency != NULL ||
3000b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru             (fCurrencyChoice != NULL && *getCurrency() != 0) ||
3001b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru             fCurrencySignCount > fgCurrencySignCountZero);
3002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
300350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    for (int32_t i=0;
3004b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i<affixPat.length() && pos >= 0; ) {
3005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar32 c = affixPat.char32At(i);
3006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i += U16_LENGTH(c);
3007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (c == kQuote) {
3009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            U_ASSERT(i <= affixPat.length());
3010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            c = affixPat.char32At(i);
3011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            i += U16_LENGTH(c);
3012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const UnicodeString* affix = NULL;
3014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            switch (c) {
3016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kCurrencySign: {
3017b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // since the currency names in choice format is saved
301850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                // the same way as other currency names,
3019b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // do not need to do currency choice parsing here.
3020b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // the general currency parsing parse against all names,
3021b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // including names in choice format.
3022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                UBool intl = i<affixPat.length() &&
3023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affixPat.char32At(i) == kCurrencySign;
3024b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (intl) {
3025b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ++i;
3026b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
3027b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                UBool plural = i<affixPat.length() &&
3028b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    affixPat.char32At(i) == kCurrencySign;
3029b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (plural) {
3030b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ++i;
3031b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    intl = FALSE;
3032b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
3033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Parse generic currency -- anything for which we
3034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // have a display name, or any 3-letter ISO code.
3035b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // Try to parse display name for our locale; first
3036b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // determine our locale.
3037b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                const char* loc = fCurrencyPluralInfo->getLocale().getName();
3038b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                ParsePosition ppos(pos);
3039b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                UChar curr[4];
3040b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                UErrorCode ec = U_ZERO_ERROR;
3041b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // Delegate parse of display name => ISO code to Currency
3042b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                uprv_parseCurrency(loc, text, ppos, type, curr, ec);
3043b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
3044b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // If parse succeeds, populate currency[0]
3045b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (U_SUCCESS(ec) && ppos.getIndex() != pos) {
3046b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if (currency) {
3047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        u_strcpy(currency, curr);
3048b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    } else {
3049b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // The formatter is currency-style but the client has not requested
3050b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // the value of the parsed currency. In this case, if that value does
3051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // not match the formatter's current value, then the parse fails.
3052b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        UChar effectiveCurr[4];
3053b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        getEffectiveCurrency(effectiveCurr, ec);
3054b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,4) != 0 ) {
3055b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        	pos = -1;
3056b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        	continue;
3057b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        }
3058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
3059b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    pos = ppos.getIndex();
3060b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                } else if (!isLenient()){
3061b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    pos = -1;
3062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
3063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                continue;
3064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
3065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternPercent:
3066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
3067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
3068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternPerMill:
3069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
3070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
3071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternPlus:
3072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
3073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
3074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternMinus:
3075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
3076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
3077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            default:
3078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // fall through to affix!=0 test, which will fail
3079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
3080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
3081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (affix != NULL) {
3083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                pos = match(text, pos, *affix);
3084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                continue;
3085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
3086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
3087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pos = match(text, pos, c);
3089b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (PatternProps::isWhiteSpace(c)) {
3090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            i = skipPatternWhiteSpace(affixPat, i);
3091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
3092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return pos - start;
3094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Match a single character at text[pos] and return the index of the
3098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * next character upon success.  Return -1 on failure.  If
3099b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * ch is a Pattern_White_Space then match a run of white space in text.
3100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) {
3102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (PatternProps::isWhiteSpace(ch)) {
3103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Advance over run of white space in input text
3104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Must see at least one white space char in input
3105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t s = pos;
3106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pos = skipPatternWhiteSpace(text, pos);
3107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (pos == s) {
3108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return -1;
3109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
3110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return pos;
3111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (pos >= 0 && text.char32At(pos) == ch) ?
3113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (pos + U16_LENGTH(ch)) : -1;
3114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Match a string at text[pos] and return the index of the next
3118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * character upon success.  Return -1 on failure.  Match a run of
3119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * white space in str with a run of white space in text.
3120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) {
3122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i=0; i<str.length() && pos >= 0; ) {
3123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar32 ch = str.char32At(i);
3124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i += U16_LENGTH(ch);
3125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (PatternProps::isWhiteSpace(ch)) {
3126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            i = skipPatternWhiteSpace(str, i);
3127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
3128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pos = match(text, pos, ch);
3129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return pos;
3131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool DecimalFormat::matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol,
3134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                         UnicodeSet *sset, UChar32 schar)
3135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{
3136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (sset != NULL) {
3137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return sset->contains(schar);
3138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return text.compare(position, length, symbol) == 0;
3141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
3142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool DecimalFormat::matchDecimal(UChar32 symbolChar,
3144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            UBool sawDecimal,  UChar32 sawDecimalChar,
3145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                             const UnicodeSet *sset, UChar32 schar) {
3146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho   if(sawDecimal) {
3147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho       return schar==sawDecimalChar;
3148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho   } else if(schar==symbolChar) {
3149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho       return TRUE;
3150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho   } else if(sset!=NULL) {
3151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return sset->contains(schar);
3152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho   } else {
3153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho       return FALSE;
3154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho   }
3155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
3156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool DecimalFormat::matchGrouping(UChar32 groupingChar,
3158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            UBool sawGrouping, UChar32 sawGroupingChar,
3159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                             const UnicodeSet *sset,
3160103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                             UChar32 /*decimalChar*/, const UnicodeSet *decimalSet,
3161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                             UChar32 schar) {
3162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if(sawGrouping) {
3163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return schar==sawGroupingChar;  // previously found
3164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else if(schar==groupingChar) {
3165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return TRUE; // char from symbols
3166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else if(sset!=NULL) {
3167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return sset->contains(schar) &&  // in groupingSet but...
3168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho           ((decimalSet==NULL) || !decimalSet->contains(schar)); // Exclude decimalSet from groupingSet
3169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
3170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return FALSE;
3171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
3173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the pointer to the localized decimal format symbols
3178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst DecimalFormatSymbols*
3180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::getDecimalFormatSymbols() const
3181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fSymbols;
3183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// De-owning the current localized symbols and adopt the new symbols.
3187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
3190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (symbolsToAdopt == NULL) {
3192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return; // do not allow caller to set fSymbols to NULL
3193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool sameSymbols = FALSE;
3196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fSymbols != NULL) {
3197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) ==
3198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) &&
3199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) ==
3200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
3201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete fSymbols;
3202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fSymbols = symbolsToAdopt;
3205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!sameSymbols) {
3206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // If the currency symbols are the same, there is no need to recalculate.
3207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setCurrencyForSymbols();
3208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    expandAffixes(NULL);
3210103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3211103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3212103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Setting the symbols is equlivalent to adopting a newly created localized
3216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// symbols.
3217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
3220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
3222103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3223103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3224103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3226b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
322750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
322850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst CurrencyPluralInfo*
3229b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::getCurrencyPluralInfo(void) const
3230b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
3231b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return fCurrencyPluralInfo;
3232b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
3233b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
3234b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
323550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
3236b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt)
3237b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
3238b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (toAdopt != NULL) {
323950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete fCurrencyPluralInfo;
3240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencyPluralInfo = toAdopt;
3241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // re-set currency affix patterns and currency affixes.
3242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (fCurrencySignCount > fgCurrencySignCountZero) {
3243b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UErrorCode status = U_ZERO_ERROR;
3244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (fAffixPatternsForCurrency) {
3245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                deleteHashForAffixPattern();
3246b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
3247b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            setupCurrencyAffixPatterns(status);
3248b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) {
3249b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // only setup the affixes of the plural pattern.
3250b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                setupCurrencyAffixes(fFormatPattern, FALSE, TRUE, status);
3251b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
3252b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
325350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
3254103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3255103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3256103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3257b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
3258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
325950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
3260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info)
3261b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
3262b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    adoptCurrencyPluralInfo(info.clone());
3263103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3264103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3265103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3266b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
3267b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
3268b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
3269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Update the currency object to match the symbols.  This method
3271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is used only when the caller has passed in a symbols object
3272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that may not be the default object for its locale.
3273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setCurrencyForSymbols() {
3276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*Bug 4212072
3277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      Update the affix strings accroding to symbols in order to keep
3278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      the affix strings up to date.
3279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      [Richard/GCL]
3280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
3281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // With the introduction of the Currency object, the currency
3283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // symbols in the DFS object are ignored.  For backward
3284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // compatibility, we check any explicitly set DFS object.  If it
3285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // is a default symbols object for its locale, we change the
3286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // currency object to one for that locale.  If it is custom,
3287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // we set the currency to null.
3288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode ec = U_ZERO_ERROR;
3289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UChar* c = NULL;
3290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char* loc = fSymbols->getLocale().getName();
329150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar intlCurrencySymbol[4];
3292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec);
3293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString currencySymbol;
3294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec);
3296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(ec)
3297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymbol
3298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == UnicodeString(intlCurrencySymbol))
3299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
3300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Trap an error in mapping locale to currency.  If we can't
3301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // map, then don't fail and set the currency to "".
3302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        c = intlCurrencySymbol;
3303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ec = U_ZERO_ERROR; // reset local error code!
3305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    setCurrencyInternally(c, ec);
3306103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3307103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3308103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the positive prefix of the number pattern.
331450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
3316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::getPositivePrefix(UnicodeString& result) const
3317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    result = fPositivePrefix;
3319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return result;
3320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
332150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the positive prefix of the number pattern.
332450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setPositivePrefix(const UnicodeString& newValue)
3327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPositivePrefix = newValue;
3329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fPosPrefixPattern;
3330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPosPrefixPattern = 0;
3331103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3332103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3333103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the negative prefix  of the number pattern.
3338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
3340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::getNegativePrefix(UnicodeString& result) const
3341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    result = fNegativePrefix;
3343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return result;
3344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the negative prefix  of the number pattern.
3348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setNegativePrefix(const UnicodeString& newValue)
3351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fNegativePrefix = newValue;
3353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fNegPrefixPattern;
3354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fNegPrefixPattern = 0;
3355103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3356103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3357103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the positive suffix of the number pattern.
3362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
3364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::getPositiveSuffix(UnicodeString& result) const
3365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    result = fPositiveSuffix;
3367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return result;
3368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the positive suffix of the number pattern.
3372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
3375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPositiveSuffix = newValue;
3377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fPosSuffixPattern;
3378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPosSuffixPattern = 0;
3379103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3380103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3381103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the negative suffix of the number pattern.
3386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
3388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::getNegativeSuffix(UnicodeString& result) const
3389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    result = fNegativeSuffix;
3391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return result;
3392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the negative suffix of the number pattern.
3396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
3399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fNegativeSuffix = newValue;
3401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete fNegSuffixPattern;
3402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fNegSuffixPattern = 0;
3403103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3404103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3405103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the multiplier of the number pattern.
341050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//   Multipliers are stored as decimal numbers (DigitLists) because that
341150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//      is the most convenient for muliplying or dividing the numbers to be formatted.
341250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//   A NULL multiplier implies one, and the scaling operations are skipped.
3413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
341450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
341550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::getMultiplier() const
3416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
341750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fMultiplier == NULL) {
341850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 1;
341950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
342050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return fMultiplier->getLong();
342150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
3422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets the multiplier of the number pattern.
3426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setMultiplier(int32_t newValue)
3428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3429c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru//  if (newValue == 0) {
3430c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru//      throw new IllegalArgumentException("Bad multiplier: " + newValue);
3431c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru//  }
343250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (newValue == 0) {
343350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        newValue = 1;     // one being the benign default value for a multiplier.
343450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
343550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (newValue == 1) {
343650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete fMultiplier;
343750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fMultiplier = NULL;
343850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
343950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (fMultiplier == NULL) {
344050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            fMultiplier = new DigitList;
344150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
344250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (fMultiplier != NULL) {
344350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            fMultiplier->set(newValue);
344450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
3445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3448103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Get the rounding increment.
3453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return A positive rounding increment, or 0.0 if rounding
3454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is not in effect.
3455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setRoundingIncrement
3456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getRoundingMode
3457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setRoundingMode
3458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querudouble DecimalFormat::getRoundingIncrement() const {
346050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fRoundingIncrement == NULL) {
346150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0.0;
346250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
346350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return fRoundingIncrement->getDouble();
346450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
3465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set the rounding increment.  This method also controls whether
3469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rounding is enabled.
3470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param newValue A positive rounding increment, or 0.0 to disable rounding.
3471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Negative increments are equivalent to 0.0.
3472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getRoundingIncrement
3473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getRoundingMode
3474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setRoundingMode
3475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setRoundingIncrement(double newValue) {
3477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (newValue > 0.0) {
3478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fRoundingIncrement == NULL) {
3479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fRoundingIncrement = new DigitList();
3480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
3481c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (fRoundingIncrement != NULL) {
348250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            fRoundingIncrement->set(newValue);
3483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            return;
3484c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
348550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
3486c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // These statements are executed if newValue is less than 0.0
3487c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // or fRoundingIncrement could not be created.
3488c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    delete fRoundingIncrement;
3489c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fRoundingIncrement = NULL;
3490103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3491103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3492103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Get the rounding mode.
3497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return A rounding mode
3498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setRoundingIncrement
3499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getRoundingIncrement
3500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setRoundingMode
3501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const {
3503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fRoundingMode;
3504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set the rounding mode.  This has no effect unless the rounding
3508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * increment is greater than zero.
3509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param roundingMode A rounding mode
3510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setRoundingIncrement
3511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getRoundingIncrement
3512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getRoundingMode
3513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
3515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fRoundingMode = roundingMode;
3516103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Get the width to which the output of <code>format()</code> is padded.
3523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return the format width, or zero if no padding is in effect
3524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setFormatWidth
3525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getPadCharacter
3526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setPadCharacter
3527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getPadPosition
3528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setPadPosition
3529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::getFormatWidth() const {
3531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fFormatWidth;
3532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set the width to which the output of <code>format()</code> is padded.
3536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This method also controls whether padding is enabled.
3537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param width the width to which to pad the result of
3538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * <code>format()</code>, or zero to disable padding.  A negative
3539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * width is equivalent to 0.
3540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getFormatWidth
3541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getPadCharacter
3542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setPadCharacter
3543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getPadPosition
3544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setPadPosition
3545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setFormatWidth(int32_t width) {
3547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fFormatWidth = (width > 0) ? width : 0;
3548103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3549103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3550103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString DecimalFormat::getPadCharacterString() const {
3554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return UnicodeString(fPad);
3555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setPadCharacter(const UnicodeString &padChar) {
3558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (padChar.length() > 0) {
3559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fPad = padChar.char32At(0);
3560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
3562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fPad = kDefaultPad;
3563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3564103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3565103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3566103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Get the position at which padding will take place.  This is the location
3571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * at which padding will be inserted if the result of <code>format()</code>
3572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is shorter than the format width.
3573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return the pad position, one of <code>kPadBeforePrefix</code>,
3574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
3575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * <code>kPadAfterSuffix</code>.
3576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setFormatWidth
3577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getFormatWidth
3578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setPadCharacter
3579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getPadCharacter
3580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setPadPosition
3581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadBeforePrefix
3582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadAfterPrefix
3583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadBeforeSuffix
3584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadAfterSuffix
3585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::EPadPosition DecimalFormat::getPadPosition() const {
3587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fPadPosition;
3588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * <strong><font face=helvetica color=red>NEW</font></strong>
3592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set the position at which padding will take place.  This is the location
3593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * at which padding will be inserted if the result of <code>format()</code>
3594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is shorter than the format width.  This has no effect unless padding is
3595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * enabled.
3596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
3597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
3598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * <code>kPadAfterSuffix</code>.
3599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setFormatWidth
3600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getFormatWidth
3601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setPadCharacter
3602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getPadCharacter
3603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getPadPosition
3604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadBeforePrefix
3605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadAfterPrefix
3606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadBeforeSuffix
3607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #kPadAfterSuffix
3608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setPadPosition(EPadPosition padPos) {
3610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fPadPosition = padPos;
3611103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3612103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3613103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return whether or not scientific notation is used.
3618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return TRUE if this object formats and parses scientific notation
3619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setScientificNotation
3620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getMinimumExponentDigits
3621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setMinimumExponentDigits
3622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isExponentSignAlwaysShown
3623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setExponentSignAlwaysShown
3624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool DecimalFormat::isScientificNotation() {
3626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fUseExponentialNotation;
3627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set whether or not scientific notation is used.
3631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param useScientific TRUE if this object formats and parses scientific
3632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * notation
3633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isScientificNotation
3634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getMinimumExponentDigits
3635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setMinimumExponentDigits
3636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isExponentSignAlwaysShown
3637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setExponentSignAlwaysShown
3638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setScientificNotation(UBool useScientific) {
3640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fUseExponentialNotation = useScientific;
3641103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3642103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3643103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the minimum exponent digits that will be shown.
3648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return the minimum exponent digits that will be shown
3649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setScientificNotation
3650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isScientificNotation
3651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setMinimumExponentDigits
3652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isExponentSignAlwaysShown
3653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setExponentSignAlwaysShown
3654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t DecimalFormat::getMinimumExponentDigits() const {
3656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fMinExponentDigits;
3657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set the minimum exponent digits that will be shown.  This has no
3661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * effect unless scientific notation is in use.
3662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param minExpDig a value >= 1 indicating the fewest exponent digits
3663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that will be shown.  Values less than 1 will be treated as 1.
3664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setScientificNotation
3665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isScientificNotation
3666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getMinimumExponentDigits
3667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isExponentSignAlwaysShown
3668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setExponentSignAlwaysShown
3669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
3671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1);
3672103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3673103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3674103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return whether the exponent sign is always shown.
3679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return TRUE if the exponent is always prefixed with either the
3680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * localized minus sign or the localized plus sign, false if only negative
3681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * exponents are prefixed with the localized minus sign.
3682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setScientificNotation
3683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isScientificNotation
3684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setMinimumExponentDigits
3685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getMinimumExponentDigits
3686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setExponentSignAlwaysShown
3687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool DecimalFormat::isExponentSignAlwaysShown() {
3689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fExponentSignAlwaysShown;
3690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set whether the exponent sign is always shown.  This has no effect
3694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * unless scientific notation is in use.
3695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param expSignAlways TRUE if the exponent is always prefixed with either
3696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the localized minus sign or the localized plus sign, false if only
3697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * negative exponents are prefixed with the localized minus sign.
3698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setScientificNotation
3699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isScientificNotation
3700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #setMinimumExponentDigits
3701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #getMinimumExponentDigits
3702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see #isExponentSignAlwaysShown
3703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
3705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fExponentSignAlwaysShown = expSignAlways;
3706103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3707103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3708103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the grouping size of the number pattern.  For example, thousand or 10
3713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// thousand groupings.
371450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
3716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::getGroupingSize() const
3717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fGroupingSize;
3719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
372050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Gets the grouping size of the number pattern.
372350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setGroupingSize(int32_t newValue)
3726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fGroupingSize = newValue;
3728103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3729103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3730103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
3736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::getSecondaryGroupingSize() const
3737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fGroupingSize2;
3739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setSecondaryGroupingSize(int32_t newValue)
3745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fGroupingSize2 = newValue;
3747103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3748103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3749103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Checks if to show the decimal separator.
3754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool
3756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::isDecimalSeparatorAlwaysShown() const
3757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fDecimalSeparatorAlwaysShown;
3759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Sets to always show the decimal separator.
3763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
3765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
3766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fDecimalSeparatorAlwaysShown = newValue;
3768103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
3769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
3770103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
3771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Emits the pattern of this DecimalFormat instance.
3775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
3777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::toPattern(UnicodeString& result) const
3778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return toPattern(result, FALSE);
3780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Emits the localized pattern this DecimalFormat instance.
3784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
3786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::toLocalizedPattern(UnicodeString& result) const
3787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
3788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return toPattern(result, TRUE);
3789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
3792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Expand the affix pattern strings into the expanded affix strings.  If any
3794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * affix pattern string is null, do not expand it.  This method should be
3795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * called any time the symbols or the affix patterns change in order to keep
3796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the expanded affix strings up to date.
3797b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * This method also will be called before formatting if format currency
379850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * plural names, since the plural name is not a static one, it is
3799b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * based on the currency plural count, the affix will be known only
380050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * after the currency plural count is know.
3801b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * In which case, the parameter
3802b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 'pluralCount' will be a non-null currency plural count.
3803b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * In all other cases, the 'pluralCount' is null, which means it is not needed.
3804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3805b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid DecimalFormat::expandAffixes(const UnicodeString* pluralCount) {
380650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FieldPositionHandler none;
3807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fPosPrefixPattern != 0) {
380850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, none, FALSE, pluralCount);
3809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fPosSuffixPattern != 0) {
381150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, none, FALSE, pluralCount);
3812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fNegPrefixPattern != 0) {
381450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, none, FALSE, pluralCount);
3815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fNegSuffixPattern != 0) {
381750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, none, FALSE, pluralCount);
3818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef FMT_DEBUG
3820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString s;
3821103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    s.append(UnicodeString("["))
3822103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      .append(DEREFSTR(fPosPrefixPattern)).append((UnicodeString)"|").append(DEREFSTR(fPosSuffixPattern))
3823103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      .append((UnicodeString)";") .append(DEREFSTR(fNegPrefixPattern)).append((UnicodeString)"|").append(DEREFSTR(fNegSuffixPattern))
3824103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        .append((UnicodeString)"]->[")
3825103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        .append(fPositivePrefix).append((UnicodeString)"|").append(fPositiveSuffix)
3826103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        .append((UnicodeString)";") .append(fNegativePrefix).append((UnicodeString)"|").append(fNegativeSuffix)
3827103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        .append((UnicodeString)"]\n");
3828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    debugout(s);
3829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
3830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Expand an affix pattern into an affix string.  All characters in the
3834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * pattern are literal unless prefixed by kQuote.  The following characters
3835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
3836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * PATTERN_MINUS, and kCurrencySign.  If kCurrencySign is doubled (kQuote +
3837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * kCurrencySign + kCurrencySign), it is interpreted as an international
383850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * currency sign. If CURRENCY_SIGN is tripled, it is interpreted as
3839b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * currency plural long names, such as "US Dollars".
3840b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Any other character after a kQuote represents itself.
3841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * kQuote must be followed by another character; kQuote may not occur by
3842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * itself at the end of the pattern.
3843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
3844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This method is used in two distinct ways.  First, it is used to expand
3845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the stored affix patterns into actual affixes.  For this usage, doFormat
3846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * must be false.  Second, it is used to expand the stored affix patterns
3847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * given a specific number (doFormat == true), for those rare cases in
3848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * which a currency format references a ChoiceFormat (e.g., en_IN display
3849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * name for INR).  The number itself is taken from digitList.
3850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
3851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * When used in the first way, this method has a side effect: It sets
3852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currencyChoice to a ChoiceFormat object, if the currency's display name
3853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in this locale is a ChoiceFormat pattern (very rare).  It only does this
3854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * if currencyChoice is null to start with.
3855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
3856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param pattern the non-null, fPossibly empty pattern
3857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param affix string to receive the expanded equivalent of pattern.
3858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Previous contents are deleted.
3859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param doFormat if false, then the pattern will be expanded, and if a
3860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currency symbol is encountered that expands to a ChoiceFormat, the
3861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * currencyChoice member variable will be initialized if it is null.  If
3862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * doFormat is true, then it is assumed that the currencyChoice has been
3863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * created, and it will be used to format the value in digitList.
3864b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param pluralCount the plural count. It is only used for currency
3865b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *                    plural format. In which case, it is the plural
3866b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *                    count of the currency amount. For example,
3867b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *                    in en_US, it is the singular "one", or the plural
3868b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *                    "other". For all other cases, it is null, and
3869b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *                    is not being used.
3870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::expandAffix(const UnicodeString& pattern,
3872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                UnicodeString& affix,
3873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                double number,
387450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                FieldPositionHandler& handler,
3875b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                UBool doFormat,
3876b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                const UnicodeString* pluralCount) const {
3877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    affix.remove();
3878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int i=0; i<pattern.length(); ) {
3879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar32 c = pattern.char32At(i);
3880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i += U16_LENGTH(c);
3881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (c == kQuote) {
3882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            c = pattern.char32At(i);
3883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            i += U16_LENGTH(c);
388450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            int beginIdx = affix.length();
3885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            switch (c) {
3886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kCurrencySign: {
3887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // As of ICU 2.2 we use the currency object, and
3888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // ignore the currency symbols in the DFS, unless
3889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // we have a null currency object.  This occurs if
3890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // resurrecting a pre-2.2 object or if the user
3891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // sets a custom DFS.
3892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                UBool intl = i<pattern.length() &&
3893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pattern.char32At(i) == kCurrencySign;
3894b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                UBool plural = FALSE;
3895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (intl) {
3896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ++i;
3897b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    plural = i<pattern.length() &&
3898b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        pattern.char32At(i) == kCurrencySign;
3899b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if (plural) {
3900b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        intl = FALSE;
3901b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        ++i;
3902b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
3903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
3904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                const UChar* currencyUChars = getCurrency();
3905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (currencyUChars[0] != 0) {
3906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    UErrorCode ec = U_ZERO_ERROR;
3907b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if (plural && pluralCount != NULL) {
3908b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        // plural name is only needed when pluralCount != null,
3909b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        // which means when formatting currency plural names.
3910b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        // For other cases, pluralCount == null,
3911b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        // and plural names are not needed.
3912b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        int32_t len;
3913b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        CharString pluralCountChar;
3914b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        pluralCountChar.appendInvariantChars(*pluralCount, ec);
3915b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        UBool isChoiceFormat;
3916b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        const UChar* s = ucurr_getPluralName(currencyUChars,
3917b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            fSymbols != NULL ? fSymbols->getLocale().getName() :
3918b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            Locale::getDefault().getName(), &isChoiceFormat,
3919b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            pluralCountChar.data(), &len, &ec);
3920b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        affix += UnicodeString(s, len);
392150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3922b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    } else if(intl) {
3923b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        affix.append(currencyUChars, -1);
392450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
3926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        int32_t len;
3927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UBool isChoiceFormat;
3928c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        // If fSymbols is NULL, use default locale
392950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        const UChar* s = ucurr_getName(currencyUChars,
393050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            fSymbols != NULL ? fSymbols->getLocale().getName() : Locale::getDefault().getName(),
393150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec);
3932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (isChoiceFormat) {
3933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            // Two modes here: If doFormat is false, we set up
3934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            // currencyChoice.  If doFormat is true, we use the
3935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            // previously created currencyChoice to format the
3936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            // value in digitList.
3937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (!doFormat) {
3938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // If the currency is handled by a ChoiceFormat,
3939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // then we're not going to use the expanded
3940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // patterns.  Instantiate the ChoiceFormat and
3941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // return.
3942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                if (fCurrencyChoice == NULL) {
3943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    // TODO Replace double-check with proper thread-safe code
3944b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    ChoiceFormat* fmt = new ChoiceFormat(UnicodeString(s), ec);
3945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    if (U_SUCCESS(ec)) {
3946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        umtx_lock(NULL);
3947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        if (fCurrencyChoice == NULL) {
3948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                            // Cast away const
3949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                            ((DecimalFormat*)this)->fCurrencyChoice = fmt;
3950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                            fmt = NULL;
3951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        }
3952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        umtx_unlock(NULL);
3953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        delete fmt;
3954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    }
3955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                }
3956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // We could almost return null or "" here, since the
3957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // expanded affixes are almost not used at all
3958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // in this situation.  However, one method --
3959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // toPattern() -- still does use the expanded
3960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // affixes, in order to set up a padding
3961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // pattern.  We use the CURRENCY_SIGN as a
3962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                // placeholder.
3963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                affix.append(kCurrencySign);
3964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            } else {
3965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                if (fCurrencyChoice != NULL) {
3966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    FieldPosition pos(0); // ignored
3967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    if (number < 0) {
3968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        number = -number;
3969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    }
3970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    fCurrencyChoice->format(number, affix, pos);
3971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                } else {
3972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    // We only arrive here if the currency choice
3973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    // format in the locale data is INVALID.
3974b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    affix.append(currencyUChars, -1);
397550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                }
3977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
3978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            continue;
3979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
3980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        affix += UnicodeString(s, len);
398150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
3983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
3984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if(intl) {
3985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
3986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
3987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
3988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
398950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
3991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
3992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
3993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternPercent:
3994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
399550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.addAttribute(kPercentField, beginIdx, affix.length());
3996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
3997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternPerMill:
3998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
399950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.addAttribute(kPermillField, beginIdx, affix.length());
4000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternPlus:
4002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
400350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.addAttribute(kSignField, beginIdx, affix.length());
4004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case kPatternMinus:
4006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
400750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                handler.addAttribute(kSignField, beginIdx, affix.length());
4008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            default:
4010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix.append(c);
4011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
4015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            affix.append(c);
4016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
4021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Append an affix to the given StringBuffer.
4022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param buf buffer to append to
4023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param isNegative
4024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param isPrefix
4025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
4026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::appendAffix(UnicodeString& buf, double number,
402750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   FieldPositionHandler& handler,
4028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                   UBool isNegative, UBool isPrefix) const {
4029b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // plural format precedes choice format
403050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fCurrencyChoice != 0 &&
4031b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencySignCount != fgCurrencySignCountInPluralFormat) {
4032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const UnicodeString* affixPat;
4033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (isPrefix) {
4034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern;
4035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
4036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern;
4037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (affixPat) {
4039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UnicodeString affixBuf;
404050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            expandAffix(*affixPat, affixBuf, number, handler, TRUE, NULL);
4041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            buf.append(affixBuf);
4042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return affixBuf.length();
4043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // else someone called a function that reset the pattern.
4045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
404650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString* affix;
4048b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) {
4049b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UnicodeString pluralCount = fCurrencyPluralInfo->getPluralRules()->select(number);
4050b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        AffixesForCurrency* oneSet;
4051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (fStyle == UNUM_CURRENCY_PLURAL) {
4052b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            oneSet = (AffixesForCurrency*)fPluralAffixesForCurrency->get(pluralCount);
4053b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
4054b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            oneSet = (AffixesForCurrency*)fAffixesForCurrency->get(pluralCount);
4055b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
4056b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (isPrefix) {
405750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            affix = isNegative ? &oneSet->negPrefixForCurrency :
4058b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                 &oneSet->posPrefixForCurrency;
4059b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
406050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            affix = isNegative ? &oneSet->negSuffixForCurrency :
4061b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                 &oneSet->posSuffixForCurrency;
4062b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
4063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
4064b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (isPrefix) {
4065b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            affix = isNegative ? &fNegativePrefix : &fPositivePrefix;
4066b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
4067b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix;
4068b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
4069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
407050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
407150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t begin = (int) buf.length();
407250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    buf.append(*affix);
407450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
407550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (handler.isRecording()) {
407650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      int32_t offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
407750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      if (offset > -1) {
407850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
407950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length());
408050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      }
408150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
408250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
408350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      if (offset > -1) {
408450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
408550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length());
408650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      }
408750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
408850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
408950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      if (offset > -1) {
409050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
409150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kSignField, begin + offset, begin + offset + aff.length());
409250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      }
409350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
409450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
409550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      if (offset > -1) {
409650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
409750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kPercentField, begin + offset, begin + offset + aff.length());
409850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      }
409950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
410050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
410150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      if (offset > -1) {
410250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
410350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        handler.addAttribute(kPermillField, begin + offset, begin + offset + aff.length());
410450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      }
410550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
4106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return affix->length();
4107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
4110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Appends an affix pattern to the given StringBuffer, quoting special
4111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * characters as needed.  Uses the internal affix pattern, if that exists,
4112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * or the literal affix, if the internal affix pattern is null.  The
4113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * appended string will generate the same affix pattern (or literal affix)
4114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * when passed to toPattern().
4115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
4116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param appendTo the affix string is appended to this
4117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param affixPattern a pattern such as fPosPrefixPattern; may be null
4118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
4119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Ignored unless affixPattern is null.  If affixPattern is null, then
4120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * expAffix is appended as a literal affix.
4121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param localized true if the appended pattern should contain localized
4122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * pattern characters; otherwise, non-localized pattern chars are appended
4123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
4124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::appendAffixPattern(UnicodeString& appendTo,
4125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                       const UnicodeString* affixPattern,
4126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                       const UnicodeString& expAffix,
4127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                       UBool localized) const {
4128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (affixPattern == 0) {
4129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        appendAffixPattern(appendTo, expAffix, localized);
4130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
4131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int i;
4132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int pos=0; pos<affixPattern->length(); pos=i) {
4133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            i = affixPattern->indexOf(kQuote, pos);
4134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (i < 0) {
4135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                UnicodeString s;
4136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affixPattern->extractBetween(pos, affixPattern->length(), s);
4137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendAffixPattern(appendTo, s, localized);
4138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (i > pos) {
4141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                UnicodeString s;
4142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affixPattern->extractBetween(pos, i, s);
4143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendAffixPattern(appendTo, s, localized);
4144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UChar32 c = affixPattern->char32At(++i);
4146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ++i;
4147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (c == kQuote) {
4148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo.append(c).append(c);
4149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Fall through and append another kQuote below
4150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (c == kCurrencySign &&
4151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                       i<affixPattern->length() &&
4152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                       affixPattern->char32At(i) == kCurrencySign) {
4153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ++i;
4154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo.append(c).append(c);
4155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (localized) {
4156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                switch (c) {
4157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                case kPatternPercent:
4158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
4159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                case kPatternPerMill:
4161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
4162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                case kPatternPlus:
4164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
4165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                case kPatternMinus:
4167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
4168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                default:
4170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    appendTo.append(c);
4171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
4173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo.append(c);
4174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
4180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Append an affix to the given StringBuffer, using quotes if
4181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * there are special characters.  Single quotes themselves must be
4182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * escaped in either case.
4183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
4184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
4185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::appendAffixPattern(UnicodeString& appendTo,
4186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  const UnicodeString& affix,
4187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  UBool localized) const {
4188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool needQuote;
4189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(localized) {
4190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0
4191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0
4192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0
4193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0
4194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0
4195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0
4196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0
4197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0
4198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0
4199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kCurrencySign) >= 0;
4200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
4202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        needQuote = affix.indexOf(kPatternZeroDigit) >= 0
4203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternGroupingSeparator) >= 0
4204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternDecimalSeparator) >= 0
4205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternPercent) >= 0
4206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternPerMill) >= 0
4207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternDigit) >= 0
4208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternSeparator) >= 0
4209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternExponent) >= 0
4210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternPlus) >= 0
4211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kPatternMinus) >= 0
4212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || affix.indexOf(kCurrencySign) >= 0;
4213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (needQuote)
4215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        appendTo += (UChar)0x0027 /*'\''*/;
4216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0)
4217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        appendTo += affix;
4218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
4219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t j = 0; j < affix.length(); ) {
4220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UChar32 c = affix.char32At(j);
4221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            j += U16_LENGTH(c);
4222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendTo += c;
4223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (c == 0x0027 /*'\''*/)
4224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                appendTo += c;
4225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (needQuote)
4228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        appendTo += (UChar)0x0027 /*'\''*/;
4229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
4232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString&
4234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::toPattern(UnicodeString& result, UBool localized) const
4235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
4236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fStyle == UNUM_CURRENCY_PLURAL) {
4237b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // the prefix or suffix pattern might not be defined yet,
4238b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // so they can not be synthesized,
4239b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // instead, get them directly.
4240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // but it might not be the actual pattern used in formatting.
424150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // the actual pattern used in formatting depends on the
4242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // formatted number's plural count.
4243b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        result = fFormatPattern;
4244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return result;
4245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
4246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    result.remove();
4247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UChar32 zero, sigDigit = kPatternSignificantDigit;
4248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString digit, group;
4249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i;
4250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits
4251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString roundingDigits;
4252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1;
4253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString padSpec;
4254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool useSigDig = areSignificantDigitsUsed();
4255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (localized) {
4257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
4258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
4259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
4260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (useSigDig) {
4261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
4262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
4265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        digit.append((UChar)kPatternDigit);
4266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        group.append((UChar)kPatternGroupingSeparator);
4267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        zero = (UChar32)kPatternZeroDigit;
4268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0) {
4270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (localized) {
4271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
4272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
4274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            padSpec.append((UChar)kPatternPadEscape);
4275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        padSpec.append(fPad);
4277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fRoundingIncrement != NULL) {
427950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        for(i=0; i<fRoundingIncrement->getCount(); ++i) {
428027f654740f2a26ad62a5c155af9199af9e69b889claireho          roundingDigits.append(zero+(fRoundingIncrement->getDigitValue(i))); // Convert to Unicode digit
4281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
428250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        roundingDecimalPos = fRoundingIncrement->getDecimalAt();
4283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t part=0; part<2; ++part) {
4285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (padPos == kPadBeforePrefix) {
4286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result.append(padSpec);
4287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        appendAffixPattern(result,
4289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    (part==0 ? fPosPrefixPattern : fNegPrefixPattern),
4290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    (part==0 ? fPositivePrefix : fNegativePrefix),
4291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    localized);
4292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) {
4293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result.append(padSpec);
4294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t sub0Start = result.length();
4296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0;
4297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) {
4298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            g += fGroupingSize2;
4299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t maxDig = 0, minDig = 0, maxSigDig = 0;
4301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (useSigDig) {
4302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            minDig = getMinimumSignificantDigits();
4303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            maxDig = maxSigDig = getMaximumSignificantDigits();
4304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
4305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            minDig = getMinimumIntegerDigits();
4306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            maxDig = getMaximumIntegerDigits();
4307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fUseExponentialNotation) {
4309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (maxDig > kMaxScientificIntegerDigits) {
4310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                maxDig = 1;
4311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if (useSigDig) {
4313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            maxDig = _max(maxDig, g+1);
4314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
4315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            maxDig = _max(_max(g, getMinimumIntegerDigits()),
4316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                          roundingDecimalPos) + 1;
4317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (i = maxDig; i > 0; --i) {
4319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (!fUseExponentialNotation && i<maxDig &&
4320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                isGroupingPosition(i)) {
4321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result.append(group);
4322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (useSigDig) {
4324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                //  #@,@###   (maxSigDig == 5, minSigDig == 2)
4325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                //  65 4321   (1-based pos, count from the right)
4326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)
4327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig
4328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (maxSigDig >= i && i > (maxSigDig - minDig)) {
4329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append(sigDigit);
4330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
4331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append(digit);
4332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
4334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (! roundingDigits.isEmpty()) {
4335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    int32_t pos = roundingDecimalPos - i;
4336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (pos >= 0 && pos < roundingDigits.length()) {
4337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
4338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        continue;
4339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (i<=minDig) {
4342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append(zero);
4343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
4344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append(digit);
4345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!useSigDig) {
4349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) {
4350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (localized) {
4351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
4352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                else {
4354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append((UChar)kPatternDecimalSeparator);
4355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t pos = roundingDecimalPos;
4358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            for (i = 0; i < getMaximumFractionDigits(); ++i) {
4359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) {
4360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (pos < 0) {
4361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        result.append(zero);
4362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    else {
4364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
4365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ++pos;
4367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    continue;
4368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (i<getMinimumFractionDigits()) {
4370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append(zero);
4371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                else {
4373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append(digit);
4374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fUseExponentialNotation) {
4378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (localized) {
4379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
4380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            else {
4382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result.append((UChar)kPatternExponent);
4383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fExponentSignAlwaysShown) {
4385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (localized) {
4386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
4387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                else {
4389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append((UChar)kPatternPlus);
4390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            for (i=0; i<fMinExponentDigits; ++i) {
4393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result.append(zero);
4394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (! padSpec.isEmpty() && !fUseExponentialNotation) {
4397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t add = fFormatWidth - result.length() + sub0Start
4398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                - ((part == 0)
4399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   ? fPositivePrefix.length() + fPositiveSuffix.length()
4400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   : fNegativePrefix.length() + fNegativeSuffix.length());
4401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while (add > 0) {
4402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result.insert(sub0Start, digit);
4403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ++maxDig;
4404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                --add;
4405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Only add a grouping separator if we have at least
4406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // 2 additional characters to be added, so we don't
4407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // end up with ",###".
4408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (add>1 && isGroupingPosition(maxDig)) {
4409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.insert(sub0Start, group);
441050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    --add;
4411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) {
4415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result.append(padSpec);
4416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (part == 0) {
4418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, localized);
4419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
4420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result.append(padSpec);
4421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UBool isDefault = FALSE;
4423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if ((fNegSuffixPattern == fPosSuffixPattern && // both null
4424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 fNegativeSuffix == fPositiveSuffix)
4425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 &&
4426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *fNegSuffixPattern == *fPosSuffixPattern))
4427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
4428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL)
4429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                {
4430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    int32_t length = fPosPrefixPattern->length();
4431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    isDefault = fNegPrefixPattern->length() == (length+2) &&
4432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        (*fNegPrefixPattern)[(int32_t)0] == kQuote &&
4433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus &&
4434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0;
4435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (!isDefault &&
4437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    fNegPrefixPattern == NULL && fPosPrefixPattern == NULL)
4438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                {
4439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    int32_t length = fPositivePrefix.length();
4440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    isDefault = fNegativePrefix.length() == (length+1) &&
4441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 &&
4442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0;
4443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (isDefault) {
4446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break; // Don't output default negative subpattern
4447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
4448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (localized) {
4449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
4450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                else {
4452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    result.append((UChar)kPatternSeparator);
4453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
4456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, localized);
4457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
4458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result.append(padSpec);
4459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return result;
4464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
4467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
4469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
4470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
4471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UParseError parseError;
4472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    applyPattern(pattern, FALSE, parseError, status);
4473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
4476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
4478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::applyPattern(const UnicodeString& pattern,
447950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            UParseError& parseError,
4480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            UErrorCode& status)
4481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
4482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    applyPattern(pattern, FALSE, parseError, status);
4483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
4485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
4487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
4488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
4489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UParseError parseError;
4490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    applyPattern(pattern, TRUE,parseError,status);
4491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
4494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
4496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
4497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                     UParseError& parseError,
4498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                     UErrorCode& status)
4499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
4500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    applyPattern(pattern, TRUE,parseError,status);
4501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
4502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------
4504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
4506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern,
4507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                              UBool localized,
4508b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                              UParseError& parseError,
4509b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                              UErrorCode& status)
4510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
4511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status))
4512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
4513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
4514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Clear error struct
4516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    parseError.offset = -1;
4517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
4518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Set the significant pattern symbols
4520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UChar32 zeroDigit               = kPatternZeroDigit; // '0'
4521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UChar32 sigDigit                = kPatternSignificantDigit; // '@'
4522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator);
4523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString decimalSeparator  ((UChar)kPatternDecimalSeparator);
4524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString percent           ((UChar)kPatternPercent);
4525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString perMill           ((UChar)kPatternPerMill);
4526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString digit             ((UChar)kPatternDigit); // '#'
4527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString separator         ((UChar)kPatternSeparator);
4528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString exponent          ((UChar)kPatternExponent);
4529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString plus              ((UChar)kPatternPlus);
4530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString minus             ((UChar)kPatternMinus);
4531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString padEscape         ((UChar)kPatternPadEscape);
4532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Substitute with the localized symbols if necessary
4533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (localized) {
4534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
4535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
4536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        groupingSeparator.  remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
4537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        decimalSeparator.   remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
4538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        percent.            remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
4539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        perMill.            remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
4540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        digit.              remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
4541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        separator.          remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
4542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        exponent.           remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol));
4543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        plus.               remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol));
4544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        minus.              remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
4545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        padEscape.          remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
4546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
4547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UChar nineDigit = (UChar)(zeroDigit + 9);
4548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t digitLen = digit.length();
4549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t groupSepLen = groupingSeparator.length();
4550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t decimalSepLen = decimalSeparator.length();
4551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t pos = 0;
4553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t patLen = pattern.length();
4554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Part 0 is the positive pattern.  Part 1, if present, is the negative
4555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // pattern.
4556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t part=0; part<2 && pos<patLen; ++part) {
4557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
4558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is
4559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // between the prefix and suffix, and consists of pattern
4560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // characters.  In the prefix and suffix, percent, perMill, and
4561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // currency symbols are recognized and translated.
4562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
4563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // It's important that we don't change any fields of this object
4565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // prematurely.  We set the following variables for the multiplier,
4566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // grouping, etc., and then only change the actual object fields if
4567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // everything parses correctly.  This also lets us register
4568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // the data from part 0 and ignore the part 1, except for the
4569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // prefix and suffix.
4570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString prefix;
4571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString suffix;
4572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t decimalPos = -1;
4573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t multiplier = 1;
4574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
4575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int8_t groupingCount = -1;
4576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int8_t groupingCount2 = -1;
4577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t padPos = -1;
4578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar32 padChar = 0;
4579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t roundingPos = -1;
4580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        DigitList roundingInc;
4581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int8_t expDigits = -1;
4582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UBool expSignAlways = FALSE;
458350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // The affix is either the prefix or the suffix.
4585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString* affix = &prefix;
458650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t start = pos;
4588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UBool isPartDone = FALSE;
4589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar32 ch;
4590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (; !isPartDone && pos < patLen; ) {
4592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Todo: account for surrogate pairs
4593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ch = pattern.char32At(pos);
4594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            switch (subpart) {
4595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case 0: // Pattern proper subpart (between prefix & suffix)
4596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Process the digits, decimal, and grouping characters.  We
4597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // record five pieces of information.  We expect the digits
4598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // to occur in the pattern ####00.00####, and we record the
4599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // number of left digits, zero (central) digits, and right
4600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // digits.  The position of the last grouping character is
4601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // recorded (should be somewhere within the first two blocks
4602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // of characters), as is the position of the decimal point,
4603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // if any (should be in the zero digits).  If there is no
4604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // decimal point, then there should be no right digits.
4605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (pattern.compare(pos, digitLen, digit) == 0) {
4606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (zeroDigitCount > 0 || sigDigitCount > 0) {
4607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ++digitRightCount;
4608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
4609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ++digitLeftCount;
4610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (groupingCount >= 0 && decimalPos < 0) {
4612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ++groupingCount;
4613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += digitLen;
4615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if ((ch >= zeroDigit && ch <= nineDigit) ||
4616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                           ch == sigDigit) {
4617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (digitRightCount > 0) {
4618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Unexpected '0'
4619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        debug("Unexpected '0'")
4620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_UNEXPECTED_TOKEN;
4621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (ch == sigDigit) {
4625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ++sigDigitCount;
4626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
4627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (ch != zeroDigit && roundingPos < 0) {
4628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            roundingPos = digitLeftCount + zeroDigitCount;
4629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
4630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (roundingPos >= 0) {
4631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            roundingInc.append((char)(ch - zeroDigit + '0'));
4632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
4633103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        ++zeroDigitCount;
4634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (groupingCount >= 0 && decimalPos < 0) {
4636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ++groupingCount;
4637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += U16_LENGTH(ch);
4639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) {
4640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (decimalPos >= 0) {
4641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Grouping separator after decimal
4642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        debug("Grouping separator after decimal")
4643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_UNEXPECTED_TOKEN;
4644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    groupingCount2 = groupingCount;
4648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    groupingCount = 0;
4649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += groupSepLen;
4650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) {
4651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (decimalPos >= 0) {
4652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Multiple decimal separators
4653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        debug("Multiple decimal separators")
4654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_MULTIPLE_DECIMAL_SEPARATORS;
4655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Intentionally incorporate the digitRightCount,
4659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // even though it is illegal for this to be > 0
4660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // at this point.  We check pattern syntax below.
4661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
4662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += decimalSepLen;
4663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
4664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (pattern.compare(pos, exponent.length(), exponent) == 0) {
4665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (expDigits >= 0) {
4666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            // Multiple exponential symbols
4667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            debug("Multiple exponential symbols")
4668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            status = U_MULTIPLE_EXPONENTIAL_SYMBOLS;
4669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            syntaxError(pattern,pos,parseError);
4670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            return;
4671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
4672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (groupingCount >= 0) {
4673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            // Grouping separator in exponential pattern
4674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            debug("Grouping separator in exponential pattern")
4675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
4676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            syntaxError(pattern,pos,parseError);
4677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            return;
4678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
4679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        pos += exponent.length();
4680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Check for positive prefix
4681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (pos < patLen
4682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            && pattern.compare(pos, plus.length(), plus) == 0) {
4683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            expSignAlways = TRUE;
4684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            pos += plus.length();
4685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
4686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Use lookahead to parse out the exponential part of the
4687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // pattern, then jump into suffix subpart.
4688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        expDigits = 0;
4689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        while (pos < patLen &&
4690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               pattern.char32At(pos) == zeroDigit) {
4691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            ++expDigits;
4692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            pos += U16_LENGTH(zeroDigit);
4693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
4694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // 1. Require at least one mantissa pattern digit
4696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // 2. Disallow "#+ @" in mantissa
4697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // 3. Require at least one exponent pattern digit
4698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (((digitLeftCount + zeroDigitCount) < 1 &&
4699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             (sigDigitCount + digitRightCount) < 1) ||
4700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            (sigDigitCount > 0 && digitLeftCount > 0) ||
4701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            expDigits < 1) {
4702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            // Malformed exponential pattern
4703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            debug("Malformed exponential pattern")
4704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
4705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            syntaxError(pattern,pos,parseError);
4706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            return;
4707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
4708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Transition to suffix subpart
4710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    subpart = 2; // suffix subpart
4711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix = &suffix;
4712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    sub0Limit = pos;
4713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    continue;
4714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case 1: // Prefix subpart
4717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case 2: // Suffix subpart
4718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Process the prefix / suffix characters
4719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Process unquoted characters seen in prefix or suffix
4720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // subpart.
4721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Several syntax characters implicitly begins the
4723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // next subpart if we are in the prefix; otherwise
4724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // they are illegal if unquoted.
4725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (!pattern.compare(pos, digitLen, digit) ||
4726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    !pattern.compare(pos, groupSepLen, groupingSeparator) ||
4727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    !pattern.compare(pos, decimalSepLen, decimalSeparator) ||
4728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    (ch >= zeroDigit && ch <= nineDigit) ||
4729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ch == sigDigit) {
4730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (subpart == 1) { // prefix subpart
4731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        subpart = 0; // pattern proper subpart
4732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        sub0Start = pos; // Reprocess this character
4733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        continue;
4734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
4735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_UNQUOTED_SPECIAL;
4736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (ch == kCurrencySign) {
4740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kQuote); // Encode currency
4741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Use lookahead to determine if the currency sign is
4742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // doubled or not.
4743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    U_ASSERT(U16_LENGTH(kCurrencySign) == 1);
4744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) {
4745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        affix->append(kCurrencySign);
4746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ++pos; // Skip over the doubled character
474750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        if ((pos+1) < pattern.length() &&
4748b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            pattern[pos+1] == kCurrencySign) {
4749b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            affix->append(kCurrencySign);
4750b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            ++pos; // Skip over the doubled character
4751b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            fCurrencySignCount = fgCurrencySignCountInPluralFormat;
4752b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        } else {
4753b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            fCurrencySignCount = fgCurrencySignCountInISOFormat;
4754b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        }
4755b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    } else {
4756b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        fCurrencySignCount = fgCurrencySignCountInSymbolFormat;
4757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Fall through to append(ch)
4759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (ch == kQuote) {
4760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // A quote outside quotes indicates either the opening
4761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // quote or two quotes, which is a quote literal.  That is,
4762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // we have the first quote in 'do' or o''clock.
4763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    U_ASSERT(U16_LENGTH(kQuote) == 1);
4764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ++pos;
4765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (pos < pattern.length() && pattern[pos] == kQuote) {
4766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        affix->append(kQuote); // Encode quote
4767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Fall through to append(ch)
4768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
4769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        subpart += 2; // open quote
4770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        continue;
4771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, separator.length(), separator) == 0) {
4773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Don't allow separators in the prefix, and don't allow
4774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // separators in the second pattern (part == 1).
4775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (subpart == 1 || part == 1) {
4776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Unexpected separator
4777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        debug("Unexpected separator")
4778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_UNEXPECTED_TOKEN;
4779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    sub2Limit = pos;
4783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    isPartDone = TRUE; // Go to next part
4784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += separator.length();
4785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, percent.length(), percent) == 0) {
4787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Next handle characters which are appended directly.
4788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (multiplier != 1) {
4789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Too many percent/perMill characters
4790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        debug("Too many percent characters")
4791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_MULTIPLE_PERCENT_SYMBOLS;
4792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kQuote); // Encode percent/perMill
4796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kPatternPercent); // Use unlocalized pattern char
4797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    multiplier = 100;
4798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += percent.length();
4799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, perMill.length(), perMill) == 0) {
4801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Next handle characters which are appended directly.
4802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (multiplier != 1) {
4803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Too many percent/perMill characters
4804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        debug("Too many perMill characters")
4805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_MULTIPLE_PERMILL_SYMBOLS;
4806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kQuote); // Encode percent/perMill
4810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kPatternPerMill); // Use unlocalized pattern char
4811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    multiplier = 1000;
4812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += perMill.length();
4813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, padEscape.length(), padEscape) == 0) {
4815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (padPos >= 0 ||               // Multiple pad specifiers
4816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        (pos+1) == pattern.length()) { // Nothing after padEscape
4817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        debug("Multiple pad specifiers")
4818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_MULTIPLE_PAD_SPECIFIERS;
4819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        syntaxError(pattern,pos,parseError);
4820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
4821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    padPos = pos;
4823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += padEscape.length();
4824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    padChar = pattern.char32At(pos);
4825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += U16_LENGTH(padChar);
4826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, minus.length(), minus) == 0) {
4828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kQuote); // Encode minus
4829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kPatternMinus);
4830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += minus.length();
4831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if (pattern.compare(pos, plus.length(), plus) == 0) {
4833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kQuote); // Encode plus
4834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    affix->append(kPatternPlus);
4835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    pos += plus.length();
4836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
4837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Unquoted, non-special characters fall through to here, as
4839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // well as other code which needs to append something to the
4840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // affix.
4841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix->append(ch);
4842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                pos += U16_LENGTH(ch);
4843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case 3: // Prefix subpart, in quote
4845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case 4: // Suffix subpart, in quote
4846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // A quote within quotes indicates either the closing
4847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // quote or two quotes, which is a quote literal.  That is,
4848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // we have the second quote in 'do' or 'don''t'.
4849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (ch == kQuote) {
4850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ++pos;
4851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (pos < pattern.length() && pattern[pos] == kQuote) {
4852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        affix->append(kQuote); // Encode quote
4853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Fall through to append(ch)
4854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
4855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        subpart -= 2; // close quote
4856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        continue;
4857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
4858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
4859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                affix->append(ch);
4860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                pos += U16_LENGTH(ch);
4861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
4862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (sub0Limit == 0) {
4866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            sub0Limit = pattern.length();
4867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (sub2Limit == 0) {
4870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            sub2Limit = pattern.length();
4871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Handle patterns with no '0' pattern character.  These patterns
4874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * are legal, but must be recodified to make sense.  "##.###" ->
4875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * "#0.###".  ".###" -> ".0##".
4876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         *
4877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * We allow patterns of the form "####" to produce a zeroDigitCount
4878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * of zero (got that?); although this seems like it might make it
4879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * possible for format() to produce empty strings, format() checks
4880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * for this condition and outputs a zero digit in this situation.
4881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * Having a zeroDigitCount of zero yields a minimum integer digits
4882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * of zero, which allows proper round-trip patterns.  We don't want
4883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * "#" to become "#0" when toPattern() is called (even though that's
4884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * what it really is, semantically).
4885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
4886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (zeroDigitCount == 0 && sigDigitCount == 0 &&
4887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            digitLeftCount > 0 && decimalPos >= 0) {
4888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Handle "###.###" and "###." and ".###"
4889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int n = decimalPos;
4890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (n == 0)
4891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ++n; // Handle ".###"
4892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            digitRightCount = digitLeftCount - n;
4893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            digitLeftCount = n - 1;
4894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            zeroDigitCount = 1;
4895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Do syntax checking on the digits, decimal points, and quotes.
4898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||
4899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            (decimalPos >= 0 &&
4900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             (sigDigitCount > 0 ||
4901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              decimalPos < digitLeftCount ||
4902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              decimalPos > (digitLeftCount + zeroDigitCount))) ||
4903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            groupingCount == 0 || groupingCount2 == 0 ||
4904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            (sigDigitCount > 0 && zeroDigitCount > 0) ||
4905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            subpart > 2)
4906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        { // subpart > 2 == unmatched quote
4907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            debug("Syntax error")
4908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_PATTERN_SYNTAX_ERROR;
4909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            syntaxError(pattern,pos,parseError);
4910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return;
4911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Make sure pad is at legal position before or after affix.
4914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (padPos >= 0) {
4915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (padPos == start) {
4916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                padPos = kPadBeforePrefix;
4917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (padPos+2 == sub0Start) {
4918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                padPos = kPadAfterPrefix;
4919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (padPos == sub0Limit) {
4920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                padPos = kPadBeforeSuffix;
4921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (padPos+2 == sub2Limit) {
4922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                padPos = kPadAfterSuffix;
4923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
4924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Illegal pad position
4925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                debug("Illegal pad position")
4926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_ILLEGAL_PAD_POSITION;
4927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                syntaxError(pattern,pos,parseError);
4928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
4929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
4931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (part == 0) {
4933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete fPosPrefixPattern;
4934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete fPosSuffixPattern;
4935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete fNegPrefixPattern;
4936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete fNegSuffixPattern;
4937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fPosPrefixPattern = new UnicodeString(prefix);
4938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* test for NULL */
4939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fPosPrefixPattern == 0) {
4940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_MEMORY_ALLOCATION_ERROR;
4941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
4942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fPosSuffixPattern = new UnicodeString(suffix);
4944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* test for NULL */
4945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fPosSuffixPattern == 0) {
4946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_MEMORY_ALLOCATION_ERROR;
4947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete fPosPrefixPattern;
4948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
4949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fNegPrefixPattern = 0;
4951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fNegSuffixPattern = 0;
4952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fUseExponentialNotation = (expDigits >= 0);
4954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fUseExponentialNotation) {
4955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fMinExponentDigits = expDigits;
4956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fExponentSignAlwaysShown = expSignAlways;
4958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
4959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // The effectiveDecimalPos is the position the decimal is at or
4960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // would be at if there is no decimal.  Note that if
4961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // decimalPos<0, then digitTotalCount == digitLeftCount +
4962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // zeroDigitCount.
4963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
4964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UBool isSigDig = (sigDigitCount > 0);
4965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            setSignificantDigitsUsed(isSigDig);
4966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (isSigDig) {
4967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMinimumSignificantDigits(sigDigitCount);
4968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMaximumSignificantDigits(sigDigitCount + digitRightCount);
4969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
4970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                int32_t minInt = effectiveDecimalPos - digitLeftCount;
4971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMinimumIntegerDigits(minInt);
4972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMaximumIntegerDigits(fUseExponentialNotation
4973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ? digitLeftCount + getMinimumIntegerDigits()
4974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    : kDoubleIntegerDigits);
4975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMaximumFractionDigits(decimalPos >= 0
4976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ? (digitTotalCount - decimalPos) : 0);
4977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMinimumFractionDigits(decimalPos >= 0
4978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
4979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            setGroupingUsed(groupingCount > 0);
4981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
4982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
4983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ? groupingCount2 : 0;
498450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            setMultiplier(multiplier);
4985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            setDecimalSeparatorAlwaysShown(decimalPos == 0
4986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    || decimalPos == digitTotalCount);
4987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (padPos >= 0) {
4988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fPadPosition = (EPadPosition) padPos;
4989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // To compute the format width, first set up sub0Limit -
4990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // sub0Start.  Add in prefix/suffix length later.
4991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // fFormatWidth = prefix.length() + suffix.length() +
4993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                //    sub0Limit - sub0Start;
4994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fFormatWidth = sub0Limit - sub0Start;
4995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fPad = padChar;
4996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
4997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fFormatWidth = 0;
4998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
4999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (roundingPos >= 0) {
500050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                roundingInc.setDecimalAt(effectiveDecimalPos - roundingPos);
5001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (fRoundingIncrement != NULL) {
5002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *fRoundingIncrement = roundingInc;
5003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
5004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    fRoundingIncrement = new DigitList(roundingInc);
5005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    /* test for NULL */
500650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    if (fRoundingIncrement == NULL) {
5007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        status = U_MEMORY_ALLOCATION_ERROR;
5008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        delete fPosPrefixPattern;
5009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        delete fPosSuffixPattern;
5010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        return;
5011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
5012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
5013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fRoundingMode = kRoundHalfEven;
5014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
5015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setRoundingIncrement(0.0);
5016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
5017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
5018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fNegPrefixPattern = new UnicodeString(prefix);
5019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* test for NULL */
5020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fNegPrefixPattern == 0) {
5021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_MEMORY_ALLOCATION_ERROR;
5022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
5023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
5024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fNegSuffixPattern = new UnicodeString(suffix);
5025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* test for NULL */
5026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fNegSuffixPattern == 0) {
5027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete fNegPrefixPattern;
5028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_MEMORY_ALLOCATION_ERROR;
5029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
5030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
5031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
5032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (pattern.length() == 0) {
5035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete fNegPrefixPattern;
5036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete fNegSuffixPattern;
5037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fNegPrefixPattern = NULL;
5038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fNegSuffixPattern = NULL;
5039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fPosPrefixPattern != NULL) {
5040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fPosPrefixPattern->remove();
5041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
5042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fPosPrefixPattern = new UnicodeString();
5043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* test for NULL */
5044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fPosPrefixPattern == 0) {
5045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_MEMORY_ALLOCATION_ERROR;
5046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
5047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
5048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
5049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fPosSuffixPattern != NULL) {
5050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fPosSuffixPattern->remove();
5051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
5052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fPosSuffixPattern = new UnicodeString();
5053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* test for NULL */
5054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fPosSuffixPattern == 0) {
5055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete fPosPrefixPattern;
5056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_MEMORY_ALLOCATION_ERROR;
5057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
5058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
5059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
5060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setMinimumIntegerDigits(0);
5062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setMaximumIntegerDigits(kDoubleIntegerDigits);
5063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setMinimumFractionDigits(0);
5064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setMaximumFractionDigits(kDoubleFractionDigits);
5065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fUseExponentialNotation = FALSE;
5067b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fCurrencySignCount = 0;
5068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setGroupingUsed(FALSE);
5069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fGroupingSize = 0;
5070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fGroupingSize2 = 0;
507150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        setMultiplier(1);
5072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setDecimalSeparatorAlwaysShown(FALSE);
5073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fFormatWidth = 0;
5074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setRoundingIncrement(0.0);
5075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // If there was no negative pattern, or if the negative pattern is
5078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // identical to the positive pattern, then prepend the minus sign to the
5079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // positive pattern to form the negative pattern.
5080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fNegPrefixPattern == NULL ||
5081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (*fNegPrefixPattern == *fPosPrefixPattern
5082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         && *fNegSuffixPattern == *fPosSuffixPattern)) {
508354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        _copy_ptr(&fNegSuffixPattern, fPosSuffixPattern);
5084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fNegPrefixPattern == NULL) {
5085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fNegPrefixPattern = new UnicodeString();
5086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* test for NULL */
5087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fNegPrefixPattern == 0) {
5088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_MEMORY_ALLOCATION_ERROR;
5089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
5090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
5091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
5092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fNegPrefixPattern->remove();
5093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
5094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fNegPrefixPattern->append(kQuote).append(kPatternMinus)
5095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            .append(*fPosPrefixPattern);
5096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef FMT_DEBUG
5098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString s;
5099103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    s.append((UnicodeString)"\"").append(pattern).append((UnicodeString)"\"->");
5100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    debugout(s);
5101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
5102b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // save the pattern
5104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fFormatPattern = pattern;
5105b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5107b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5108b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
5109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) {
5110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    expandAffixes(pluralCount);
5111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fFormatWidth > 0) {
5112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Finish computing format width (see above)
511350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // TODO: how to handle fFormatWidth,
5114b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // need to save in f(Plural)AffixesForCurrecy?
5115b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length();
5116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
5121b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::applyPattern(const UnicodeString& pattern,
5122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            UBool localized,
5123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            UParseError& parseError,
5124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            UErrorCode& status)
512550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
5126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // do the following re-set first. since they change private data by
5127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // apply pattern again.
5128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (pattern.indexOf(kCurrencySign) != -1) {
512950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (fCurrencyPluralInfo == NULL) {
513050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // initialize currencyPluralInfo if needed
5131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
5132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
5133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (fAffixPatternsForCurrency == NULL) {
5134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            setupCurrencyAffixPatterns(status);
5135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
5136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (pattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) {
5137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // only setup the affixes of the current pattern.
5138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            setupCurrencyAffixes(pattern, TRUE, FALSE, status);
5139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
5140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    applyPatternWithoutExpandAffix(pattern, localized, parseError, status);
5142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    expandAffixAdjustWidth(NULL);
5143103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5144103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5145103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5146b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
515050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::applyPatternInternally(const UnicodeString& pluralCount,
5151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                      const UnicodeString& pattern,
5152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                      UBool localized,
5153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                      UParseError& parseError,
5154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                      UErrorCode& status) {
5155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    applyPatternWithoutExpandAffix(pattern, localized, parseError, status);
5156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    expandAffixAdjustWidth(&pluralCount);
5157103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5158103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5159103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
5164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Sets the maximum number of digits allowed in the integer portion of a
5165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * number. This override limits the integer digit count to 309.
5166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see NumberFormat#setMaximumIntegerDigits
5167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
5168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
5169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormat::setMaximumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
5170103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5171103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5172103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
5176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Sets the minimum number of digits allowed in the integer portion of a
5177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * number. This override limits the integer digit count to 309.
5178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see NumberFormat#setMinimumIntegerDigits
5179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
5180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
5181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
5182103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5183103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5184103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
5188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Sets the maximum number of digits allowed in the fraction portion of a
5189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * number. This override limits the fraction digit count to 340.
5190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see NumberFormat#setMaximumFractionDigits
5191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
5192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
5193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits));
5194103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5195103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5196103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
5200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Sets the minimum number of digits allowed in the fraction portion of a
5201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * number. This override limits the fraction digit count to 340.
5202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see NumberFormat#setMinimumFractionDigits
5203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
5204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
5205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits));
5206103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5207103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5208103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::getMinimumSignificantDigits() const {
5212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fMinSignificantDigits;
5213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t DecimalFormat::getMaximumSignificantDigits() const {
5216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fMaxSignificantDigits;
5217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setMinimumSignificantDigits(int32_t min) {
5220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (min < 1) {
522150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        min = 1;
5222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // pin max sig dig to >= min
5224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t max = _max(fMaxSignificantDigits, min);
5225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMinSignificantDigits = min;
5226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMaxSignificantDigits = max;
5227103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5228103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5229103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setMaximumSignificantDigits(int32_t max) {
5233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (max < 1) {
5234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        max = 1;
5235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // pin min sig dig to 1..max
5237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_ASSERT(fMinSignificantDigits >= 1);
5238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t min = _min(fMinSignificantDigits, max);
5239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMinSignificantDigits = min;
5240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fMaxSignificantDigits = max;
5241103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5242103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5243103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool DecimalFormat::areSignificantDigitsUsed() const {
5247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fUseSignificantDigits;
5248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
5251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fUseSignificantDigits = useSignificantDigits;
5252103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5253103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5254103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
525750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormat::setCurrencyInternally(const UChar* theCurrency,
5258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                          UErrorCode& ec) {
5259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // If we are a currency format, then modify our affixes to
5260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // encode the currency symbol for the given currency in our
5261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // locale, and adjust the decimal digits and rounding for the
5262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // given currency.
5263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Note: The code is ordered so that this object is *not changed*
5265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // until we are sure we are going to succeed.
526650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // NULL or empty currency is *legal* and indicates no currency.
5268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool isCurr = (theCurrency && *theCurrency);
5269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    double rounding = 0.0;
5271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t frac = 0;
5272b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencySignCount > fgCurrencySignCountZero && isCurr) {
5273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        rounding = ucurr_getRoundingIncrement(theCurrency, &ec);
5274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        frac = ucurr_getDefaultFractionDigits(theCurrency, &ec);
5275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
527650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NumberFormat::setCurrency(theCurrency, ec);
5278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(ec)) return;
5279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5280b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fCurrencySignCount > fgCurrencySignCountZero) {
5281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // NULL or empty currency is *legal* and indicates no currency.
5282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (isCurr) {
5283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            setRoundingIncrement(rounding);
5284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            setMinimumFractionDigits(frac);
5285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            setMaximumFractionDigits(frac);
5286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
5287b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        expandAffixes(NULL);
5288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5291103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
5295b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // set the currency before compute affixes to get the right currency names
5296b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    NumberFormat::setCurrency(theCurrency, ec);
5297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fFormatPattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) {
5298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UnicodeString savedPtn = fFormatPattern;
5299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        setupCurrencyAffixes(fFormatPattern, TRUE, TRUE, ec);
5300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UParseError parseErr;
5301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        applyPattern(savedPtn, FALSE, parseErr, ec);
5302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // set the currency after apply pattern to get the correct rounding/fraction
5304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    setCurrencyInternally(theCurrency, ec);
5305103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5306103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5307103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Deprecated variant with no UErrorCode parameter
5311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid DecimalFormat::setCurrency(const UChar* theCurrency) {
5312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode ec = U_ZERO_ERROR;
5313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setCurrency(theCurrency, ec);
5314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5315103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    handleChanged();
5316103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5319c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
5320c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (fSymbols == NULL) {
5321c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ec = U_MEMORY_ALLOCATION_ERROR;
5322c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
5323c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
5324c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ec = U_ZERO_ERROR;
5325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UChar* c = getCurrency();
5326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*c == 0) {
5327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const UnicodeString &intl =
5328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
5329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        c = intl.getBuffer(); // ok for intl to go out of scope
5330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    u_strncpy(result, c, 3);
5332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    result[3] = 0;
5333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
5336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the number of fraction digits to display, or the total
5337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * number of digits for significant digit formats and exponential
5338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * formats.
5339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
5340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
534150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::precision() const {
5342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (areSignificantDigitsUsed()) {
5343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return getMaximumSignificantDigits();
5344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else if (fUseExponentialNotation) {
5345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return getMinimumIntegerDigits() + getMaximumFractionDigits();
5346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
534750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return getMaximumFractionDigits();
5348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
5349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
5350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5351b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5352b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// TODO: template algorithm
5353b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruHashtable*
5354b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::initHashForAffix(UErrorCode& status) {
5355b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
5356b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
5357b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5358b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    Hashtable* hTable;
5359b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
5360b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
5361b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
5362b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if ( U_FAILURE(status) ) {
5364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete hTable;
5365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
5366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
536750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    hTable->setValueComparator(decimfmtAffixValueComparator);
5368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return hTable;
5369b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5370b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5371b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruHashtable*
5372b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::initHashForAffixPattern(UErrorCode& status) {
5373b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
5374b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
5375b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    Hashtable* hTable;
5377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
5378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
5379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
5380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if ( U_FAILURE(status) ) {
5382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete hTable;
5383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
5384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
538550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    hTable->setValueComparator(decimfmtAffixPatternValueComparator);
5386b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return hTable;
5387b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
539050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::deleteHashForAffix(Hashtable*& table)
5391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
5392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( table == NULL ) {
5393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
5394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
5396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
5397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    while ( (element = table->nextElement(pos)) != NULL ) {
5398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UHashTok valueTok = element->value;
5399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer;
5400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        delete value;
5401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5402b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete table;
5403b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    table = NULL;
5404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
540950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormat::deleteHashForAffixPattern()
5410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
5411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( fAffixPatternsForCurrency == NULL ) {
5412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
5413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
5415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
5416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
5417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UHashTok valueTok = element->value;
5418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
5419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        delete value;
5420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete fAffixPatternsForCurrency;
5422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fAffixPatternsForCurrency = NULL;
5423b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
5427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::copyHashForAffixPattern(const Hashtable* source,
5428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                       Hashtable* target,
5429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                       UErrorCode& status) {
5430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
5431b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
5432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5433b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
5434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
5435b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( source ) {
5436b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        while ( (element = source->nextElement(pos)) != NULL ) {
5437b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok keyTok = element->key;
5438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
5439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok valueTok = element->value;
5440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
5441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            AffixPatternsForCurrency* copy = new AffixPatternsForCurrency(
5442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->negPrefixPatternForCurrency,
5443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->negSuffixPatternForCurrency,
5444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->posPrefixPatternForCurrency,
5445b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->posSuffixPatternForCurrency,
5446b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->patternType);
5447b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            target->put(UnicodeString(*key), copy, status);
5448b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( U_FAILURE(status) ) {
5449b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                return;
5450b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
5451b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
5452b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5453b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5454b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
545554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusDecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr,
545654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                            int32_t newValue,
545754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                            UErrorCode &status) {
545854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  if(U_FAILURE(status)) return *this;
545954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
546054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  switch(attr) {
546154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  case UNUM_LENIENT_PARSE:
546254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    setLenient(newValue!=0);
546354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    break;
546454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
546554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_PARSE_INT_ONLY:
546654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setParseIntegerOnly(newValue!=0);
546754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      break;
546854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
546954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_GROUPING_USED:
547054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setGroupingUsed(newValue!=0);
547154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      break;
547254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
547354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_DECIMAL_ALWAYS_SHOWN:
547454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setDecimalSeparatorAlwaysShown(newValue!=0);
547554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
547654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
547754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MAX_INTEGER_DIGITS:
547854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMaximumIntegerDigits(newValue);
547954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
548054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
548154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MIN_INTEGER_DIGITS:
548254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMinimumIntegerDigits(newValue);
548354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
548454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
548554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_INTEGER_DIGITS:
548654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMinimumIntegerDigits(newValue);
548754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMaximumIntegerDigits(newValue);
548854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
548954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
549054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MAX_FRACTION_DIGITS:
549154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMaximumFractionDigits(newValue);
549254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
549354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
549454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MIN_FRACTION_DIGITS:
549554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMinimumFractionDigits(newValue);
549654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
549754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
549854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_FRACTION_DIGITS:
549954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMinimumFractionDigits(newValue);
550054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMaximumFractionDigits(newValue);
550154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      break;
550254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
550354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_SIGNIFICANT_DIGITS_USED:
550454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setSignificantDigitsUsed(newValue!=0);
550554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
550654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
550754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MAX_SIGNIFICANT_DIGITS:
550854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMaximumSignificantDigits(newValue);
550954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
551054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
551154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MIN_SIGNIFICANT_DIGITS:
551254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMinimumSignificantDigits(newValue);
551354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
551454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
551554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MULTIPLIER:
551654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setMultiplier(newValue);
551754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       break;
551854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
551954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_GROUPING_SIZE:
552054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setGroupingSize(newValue);
552154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
552254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
552354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_ROUNDING_MODE:
552454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setRoundingMode((DecimalFormat::ERoundingMode)newValue);
552554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
552654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
552754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_FORMAT_WIDTH:
552854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setFormatWidth(newValue);
552954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
553054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
553154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_PADDING_POSITION:
553254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        /** The position at which padding will take place. */
553354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setPadPosition((DecimalFormat::EPadPosition)newValue);
553454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
553554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
553654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_SECONDARY_GROUPING_SIZE:
553754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setSecondaryGroupingSize(newValue);
553854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
553954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
554054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if UCONFIG_HAVE_PARSEALLINPUT
554154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_PARSE_ALL_INPUT:
554254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      setParseAllInput((UNumberFormatAttributeValue)newValue);
554354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
554454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
554554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
554654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /* These are stored in fBoolFlags */
554754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_PARSE_NO_EXPONENT:
554854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
554954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      if(!fBoolFlags.isValidValue(newValue)) {
555054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          status = U_ILLEGAL_ARGUMENT_ERROR;
555154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      } else {
555254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius          fBoolFlags.set(attr, newValue);
555354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      }
555454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      break;
555554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
55568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UNUM_SCALE:
55578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        fScale = newValue;
55588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        break;
55598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
556054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    default:
556154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      status = U_UNSUPPORTED_ERROR;
556254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      break;
556354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  }
556454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  return *this;
556554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
556654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
556754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusint32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr,
556854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                     UErrorCode &status ) const {
556954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  if(U_FAILURE(status)) return -1;
557054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  switch(attr) {
557154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_LENIENT_PARSE:
557254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return isLenient();
557354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
557454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_PARSE_INT_ONLY:
557554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return isParseIntegerOnly();
557654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
557754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_GROUPING_USED:
557854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return isGroupingUsed();
557954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
558054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_DECIMAL_ALWAYS_SHOWN:
558154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return isDecimalSeparatorAlwaysShown();
558254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
558354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MAX_INTEGER_DIGITS:
558454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMaximumIntegerDigits();
558554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
558654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MIN_INTEGER_DIGITS:
558754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMinimumIntegerDigits();
558854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
558954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_INTEGER_DIGITS:
559054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // TBD: what should this return?
559154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMinimumIntegerDigits();
559254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
559354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MAX_FRACTION_DIGITS:
559454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMaximumFractionDigits();
559554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
559654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MIN_FRACTION_DIGITS:
559754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMinimumFractionDigits();
559854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
559954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_FRACTION_DIGITS:
560054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // TBD: what should this return?
560154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMinimumFractionDigits();
560254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
560354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_SIGNIFICANT_DIGITS_USED:
560454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return areSignificantDigitsUsed();
560554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
560654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MAX_SIGNIFICANT_DIGITS:
560754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMaximumSignificantDigits();
560854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
560954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MIN_SIGNIFICANT_DIGITS:
561054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMinimumSignificantDigits();
561154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
561254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_MULTIPLIER:
561354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getMultiplier();
561454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
561554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_GROUPING_SIZE:
561654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getGroupingSize();
561754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
561854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_ROUNDING_MODE:
561954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getRoundingMode();
562054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
562154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_FORMAT_WIDTH:
562254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getFormatWidth();
562354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
562454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_PADDING_POSITION:
562554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getPadPosition();
562654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
562754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_SECONDARY_GROUPING_SIZE:
562854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return getSecondaryGroupingSize();
562954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
563054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /* These are stored in fBoolFlags */
563154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_PARSE_NO_EXPONENT:
563254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
563354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      return fBoolFlags.get(attr);
563454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
56358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UNUM_SCALE:
56368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        return fScale;
56378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
563854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    default:
563954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        status = U_UNSUPPORTED_ERROR;
564054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
564154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  }
564254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
564354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  return -1; /* undefined */
564454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
564554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
5646103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_HAVE_PARSEALLINPUT
5647103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {
5648103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  fParseAllInput = value;
5649103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_FORMAT_FASTPATHS_49
5650103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  handleChanged();
5651103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5652103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
5653103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
5654b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5655b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
5656b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDecimalFormat::copyHashForAffix(const Hashtable* source,
5657b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                Hashtable* target,
5658b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                UErrorCode& status) {
5659b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
5660b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
5661b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5662b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
5663b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
5664b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( source ) {
5665b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        while ( (element = source->nextElement(pos)) != NULL ) {
5666b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok keyTok = element->key;
5667b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
5668b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5669b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok valueTok = element->value;
5670b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer;
5671b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            AffixesForCurrency* copy = new AffixesForCurrency(
5672b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->negPrefixForCurrency,
5673b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->negSuffixForCurrency,
5674b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->posPrefixForCurrency,
5675b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                value->posSuffixForCurrency);
5676b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            target->put(UnicodeString(*key), copy, status);
5677b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( U_FAILURE(status) ) {
5678b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                return;
5679b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
5680b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
5681b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
5682b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
5683b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
5685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
5687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof
5689