~ubuntu-branches/ubuntu/gutsy/icu/gutsy-updates

« back to all changes in this revision

Viewing changes to source/i18n/decimfmt.cpp

  • Committer: Package Import Robot
  • Author(s): Jay Berkenbilt
  • Date: 2005-11-19 11:29:31 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20051119112931-vcizkrp10tli4enw
Tags: 3.4-3
Explicitly build with g++ 3.4.  The current ICU fails its test suite
with 4.0 but not with 3.4.  Future versions should work properly with
4.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
*******************************************************************************
3
 
* Copyright (C) 1997-2001, International Business Machines Corporation and    *
4
 
* others. All Rights Reserved.                                                *
5
 
*******************************************************************************
6
 
*
7
 
* File DECIMFMT.CPP
8
 
*
9
 
* Modification History:
10
 
*
11
 
*   Date        Name        Description
12
 
*   02/19/97    aliu        Converted from java.
13
 
*   03/20/97    clhuang     Implemented with new APIs.
14
 
*   03/31/97    aliu        Moved isLONG_MIN to DigitList, and fixed it.
15
 
*   04/3/97     aliu        Rewrote parsing and formatting completely, and
16
 
*                           cleaned up and debugged.  Actually works now.
17
 
*                           Implemented NAN and INF handling, for both parsing
18
 
*                           and formatting.  Extensive testing & debugging.
19
 
*   04/10/97    aliu        Modified to compile on AIX.
20
 
*   04/16/97    aliu        Rewrote to use DigitList, which has been resurrected.
21
 
*                           Changed DigitCount to int per code review.
22
 
*   07/09/97    helena      Made ParsePosition into a class.
23
 
*   08/26/97    aliu        Extensive changes to applyPattern; completely
24
 
*                           rewritten from the Java.
25
 
*   09/09/97    aliu        Ported over support for exponential formats.
26
 
*   07/20/98    stephen     JDK 1.2 sync up.
27
 
*                             Various instances of '0' replaced with 'NULL'
28
 
*                             Check for grouping size in subFormat()
29
 
*                             Brought subParse() in line with Java 1.2
30
 
*                             Added method appendAffix()
31
 
*   08/24/1998  srl         Removed Mutex calls. This is not a thread safe class!
32
 
*   02/22/99    stephen     Removed character literals for EBCDIC safety
33
 
*   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
34
 
*   06/28/99    stephen     Fixed bugs in toPattern().
35
 
*   06/29/99    stephen     Fixed operator= to copy fFormatWidth, fPad, 
36
 
*                             fPadPosition
37
 
********************************************************************************
38
 
*/
39
 
 
40
 
#include "unicode/decimfmt.h"
41
 
#include "digitlst.h"
42
 
#include "unicode/dcfmtsym.h"
43
 
#include "unicode/resbund.h"
44
 
#include "unicode/uchar.h"
45
 
#include "cmemory.h"
46
 
 
47
 
U_NAMESPACE_BEGIN
48
 
 
49
 
//#define FMT_DEBUG
50
 
 
51
 
#ifdef FMT_DEBUG
52
 
#include <stdio.h>
53
 
static void debugout(UnicodeString s) {
54
 
    char buf[2000];
55
 
    s.extract((int32_t) 0, s.length(), buf);
56
 
    printf("%s", buf);
57
 
}
58
 
#define debug(x) printf("%s", x);
59
 
#else
60
 
#define debugout(x)
61
 
#define debug(x)
62
 
#endif
63
 
 
64
 
// *****************************************************************************
65
 
// class DecimalFormat
66
 
// *****************************************************************************
67
 
 
68
 
const char DecimalFormat::fgClassID = 0; // Value is irrelevant
69
 
 
70
 
// Constants for characters used in programmatic (unlocalized) patterns.
71
 
const UChar DecimalFormat::kPatternZeroDigit           = 0x0030 /*'0'*/;
72
 
const UChar DecimalFormat::kPatternGroupingSeparator   = 0x002C /*','*/;
73
 
const UChar DecimalFormat::kPatternDecimalSeparator    = 0x002E /*'.'*/;
74
 
const UChar DecimalFormat::kPatternPerMill             = 0x2030;
75
 
const UChar DecimalFormat::kPatternPercent             = 0x0025 /*'%'*/;
76
 
const UChar DecimalFormat::kPatternDigit               = 0x0023 /*'#'*/;
77
 
const UChar DecimalFormat::kPatternSeparator           = 0x003B /*';'*/;
78
 
const UChar DecimalFormat::kPatternExponent            = 0x0045 /*'E'*/;
79
 
const UChar DecimalFormat::kPatternPlus                = 0x002B /*'+'*/;
80
 
const UChar DecimalFormat::kPatternMinus               = 0x002D /*'-'*/;
81
 
const UChar DecimalFormat::kPatternPadEscape           = 0x002A /*'*'*/;
82
 
const UChar DecimalFormat::kCurrencySign               = 0x00A4;
83
 
const UChar DecimalFormat::kQuote                      = 0x0027 /*'\''*/;
84
 
 
85
 
//const int8_t DecimalFormat::fgMaxDigit                  = 9;
86
 
 
87
 
const int32_t DecimalFormat::kDoubleIntegerDigits  = 309;
88
 
const int32_t DecimalFormat::kDoubleFractionDigits = 340;
89
 
 
90
 
/**
91
 
 * These are the tags we expect to see in normal resource bundle files associated
92
 
 * with a locale.
93
 
 */
94
 
const char DecimalFormat::fgNumberPatterns[]="NumberPatterns";
95
 
 
96
 
//------------------------------------------------------------------------------
97
 
// Constructs a DecimalFormat instance in the default locale.
98
 
 
99
 
DecimalFormat::DecimalFormat(UErrorCode& status)
100
 
: NumberFormat(), 
101
 
  fPosPrefixPattern(0), 
102
 
  fPosSuffixPattern(0), 
103
 
  fNegPrefixPattern(0), 
104
 
  fNegSuffixPattern(0),
105
 
  fSymbols(0)
106
 
{
107
 
    UParseError parseError;
108
 
    construct(status, parseError);
109
 
}
110
 
 
111
 
//------------------------------------------------------------------------------
112
 
// Constructs a DecimalFormat instance with the specified number format
113
 
// pattern in the default locale.
114
 
 
115
 
DecimalFormat::DecimalFormat(const UnicodeString& pattern,
116
 
                             UErrorCode& status)
117
 
: NumberFormat(),
118
 
  fPosPrefixPattern(0), 
119
 
  fPosSuffixPattern(0), 
120
 
  fNegPrefixPattern(0), 
121
 
  fNegSuffixPattern(0),
122
 
  fSymbols(0)
123
 
{
124
 
    UParseError parseError;
125
 
    construct(status, parseError, &pattern);
126
 
}
127
 
 
128
 
//------------------------------------------------------------------------------
129
 
// Constructs a DecimalFormat instance with the specified number format
130
 
// pattern and the number format symbols in the default locale.  The
131
 
// created instance owns the symbols.
132
 
 
133
 
DecimalFormat::DecimalFormat(const UnicodeString& pattern,
134
 
                             DecimalFormatSymbols* symbolsToAdopt,
135
 
                             UErrorCode& status)
136
 
: NumberFormat(),
137
 
  fPosPrefixPattern(0), 
138
 
  fPosSuffixPattern(0), 
139
 
  fNegPrefixPattern(0), 
140
 
  fNegSuffixPattern(0),
141
 
  fSymbols(0)
142
 
{
143
 
    UParseError parseError;
144
 
    if (symbolsToAdopt == NULL)
145
 
        status = U_ILLEGAL_ARGUMENT_ERROR;
146
 
    construct(status, parseError, &pattern, symbolsToAdopt);
147
 
}
148
 
 
149
 
DecimalFormat::DecimalFormat(  const UnicodeString& pattern,
150
 
                    DecimalFormatSymbols* symbolsToAdopt,
151
 
                    UParseError& parseErr,
152
 
                    UErrorCode& status)
153
 
: NumberFormat(),
154
 
  fPosPrefixPattern(0), 
155
 
  fPosSuffixPattern(0), 
156
 
  fNegPrefixPattern(0), 
157
 
  fNegSuffixPattern(0),
158
 
  fSymbols(0)
159
 
{
160
 
    if (symbolsToAdopt == NULL)
161
 
        status = U_ILLEGAL_ARGUMENT_ERROR;
162
 
    construct(status,parseErr, &pattern, symbolsToAdopt);
163
 
}
164
 
//------------------------------------------------------------------------------
165
 
// Constructs a DecimalFormat instance with the specified number format
166
 
// pattern and the number format symbols in the default locale.  The
167
 
// created instance owns the clone of the symbols.
168
 
 
169
 
DecimalFormat::DecimalFormat(const UnicodeString& pattern,
170
 
                             const DecimalFormatSymbols& symbols,
171
 
                             UErrorCode& status)
172
 
: NumberFormat(),
173
 
  fPosPrefixPattern(0), 
174
 
  fPosSuffixPattern(0), 
175
 
  fNegPrefixPattern(0), 
176
 
  fNegSuffixPattern(0),
177
 
  fSymbols(0)
178
 
{
179
 
    UParseError parseError;
180
 
    construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
181
 
}
182
 
 
183
 
//------------------------------------------------------------------------------
184
 
// Constructs a DecimalFormat instance with the specified number format
185
 
// pattern and the number format symbols in the desired locale.  The
186
 
// created instance owns the symbols.
187
 
 
188
 
void
189
 
DecimalFormat::construct(UErrorCode&             status,
190
 
                         UParseError&           parseErr,
191
 
                         const UnicodeString*   pattern,
192
 
                         DecimalFormatSymbols*  symbolsToAdopt,
193
 
                         const Locale&          locale)
194
 
{
195
 
    fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!!
196
 
//    fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!!
197
 
    fRoundingIncrement = NULL;
198
 
    fRoundingDouble = 0.0;
199
 
    fRoundingMode = kRoundHalfEven;
200
 
    fPad = kPatternPadEscape;
201
 
    fPadPosition = kPadBeforePrefix;
202
 
    if (U_FAILURE(status))
203
 
        return;
204
 
 
205
 
    fPosPrefixPattern = fPosSuffixPattern = NULL;
206
 
    fNegPrefixPattern = fNegSuffixPattern = NULL;
207
 
    fMultiplier = 1;
208
 
    fGroupingSize = 3;
209
 
    fGroupingSize2 = 0;
210
 
    fDecimalSeparatorAlwaysShown = FALSE;
211
 
    fIsCurrencyFormat = FALSE;
212
 
    fUseExponentialNotation = FALSE;
213
 
    fMinExponentDigits = 0;
214
 
 
215
 
    if (fSymbols == NULL)
216
 
    {
217
 
        fSymbols = new DecimalFormatSymbols(locale, status);
218
 
    }
219
 
 
220
 
    UnicodeString str;
221
 
    // Uses the default locale's number format pattern if there isn't
222
 
    // one specified.
223
 
    if (pattern == NULL)
224
 
    {
225
 
        ResourceBundle resource((char *)0, Locale::getDefault(), status);
226
 
 
227
 
        str = resource.get(fgNumberPatterns, status).getStringEx((int32_t)0, status);
228
 
        pattern = &str;
229
 
    }
230
 
 
231
 
    if (U_FAILURE(status))
232
 
    {
233
 
        return;
234
 
    }
235
 
    
236
 
    applyPattern(*pattern, FALSE /*not localized*/,parseErr, status);
237
 
}
238
 
 
239
 
//------------------------------------------------------------------------------
240
 
 
241
 
DecimalFormat::~DecimalFormat()
242
 
{
243
 
//    delete fDigitList;
244
 
    delete fPosPrefixPattern;
245
 
    delete fPosSuffixPattern;
246
 
    delete fNegPrefixPattern;
247
 
    delete fNegSuffixPattern;
248
 
    delete fSymbols;
249
 
    delete fRoundingIncrement;
250
 
}
251
 
 
252
 
//------------------------------------------------------------------------------
253
 
// copy constructor
254
 
 
255
 
DecimalFormat::DecimalFormat(const DecimalFormat &source)
256
 
:   NumberFormat(source),
257
 
//    fDigitList(NULL),
258
 
    fPosPrefixPattern(NULL),
259
 
    fPosSuffixPattern(NULL),
260
 
    fNegPrefixPattern(NULL),
261
 
    fNegSuffixPattern(NULL),
262
 
    fSymbols(NULL),
263
 
    fRoundingIncrement(NULL)
264
 
{
265
 
    *this = source;
266
 
}
267
 
 
268
 
//------------------------------------------------------------------------------
269
 
// assignment operator
270
 
// Note that fDigitList is not considered a significant part of the
271
 
// DecimalFormat because it's used as a buffer to process the numbers.
272
 
 
273
 
static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) {
274
 
    if (source == NULL) {
275
 
        delete *pdest;
276
 
        *pdest = NULL;
277
 
    } else if (*pdest == NULL) {
278
 
        *pdest = new UnicodeString(*source);
279
 
    } else {
280
 
        **pdest  = *source;
281
 
    }
282
 
}
283
 
 
284
 
DecimalFormat&
285
 
DecimalFormat::operator=(const DecimalFormat& rhs)
286
 
{
287
 
  if(this != &rhs) {
288
 
    NumberFormat::operator=(rhs);
289
 
    fPositivePrefix = rhs.fPositivePrefix;
290
 
    fPositiveSuffix = rhs.fPositiveSuffix;
291
 
    fNegativePrefix = rhs.fNegativePrefix;
292
 
    fNegativeSuffix = rhs.fNegativeSuffix;
293
 
    _copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
294
 
    _copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
295
 
    _copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
296
 
    _copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
297
 
    if(rhs.fRoundingIncrement == NULL) {
298
 
      delete fRoundingIncrement;
299
 
      fRoundingIncrement = NULL;
300
 
    } 
301
 
    else if(fRoundingIncrement == NULL) {
302
 
      fRoundingIncrement = new DigitList(*rhs.fRoundingIncrement);
303
 
    }
304
 
    else {
305
 
      *fRoundingIncrement = *rhs.fRoundingIncrement;
306
 
    }
307
 
    fRoundingDouble = rhs.fRoundingDouble;
308
 
    fMultiplier = rhs.fMultiplier;
309
 
    fGroupingSize = rhs.fGroupingSize;
310
 
    fGroupingSize2 = rhs.fGroupingSize2;
311
 
    fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
312
 
    if(fSymbols == NULL) 
313
 
        fSymbols = new DecimalFormatSymbols(*rhs.fSymbols);
314
 
    else 
315
 
        *fSymbols = *rhs.fSymbols;
316
 
    fUseExponentialNotation = rhs.fUseExponentialNotation;
317
 
    fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
318
 
    /*Bertrand A. D. Update 98.03.17*/
319
 
    fIsCurrencyFormat = rhs.fIsCurrencyFormat;
320
 
    /*end of Update*/
321
 
    fMinExponentDigits = rhs.fMinExponentDigits;
322
 
//    if (fDigitList == NULL)
323
 
//        fDigitList = new DigitList();
324
 
    
325
 
    /* sfb 990629 */
326
 
    fFormatWidth = rhs.fFormatWidth;
327
 
    fPad = rhs.fPad;
328
 
    fPadPosition = rhs.fPadPosition;
329
 
    /* end sfb */
330
 
  }
331
 
  return *this;
332
 
}
333
 
 
334
 
//------------------------------------------------------------------------------
335
 
 
336
 
UBool
337
 
DecimalFormat::operator==(const Format& that) const
338
 
{
339
 
    if (this == &that)
340
 
        return TRUE;
341
 
 
342
 
    if (getDynamicClassID() != that.getDynamicClassID())
343
 
        return FALSE;
344
 
 
345
 
    const DecimalFormat* other = (DecimalFormat*)&that;
346
 
 
347
 
#ifdef FMT_DEBUG
348
 
    // This code makes it easy to determine why two format objects that should
349
 
    // be equal aren't.
350
 
    UBool first = TRUE;
351
 
    if (!NumberFormat::operator==(that)) {
352
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
353
 
        debug("NumberFormat::!=");
354
 
    }
355
 
    if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null
356
 
              fPositivePrefix == other->fPositivePrefix)
357
 
           || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
358
 
               *fPosPrefixPattern  == *other->fPosPrefixPattern))) {
359
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
360
 
        debug("Pos Prefix !=");
361
 
    }
362
 
    if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null
363
 
           fPositiveSuffix == other->fPositiveSuffix)
364
 
          || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
365
 
              *fPosSuffixPattern  == *other->fPosSuffixPattern))) {
366
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
367
 
        debug("Pos Suffix !=");
368
 
    }
369
 
    if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null
370
 
           fNegativePrefix == other->fNegativePrefix)
371
 
          || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
372
 
              *fNegPrefixPattern  == *other->fNegPrefixPattern))) {
373
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
374
 
        debug("Neg Prefix ");
375
 
        if (fNegPrefixPattern == NULL) {
376
 
            debug("NULL(");
377
 
            debugout(fNegativePrefix);
378
 
            debug(")");
379
 
        } else {
380
 
            debugout(*fNegPrefixPattern);
381
 
        }
382
 
        debug(" != ");
383
 
        if (other->fNegPrefixPattern == NULL) {
384
 
            debug("NULL(");
385
 
            debugout(other->fNegativePrefix);
386
 
            debug(")");
387
 
        } else {
388
 
            debugout(*other->fNegPrefixPattern);
389
 
        }
390
 
    }
391
 
    if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null
392
 
           fNegativeSuffix == other->fNegativeSuffix)
393
 
          || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
394
 
              *fNegSuffixPattern  == *other->fNegSuffixPattern))) {
395
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
396
 
        debug("Neg Suffix ");
397
 
        if (fNegSuffixPattern == NULL) {
398
 
            debug("NULL(");
399
 
            debugout(fNegativeSuffix);
400
 
            debug(")");
401
 
        } else {
402
 
            debugout(*fNegSuffixPattern);
403
 
        }
404
 
        debug(" != ");
405
 
        if (other->fNegSuffixPattern == NULL) {
406
 
            debug("NULL(");
407
 
            debugout(other->fNegativeSuffix);
408
 
            debug(")");
409
 
        } else {
410
 
            debugout(*other->fNegSuffixPattern);
411
 
        }
412
 
    }
413
 
    if (!((fRoundingIncrement == other->fRoundingIncrement) // both null
414
 
          || (fRoundingIncrement != NULL &&
415
 
              other->fRoundingIncrement != NULL &&
416
 
              *fRoundingIncrement == *other->fRoundingIncrement))) {
417
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
418
 
        debug("Rounding Increment !=");
419
 
              }
420
 
    if (fMultiplier != other->fMultiplier) {
421
 
        if (first) { printf("[ "); first = FALSE; }
422
 
        printf("Multiplier %ld != %ld", fMultiplier, other->fMultiplier);
423
 
    }
424
 
    if (fGroupingSize != other->fGroupingSize) {
425
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
426
 
        printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize);
427
 
    }
428
 
    if (fGroupingSize2 != other->fGroupingSize2) {
429
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
430
 
        printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2);
431
 
    }
432
 
    if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) {
433
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
434
 
        printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown);
435
 
    }
436
 
    if (fUseExponentialNotation != other->fUseExponentialNotation) {
437
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
438
 
        debug("Use Exp !=");
439
 
    }
440
 
    if (!(!fUseExponentialNotation ||
441
 
          fMinExponentDigits != other->fMinExponentDigits)) {
442
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
443
 
        debug("Exp Digits !=");
444
 
    }
445
 
    if (*fSymbols != *(other->fSymbols)) {
446
 
        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
447
 
        debug("Symbols !=");
448
 
    }
449
 
    if (!first) { printf(" ]"); }
450
 
#endif
451
 
 
452
 
    return (NumberFormat::operator==(that) &&
453
 
            ((fPosPrefixPattern == other->fPosPrefixPattern && // both null
454
 
              fPositivePrefix == other->fPositivePrefix)
455
 
             || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
456
 
                 *fPosPrefixPattern  == *other->fPosPrefixPattern)) &&
457
 
            ((fPosSuffixPattern == other->fPosSuffixPattern && // both null
458
 
              fPositiveSuffix == other->fPositiveSuffix)
459
 
             || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
460
 
                 *fPosSuffixPattern  == *other->fPosSuffixPattern)) &&
461
 
            ((fNegPrefixPattern == other->fNegPrefixPattern && // both null
462
 
              fNegativePrefix == other->fNegativePrefix)
463
 
             || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
464
 
                 *fNegPrefixPattern  == *other->fNegPrefixPattern)) &&
465
 
            ((fNegSuffixPattern == other->fNegSuffixPattern && // both null
466
 
              fNegativeSuffix == other->fNegativeSuffix)
467
 
             || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
468
 
                 *fNegSuffixPattern  == *other->fNegSuffixPattern)) &&
469
 
            ((fRoundingIncrement == other->fRoundingIncrement) // both null
470
 
             || (fRoundingIncrement != NULL &&
471
 
                 other->fRoundingIncrement != NULL &&
472
 
                 *fRoundingIncrement == *other->fRoundingIncrement)) &&
473
 
        fMultiplier == other->fMultiplier &&
474
 
        fGroupingSize == other->fGroupingSize &&
475
 
        fGroupingSize2 == other->fGroupingSize2 &&
476
 
        fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown &&
477
 
        fUseExponentialNotation == other->fUseExponentialNotation &&
478
 
        (!fUseExponentialNotation ||
479
 
         fMinExponentDigits == other->fMinExponentDigits) &&
480
 
        *fSymbols == *(other->fSymbols));
481
 
}
482
 
 
483
 
//------------------------------------------------------------------------------
484
 
 
485
 
Format*
486
 
DecimalFormat::clone() const
487
 
{
488
 
    return new DecimalFormat(*this);
489
 
}
490
 
 
491
 
//------------------------------------------------------------------------------
492
 
 
493
 
UnicodeString&
494
 
DecimalFormat::format(int32_t number,
495
 
                      UnicodeString& result,
496
 
                      FieldPosition& fieldPosition) const
497
 
{
498
 
    DigitList digits;
499
 
 
500
 
    // Clears field positions.
501
 
    fieldPosition.setBeginIndex(0);
502
 
    fieldPosition.setEndIndex(0);
503
 
 
504
 
    // If we are to do rounding, we need to move into the BigDecimal
505
 
    // domain in order to do divide/multiply correctly.
506
 
    // ||
507
 
    // In general, long values always represent real finite numbers, so
508
 
    // we don't have to check for +/- Infinity or NaN.  However, there
509
 
    // is one case we have to be careful of:  The multiplier can push
510
 
    // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
511
 
    // check for this before multiplying, and if it happens we use doubles
512
 
    // instead, trading off accuracy for range.
513
 
    if (fRoundingIncrement != NULL
514
 
        || (fMultiplier != 0 && (number > (INT32_MAX / fMultiplier)
515
 
                              || number < (INT32_MIN / fMultiplier))))
516
 
    {
517
 
        digits.set(((double)number) * fMultiplier,
518
 
                   fUseExponentialNotation ?
519
 
                            getMinimumIntegerDigits() + getMaximumFractionDigits() : 0,
520
 
                   !fUseExponentialNotation);
521
 
    }
522
 
    else
523
 
    {
524
 
        digits.set(number * fMultiplier,
525
 
                   fUseExponentialNotation ?
526
 
                            getMinimumIntegerDigits() + getMaximumFractionDigits() : 0);
527
 
    }
528
 
 
529
 
    return subformat(result, fieldPosition, digits, TRUE);
530
 
}
531
 
 
532
 
//------------------------------------------------------------------------------
533
 
 
534
 
UnicodeString&
535
 
DecimalFormat::format(  double number,
536
 
                        UnicodeString& result,
537
 
                        FieldPosition& fieldPosition) const
538
 
{
539
 
    // Clears field positions.
540
 
    fieldPosition.setBeginIndex(0);
541
 
    fieldPosition.setEndIndex(0);
542
 
 
543
 
    // Special case for NaN, sets the begin and end index to be the
544
 
    // the string length of localized name of NaN.
545
 
    if (uprv_isNaN(number))
546
 
    {
547
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
548
 
            fieldPosition.setBeginIndex(result.length());
549
 
 
550
 
        result += fSymbols->getSymbol(DecimalFormatSymbols::kNaNSymbol);
551
 
 
552
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
553
 
            fieldPosition.setEndIndex(result.length());
554
 
 
555
 
        addPadding(result, fieldPosition, FALSE, FALSE /*ignored*/);
556
 
        return result;
557
 
    }
558
 
 
559
 
    /* Detecting whether a double is negative is easy with the exception of
560
 
     * the value -0.0.  This is a double which has a zero mantissa (and
561
 
     * exponent), but a negative sign bit.  It is semantically distinct from
562
 
     * a zero with a positive sign bit, and this distinction is important
563
 
     * to certain kinds of computations.  However, it's a little tricky to
564
 
     * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
565
 
     * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
566
 
     * -Infinity.  Proper detection of -0.0 is needed to deal with the
567
 
     * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
568
 
     */
569
 
    UBool isNegative = uprv_isNegative(number);
570
 
 
571
 
    // Do this BEFORE checking to see if value is infinite! Sets the
572
 
    // begin and end index to be length of the string composed of
573
 
    // localized name of Infinite and the positive/negative localized
574
 
    // signs.
575
 
 
576
 
    number *= fMultiplier;
577
 
 
578
 
    // Apply rounding after multiplier
579
 
    if (fRoundingIncrement != NULL) {
580
 
        if (isNegative)     // For rounding in the correct direction
581
 
            number = -number;
582
 
        number = fRoundingDouble
583
 
            * round(number / fRoundingDouble, fRoundingMode, isNegative);
584
 
        if (isNegative)
585
 
            number = -number;
586
 
    }
587
 
 
588
 
    // Special case for INFINITE,
589
 
    if (uprv_isInfinite(number))
590
 
    {
591
 
        result += (isNegative ? fNegativePrefix : fPositivePrefix);
592
 
 
593
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
594
 
            fieldPosition.setBeginIndex(result.length());
595
 
 
596
 
        result += fSymbols->getSymbol(DecimalFormatSymbols::kInfinitySymbol);
597
 
 
598
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
599
 
            fieldPosition.setEndIndex(result.length());
600
 
 
601
 
        result += (isNegative ? fNegativeSuffix : fPositiveSuffix);
602
 
 
603
 
        addPadding(result, fieldPosition, TRUE, isNegative);
604
 
        return result;
605
 
    }
606
 
 
607
 
    DigitList digits;
608
 
 
609
 
    // This detects negativity too.
610
 
    digits.set(number, fUseExponentialNotation ?
611
 
                             getMinimumIntegerDigits() + getMaximumFractionDigits() :
612
 
                             getMaximumFractionDigits(),
613
 
                             !fUseExponentialNotation);
614
 
 
615
 
    return subformat(result, fieldPosition, digits, FALSE);
616
 
}
617
 
 
618
 
/**
619
 
 * Round a double value to the nearest integer according to the
620
 
 * given mode.
621
 
 * @param a the absolute value of the number to be rounded
622
 
 * @param mode a BigDecimal rounding mode
623
 
 * @param isNegative true if the number to be rounded is negative
624
 
 * @return the absolute value of the rounded result
625
 
 */
626
 
double DecimalFormat::round(double a, ERoundingMode mode, UBool isNegative) {
627
 
    switch (mode) {
628
 
    case kRoundCeiling:
629
 
        return isNegative ? uprv_floor(a) : uprv_ceil(a);
630
 
    case kRoundFloor:
631
 
        return isNegative ? uprv_ceil(a) : uprv_floor(a);
632
 
    case kRoundDown:
633
 
        return uprv_floor(a);
634
 
    case kRoundUp:
635
 
        return uprv_ceil(a);
636
 
    case kRoundHalfEven:
637
 
        {
638
 
            double f = uprv_floor(a);
639
 
            if ((a - f) != 0.5) {
640
 
                return uprv_floor(a + 0.5);
641
 
            }
642
 
            double g = f / 2.0;
643
 
            return (g == uprv_floor(g)) ? f : (f + 1.0);
644
 
        }
645
 
    case kRoundHalfDown:
646
 
        return ((a - uprv_floor(a)) <= 0.5) ? uprv_floor(a) : uprv_ceil(a);
647
 
    case kRoundHalfUp:
648
 
        return ((a - uprv_floor(a)) < 0.5) ? uprv_floor(a) : uprv_ceil(a);
649
 
    }
650
 
    return 1.0;
651
 
}
652
 
 
653
 
UnicodeString&
654
 
DecimalFormat::format(  const Formattable& obj,
655
 
                        UnicodeString& result,
656
 
                        FieldPosition& fieldPosition,
657
 
                        UErrorCode& status) const
658
 
{
659
 
    return NumberFormat::format(obj, result, fieldPosition, status);
660
 
}
661
 
 
662
 
/**
663
 
 * Return true if a grouping separator belongs at the given
664
 
 * position, based on whether grouping is in use and the values of
665
 
 * the primary and secondary grouping interval.
666
 
 * @param pos the number of integer digits to the right of
667
 
 * the current position.  Zero indicates the position after the
668
 
 * rightmost integer digit.
669
 
 * @return true if a grouping character belongs at the current
670
 
 * position.
671
 
 */
672
 
UBool DecimalFormat::isGroupingPosition(int32_t pos) const {
673
 
    UBool result = FALSE;
674
 
    if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) {
675
 
        if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) {
676
 
            result = ((pos - fGroupingSize) % fGroupingSize2) == 0;
677
 
        } else {
678
 
            result = pos % fGroupingSize == 0;
679
 
        }
680
 
    }
681
 
    return result;
682
 
}
683
 
 
684
 
//------------------------------------------------------------------------------
685
 
 
686
 
/**
687
 
 * Complete the formatting of a finite number.  On entry, the fDigitList must
688
 
 * be filled in with the correct digits.
689
 
 */
690
 
UnicodeString&
691
 
DecimalFormat::subformat(UnicodeString& result,
692
 
                         FieldPosition& fieldPosition,
693
 
                         DigitList&     digits,
694
 
                         UBool         isInteger) const
695
 
{
696
 
    // Gets the localized zero Unicode character.
697
 
    UChar32 zero = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
698
 
    int32_t zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
699
 
    UnicodeString grouping(fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
700
 
    UnicodeString decimal(fIsCurrencyFormat ?
701
 
        fSymbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol) :
702
 
        fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
703
 
    int32_t maxIntDig = getMaximumIntegerDigits();
704
 
    int32_t minIntDig = getMinimumIntegerDigits();
705
 
 
706
 
    /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
707
 
     * format as zero.  This allows sensible computations and preserves
708
 
     * relations such as signum(1/x) = signum(x), where x is +Infinity or
709
 
     * -Infinity.  Prior to this fix, we always formatted zero values as if
710
 
     * they were positive.  Liu 7/6/98.
711
 
     */
712
 
    if (digits.isZero())
713
 
    {
714
 
        digits.fDecimalAt = digits.fCount = 0; // Normalize
715
 
    }
716
 
 
717
 
    // Appends the prefix.
718
 
    result += (digits.fIsPositive ? fPositivePrefix : fNegativePrefix);
719
 
 
720
 
    if (fUseExponentialNotation)
721
 
    {
722
 
        // Record field information for caller.
723
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
724
 
        {
725
 
            fieldPosition.setBeginIndex(result.length());
726
 
            fieldPosition.setEndIndex(-1);
727
 
        }
728
 
        else if (fieldPosition.getField() == NumberFormat::kFractionField)
729
 
        {
730
 
            fieldPosition.setBeginIndex(-1);
731
 
        }
732
 
 
733
 
        // Minimum integer digits are handled in exponential format by
734
 
        // adjusting the exponent.  For example, 0.01234 with 3 minimum
735
 
        // integer digits is "123.4E-4".
736
 
 
737
 
        // Maximum integer digits are interpreted as indicating the
738
 
        // repeating range.  This is useful for engineering notation, in
739
 
        // which the exponent is restricted to a multiple of 3.  For
740
 
        // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
741
 
        // If maximum integer digits are defined and are larger than
742
 
        // minimum integer digits, then minimum integer digits are
743
 
        // ignored.
744
 
        int32_t exponent = digits.fDecimalAt;
745
 
        if (maxIntDig > 1 && maxIntDig != minIntDig) {
746
 
            // A exponent increment is defined; adjust to it.
747
 
            exponent = (exponent > 0) ? (exponent - 1) / maxIntDig
748
 
                                      : (exponent / maxIntDig) - 1;
749
 
            exponent *= maxIntDig;
750
 
        } else {
751
 
            // No exponent increment is defined; use minimum integer digits.
752
 
            // If none is specified, as in "#E0", generate 1 integer digit.
753
 
            exponent -= (minIntDig > 0 || getMinimumFractionDigits() > 0)
754
 
                        ? minIntDig : 1;
755
 
        }
756
 
 
757
 
        // We now output a minimum number of digits, and more if there
758
 
        // are more digits, up to the maximum number of digits.  We
759
 
        // place the decimal point after the "integer" digits, which
760
 
        // are the first (decimalAt - exponent) digits.
761
 
        int32_t minimumDigits =  minIntDig + getMinimumFractionDigits();
762
 
        // The number of integer digits is handled specially if the number
763
 
        // is zero, since then there may be no digits.
764
 
        int32_t integerDigits = digits.isZero() ? minIntDig :
765
 
            digits.fDecimalAt - exponent;
766
 
        int32_t totalDigits = digits.fCount;
767
 
        if (minimumDigits > totalDigits)
768
 
            totalDigits = minimumDigits;
769
 
        if (integerDigits > totalDigits)
770
 
            totalDigits = integerDigits;
771
 
 
772
 
        // totalDigits records total number of digits needs to be processed
773
 
        int32_t i;
774
 
        for (i=0; i<totalDigits; ++i)
775
 
        {
776
 
            if (i == integerDigits)
777
 
            {
778
 
                // Record field information for caller.
779
 
                if (fieldPosition.getField() == NumberFormat::kIntegerField)
780
 
                    fieldPosition.setEndIndex(result.length());
781
 
 
782
 
                result += (decimal);
783
 
 
784
 
                // Record field information for caller.
785
 
                if (fieldPosition.getField() == NumberFormat::kFractionField)
786
 
                    fieldPosition.setBeginIndex(result.length());
787
 
            }
788
 
            // Restores the digit character or pads the buffer with zeros.
789
 
            UChar32 c = (UChar32)((i < digits.fCount) ?
790
 
                          (digits.fDigits[i] + zeroDelta) :
791
 
                          zero);
792
 
            result += c;
793
 
        }
794
 
 
795
 
        // Record field information
796
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
797
 
        {
798
 
            if (fieldPosition.getEndIndex() < 0)
799
 
                fieldPosition.setEndIndex(result.length());
800
 
        }
801
 
        else if (fieldPosition.getField() == NumberFormat::kFractionField)
802
 
        {
803
 
            if (fieldPosition.getBeginIndex() < 0)
804
 
                fieldPosition.setBeginIndex(result.length());
805
 
            fieldPosition.setEndIndex(result.length());
806
 
        }
807
 
 
808
 
        // The exponent is output using the pattern-specified minimum
809
 
        // exponent digits.  There is no maximum limit to the exponent
810
 
        // digits, since truncating the exponent would result in an
811
 
        // unacceptable inaccuracy.
812
 
        result += fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol);
813
 
        
814
 
        // For zero values, we force the exponent to zero.  We
815
 
        // must do this here, and not earlier, because the value
816
 
        // is used to determine integer digit count above.
817
 
        if (digits.isZero())
818
 
            exponent = 0;
819
 
 
820
 
        if (exponent < 0) {
821
 
            result += fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol);
822
 
        } else if (fExponentSignAlwaysShown) {
823
 
            result += fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol);
824
 
        }
825
 
 
826
 
        DigitList expDigits;
827
 
        expDigits.set(exponent);
828
 
        for (i=expDigits.fDecimalAt; i<fMinExponentDigits; ++i)
829
 
            result += (zero);
830
 
        for (i=0; i<expDigits.fDecimalAt; ++i)
831
 
        {
832
 
            UChar32 c = (UChar32)((i < expDigits.fCount) ?
833
 
                          (expDigits.fDigits[i] + zeroDelta) : zero);
834
 
            result += c;
835
 
        }
836
 
    }
837
 
    else  // Not using exponential notation
838
 
    {
839
 
        // Record field information for caller.
840
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
841
 
            fieldPosition.setBeginIndex(result.length());
842
 
 
843
 
        // Output the integer portion.  Here 'count' is the total
844
 
        // number of integer digits we will display, including both
845
 
        // leading zeros required to satisfy getMinimumIntegerDigits,
846
 
        // and actual digits present in the number.
847
 
        int32_t count = minIntDig;
848
 
        int32_t digitIndex = 0; // Index into digits.fDigits[]
849
 
        if (digits.fDecimalAt > 0 && count < digits.fDecimalAt)
850
 
            count = digits.fDecimalAt;
851
 
 
852
 
        // Handle the case where getMaximumIntegerDigits() is smaller
853
 
        // than the real number of integer digits.  If this is so, we
854
 
        // output the least significant max integer digits.  For example,
855
 
        // the value 1997 printed with 2 max integer digits is just "97".
856
 
 
857
 
        if (count > maxIntDig)
858
 
        {
859
 
            count = maxIntDig;
860
 
            digitIndex = digits.fDecimalAt - count;
861
 
        }
862
 
 
863
 
        int32_t sizeBeforeIntegerPart = result.length();
864
 
 
865
 
        int32_t i;
866
 
        for (i=count-1; i>=0; --i)
867
 
        {
868
 
            if (i < digits.fDecimalAt && digitIndex < digits.fCount)
869
 
            {
870
 
                // Output a real digit
871
 
                result += ((UChar32)(digits.fDigits[digitIndex++] + zeroDelta));
872
 
            }
873
 
            else
874
 
            {
875
 
                // Output a leading zero
876
 
                result += (zero);
877
 
            }
878
 
 
879
 
            // Output grouping separator if necessary.
880
 
            if (isGroupingPosition(i)) {
881
 
                result.append(grouping);
882
 
            }
883
 
        }
884
 
 
885
 
        // Record field information for caller.
886
 
        if (fieldPosition.getField() == NumberFormat::kIntegerField)
887
 
            fieldPosition.setEndIndex(result.length());
888
 
 
889
 
        // Determine whether or not there are any printable fractional
890
 
        // digits.  If we've used up the digits we know there aren't.
891
 
        UBool fractionPresent = (getMinimumFractionDigits() > 0) ||
892
 
            (!isInteger && digitIndex < digits.fCount);
893
 
 
894
 
        // If there is no fraction present, and we haven't printed any
895
 
        // integer digits, then print a zero.  Otherwise we won't print
896
 
        // _any_ digits, and we won't be able to parse this string.
897
 
        if (!fractionPresent && result.length() == sizeBeforeIntegerPart)
898
 
            result += (zero);
899
 
 
900
 
        // Output the decimal separator if we always do so.
901
 
        if (fDecimalSeparatorAlwaysShown || fractionPresent)
902
 
            result += (decimal);
903
 
 
904
 
        // Record field information for caller.
905
 
        if (fieldPosition.getField() == NumberFormat::kFractionField)
906
 
            fieldPosition.setBeginIndex(result.length());
907
 
 
908
 
        int32_t maxFracDigits = getMaximumFractionDigits();
909
 
        int32_t negDecimalAt = -digits.fDecimalAt;
910
 
        for (i=0; i < maxFracDigits; ++i)
911
 
        {
912
 
            if (!isInteger && digitIndex < digits.fCount)
913
 
            {
914
 
                if (i >= negDecimalAt)
915
 
                {
916
 
                    // Output a digit
917
 
                    result += ((UChar32)(digits.fDigits[digitIndex++] + zeroDelta));
918
 
                }
919
 
                else
920
 
                {
921
 
                    // Output leading fractional zeros.  These are zeros that come after
922
 
                    // the decimal but before any significant digits.  These are only
923
 
                    // output if abs(number being formatted) < 1.0.
924
 
                    result += zero;
925
 
                }
926
 
            }
927
 
            else
928
 
            {
929
 
                // Here is where we escape from the loop.  We escape if we've output
930
 
                // the maximum fraction digits (specified in the for expression above).
931
 
                // We also stop when we've output the minimum digits and either:
932
 
                // we have an integer, so there is no fractional stuff to display,
933
 
                // or we're out of significant digits.
934
 
                if (i >= getMinimumFractionDigits())
935
 
                    break;
936
 
 
937
 
                // No precision is left.
938
 
                result += zero;
939
 
            }
940
 
        }
941
 
 
942
 
        // Record field information for caller.
943
 
        if (fieldPosition.getField() == NumberFormat::kFractionField)
944
 
            fieldPosition.setEndIndex(result.length());
945
 
    }
946
 
 
947
 
    result += (digits.fIsPositive ? fPositiveSuffix : fNegativeSuffix);
948
 
 
949
 
    addPadding(result, fieldPosition, TRUE, !digits.fIsPositive);
950
 
    return result;
951
 
}
952
 
 
953
 
/**
954
 
 * Inserts the character fPad as needed to expand result to fFormatWidth.
955
 
 * @param result the string to be padded
956
 
 * @param hasAffixes if true, padding is positioned appropriately before or
957
 
 * after affixes.  If false, then isNegative is ignored, and there are only
958
 
 * two effective pad positions: kPadBeforePrefix/kPadAfterPrefix and
959
 
 * kPadBeforeSuffix/kPadAfterSuffix.
960
 
 * @param isNegative must be true if result contains a formatted negative
961
 
 * number, and false otherwise.  Ignored if hasAffixes is false.
962
 
 */
963
 
void DecimalFormat::addPadding(UnicodeString& result,
964
 
                               FieldPosition& fieldPosition,
965
 
                               UBool hasAffixes,
966
 
                               UBool isNegative) const
967
 
{
968
 
    if (fFormatWidth > 0) {
969
 
        int32_t len = fFormatWidth - result.length();
970
 
        if (len > 0) {
971
 
            UnicodeString padding;
972
 
            for (int32_t i=0; i<len; ++i) {
973
 
                padding += fPad;
974
 
            }
975
 
            switch (fPadPosition) {
976
 
            case kPadAfterPrefix:
977
 
                if (hasAffixes) {
978
 
                    result.insert(isNegative ? fNegativePrefix.length()
979
 
                                             : fPositivePrefix.length(),
980
 
                                  padding);
981
 
                    break;
982
 
                } // else fall through to next case
983
 
            case kPadBeforePrefix:
984
 
                result.insert(0, padding);
985
 
                break;
986
 
            case kPadBeforeSuffix:
987
 
                if (hasAffixes) {
988
 
                    result.insert(result.length() -
989
 
                                  (isNegative ? fNegativeSuffix.length()
990
 
                                              : fPositiveSuffix.length()),
991
 
                                  padding);
992
 
                    break;
993
 
                } // else fall through to next case
994
 
            case kPadAfterSuffix:
995
 
                result += padding;
996
 
                break;
997
 
            }
998
 
            fieldPosition.setBeginIndex(len + fieldPosition.getBeginIndex());
999
 
            fieldPosition.setEndIndex(len + fieldPosition.getEndIndex());
1000
 
        }
1001
 
    }
1002
 
}
1003
 
 
1004
 
//------------------------------------------------------------------------------
1005
 
 
1006
 
void
1007
 
DecimalFormat::parse(const UnicodeString& text,
1008
 
                     Formattable& result,
1009
 
                     UErrorCode& status) const
1010
 
{
1011
 
    NumberFormat::parse(text, result, status);
1012
 
}
1013
 
 
1014
 
void
1015
 
DecimalFormat::parse(const UnicodeString& text,
1016
 
                     Formattable& result,
1017
 
                     ParsePosition& parsePosition) const
1018
 
{
1019
 
    int32_t backup = parsePosition.getIndex();
1020
 
    int32_t i;
1021
 
    int32_t padLen = fPad.length();
1022
 
 
1023
 
    // Skip padding characters, if any
1024
 
    if (fFormatWidth > 0) {
1025
 
        i = parsePosition.getIndex();
1026
 
        while (i < text.length() && !text.compare(i, padLen, fPad, 0, padLen)) {
1027
 
            i += padLen;
1028
 
        }
1029
 
        parsePosition.setIndex(i);
1030
 
    }
1031
 
 
1032
 
    // special case NaN
1033
 
    // If the text is composed of the representation of NaN, returns NaN.length
1034
 
    UnicodeString nan(fSymbols->getSymbol(DecimalFormatSymbols::kNaNSymbol));
1035
 
    int32_t nanLen = (text.compare(parsePosition.getIndex(), nan.length(), nan)
1036
 
        ? 0 : nan.length());
1037
 
    if (nanLen) {
1038
 
        parsePosition.setIndex(parsePosition.getIndex() + nanLen);
1039
 
        result.setDouble(uprv_getNaN());
1040
 
        return;
1041
 
    }
1042
 
 
1043
 
    // status is used to record whether a number is infinite.
1044
 
    UBool status[fgStatusLength];
1045
 
    DigitList digits;
1046
 
 
1047
 
    if (!subparse(text, parsePosition, digits, status)) {
1048
 
        parsePosition.setIndex(backup);
1049
 
        return;
1050
 
    }
1051
 
    if (fFormatWidth < 0) {
1052
 
        i = parsePosition.getIndex();
1053
 
        while (i < text.length() && !text.compare(i, padLen, fPad, 0, padLen)) {
1054
 
            i += padLen;
1055
 
        }
1056
 
        parsePosition.setIndex(i);
1057
 
    }
1058
 
 
1059
 
    // Handle infinity
1060
 
    if (status[fgStatusInfinite]) {
1061
 
        double inf = uprv_getInfinity();
1062
 
        result.setDouble(digits.fIsPositive ? inf : -inf);
1063
 
        return;
1064
 
    }
1065
 
 
1066
 
    // Do as much of the multiplier conversion as possible without
1067
 
    // losing accuracy.
1068
 
    int32_t mult = fMultiplier; // Don't modify this.multiplier
1069
 
    while (mult % 10 == 0) {
1070
 
        mult /= 10;
1071
 
        --digits.fDecimalAt;
1072
 
    }
1073
 
 
1074
 
    // Handle integral values.  We want to return the most
1075
 
    // parsimonious type that will accommodate all of the result's
1076
 
    // precision.  We therefore only return a long if the result fits
1077
 
    // entirely within a long (taking into account the multiplier) --
1078
 
    // otherwise we fall through and return a double.  When more
1079
 
    // numeric types are supported by Formattable (e.g., 64-bit
1080
 
    // integers, bignums) we will extend this logic to include them.
1081
 
    if (digits.fitsIntoLong(isParseIntegerOnly())) {
1082
 
        int32_t n = digits.getLong();
1083
 
        if (n % mult == 0) {
1084
 
            result.setLong(n / mult);
1085
 
            return;
1086
 
        }
1087
 
        else {  // else handle the remainder
1088
 
            result.setDouble(((double)n) / mult);
1089
 
            return;
1090
 
        }
1091
 
    }
1092
 
    else {
1093
 
        // Handle non-integral or very large values
1094
 
        // Dividing by one is okay and not that costly.
1095
 
        result.setDouble(digits.getDouble() / mult);
1096
 
        return;
1097
 
    }
1098
 
}
1099
 
 
1100
 
 
1101
 
/*
1102
 
This is an old implimentation that was preparing for 64-bit numbers in ICU.
1103
 
It is very slow, and 64-bit numbers are not ANSI-C compatible. This code
1104
 
is here if we change our minds.
1105
 
*/
1106
 
/**
1107
 
 * Parse the given text into a number.  The text is parsed beginning at
1108
 
 * parsePosition, until an unparseable character is seen.
1109
 
 * @param text The string to parse.
1110
 
 * @param parsePosition The position at which to being parsing.  Upon
1111
 
 * return, the first unparseable character.
1112
 
 * @param digits The DigitList to set to the parsed value.
1113
 
 * @param isExponent If true, parse an exponent.  This means no
1114
 
 * infinite values and integer only. By default it's really false.
1115
 
 * @param status Upon return contains boolean status flags indicating
1116
 
 * whether the value was infinite and whether it was positive.
1117
 
 */
1118
 
UBool DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePosition,
1119
 
                               DigitList& digits, UBool* status) const
1120
 
{
1121
 
    int32_t position = parsePosition.getIndex();
1122
 
    int32_t oldStart = position;
1123
 
 
1124
 
    // check for positivePrefix; take longest
1125
 
    UBool gotPositive = text.compare(position,fPositivePrefix.length(),fPositivePrefix,0,
1126
 
                                      fPositivePrefix.length()) == 0;
1127
 
    UBool gotNegative = text.compare(position,fNegativePrefix.length(),fNegativePrefix,0,
1128
 
                                      fNegativePrefix.length()) == 0;
1129
 
    // If the number is positive and negative at the same time,
1130
 
    // 1. the number is positive if the positive prefix is longer
1131
 
    // 2. the number is negative if the negative prefix is longer
1132
 
    if (gotPositive && gotNegative) {
1133
 
        if (fPositivePrefix.length() > fNegativePrefix.length())
1134
 
            gotNegative = FALSE;
1135
 
        else if (fPositivePrefix.length() < fNegativePrefix.length())
1136
 
            gotPositive = FALSE;
1137
 
    }
1138
 
    if(gotPositive)
1139
 
        position += fPositivePrefix.length();
1140
 
    else if(gotNegative)
1141
 
        position += fNegativePrefix.length();
1142
 
    else {
1143
 
        parsePosition.setErrorIndex(position);
1144
 
        return FALSE;
1145
 
    }
1146
 
 
1147
 
    // process digits or Inf, find decimal position
1148
 
    UnicodeString inf(fSymbols->getSymbol(DecimalFormatSymbols::kInfinitySymbol));
1149
 
    int32_t infLen = (text.compare(position, inf.length(), inf)
1150
 
        ? 0 : inf.length());
1151
 
    position += infLen; // infLen is non-zero when it does equal to infinity
1152
 
    status[fgStatusInfinite] = (UBool)infLen;
1153
 
    if (!infLen)
1154
 
    {
1155
 
        // We now have a string of digits, possibly with grouping symbols,
1156
 
        // and decimal points.  We want to process these into a DigitList.
1157
 
        // We don't want to put a bunch of leading zeros into the DigitList
1158
 
        // though, so we keep track of the location of the decimal point,
1159
 
        // put only significant digits into the DigitList, and adjust the
1160
 
        // exponent as needed.
1161
 
 
1162
 
        digits.fDecimalAt = digits.fCount = 0;
1163
 
        UChar32 zero = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
1164
 
        UnicodeString decimal(fIsCurrencyFormat
1165
 
            ? fSymbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol)
1166
 
            : fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
1167
 
        UnicodeString grouping(fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
1168
 
        UnicodeString exponentChar(fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol));
1169
 
        UBool sawDecimal = FALSE;
1170
 
        UBool sawDigit = FALSE;
1171
 
        int32_t backup = -1;
1172
 
        UChar32 ch;
1173
 
        int32_t digit;
1174
 
        int32_t textLength = text.length(); // One less pointer to follow
1175
 
        int32_t groupingLen = grouping.length();
1176
 
        int32_t decimalLen = decimal.length();
1177
 
 
1178
 
        // We have to track digitCount ourselves, because digits.fCount will
1179
 
        // pin when the maximum allowable digits is reached.
1180
 
        int32_t digitCount = 0;
1181
 
 
1182
 
        for (; position < textLength; position += 1 + UTF_NEED_MULTIPLE_UCHAR(ch))
1183
 
        {
1184
 
            ch = text.char32At(position);
1185
 
 
1186
 
            /* We recognize all digit ranges, not only the Latin digit range
1187
 
             * '0'..'9'.  We do so by using the Character.digit() method,
1188
 
             * which converts a valid Unicode digit to the range 0..9.
1189
 
             *
1190
 
             * The character 'ch' may be a digit.  If so, place its value
1191
 
             * from 0 to 9 in 'digit'.  First try using the locale digit,
1192
 
             * which may or MAY NOT be a standard Unicode digit range.  If
1193
 
             * this fails, try using the standard Unicode digit ranges by
1194
 
             * calling Character.digit().  If this also fails, digit will
1195
 
             * have a value outside the range 0..9.
1196
 
             */
1197
 
            digit = ch - zero;
1198
 
            if (digit < 0 || digit > 9)
1199
 
            {
1200
 
                digit = u_charDigitValue(ch);
1201
 
            }
1202
 
 
1203
 
            if (digit > 0 && digit <= 9)
1204
 
            {
1205
 
                // Cancel out backup setting (see grouping handler below)
1206
 
                backup = -1;
1207
 
 
1208
 
                sawDigit = TRUE;
1209
 
                // output a regular non-zero digit.
1210
 
                ++digitCount;
1211
 
                digits.append((char)(digit + '0'));
1212
 
            }
1213
 
            else if (digit == 0)
1214
 
            {
1215
 
                // Cancel out backup setting (see grouping handler below)
1216
 
                backup = -1;
1217
 
                sawDigit = TRUE;
1218
 
 
1219
 
                // Check for leading zeros
1220
 
                if (digits.fCount != 0)
1221
 
                {
1222
 
                    // output a regular zero digit.
1223
 
                    ++digitCount;
1224
 
                    digits.append((char)(digit + '0'));
1225
 
                }
1226
 
                else if (sawDecimal)
1227
 
                {
1228
 
                    // If we have seen the decimal, but no significant digits yet,
1229
 
                    // then we account for leading zeros by decrementing the
1230
 
                    // digits.fDecimalAt into negative values.
1231
 
                    --digits.fDecimalAt;
1232
 
                }
1233
 
                // else ignore leading zeros in integer part of number.
1234
 
            }
1235
 
            else if (!text.compare(position, groupingLen, grouping) && isGroupingUsed())
1236
 
            {
1237
 
                // Ignore grouping characters, if we are using them, but require
1238
 
                // that they be followed by a digit.  Otherwise we backup and
1239
 
                // reprocess them.
1240
 
                backup = position;
1241
 
            }
1242
 
            else if (!text.compare(position, decimalLen, decimal) && !isParseIntegerOnly() && !sawDecimal)
1243
 
            {
1244
 
                // If we're only parsing integers, or if we ALREADY saw the
1245
 
                // decimal, then don't parse this one.
1246
 
 
1247
 
                digits.fDecimalAt = digitCount; // Not digits.fCount!
1248
 
                sawDecimal = TRUE;
1249
 
            }
1250
 
            else if (!text.caseCompare(position,
1251
 
                fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol).length(),
1252
 
                fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol),
1253
 
                U_FOLD_CASE_DEFAULT))    // error code is set below if !sawDigit
1254
 
            {
1255
 
                // Parse sign, if present
1256
 
                int32_t pos = position + 1; // position + exponentSep.length();
1257
 
                DigitList exponentDigits;
1258
 
 
1259
 
                if (pos < textLength)
1260
 
                {
1261
 
                    if (!text.compare(pos,
1262
 
                        fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol).length(),
1263
 
                        fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol)))
1264
 
                    {
1265
 
                        ++pos;
1266
 
                    }
1267
 
                    else if (!text.compare(pos,
1268
 
                        fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol).length(),
1269
 
                        fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol)))
1270
 
                    {
1271
 
                        ++pos;
1272
 
                        exponentDigits.fIsPositive = FALSE;
1273
 
                    }
1274
 
                }
1275
 
 
1276
 
                while (pos < textLength) {
1277
 
                    ch = text[(int32_t)pos];
1278
 
                    digit = ch - zero;
1279
 
 
1280
 
                    if (digit < 0 || digit > 9) {
1281
 
                        digit = u_charDigitValue(ch);
1282
 
                    }
1283
 
                    if (0 <= digit && digit <= 9) {
1284
 
                        ++pos;
1285
 
                        exponentDigits.append((char)(digit + '0'));
1286
 
                    } else {
1287
 
                        break;
1288
 
                    }
1289
 
                }
1290
 
 
1291
 
                if (exponentDigits.fCount > 0) {
1292
 
                    exponentDigits.fDecimalAt = exponentDigits.fCount;
1293
 
                    digits.fDecimalAt += exponentDigits.getLong();
1294
 
                    position = pos; // Advance past the exponent
1295
 
                }
1296
 
 
1297
 
                break; // Whether we fail or succeed, we exit this loop
1298
 
            }
1299
 
            else
1300
 
                break;
1301
 
        }
1302
 
 
1303
 
        if (backup != -1)
1304
 
        {
1305
 
            position = backup;
1306
 
        }
1307
 
 
1308
 
        // If there was no decimal point we have an integer
1309
 
        if (!sawDecimal)
1310
 
        {
1311
 
            digits.fDecimalAt += digitCount; // Not digits.fCount!
1312
 
        }
1313
 
 
1314
 
        // If none of the text string was recognized.  For example, parse
1315
 
        // "x" with pattern "#0.00" (return index and error index both 0)
1316
 
        // parse "$" with pattern "$#0.00". (return index 0 and error index
1317
 
        // 1).
1318
 
        if (!sawDigit && digitCount == 0) {
1319
 
            parsePosition.setIndex(oldStart);
1320
 
            parsePosition.setErrorIndex(oldStart);
1321
 
            return FALSE;
1322
 
        }
1323
 
    }
1324
 
 
1325
 
    // check for positiveSuffix
1326
 
    if (gotPositive && fPositiveSuffix.length() > 0)
1327
 
    {
1328
 
        gotPositive = text.compare(position,fPositiveSuffix.length(),fPositiveSuffix,0,
1329
 
                                   fPositiveSuffix.length()) == 0;
1330
 
    }
1331
 
    if (gotNegative && fNegativeSuffix.length() > 0)
1332
 
    {
1333
 
        gotNegative = text.compare(position,fNegativeSuffix.length(),fNegativeSuffix,0,
1334
 
                                   fNegativeSuffix.length()) == 0;
1335
 
    }
1336
 
 
1337
 
    // if both match, take longest
1338
 
    if (gotPositive && gotNegative)
1339
 
    {
1340
 
        if (fPositiveSuffix.length() > fNegativeSuffix.length())
1341
 
        {
1342
 
            gotNegative = FALSE;
1343
 
        }
1344
 
        else if (fPositiveSuffix.length() < fNegativeSuffix.length())
1345
 
        {
1346
 
            gotPositive = FALSE;
1347
 
        }
1348
 
        else
1349
 
        {
1350
 
            gotPositive = TRUE; // Make them equal to each other.
1351
 
            gotNegative = TRUE;
1352
 
        }
1353
 
    }
1354
 
 
1355
 
    // fail if neither or both
1356
 
    if (gotPositive == gotNegative)
1357
 
    {
1358
 
        parsePosition.setErrorIndex(position);
1359
 
        return FALSE;
1360
 
    }
1361
 
 
1362
 
    parsePosition.setIndex(position +
1363
 
                           (gotPositive ? fPositiveSuffix.length() :
1364
 
                            fNegativeSuffix.length())); // mark success!
1365
 
 
1366
 
    digits.fIsPositive = gotPositive;
1367
 
 
1368
 
    if(parsePosition.getIndex() == oldStart)
1369
 
    {
1370
 
        parsePosition.setErrorIndex(position);
1371
 
        return FALSE;
1372
 
    }
1373
 
    return TRUE;
1374
 
}
1375
 
 
1376
 
 
1377
 
//------------------------------------------------------------------------------
1378
 
// Gets the pointer to the localized decimal format symbols
1379
 
 
1380
 
const DecimalFormatSymbols*
1381
 
DecimalFormat::getDecimalFormatSymbols() const
1382
 
{
1383
 
    return fSymbols;
1384
 
}
1385
 
 
1386
 
//------------------------------------------------------------------------------
1387
 
// De-owning the current localized symbols and adopt the new symbols.
1388
 
 
1389
 
void
1390
 
DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
1391
 
{
1392
 
    if (fSymbols != NULL)
1393
 
        delete fSymbols;
1394
 
 
1395
 
    fSymbols = symbolsToAdopt;
1396
 
}
1397
 
//------------------------------------------------------------------------------
1398
 
// Setting the symbols is equlivalent to adopting a newly created localized
1399
 
// symbols.
1400
 
 
1401
 
void
1402
 
DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
1403
 
{
1404
 
    adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
1405
 
    expandAffixes();
1406
 
}
1407
 
 
1408
 
//------------------------------------------------------------------------------
1409
 
// Gets the positive prefix of the number pattern.
1410
 
 
1411
 
UnicodeString&
1412
 
DecimalFormat::getPositivePrefix(UnicodeString& result) const
1413
 
{
1414
 
    result = fPositivePrefix;
1415
 
    return result;
1416
 
}
1417
 
 
1418
 
//------------------------------------------------------------------------------
1419
 
// Sets the positive prefix of the number pattern.
1420
 
 
1421
 
void
1422
 
DecimalFormat::setPositivePrefix(const UnicodeString& newValue)
1423
 
{
1424
 
    fPositivePrefix = newValue;
1425
 
    delete fPosPrefixPattern;
1426
 
    fPosPrefixPattern = 0;
1427
 
}
1428
 
 
1429
 
//------------------------------------------------------------------------------
1430
 
// Gets the negative prefix  of the number pattern.
1431
 
 
1432
 
UnicodeString&
1433
 
DecimalFormat::getNegativePrefix(UnicodeString& result) const
1434
 
{
1435
 
    result = fNegativePrefix;
1436
 
    return result;
1437
 
}
1438
 
 
1439
 
//------------------------------------------------------------------------------
1440
 
// Gets the negative prefix  of the number pattern.
1441
 
 
1442
 
void
1443
 
DecimalFormat::setNegativePrefix(const UnicodeString& newValue)
1444
 
{
1445
 
    fNegativePrefix = newValue;
1446
 
    delete fNegPrefixPattern;
1447
 
    fNegPrefixPattern = 0;
1448
 
}
1449
 
 
1450
 
//------------------------------------------------------------------------------
1451
 
// Gets the positive suffix of the number pattern.
1452
 
 
1453
 
UnicodeString&
1454
 
DecimalFormat::getPositiveSuffix(UnicodeString& result) const
1455
 
{
1456
 
    result = fPositiveSuffix;
1457
 
    return result;
1458
 
}
1459
 
 
1460
 
//------------------------------------------------------------------------------
1461
 
// Sets the positive suffix of the number pattern.
1462
 
 
1463
 
void
1464
 
DecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
1465
 
{
1466
 
    fPositiveSuffix = newValue;
1467
 
    delete fPosSuffixPattern;
1468
 
    fPosSuffixPattern = 0;
1469
 
}
1470
 
 
1471
 
//------------------------------------------------------------------------------
1472
 
// Gets the negative suffix of the number pattern.
1473
 
 
1474
 
UnicodeString&
1475
 
DecimalFormat::getNegativeSuffix(UnicodeString& result) const
1476
 
{
1477
 
    result = fNegativeSuffix;
1478
 
    return result;
1479
 
}
1480
 
 
1481
 
//------------------------------------------------------------------------------
1482
 
// Sets the negative suffix of the number pattern.
1483
 
 
1484
 
void
1485
 
DecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
1486
 
{
1487
 
    fNegativeSuffix = newValue;
1488
 
    delete fNegSuffixPattern;
1489
 
    fNegSuffixPattern = 0;
1490
 
}
1491
 
 
1492
 
//------------------------------------------------------------------------------
1493
 
// Gets the multiplier of the number pattern.
1494
 
 
1495
 
int32_t DecimalFormat::getMultiplier() const
1496
 
{
1497
 
    return fMultiplier;
1498
 
}
1499
 
 
1500
 
//------------------------------------------------------------------------------
1501
 
// Sets the multiplier of the number pattern.
1502
 
void
1503
 
DecimalFormat::setMultiplier(int32_t newValue)
1504
 
{
1505
 
    // This shouldn't be set to 0.
1506
 
    // Due to compatibility with ICU4J we cannot set an error code and refuse 0.
1507
 
    // So the rest of the code should ignore fMultiplier when it's 0. [grhoten]
1508
 
    fMultiplier = newValue;
1509
 
}
1510
 
 
1511
 
/**
1512
 
 * Get the rounding increment.
1513
 
 * @return A positive rounding increment, or 0.0 if rounding
1514
 
 * is not in effect.
1515
 
 * @see #setRoundingIncrement
1516
 
 * @see #getRoundingMode
1517
 
 * @see #setRoundingMode
1518
 
 */
1519
 
double DecimalFormat::getRoundingIncrement() {
1520
 
    return fRoundingDouble;
1521
 
}
1522
 
 
1523
 
/**
1524
 
 * Set the rounding increment.  This method also controls whether
1525
 
 * rounding is enabled.
1526
 
 * @param newValue A positive rounding increment, or 0.0 to disable rounding.
1527
 
 * Negative increments are equivalent to 0.0.
1528
 
 * @see #getRoundingIncrement
1529
 
 * @see #getRoundingMode
1530
 
 * @see #setRoundingMode
1531
 
 */
1532
 
void DecimalFormat::setRoundingIncrement(double newValue) {
1533
 
    if (newValue > 0.0) {
1534
 
        if (fRoundingIncrement == NULL) {
1535
 
            fRoundingIncrement = new DigitList();
1536
 
        }
1537
 
        fRoundingIncrement->set((int32_t)newValue);
1538
 
        fRoundingDouble = newValue;
1539
 
    } else {
1540
 
        delete fRoundingIncrement;
1541
 
        fRoundingIncrement = NULL;
1542
 
        fRoundingDouble = 0.0;
1543
 
    }
1544
 
}
1545
 
 
1546
 
/**
1547
 
 * Get the rounding mode.
1548
 
 * @return A rounding mode
1549
 
 * @see #setRoundingIncrement
1550
 
 * @see #getRoundingIncrement
1551
 
 * @see #setRoundingMode
1552
 
 */
1553
 
DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() {
1554
 
    return fRoundingMode;
1555
 
}
1556
 
 
1557
 
/**
1558
 
 * Set the rounding mode.  This has no effect unless the rounding
1559
 
 * increment is greater than zero.
1560
 
 * @param roundingMode A rounding mode
1561
 
 * @see #setRoundingIncrement
1562
 
 * @see #getRoundingIncrement
1563
 
 * @see #getRoundingMode
1564
 
 */
1565
 
void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
1566
 
    fRoundingMode = roundingMode;
1567
 
}
1568
 
 
1569
 
/**
1570
 
 * Get the width to which the output of <code>format()</code> is padded.
1571
 
 * @return the format width, or zero if no padding is in effect
1572
 
 * @see #setFormatWidth
1573
 
 * @see #getPadCharacter
1574
 
 * @see #setPadCharacter
1575
 
 * @see #getPadPosition
1576
 
 * @see #setPadPosition
1577
 
 */
1578
 
int32_t DecimalFormat::getFormatWidth() {
1579
 
    return fFormatWidth;
1580
 
}
1581
 
 
1582
 
/**
1583
 
 * Set the width to which the output of <code>format()</code> is padded.
1584
 
 * This method also controls whether padding is enabled.
1585
 
 * @param width the width to which to pad the result of
1586
 
 * <code>format()</code>, or zero to disable padding.  A negative
1587
 
 * width is equivalent to 0.
1588
 
 * @see #getFormatWidth
1589
 
 * @see #getPadCharacter
1590
 
 * @see #setPadCharacter
1591
 
 * @see #getPadPosition
1592
 
 * @see #setPadPosition
1593
 
 */
1594
 
void DecimalFormat::setFormatWidth(int32_t width) {
1595
 
    fFormatWidth = (width > 0) ? width : 0;
1596
 
}
1597
 
 
1598
 
/**
1599
 
 * Get the character used to pad to the format width.  The default is ' '.
1600
 
 * @return the pad character
1601
 
 * @see #setFormatWidth
1602
 
 * @see #getFormatWidth
1603
 
 * @see #setPadCharacter
1604
 
 * @see #getPadPosition
1605
 
 * @see #setPadPosition
1606
 
 */
1607
 
UnicodeString DecimalFormat::getPadCharacterString() {
1608
 
    return fPad;
1609
 
}
1610
 
 
1611
 
/**
1612
 
 * Set the character used to pad to the format width.  This has no effect
1613
 
 * unless padding is enabled.
1614
 
 * @param padChar the pad character
1615
 
 * @see #setFormatWidth
1616
 
 * @see #getFormatWidth
1617
 
 * @see #getPadCharacter
1618
 
 * @see #getPadPosition
1619
 
 * @see #setPadPosition
1620
 
 */
1621
 
void DecimalFormat::setPadCharacter(UnicodeString padChar) {
1622
 
    if (padChar.length() > 0) {
1623
 
        fPad = padChar;
1624
 
    }
1625
 
    else {
1626
 
        fPad = kPatternPadEscape;
1627
 
    }
1628
 
}
1629
 
 
1630
 
/**
1631
 
 * Get the position at which padding will take place.  This is the location
1632
 
 * at which padding will be inserted if the result of <code>format()</code>
1633
 
 * is shorter than the format width.
1634
 
 * @return the pad position, one of <code>kPadBeforePrefix</code>,
1635
 
 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
1636
 
 * <code>kPadAfterSuffix</code>.
1637
 
 * @see #setFormatWidth
1638
 
 * @see #getFormatWidth
1639
 
 * @see #setPadCharacter
1640
 
 * @see #getPadCharacter
1641
 
 * @see #setPadPosition
1642
 
 * @see #kPadBeforePrefix
1643
 
 * @see #kPadAfterPrefix
1644
 
 * @see #kPadBeforeSuffix
1645
 
 * @see #kPadAfterSuffix
1646
 
 */
1647
 
DecimalFormat::EPadPosition DecimalFormat::getPadPosition() {
1648
 
    return fPadPosition;
1649
 
}
1650
 
 
1651
 
/**
1652
 
 * <strong><font face=helvetica color=red>NEW</font></strong>
1653
 
 * Set the position at which padding will take place.  This is the location
1654
 
 * at which padding will be inserted if the result of <code>format()</code>
1655
 
 * is shorter than the format width.  This has no effect unless padding is
1656
 
 * enabled.
1657
 
 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
1658
 
 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
1659
 
 * <code>kPadAfterSuffix</code>.
1660
 
 * @see #setFormatWidth
1661
 
 * @see #getFormatWidth
1662
 
 * @see #setPadCharacter
1663
 
 * @see #getPadCharacter
1664
 
 * @see #getPadPosition
1665
 
 * @see #kPadBeforePrefix
1666
 
 * @see #kPadAfterPrefix
1667
 
 * @see #kPadBeforeSuffix
1668
 
 * @see #kPadAfterSuffix
1669
 
 */
1670
 
void DecimalFormat::setPadPosition(EPadPosition padPos) {
1671
 
    fPadPosition = padPos;
1672
 
}
1673
 
 
1674
 
/**
1675
 
 * Return whether or not scientific notation is used.
1676
 
 * @return TRUE if this object formats and parses scientific notation
1677
 
 * @see #setScientificNotation
1678
 
 * @see #getMinimumExponentDigits
1679
 
 * @see #setMinimumExponentDigits
1680
 
 * @see #isExponentSignAlwaysShown
1681
 
 * @see #setExponentSignAlwaysShown
1682
 
 */
1683
 
UBool DecimalFormat::isScientificNotation() {
1684
 
    return fUseExponentialNotation;
1685
 
}
1686
 
 
1687
 
/**
1688
 
 * Set whether or not scientific notation is used.
1689
 
 * @param useScientific TRUE if this object formats and parses scientific
1690
 
 * notation
1691
 
 * @see #isScientificNotation
1692
 
 * @see #getMinimumExponentDigits
1693
 
 * @see #setMinimumExponentDigits
1694
 
 * @see #isExponentSignAlwaysShown
1695
 
 * @see #setExponentSignAlwaysShown
1696
 
 */
1697
 
void DecimalFormat::setScientificNotation(UBool useScientific) {
1698
 
    fUseExponentialNotation = useScientific;
1699
 
    if (fUseExponentialNotation && fMinExponentDigits < 1) {
1700
 
        fMinExponentDigits = 1;
1701
 
    }
1702
 
}
1703
 
 
1704
 
/**
1705
 
 * Return the minimum exponent digits that will be shown.
1706
 
 * @return the minimum exponent digits that will be shown
1707
 
 * @see #setScientificNotation
1708
 
 * @see #isScientificNotation
1709
 
 * @see #setMinimumExponentDigits
1710
 
 * @see #isExponentSignAlwaysShown
1711
 
 * @see #setExponentSignAlwaysShown
1712
 
 */
1713
 
int8_t DecimalFormat::getMinimumExponentDigits() {
1714
 
    return fMinExponentDigits;
1715
 
}
1716
 
 
1717
 
/**
1718
 
 * Set the minimum exponent digits that will be shown.  This has no
1719
 
 * effect unless scientific notation is in use.
1720
 
 * @param minExpDig a value >= 1 indicating the fewest exponent digits
1721
 
 * that will be shown.  Values less than 1 will be treated as 1.
1722
 
 * @see #setScientificNotation
1723
 
 * @see #isScientificNotation
1724
 
 * @see #getMinimumExponentDigits
1725
 
 * @see #isExponentSignAlwaysShown
1726
 
 * @see #setExponentSignAlwaysShown
1727
 
 */
1728
 
void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
1729
 
    fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1);
1730
 
}
1731
 
 
1732
 
/**
1733
 
 * Return whether the exponent sign is always shown.
1734
 
 * @return TRUE if the exponent is always prefixed with either the
1735
 
 * localized minus sign or the localized plus sign, false if only negative
1736
 
 * exponents are prefixed with the localized minus sign.
1737
 
 * @see #setScientificNotation
1738
 
 * @see #isScientificNotation
1739
 
 * @see #setMinimumExponentDigits
1740
 
 * @see #getMinimumExponentDigits
1741
 
 * @see #setExponentSignAlwaysShown
1742
 
 */
1743
 
UBool DecimalFormat::isExponentSignAlwaysShown() {
1744
 
    return fExponentSignAlwaysShown;
1745
 
}
1746
 
 
1747
 
/**
1748
 
 * Set whether the exponent sign is always shown.  This has no effect
1749
 
 * unless scientific notation is in use.
1750
 
 * @param expSignAlways TRUE if the exponent is always prefixed with either
1751
 
 * the localized minus sign or the localized plus sign, false if only
1752
 
 * negative exponents are prefixed with the localized minus sign.
1753
 
 * @see #setScientificNotation
1754
 
 * @see #isScientificNotation
1755
 
 * @see #setMinimumExponentDigits
1756
 
 * @see #getMinimumExponentDigits
1757
 
 * @see #isExponentSignAlwaysShown
1758
 
 */
1759
 
void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
1760
 
    fExponentSignAlwaysShown = expSignAlways;
1761
 
}
1762
 
 
1763
 
//------------------------------------------------------------------------------
1764
 
// Gets the grouping size of the number pattern.  For example, thousand or 10
1765
 
// thousand groupings.
1766
 
 
1767
 
int32_t
1768
 
DecimalFormat::getGroupingSize() const
1769
 
{
1770
 
    return fGroupingSize;
1771
 
}
1772
 
 
1773
 
//------------------------------------------------------------------------------
1774
 
// Gets the grouping size of the number pattern.
1775
 
 
1776
 
void
1777
 
DecimalFormat::setGroupingSize(int32_t newValue)
1778
 
{
1779
 
    fGroupingSize = newValue;
1780
 
}
1781
 
 
1782
 
//------------------------------------------------------------------------------
1783
 
 
1784
 
int32_t
1785
 
DecimalFormat::getSecondaryGroupingSize() const
1786
 
{
1787
 
    return fGroupingSize2;
1788
 
}
1789
 
 
1790
 
//------------------------------------------------------------------------------
1791
 
 
1792
 
void
1793
 
DecimalFormat::setSecondaryGroupingSize(int32_t newValue)
1794
 
{
1795
 
    fGroupingSize2 = newValue;
1796
 
}
1797
 
 
1798
 
//------------------------------------------------------------------------------
1799
 
// Checks if to show the decimal separator.
1800
 
 
1801
 
UBool
1802
 
DecimalFormat::isDecimalSeparatorAlwaysShown() const
1803
 
{
1804
 
    return fDecimalSeparatorAlwaysShown;
1805
 
}
1806
 
 
1807
 
//------------------------------------------------------------------------------
1808
 
// Sets to always show the decimal separator.
1809
 
 
1810
 
void
1811
 
DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
1812
 
{
1813
 
    fDecimalSeparatorAlwaysShown = newValue;
1814
 
}
1815
 
 
1816
 
//------------------------------------------------------------------------------
1817
 
// Emits the pattern of this DecimalFormat instance.
1818
 
 
1819
 
UnicodeString&
1820
 
DecimalFormat::toPattern(UnicodeString& result) const
1821
 
{
1822
 
    return toPattern(result, FALSE);
1823
 
}
1824
 
 
1825
 
//------------------------------------------------------------------------------
1826
 
// Emits the localized pattern this DecimalFormat instance.
1827
 
 
1828
 
UnicodeString&
1829
 
DecimalFormat::toLocalizedPattern(UnicodeString& result) const
1830
 
{
1831
 
    return toPattern(result, TRUE);
1832
 
}
1833
 
 
1834
 
//------------------------------------------------------------------------------
1835
 
/**
1836
 
 * Expand the affix pattern strings into the expanded affix strings.  If any
1837
 
 * affix pattern string is null, do not expand it.  This method should be
1838
 
 * called any time the symbols or the affix patterns change in order to keep
1839
 
 * the expanded affix strings up to date.
1840
 
 */
1841
 
void DecimalFormat::expandAffixes(void) {
1842
 
    if (fPosPrefixPattern != 0) {
1843
 
        expandAffix(*fPosPrefixPattern, fPositivePrefix);
1844
 
    }
1845
 
    if (fPosSuffixPattern != 0) {
1846
 
        expandAffix(*fPosSuffixPattern, fPositiveSuffix);
1847
 
    }
1848
 
    if (fNegPrefixPattern != 0) {
1849
 
        expandAffix(*fNegPrefixPattern, fNegativePrefix);
1850
 
    }
1851
 
    if (fNegSuffixPattern != 0) {
1852
 
        expandAffix(*fNegSuffixPattern, fNegativeSuffix);
1853
 
    }
1854
 
#ifdef FMT_DEBUG
1855
 
    UnicodeString s;
1856
 
    s.append("[")
1857
 
        .append(*fPosPrefixPattern).append("|").append(*fPosSuffixPattern)
1858
 
        .append(";") .append(*fNegPrefixPattern).append("|").append(*fNegSuffixPattern)
1859
 
        .append("]->[")
1860
 
        .append(fPositivePrefix).append("|").append(fPositiveSuffix)
1861
 
        .append(";") .append(fNegativePrefix).append("|").append(fNegativeSuffix)
1862
 
        .append("]\n");
1863
 
    debugout(s);
1864
 
#endif
1865
 
}
1866
 
 
1867
 
/**
1868
 
 * Expand an affix pattern into an affix string.  All characters in the
1869
 
 * pattern are literal unless prefixed by kQuote.  The following characters
1870
 
 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
1871
 
 * PATTERN_MINUS, and kCurrencySign.  If kCurrencySign is doubled (kQuote +
1872
 
 * kCurrencySign + kCurrencySign), it is interpreted as an international
1873
 
 * currency sign.  Any other character after a kQuote represents itself.
1874
 
 * kQuote must be followed by another character; kQuote may not occur by
1875
 
 * itself at the end of the pattern.
1876
 
 *
1877
 
 * @param pattern the non-null, fPossibly empty pattern
1878
 
 * @param affix string to receive the expanded equivalent of pattern
1879
 
 */
1880
 
void DecimalFormat::expandAffix(const UnicodeString& pattern,
1881
 
                                UnicodeString& affix) const {
1882
 
    affix.remove();
1883
 
    for (int i=0; i<pattern.length(); ) {
1884
 
        UChar32 c = pattern.char32At(i++);
1885
 
        if (c == kQuote) {
1886
 
            c = pattern.char32At(i++);
1887
 
            switch (c) {
1888
 
            case kCurrencySign:
1889
 
                {
1890
 
                    if (i<pattern.length() &&
1891
 
                        pattern.char32At(i) == kCurrencySign) {
1892
 
                        ++i;
1893
 
                        affix += fSymbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
1894
 
                    } else {
1895
 
                        affix += fSymbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol);
1896
 
                    }
1897
 
                }
1898
 
                continue;
1899
 
            case kPatternPercent:
1900
 
                affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol));
1901
 
                break;
1902
 
            case kPatternPerMill:
1903
 
                affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol));
1904
 
                break;
1905
 
            case kPatternPlus:
1906
 
                affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol));
1907
 
                break;
1908
 
            case kPatternMinus:
1909
 
                affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol));
1910
 
                break;
1911
 
            default:
1912
 
                affix.append(c);
1913
 
                break;
1914
 
            }
1915
 
        }
1916
 
        else {
1917
 
            affix.append(c);
1918
 
        }
1919
 
    }
1920
 
}
1921
 
 
1922
 
/**
1923
 
 * Appends an affix pattern to the given StringBuffer, quoting special
1924
 
 * characters as needed.  Uses the internal affix pattern, if that exists,
1925
 
 * or the literal affix, if the internal affix pattern is null.  The
1926
 
 * appended string will generate the same affix pattern (or literal affix)
1927
 
 * when passed to toPattern().
1928
 
 *
1929
 
 * @param buffer the affix string is appended to this
1930
 
 * @param affixPattern a pattern such as fPosPrefixPattern; may be null
1931
 
 * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
1932
 
 * Ignored unless affixPattern is null.  If affixPattern is null, then
1933
 
 * expAffix is appended as a literal affix.
1934
 
 * @param localized true if the appended pattern should contain localized
1935
 
 * pattern characters; otherwise, non-localized pattern chars are appended
1936
 
 */
1937
 
void DecimalFormat::appendAffix(UnicodeString& buffer,
1938
 
                                const UnicodeString* affixPattern,
1939
 
                                const UnicodeString& expAffix,
1940
 
                                UBool localized) const {
1941
 
    if (affixPattern == 0) {
1942
 
        appendAffix(buffer, expAffix, localized);
1943
 
    } else {
1944
 
        int i;
1945
 
        for (int pos=0; pos<affixPattern->length(); pos=i) {
1946
 
            i = affixPattern->indexOf(kQuote, pos);
1947
 
            if (i < 0) {
1948
 
                UnicodeString s;
1949
 
                affixPattern->extractBetween(pos, affixPattern->length(), s);
1950
 
                appendAffix(buffer, s, localized);
1951
 
                break;
1952
 
            }
1953
 
            if (i > pos) {
1954
 
                UnicodeString s;
1955
 
                affixPattern->extractBetween(pos, i, s);
1956
 
                appendAffix(buffer, s, localized);
1957
 
            }
1958
 
            UChar32 c = affixPattern->char32At(++i);
1959
 
            ++i;
1960
 
            if (c == kQuote) {
1961
 
                buffer.append(c).append(c);
1962
 
                // Fall through and append another kQuote below
1963
 
            } else if (c == kCurrencySign &&
1964
 
                       i<affixPattern->length() &&
1965
 
                       affixPattern->char32At(i) == kCurrencySign) {
1966
 
                ++i;
1967
 
                buffer.append(c).append(c);
1968
 
            } else if (localized) {
1969
 
                switch (c) {
1970
 
                case kPatternPercent:
1971
 
                    buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol));
1972
 
                    break;
1973
 
                case kPatternPerMill:
1974
 
                    buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol));
1975
 
                    break;
1976
 
                case kPatternPlus:
1977
 
                    buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol));
1978
 
                    break;
1979
 
                case kPatternMinus:
1980
 
                    buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol));
1981
 
                    break;
1982
 
                default:
1983
 
                    buffer.append(c);
1984
 
                }
1985
 
            } else {
1986
 
                buffer.append(c);
1987
 
            }
1988
 
        }
1989
 
    }
1990
 
}
1991
 
 
1992
 
/**
1993
 
 * Append an affix to the given StringBuffer, using quotes if
1994
 
 * there are special characters.  Single quotes themselves must be
1995
 
 * escaped in either case.
1996
 
 */
1997
 
void
1998
 
DecimalFormat::appendAffix(    UnicodeString& buffer,
1999
 
                            const UnicodeString& affix,
2000
 
                            UBool localized) const {
2001
 
    UBool needQuote;
2002
 
    if(localized) {
2003
 
        needQuote = affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0
2004
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0
2005
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0
2006
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0
2007
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0
2008
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0
2009
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0
2010
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0
2011
 
            || affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0
2012
 
            || affix.indexOf(kCurrencySign) >= 0;
2013
 
    }
2014
 
    else {
2015
 
        needQuote = affix.indexOf(kPatternZeroDigit) >= 0
2016
 
            || affix.indexOf(kPatternGroupingSeparator) >= 0
2017
 
            || affix.indexOf(kPatternDecimalSeparator) >= 0
2018
 
            || affix.indexOf(kPatternPercent) >= 0
2019
 
            || affix.indexOf(kPatternPerMill) >= 0
2020
 
            || affix.indexOf(kPatternDigit) >= 0
2021
 
            || affix.indexOf(kPatternSeparator) >= 0
2022
 
            || affix.indexOf(kPatternExponent) >= 0
2023
 
            || affix.indexOf(kPatternPlus) >= 0
2024
 
            || affix.indexOf(kPatternMinus) >= 0
2025
 
            || affix.indexOf(kCurrencySign) >= 0;
2026
 
    }
2027
 
    if (needQuote)
2028
 
        buffer += (UChar)0x0027 /*'\''*/;
2029
 
    if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0)
2030
 
        buffer += affix;
2031
 
    else {
2032
 
        for (int32_t j = 0; j < affix.length(); ++j) {
2033
 
            UChar32 c = affix.char32At(j);
2034
 
            buffer += c;
2035
 
            if (c == 0x0027 /*'\''*/)
2036
 
                buffer += c;
2037
 
            j = j + UTF_NEED_MULTIPLE_UCHAR(c);
2038
 
        }
2039
 
    }
2040
 
    if (needQuote)
2041
 
        buffer += (UChar)0x0027 /*'\''*/;
2042
 
}
2043
 
 
2044
 
//------------------------------------------------------------------------------
2045
 
 
2046
 
/* Tell the VC++ compiler not to spew out the warnings about integral size conversion */
2047
 
/*
2048
 
#ifdef _WIN32
2049
 
#pragma warning( disable : 4761 )
2050
 
#endif
2051
 
*/
2052
 
 
2053
 
UnicodeString&
2054
 
DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
2055
 
{
2056
 
    result.remove();
2057
 
    UChar32 zero;
2058
 
    UnicodeString digit;
2059
 
    UnicodeString group;
2060
 
    int32_t i;
2061
 
    int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits
2062
 
    UnicodeString roundingDigits;
2063
 
    int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1;
2064
 
    UnicodeString padSpec;
2065
 
 
2066
 
    if (localized) {
2067
 
        digit = fSymbols->getSymbol(DecimalFormatSymbols::kDigitSymbol);
2068
 
        group = fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
2069
 
        zero = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
2070
 
    }
2071
 
    else {
2072
 
        digit.append((UChar)kPatternDigit);
2073
 
        group.append((UChar)kPatternGroupingSeparator);
2074
 
        zero = (UChar32)kPatternZeroDigit;
2075
 
    }
2076
 
    if (fFormatWidth > 0) {
2077
 
        if (localized) {
2078
 
            padSpec.append(fSymbols->getSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
2079
 
        }
2080
 
        else {
2081
 
            padSpec.append((UChar)kPatternPadEscape);
2082
 
        }
2083
 
        padSpec.append(fPad);
2084
 
    }
2085
 
    if (fRoundingIncrement != NULL) {
2086
 
        for(i=0; i<fRoundingIncrement->fCount; ++i) {
2087
 
            roundingDigits.append((UChar)fRoundingIncrement->fDigits[i]);
2088
 
        }
2089
 
        roundingDecimalPos = fRoundingIncrement->fDecimalAt;
2090
 
    }
2091
 
    for (int32_t part=0; part<2; ++part) {
2092
 
        if (padPos == kPadBeforePrefix) {
2093
 
            result.append(padSpec);
2094
 
        }
2095
 
        appendAffix(result,
2096
 
                    (part==0 ? fPosPrefixPattern : fNegPrefixPattern),
2097
 
                    (part==0 ? fPositivePrefix : fNegativePrefix),
2098
 
                    localized);
2099
 
        if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) {
2100
 
            result.append(padSpec);
2101
 
        }
2102
 
        int32_t sub0Start = result.length();
2103
 
        int32_t g = isGroupingUsed() ? uprv_max(0, fGroupingSize) : 0;
2104
 
        if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) {
2105
 
            g += fGroupingSize2;
2106
 
        }
2107
 
        int32_t maxIntDig = fUseExponentialNotation ? getMaximumIntegerDigits() :
2108
 
          (uprv_max(uprv_max(g, getMinimumIntegerDigits()),
2109
 
                   roundingDecimalPos) + 1);
2110
 
        for (i = maxIntDig; i > 0; --i) {
2111
 
            if (!fUseExponentialNotation && i<maxIntDig &&
2112
 
                isGroupingPosition(i)) {
2113
 
                result.append(group);
2114
 
            }
2115
 
            if (! roundingDigits.isEmpty()) {
2116
 
                int32_t pos = roundingDecimalPos - i;
2117
 
                if (pos >= 0 && pos < roundingDigits.length()) {
2118
 
                    result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
2119
 
                    continue;
2120
 
                }
2121
 
            }
2122
 
            if (i<=getMinimumIntegerDigits()) {
2123
 
                result.append(zero);
2124
 
            }
2125
 
            else {
2126
 
                result.append(digit);
2127
 
            }
2128
 
        }
2129
 
        if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) {
2130
 
            if (localized) {
2131
 
                result.append(fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
2132
 
            }
2133
 
            else {
2134
 
                result.append((UChar)kPatternDecimalSeparator);
2135
 
            }
2136
 
        }
2137
 
        int32_t pos = roundingDecimalPos;
2138
 
        for (i = 0; i < getMaximumFractionDigits(); ++i) {
2139
 
            if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) {
2140
 
                if (pos < 0) {
2141
 
                    result.append(zero);
2142
 
                }
2143
 
                else {
2144
 
                    result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
2145
 
                }
2146
 
                ++pos;
2147
 
                continue;
2148
 
            }
2149
 
            if (i<getMinimumFractionDigits()) {
2150
 
                result.append(zero);
2151
 
            }
2152
 
            else {
2153
 
                result.append(digit);
2154
 
            }
2155
 
        }
2156
 
        if (fUseExponentialNotation) {
2157
 
            if (localized) {
2158
 
                result.append(fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol));
2159
 
            }
2160
 
            else {
2161
 
                result.append((UChar)kPatternExponent);
2162
 
            }
2163
 
            if (fExponentSignAlwaysShown) {
2164
 
                if (localized) {
2165
 
                    result.append(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol));
2166
 
                }
2167
 
                else {
2168
 
                    result.append((UChar)kPatternPlus);
2169
 
                }
2170
 
            }
2171
 
            for (i=0; i<fMinExponentDigits; ++i) {
2172
 
                result.append(zero);
2173
 
            }
2174
 
        }
2175
 
        if (! padSpec.isEmpty() && !fUseExponentialNotation) {
2176
 
            int32_t add = fFormatWidth - result.length() + sub0Start
2177
 
                - ((part == 0)
2178
 
                   ? fPositivePrefix.length() + fPositiveSuffix.length()
2179
 
                   : fNegativePrefix.length() + fNegativeSuffix.length());
2180
 
            while (add > 0) {
2181
 
                result.insert(sub0Start, digit);
2182
 
                ++maxIntDig;
2183
 
                --add;
2184
 
                // Only add a grouping separator if we have at least
2185
 
                // 2 additional characters to be added, so we don't
2186
 
                // end up with ",###".
2187
 
                if (add>1 && isGroupingPosition(maxIntDig)) {
2188
 
                    result.insert(sub0Start, group);
2189
 
                    --add;                        
2190
 
                }
2191
 
            }
2192
 
        }
2193
 
        if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) {
2194
 
            result.append(padSpec);
2195
 
        }
2196
 
        if (part == 0) {
2197
 
            appendAffix(result, fPosSuffixPattern, fPositiveSuffix, localized);
2198
 
            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
2199
 
                result.append(padSpec);
2200
 
            }
2201
 
            UBool isDefault = FALSE;
2202
 
            if ((fNegSuffixPattern == fPosSuffixPattern && // both null
2203
 
                 fNegativeSuffix == fPositiveSuffix)
2204
 
                || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 &&
2205
 
                    *fNegSuffixPattern == *fPosSuffixPattern))
2206
 
            {
2207
 
                if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL)
2208
 
                {
2209
 
                    int32_t length = fPosPrefixPattern->length();
2210
 
                    isDefault = fNegPrefixPattern->length() == (length+2) &&
2211
 
                        (*fNegPrefixPattern)[(int32_t)0] == kQuote &&
2212
 
                        (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus &&
2213
 
                        fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0;
2214
 
                }
2215
 
                if (!isDefault &&
2216
 
                    fNegPrefixPattern == NULL && fPosPrefixPattern == NULL)
2217
 
                {
2218
 
                    int32_t length = fPositivePrefix.length();
2219
 
                    isDefault = fNegativePrefix.length() == (length+1) &&
2220
 
                        fNegativePrefix.compare(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 &&
2221
 
                        fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0;
2222
 
                }
2223
 
            }
2224
 
            if (isDefault) {
2225
 
                break; // Don't output default negative subpattern
2226
 
            } else {
2227
 
                if (localized) {
2228
 
                    result.append(fSymbols->getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
2229
 
                }
2230
 
                else {
2231
 
                    result.append((UChar)kPatternSeparator);
2232
 
                }
2233
 
            }
2234
 
        } else {
2235
 
            appendAffix(result, fNegSuffixPattern, fNegativeSuffix, localized);
2236
 
            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
2237
 
                result.append(padSpec);
2238
 
            }
2239
 
        }
2240
 
    }
2241
 
 
2242
 
    return result;
2243
 
}
2244
 
 
2245
 
//------------------------------------------------------------------------------
2246
 
 
2247
 
void
2248
 
DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
2249
 
{
2250
 
    UParseError parseError;
2251
 
    applyPattern(pattern, FALSE, parseError, status);
2252
 
}
2253
 
 
2254
 
//------------------------------------------------------------------------------
2255
 
 
2256
 
void
2257
 
DecimalFormat::applyPattern(const UnicodeString& pattern,
2258
 
                            UParseError& parseError, 
2259
 
                            UErrorCode& status)
2260
 
{
2261
 
    applyPattern(pattern, FALSE, parseError, status);
2262
 
}
2263
 
//------------------------------------------------------------------------------
2264
 
 
2265
 
void
2266
 
DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
2267
 
{
2268
 
    UParseError parseError;
2269
 
    applyPattern(pattern, TRUE,parseError,status);
2270
 
}
2271
 
 
2272
 
//------------------------------------------------------------------------------
2273
 
 
2274
 
void
2275
 
DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
2276
 
                                     UParseError& parseError,
2277
 
                                     UErrorCode& status)
2278
 
{
2279
 
    applyPattern(pattern, TRUE,parseError,status);
2280
 
}
2281
 
 
2282
 
//------------------------------------------------------------------------------
2283
 
 
2284
 
void
2285
 
DecimalFormat::applyPattern(const UnicodeString& pattern,
2286
 
                            UBool localized,
2287
 
                            UParseError& parseError,
2288
 
                            UErrorCode& status)
2289
 
{
2290
 
    if (U_FAILURE(status))
2291
 
    {
2292
 
        return;
2293
 
    }
2294
 
    // Clear error struct
2295
 
    parseError.offset = -1;
2296
 
    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
2297
 
 
2298
 
    // Set the significant pattern symbols
2299
 
    UChar32 zeroDigit               = kPatternZeroDigit;
2300
 
    UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator);
2301
 
    UnicodeString decimalSeparator  ((UChar)kPatternDecimalSeparator);
2302
 
    UnicodeString percent           ((UChar)kPatternPercent);
2303
 
    UnicodeString perMill           ((UChar)kPatternPerMill);
2304
 
    UnicodeString digit             ((UChar)kPatternDigit);
2305
 
    UnicodeString separator         ((UChar)kPatternSeparator);
2306
 
    UnicodeString exponent          ((UChar)kPatternExponent);
2307
 
    UnicodeString plus              ((UChar)kPatternPlus);
2308
 
    UnicodeString minus             ((UChar)kPatternMinus);
2309
 
    UnicodeString padEscape         ((UChar)kPatternPadEscape);
2310
 
    // Substitute with the localized symbols if necessary
2311
 
    if (localized) {
2312
 
        zeroDigit         = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
2313
 
        groupingSeparator = fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
2314
 
        decimalSeparator  = fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
2315
 
        percent           = fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol);
2316
 
        perMill           = fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol);
2317
 
        digit             = fSymbols->getSymbol(DecimalFormatSymbols::kDigitSymbol);
2318
 
        separator         = fSymbols->getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
2319
 
        exponent          = fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol);
2320
 
        plus              = fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2321
 
        minus             = fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol);
2322
 
        padEscape         = fSymbols->getSymbol(DecimalFormatSymbols::kPadEscapeSymbol);
2323
 
    }
2324
 
    UChar nineDigit = (UChar)(zeroDigit + 9);
2325
 
    int32_t digitLen = digit.length();
2326
 
    int32_t groupSepLen = groupingSeparator.length();
2327
 
    int32_t decimalSepLen = decimalSeparator.length();
2328
 
 
2329
 
    int32_t pos = 0;
2330
 
    int32_t patLen = pattern.length();
2331
 
    // Part 0 is the positive pattern.  Part 1, if present, is the negative
2332
 
    // pattern.
2333
 
    for (int32_t part=0; part<2 && pos<patLen; ++part) {
2334
 
        // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
2335
 
        // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is
2336
 
        // between the prefix and suffix, and consists of pattern
2337
 
        // characters.  In the prefix and suffix, percent, perMill, and
2338
 
        // currency symbols are recognized and translated.
2339
 
        int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
2340
 
 
2341
 
        // It's important that we don't change any fields of this object
2342
 
        // prematurely.  We set the following variables for the multiplier,
2343
 
        // grouping, etc., and then only change the actual object fields if
2344
 
        // everything parses correctly.  This also lets us register
2345
 
        // the data from part 0 and ignore the part 1, except for the
2346
 
        // prefix and suffix.
2347
 
        UnicodeString prefix;
2348
 
        UnicodeString suffix;
2349
 
        int32_t decimalPos = -1;
2350
 
        int32_t multiplier = 1;
2351
 
        int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2352
 
        int8_t groupingCount = -1;
2353
 
        int8_t groupingCount2 = -1;
2354
 
        int32_t padPos = -1;
2355
 
        UnicodeString padChar;
2356
 
        int32_t roundingPos = -1;
2357
 
        DigitList roundingInc;
2358
 
        int8_t expDigits = -1;
2359
 
        UBool expSignAlways = FALSE;
2360
 
        UBool isCurrency = FALSE;
2361
 
        
2362
 
        // The affix is either the prefix or the suffix.
2363
 
        UnicodeString* affix = &prefix;
2364
 
        
2365
 
        int32_t start = pos;
2366
 
        UBool isPartDone = FALSE;
2367
 
        UChar32 ch;
2368
 
 
2369
 
        for (; !isPartDone && pos < patLen; pos += UTF_NEED_MULTIPLE_UCHAR(ch)) {
2370
 
            // Todo: account for surrogate pairs
2371
 
            ch = pattern.char32At(pos);
2372
 
            switch (subpart) {
2373
 
            case 0: // Pattern proper subpart (between prefix & suffix)
2374
 
                // Process the digits, decimal, and grouping characters.  We
2375
 
                // record five pieces of information.  We expect the digits
2376
 
                // to occur in the pattern ####00.00####, and we record the
2377
 
                // number of left digits, zero (central) digits, and right
2378
 
                // digits.  The position of the last grouping character is
2379
 
                // recorded (should be somewhere within the first two blocks
2380
 
                // of characters), as is the position of the decimal point,
2381
 
                // if any (should be in the zero digits).  If there is no
2382
 
                // decimal point, then there should be no right digits.
2383
 
                if (pattern.compare(pos, digitLen, digit) == 0) {
2384
 
                    if (zeroDigitCount > 0) {
2385
 
                        ++digitRightCount;
2386
 
                    } else {
2387
 
                        ++digitLeftCount;
2388
 
                    }
2389
 
                    if (groupingCount >= 0 && decimalPos < 0) {
2390
 
                        ++groupingCount;
2391
 
                    }
2392
 
                    pos += digitLen;
2393
 
                } else if (ch >= zeroDigit && ch <= nineDigit) {
2394
 
                    if (digitRightCount > 0) {
2395
 
                        // Unexpected '0'
2396
 
                        debug("Unexpected '0'")
2397
 
                        status = U_UNEXPECTED_TOKEN;
2398
 
                        syntaxError(pattern,pos,parseError);
2399
 
                        return;
2400
 
                    }
2401
 
                    ++zeroDigitCount;
2402
 
                    if (groupingCount >= 0 && decimalPos < 0) {
2403
 
                        ++groupingCount;
2404
 
                    }
2405
 
                    if (ch != zeroDigit && roundingPos < 0) {
2406
 
                        roundingPos = digitLeftCount + zeroDigitCount;
2407
 
                    }
2408
 
                    if (roundingPos >= 0) {
2409
 
                        roundingInc.append((char)(ch - zeroDigit + '0'));
2410
 
                    }
2411
 
                    pos++;
2412
 
                } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) {
2413
 
                    if (decimalPos >= 0) {
2414
 
                        // Grouping separator after decimal
2415
 
                        debug("Grouping separator after decimal")
2416
 
                        status = U_UNEXPECTED_TOKEN;
2417
 
                        syntaxError(pattern,pos,parseError);
2418
 
                        return;
2419
 
                    }
2420
 
                    groupingCount2 = groupingCount;
2421
 
                    groupingCount = 0;
2422
 
                    pos += groupSepLen;
2423
 
                } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) {
2424
 
                    if (decimalPos >= 0) {
2425
 
                        // Multiple decimal separators
2426
 
                        debug("Multiple decimal separators")
2427
 
                        status = U_MULTIPLE_DECIMAL_SEPERATORS;
2428
 
                        syntaxError(pattern,pos,parseError);
2429
 
                        return;
2430
 
                    }
2431
 
                    // Intentionally incorporate the digitRightCount,
2432
 
                    // even though it is illegal for this to be > 0
2433
 
                    // at this point.  We check pattern syntax below.
2434
 
                    decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
2435
 
                    pos += decimalSepLen;
2436
 
                } else {
2437
 
                    if (pattern.compare(pos, exponent.length(), exponent) == 0) {
2438
 
                        if (expDigits >= 0) {
2439
 
                            // Multiple exponential symbols
2440
 
                            debug("Multiple exponential symbols")
2441
 
                            status = U_MULTIPLE_EXPONENTIAL_SYMBOLS;
2442
 
                            syntaxError(pattern,pos,parseError);
2443
 
                            return;
2444
 
                        }
2445
 
                        if (groupingCount >= 0) {
2446
 
                            // Grouping separator in exponential pattern
2447
 
                            debug("Grouping separator in exponential pattern")
2448
 
                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
2449
 
                            syntaxError(pattern,pos,parseError);
2450
 
                            return;
2451
 
                        }
2452
 
                        // Check for positive prefix
2453
 
                        if ((pos+1) < patLen
2454
 
                            && pattern.compare((int32_t) (pos+1), plus.length(), plus) == 0)
2455
 
                        {
2456
 
                            expSignAlways = TRUE;
2457
 
                            pos += plus.length();
2458
 
                        }
2459
 
                        // Use lookahead to parse out the exponential part of the
2460
 
                        // pattern, then jump into suffix subpart.
2461
 
                        expDigits = 0;
2462
 
                        pos += exponent.length() - 1;
2463
 
                        while (++pos < patLen &&
2464
 
                               pattern[(int32_t) pos] == zeroDigit)
2465
 
                        {
2466
 
                            ++expDigits;
2467
 
                        }
2468
 
 
2469
 
                        if ((digitLeftCount + zeroDigitCount) < 1 ||
2470
 
                            expDigits < 1) {
2471
 
                            // Malformed exponential pattern
2472
 
                            debug("Malformed exponential pattern")
2473
 
                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
2474
 
                            syntaxError(pattern,pos,parseError);
2475
 
                            return;
2476
 
                        }
2477
 
                    }
2478
 
                    // Transition to suffix subpart
2479
 
                    subpart = 2; // suffix subpart
2480
 
                    affix = &suffix;
2481
 
                    sub0Limit = pos;
2482
 
                    continue;
2483
 
                }
2484
 
                break;
2485
 
            case 1: // Prefix subpart
2486
 
            case 2: // Suffix subpart
2487
 
                // Process the prefix / suffix characters
2488
 
                // Process unquoted characters seen in prefix or suffix
2489
 
                // subpart.
2490
 
                if (pattern.compare(pos, digitLen, digit) == 0) {
2491
 
                    // Any of these characters implicitly begins the
2492
 
                    // next subpart if we are in the prefix
2493
 
                    if (subpart == 1) { // prefix subpart
2494
 
                        subpart = 0; // pattern proper subpart
2495
 
                        sub0Start = pos; // Reprocess this character
2496
 
                        continue;
2497
 
                    }
2498
 
                    pos += digitLen;
2499
 
                    // Fall through to append(ch)
2500
 
                } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) {
2501
 
                    // Any of these characters implicitly begins the
2502
 
                    // next subpart if we are in the prefix
2503
 
                    if (subpart == 1) { // prefix subpart
2504
 
                        subpart = 0; // pattern proper subpart
2505
 
                        sub0Start = pos; // Reprocess this character
2506
 
                        continue;
2507
 
                    }
2508
 
                    pos += groupSepLen;
2509
 
                    // Fall through to append(ch)
2510
 
                } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) {
2511
 
                    // Any of these characters implicitly begins the
2512
 
                    // next subpart if we are in the prefix
2513
 
                    if (subpart == 1) { // prefix subpart
2514
 
                        subpart = 0; // pattern proper subpart
2515
 
                        sub0Start = pos; // Reprocess this character
2516
 
                        continue;
2517
 
                    }
2518
 
                    pos += decimalSepLen;
2519
 
                    // Fall through to append(ch)
2520
 
                } else if (ch >= zeroDigit && ch <= nineDigit) {
2521
 
                    // Any of these characters implicitly begins the
2522
 
                    // next subpart if we are in the prefix
2523
 
                    if (subpart == 1) { // prefix subpart
2524
 
                        subpart = 0; // pattern proper subpart
2525
 
                        sub0Start = pos; // Reprocess this character
2526
 
                        continue;
2527
 
                    }
2528
 
                    pos++;
2529
 
                    // Fall through to append(ch)
2530
 
                } else if (ch == kCurrencySign) {
2531
 
                    // Use lookahead to determine if the currency sign is
2532
 
                    // doubled or not.
2533
 
                    pos++;
2534
 
                    affix->append(kQuote); // Encode currency
2535
 
                    if (pos < pattern.length() && pattern[pos] == kCurrencySign)
2536
 
                    {
2537
 
                        affix->append(kCurrencySign);
2538
 
                        ++pos; // Skip over the doubled character
2539
 
                    }
2540
 
                    isCurrency = TRUE;
2541
 
                    // Fall through to append(ch)
2542
 
                } else if (ch == kQuote) {
2543
 
                    // A quote outside quotes indicates either the opening
2544
 
                    // quote or two quotes, which is a quote literal.  That is,
2545
 
                    // we have the first quote in 'do' or o''clock.
2546
 
                    ++pos;
2547
 
                    if (pos < pattern.length() && pattern[pos] == kQuote) {
2548
 
                        affix->append(kQuote); // Encode quote
2549
 
                        ++pos;
2550
 
                        // Fall through to append(ch)
2551
 
                    } else {
2552
 
                        subpart += 2; // open quote
2553
 
                        continue;
2554
 
                    }
2555
 
                } else if (pattern.compare(pos, separator.length(), separator) == 0) {
2556
 
                    // Don't allow separators in the prefix, and don't allow
2557
 
                    // separators in the second pattern (part == 1).
2558
 
                    if (subpart == 1 || part == 1) {
2559
 
                        // Unexpected separator
2560
 
                        debug("Unexpected separator")
2561
 
                        status = U_UNEXPECTED_TOKEN;
2562
 
                        syntaxError(pattern,pos,parseError);
2563
 
                        return;
2564
 
                    }
2565
 
                    sub2Limit = pos;
2566
 
                    isPartDone = TRUE; // Go to next part
2567
 
                    pos += separator.length();
2568
 
                    break;
2569
 
                } else if (pattern.compare(pos, percent.length(), percent) == 0) {
2570
 
                    // Next handle characters which are appended directly.
2571
 
                    if (multiplier != 1) {
2572
 
                        // Too many percent/perMill characters
2573
 
                        debug("Too many percent characters")
2574
 
                        status = U_MULTIPLE_PERCENT_SYMBOLS;
2575
 
                        syntaxError(pattern,pos,parseError);
2576
 
                        return;
2577
 
                    }
2578
 
                    affix->append(kQuote); // Encode percent/perMill
2579
 
                    multiplier = 100;
2580
 
                    ch = kPatternPercent; // Use unlocalized pattern char
2581
 
                    pos += percent.length();
2582
 
                    // Fall through to append(ch)
2583
 
                } else if (pattern.compare(pos, perMill.length(), perMill) == 0) {
2584
 
                    // Next handle characters which are appended directly.
2585
 
                    if (multiplier != 1) {
2586
 
                        // Too many percent/perMill characters
2587
 
                        debug("Too many perMill characters")
2588
 
                        status = U_MULTIPLE_PERMILL_SYMBOLS;
2589
 
                        syntaxError(pattern,pos,parseError);
2590
 
                        return;
2591
 
                    }
2592
 
                    affix->append(kQuote); // Encode percent/perMill
2593
 
                    multiplier = 1000;
2594
 
                    ch = kPatternPerMill; // Use unlocalized pattern char
2595
 
                    pos += perMill.length();
2596
 
                    // Fall through to append(ch)
2597
 
                } else if (pattern.compare(pos, padEscape.length(), padEscape) == 0) {
2598
 
                    if (padPos >= 0 ||               // Multiple pad specifiers
2599
 
                        (pos+1) == pattern.length()) { // Nothing after padEscape
2600
 
                        debug("Multiple pad specifiers")
2601
 
                        status = U_MULTIPLE_PAD_SPECIFIERS;
2602
 
                        syntaxError(pattern,pos,parseError);
2603
 
                        return;
2604
 
                    }
2605
 
                    padPos = pos;
2606
 
                    padChar = pattern.char32At(++pos);
2607
 
                    pos += 1 + UTF_NEED_MULTIPLE_UCHAR(pattern.char32At(pos));
2608
 
//                    pos += padEscape.length();
2609
 
                    continue;
2610
 
                } else if (pattern.compare(pos, minus.length(), minus) == 0) {
2611
 
                    affix->append(kQuote); // Encode minus
2612
 
                    ch = kPatternMinus;
2613
 
                    pos += minus.length();
2614
 
                    // Fall through to append(ch)
2615
 
                } else if (pattern.compare(pos, plus.length(), plus) == 0) {
2616
 
                    affix->append(kQuote); // Encode plus
2617
 
                    ch = kPatternPlus;
2618
 
                    pos += plus.length();
2619
 
                    // Fall through to append(ch)
2620
 
                } else {
2621
 
                    pos++;
2622
 
                }
2623
 
                // Unquoted, non-special characters fall through to here, as
2624
 
                // well as other code which needs to append something to the
2625
 
                // affix.
2626
 
                affix->append(ch);
2627
 
                break;
2628
 
            case 3: // Prefix subpart, in quote
2629
 
            case 4: // Suffix subpart, in quote
2630
 
                // A quote within quotes indicates either the closing
2631
 
                // quote or two quotes, which is a quote literal.  That is,
2632
 
                // we have the second quote in 'do' or 'don''t'.
2633
 
                pos++;
2634
 
                if (ch == kQuote) {
2635
 
                    if (pos < pattern.length() && pattern[pos] == kQuote) {
2636
 
                        ++pos;
2637
 
                        affix->append(kQuote); // Encode quote
2638
 
                        // Fall through to append(ch)
2639
 
                    } else {
2640
 
                        subpart -= 2; // close quote
2641
 
                        continue;
2642
 
                    }
2643
 
                }
2644
 
                affix->append(ch);
2645
 
                break;
2646
 
            }
2647
 
        }
2648
 
 
2649
 
        if (sub0Limit == 0) {
2650
 
            sub0Limit = pattern.length();
2651
 
        }
2652
 
 
2653
 
        if (sub2Limit == 0) {
2654
 
            sub2Limit = pattern.length();
2655
 
        }
2656
 
 
2657
 
        /* Handle patterns with no '0' pattern character.  These patterns
2658
 
         * are legal, but must be recodified to make sense.  "##.###" ->
2659
 
         * "#0.###".  ".###" -> ".0##".
2660
 
         *
2661
 
         * We allow patterns of the form "####" to produce a zeroDigitCount
2662
 
         * of zero (got that?); although this seems like it might make it
2663
 
         * possible for format() to produce empty strings, format() checks
2664
 
         * for this condition and outputs a zero digit in this situation.
2665
 
         * Having a zeroDigitCount of zero yields a minimum integer digits
2666
 
         * of zero, which allows proper round-trip patterns.  We don't want
2667
 
         * "#" to become "#0" when toPattern() is called (even though that's
2668
 
         * what it really is, semantically).
2669
 
         */
2670
 
        if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
2671
 
            // Handle "###.###" and "###." and ".###"
2672
 
            int n = decimalPos;
2673
 
            if (n == 0)
2674
 
                ++n; // Handle ".###"
2675
 
            digitRightCount = digitLeftCount - n;
2676
 
            digitLeftCount = n - 1;
2677
 
            zeroDigitCount = 1;
2678
 
        }
2679
 
 
2680
 
        // Do syntax checking on the digits, decimal points, and quotes.
2681
 
        if ((decimalPos < 0 && digitRightCount > 0) ||
2682
 
            (decimalPos >= 0 &&
2683
 
             (decimalPos < digitLeftCount ||
2684
 
              decimalPos > (digitLeftCount + zeroDigitCount))) ||
2685
 
            groupingCount == 0 || groupingCount2 == 0 ||
2686
 
            subpart > 2)
2687
 
        { // subpart > 2 == unmatched quote
2688
 
            debug("Syntax error")
2689
 
            status = U_PATTERN_SYNTAX_ERROR;
2690
 
            syntaxError(pattern,pos,parseError);
2691
 
            return;
2692
 
        }
2693
 
 
2694
 
        // Make sure pad is at legal position before or after affix.
2695
 
        if (padPos >= 0) {
2696
 
            if (padPos == start) {
2697
 
                padPos = kPadBeforePrefix;
2698
 
            } else if (padPos+2 == sub0Start) {
2699
 
                padPos = kPadAfterPrefix;
2700
 
            } else if (padPos == sub0Limit) {
2701
 
                padPos = kPadBeforeSuffix;
2702
 
            } else if (padPos+2 == sub2Limit) {
2703
 
                padPos = kPadAfterSuffix;
2704
 
            } else {
2705
 
                // Illegal pad position
2706
 
                debug("Illegal pad position")
2707
 
                status = U_ILLEGAL_PAD_POSITION;
2708
 
                syntaxError(pattern,pos,parseError);
2709
 
                return;
2710
 
            }
2711
 
        }
2712
 
 
2713
 
        if (part == 0) {
2714
 
            delete fPosPrefixPattern;
2715
 
            delete fPosSuffixPattern;
2716
 
            delete fNegPrefixPattern;
2717
 
            delete fNegSuffixPattern;
2718
 
            fPosPrefixPattern = new UnicodeString(prefix);
2719
 
            fPosSuffixPattern = new UnicodeString(suffix);
2720
 
            fNegPrefixPattern = 0;
2721
 
            fNegSuffixPattern = 0;
2722
 
 
2723
 
            fUseExponentialNotation = (expDigits >= 0);
2724
 
            if (fUseExponentialNotation) {
2725
 
                fMinExponentDigits = expDigits;
2726
 
            }
2727
 
            fExponentSignAlwaysShown = expSignAlways;
2728
 
            fIsCurrencyFormat = isCurrency;
2729
 
            int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
2730
 
            // The effectiveDecimalPos is the position the decimal is at or
2731
 
            // would be at if there is no decimal.  Note that if
2732
 
            // decimalPos<0, then digitTotalCount == digitLeftCount +
2733
 
            // zeroDigitCount.
2734
 
            int effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
2735
 
            setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
2736
 
            setMaximumIntegerDigits(fUseExponentialNotation
2737
 
                    ? digitLeftCount + getMinimumIntegerDigits()
2738
 
                    : kDoubleIntegerDigits);
2739
 
            setMaximumFractionDigits(decimalPos >= 0
2740
 
                    ? (digitTotalCount - decimalPos) : 0);
2741
 
            setMinimumFractionDigits(decimalPos >= 0
2742
 
                    ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
2743
 
            setGroupingUsed(groupingCount > 0);
2744
 
            fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
2745
 
            fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
2746
 
                ? groupingCount2 : 0;
2747
 
            fMultiplier = multiplier;
2748
 
            setDecimalSeparatorAlwaysShown(decimalPos == 0
2749
 
                    || decimalPos == digitTotalCount);
2750
 
            if (padPos >= 0) {
2751
 
                fPadPosition = (EPadPosition) padPos;
2752
 
                // To compute the format width, first set up sub0Limit -
2753
 
                // sub0Start.  Add in prefix/suffix length later.
2754
 
 
2755
 
                // fFormatWidth = prefix.length() + suffix.length() +
2756
 
                //    sub0Limit - sub0Start;
2757
 
                fFormatWidth = sub0Limit - sub0Start;
2758
 
                fPad = padChar;
2759
 
            } else {
2760
 
                fFormatWidth = 0;
2761
 
            }
2762
 
            if (roundingPos >= 0) {
2763
 
                roundingInc.fDecimalAt = effectiveDecimalPos - roundingPos;
2764
 
                if (fRoundingIncrement != NULL) {
2765
 
                    *fRoundingIncrement = roundingInc;
2766
 
                } else {
2767
 
                    fRoundingIncrement = new DigitList(roundingInc);
2768
 
                }
2769
 
                fRoundingDouble = fRoundingIncrement->getDouble();
2770
 
                fRoundingMode = kRoundHalfEven;
2771
 
            } else {
2772
 
                setRoundingIncrement(0.0);
2773
 
            }
2774
 
        } else {
2775
 
            fNegPrefixPattern = new UnicodeString(prefix);
2776
 
            fNegSuffixPattern = new UnicodeString(suffix);
2777
 
        }
2778
 
    }
2779
 
 
2780
 
    if (pattern.length() == 0) {
2781
 
        delete fNegPrefixPattern;
2782
 
        delete fNegSuffixPattern;
2783
 
        fNegPrefixPattern = NULL;
2784
 
        fNegSuffixPattern = NULL;
2785
 
        if (fPosPrefixPattern != NULL) {
2786
 
            fPosPrefixPattern->remove();
2787
 
        } else {
2788
 
            fPosPrefixPattern = new UnicodeString();
2789
 
        }
2790
 
        if (fPosSuffixPattern != NULL) {
2791
 
            fPosSuffixPattern->remove();
2792
 
        } else {
2793
 
            fPosSuffixPattern = new UnicodeString();
2794
 
        }
2795
 
 
2796
 
        setMinimumIntegerDigits(0);
2797
 
        setMaximumIntegerDigits(kDoubleIntegerDigits);
2798
 
        setMinimumFractionDigits(0);
2799
 
        setMaximumFractionDigits(kDoubleFractionDigits);
2800
 
 
2801
 
        fUseExponentialNotation = FALSE;
2802
 
        fIsCurrencyFormat = FALSE;
2803
 
        setGroupingUsed(FALSE);
2804
 
        fGroupingSize = 0;
2805
 
        fGroupingSize2 = 0;
2806
 
        fMultiplier = 1;
2807
 
        setDecimalSeparatorAlwaysShown(FALSE);
2808
 
        fFormatWidth = 0;
2809
 
        setRoundingIncrement(0.0);
2810
 
    }
2811
 
 
2812
 
    // If there was no negative pattern, or if the negative pattern is
2813
 
    // identical to the positive pattern, then prepend the minus sign to the
2814
 
    // positive pattern to form the negative pattern.
2815
 
    if (fNegPrefixPattern == NULL ||
2816
 
        (*fNegPrefixPattern == *fPosPrefixPattern
2817
 
         && *fNegSuffixPattern == *fPosSuffixPattern)) {
2818
 
        _copy_us_ptr(&fNegSuffixPattern, fPosSuffixPattern);
2819
 
        if (fNegPrefixPattern == NULL) {
2820
 
            fNegPrefixPattern = new UnicodeString();
2821
 
        } else {
2822
 
            fNegPrefixPattern->remove();
2823
 
        }
2824
 
        fNegPrefixPattern->append(kQuote).append(kPatternMinus)
2825
 
            .append(*fPosPrefixPattern);
2826
 
    }
2827
 
#ifdef FMT_DEBUG
2828
 
    UnicodeString s;
2829
 
    s.append("\"").append(pattern).append("\"->");
2830
 
    debugout(s);
2831
 
#endif
2832
 
    expandAffixes();
2833
 
    if (fFormatWidth > 0) {
2834
 
        // Finish computing format width (see above)
2835
 
        fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length();
2836
 
    }
2837
 
}
2838
 
 
2839
 
/**
2840
 
 * Sets the maximum number of digits allowed in the integer portion of a
2841
 
 * number. This override limits the integer digit count to 309.
2842
 
 * @see NumberFormat#setMaximumIntegerDigits
2843
 
 */
2844
 
void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
2845
 
    NumberFormat::setMaximumIntegerDigits(uprv_min(newValue, kDoubleIntegerDigits));
2846
 
}
2847
 
 
2848
 
/**
2849
 
 * Sets the minimum number of digits allowed in the integer portion of a
2850
 
 * number. This override limits the integer digit count to 309.
2851
 
 * @see NumberFormat#setMinimumIntegerDigits
2852
 
 */
2853
 
void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
2854
 
    NumberFormat::setMinimumIntegerDigits(uprv_min(newValue, kDoubleIntegerDigits));
2855
 
}
2856
 
 
2857
 
/**
2858
 
 * Sets the maximum number of digits allowed in the fraction portion of a
2859
 
 * number. This override limits the fraction digit count to 340.
2860
 
 * @see NumberFormat#setMaximumFractionDigits
2861
 
 */
2862
 
void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
2863
 
    NumberFormat::setMaximumFractionDigits(uprv_min(newValue, kDoubleFractionDigits));
2864
 
}
2865
 
 
2866
 
/**
2867
 
 * Sets the minimum number of digits allowed in the fraction portion of a
2868
 
 * number. This override limits the fraction digit count to 340.
2869
 
 * @see NumberFormat#setMinimumFractionDigits
2870
 
 */
2871
 
void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
2872
 
    NumberFormat::setMinimumFractionDigits(uprv_min(newValue, kDoubleFractionDigits));
2873
 
}
2874
 
 
2875
 
U_NAMESPACE_END
2876
 
 
2877
 
//eof