1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 1997-2009, International Business Machines Corporation and    *
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* others. All Rights Reserved.                                                *
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File CHOICFMT.CPP
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History:
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Date        Name        Description
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   02/19/97    aliu        Converted from java.
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   03/20/97    helena      Finished first cut of implementation and got rid
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*                           of nextDouble/previousDouble and replaced with
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*                           boolean array.
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   4/10/97     aliu        Clean up.  Modified to work on AIX.
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   06/04/97    helena      Fixed applyPattern(), toPattern() and not to include
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*                           wchar.h.
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   07/09/97    helena      Made ParsePosition into a class.
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   08/06/97    nos         removed overloaded constructor, fixed 'format(array)'
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   07/22/98    stephen     JDK 1.2 Sync - removed UBool array (doubleFlags)
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   02/22/99    stephen     Removed character literals for EBCDIC safety
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************************
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/choicfmt.h"
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/numfmt.h"
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/locid.h"
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cpputils.h"
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h"
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "putilimp.h"
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <float.h>
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// *****************************************************************************
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// class ChoiceFormat
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// *****************************************************************************
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ChoiceFormat)
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Special characters used by ChoiceFormat.  There are two characters
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// used interchangeably to indicate <=.  Either is parsed, but only
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// LESS_EQUAL is generated by toPattern().
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SINGLE_QUOTE ((UChar)0x0027)   /*'*/
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LESS_THAN    ((UChar)0x003C)   /*<*/
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LESS_EQUAL   ((UChar)0x0023)   /*#*/
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LESS_EQUAL2  ((UChar)0x2264)
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define VERTICAL_BAR ((UChar)0x007C)   /*|*/
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MINUS        ((UChar)0x002D)   /*-*/
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef INFINITY
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#undef INFINITY
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define INFINITY     ((UChar)0x221E)
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gPositiveInfinity[] = {INFINITY, 0};
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gNegativeInfinity[] = {MINUS, INFINITY, 0};
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define POSITIVE_INF_STRLEN 1
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define NEGATIVE_INF_STRLEN 2
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Creates a ChoiceFormat instance based on the pattern.
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::ChoiceFormat(const UnicodeString& newPattern,
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UErrorCode& status)
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fChoiceLimits(0),
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fClosures(0),
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fChoiceFormats(0),
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fCount(0)
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    applyPattern(newPattern, status);
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Creates a ChoiceFormat instance with the limit array and
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// format strings for each limit.
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::ChoiceFormat(const double* limits,
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           const UnicodeString* formats,
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           int32_t cnt )
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fChoiceLimits(0),
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fClosures(0),
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fChoiceFormats(0),
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fCount(0)
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    setChoices(limits, formats, cnt );
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::ChoiceFormat(const double* limits,
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           const UBool* closures,
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           const UnicodeString* formats,
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           int32_t cnt )
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fChoiceLimits(0),
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fClosures(0),
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fChoiceFormats(0),
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fCount(0)
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    setChoices(limits, closures, formats, cnt );
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// copy constructor
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::ChoiceFormat(const    ChoiceFormat&   that)
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): NumberFormat(that),
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fChoiceLimits(0),
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fClosures(0),
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fChoiceFormats(0)
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    *this = that;
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Private constructor that creates a
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ChoiceFormat instance based on the
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// pattern and populates UParseError
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::ChoiceFormat(const UnicodeString& newPattern,
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UParseError& parseError,
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UErrorCode& status)
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fChoiceLimits(0),
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fClosures(0),
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fChoiceFormats(0),
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fCount(0)
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    applyPattern(newPattern,parseError, status);
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::operator==(const Format& that) const
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (this == &that) return TRUE;
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (!NumberFormat::operator==(that)) return FALSE;
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ChoiceFormat& thatAlias = (ChoiceFormat&)that;
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fCount != thatAlias.fCount) return FALSE;
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Checks the limits, the corresponding format string and LE or LT flags.
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // LE means less than and equal to, LT means less than.
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int32_t i = 0; i < fCount; i++) {
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if ((fChoiceLimits[i] != thatAlias.fChoiceLimits[i]) ||
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            (fClosures[i] != thatAlias.fClosures[i]) ||
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            (fChoiceFormats[i] != thatAlias.fChoiceFormats[i]))
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return FALSE;
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return TRUE;
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// copy constructor
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ChoiceFormat&
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::operator=(const   ChoiceFormat& that)
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (this != &that) {
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        NumberFormat::operator=(that);
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCount = that.fCount;
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(fChoiceLimits);
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fChoiceLimits = NULL;
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(fClosures);
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fClosures = NULL;
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete [] fChoiceFormats;
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fChoiceFormats = NULL;
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fChoiceLimits = (double*) uprv_malloc( sizeof(double) * fCount);
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fClosures = (UBool*) uprv_malloc( sizeof(UBool) * fCount);
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fChoiceFormats = new UnicodeString[fCount];
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // check for memory allocation error
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!fChoiceLimits || !fClosures || !fChoiceFormats) {
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (fChoiceLimits) {
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uprv_free(fChoiceLimits);
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fChoiceLimits = NULL;
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (fClosures) {
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uprv_free(fClosures);
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fClosures = NULL;
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (fChoiceFormats) {
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                delete[] fChoiceFormats;
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fChoiceFormats = NULL;
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_arrayCopy(that.fChoiceLimits, fChoiceLimits, fCount);
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_arrayCopy(that.fClosures, fClosures, fCount);
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_arrayCopy(that.fChoiceFormats, fChoiceFormats, fCount);
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return *this;
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::~ChoiceFormat()
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(fChoiceLimits);
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fChoiceLimits = NULL;
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(fClosures);
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fClosures = NULL;
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete [] fChoiceFormats;
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fChoiceFormats = NULL;
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fCount = 0;
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Convert a string to a double value
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)double
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::stod(const UnicodeString& string)
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char source[256];
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char* end;
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    string.extract(0, string.length(), source, (int32_t)sizeof(source), US_INV);    /* invariant codepage */
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return uprv_strtod(source,&end);
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Convert a double value to a string without the overhead of ICU.
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::dtos(double value,
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   UnicodeString& string)
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Buffer to contain the digits and any extra formatting stuff. */
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char temp[DBL_DIG + 16];
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *itrPtr = temp;
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *expPtr;
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sprintf(temp, "%.*g", DBL_DIG, value);
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Find and convert the decimal point.
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)       Using setlocale on some machines will cause sprintf to use a comma for certain locales.
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    */
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (*itrPtr && (*itrPtr == '-' || isdigit(*itrPtr))) {
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        itrPtr++;
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (*itrPtr != 0 && *itrPtr != 'e') {
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* We reached something that looks like a decimal point.
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        In case someone used setlocale(), which changes the decimal point. */
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *itrPtr = '.';
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        itrPtr++;
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Search for the exponent */
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (*itrPtr && *itrPtr != 'e') {
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        itrPtr++;
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (*itrPtr == 'e') {
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        itrPtr++;
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Verify the exponent sign */
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (*itrPtr == '+' || *itrPtr == '-') {
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            itrPtr++;
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Remove leading zeros. You will see this on Windows machines. */
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        expPtr = itrPtr;
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while (*itrPtr == '0') {
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            itrPtr++;
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (*itrPtr && expPtr != itrPtr) {
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* Shift the exponent without zeros. */
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            while (*itrPtr) {
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *(expPtr++)  = *(itrPtr++);
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // NULL terminate
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            *expPtr = 0;
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    string = UnicodeString(temp, -1, US_INV);    /* invariant codepage */
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return string;
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// calls the overloaded applyPattern method.
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::applyPattern(const UnicodeString& pattern,
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UErrorCode& status)
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UParseError parseError;
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    applyPattern(pattern, parseError, status);
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Applies the pattern to this ChoiceFormat instance.
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::applyPattern(const UnicodeString& pattern,
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UParseError& parseError,
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UErrorCode& status)
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status))
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Clear error struct
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    parseError.offset = -1;
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Perform 2 passes.  The first computes the number of limits in
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // this pattern (fCount), which is 1 more than the number of
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // literal VERTICAL_BAR characters.
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t count = 1;
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i;
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (i=0; i<pattern.length(); ++i) {
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar c = pattern[i];
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (c == SINGLE_QUOTE) {
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Skip over the entire quote, including embedded
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // contiguous pairs of SINGLE_QUOTE.
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for (;;) {
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                do {
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++i;
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } while (i<pattern.length() &&
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         pattern[i] != SINGLE_QUOTE);
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if ((i+1)<pattern.length() &&
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    pattern[i+1] == SINGLE_QUOTE) {
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // SINGLE_QUOTE pair; skip over it
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++i;
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else {
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (c == VERTICAL_BAR) {
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++count;
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Allocate the required storage.
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    double *newLimits = (double*) uprv_malloc( sizeof(double) * count);
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* test for NULL */
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (newLimits == 0) {
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_MEMORY_ALLOCATION_ERROR;
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool *newClosures = (UBool*) uprv_malloc( sizeof(UBool) * count);
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* test for NULL */
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (newClosures == 0) {
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_MEMORY_ALLOCATION_ERROR;
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(newLimits);
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString *newFormats = new UnicodeString[count];
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* test for NULL */
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (newFormats == 0) {
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_MEMORY_ALLOCATION_ERROR;
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(newLimits);
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(newClosures);
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Perform the second pass
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t k = 0; // index into newXxx[] arrays
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString buf; // scratch buffer
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool inQuote = FALSE;
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool inNumber = TRUE; // TRUE before < or #, FALSE after
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (i=0; i<pattern.length(); ++i) {
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar c = pattern[i];
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (c == SINGLE_QUOTE) {
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Check for SINGLE_QUOTE pair indicating a literal quote
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((i+1) < pattern.length() &&
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pattern[i+1] == SINGLE_QUOTE) {
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                buf += SINGLE_QUOTE;
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++i;
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                inQuote = !inQuote;
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (inQuote) {
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            buf += c;
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (c == LESS_THAN || c == LESS_EQUAL || c == LESS_EQUAL2) {
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (!inNumber || buf.length() == 0) {
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                goto error;
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            inNumber = FALSE;
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            double limit;
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            buf.trim();
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (!buf.compare(gPositiveInfinity, POSITIVE_INF_STRLEN)) {
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                limit = uprv_getInfinity();
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (!buf.compare(gNegativeInfinity, NEGATIVE_INF_STRLEN)) {
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                limit = -uprv_getInfinity();
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                limit = stod(buf);
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (k == count) {
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // This shouldn't happen.  If it does, it means that
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // the count determined in the first pass did not
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // match the number of elements found in the second
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // pass.
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                goto error;
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            newLimits[k] = limit;
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            newClosures[k] = (c == LESS_THAN);
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (k > 0 && limit <= newLimits[k-1]) {
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Each limit must be strictly > than the previous
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // limit.  One exception: Two subsequent limits may be
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // == if the first closure is FALSE and the second
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // closure is TRUE.  This places the limit value in
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // the second interval.
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (!(limit == newLimits[k-1] &&
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      !newClosures[k-1] &&
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      newClosures[k])) {
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    goto error;
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            buf.truncate(0);
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (c == VERTICAL_BAR) {
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (inNumber) {
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                goto error;
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            inNumber = TRUE;
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            newFormats[k] = buf;
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++k;
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            buf.truncate(0);
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            buf += c;
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (k != (count-1) || inNumber || inQuote) {
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        goto error;
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newFormats[k] = buf;
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Don't modify this object until the parse succeeds
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(fChoiceLimits);
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(fClosures);
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete[] fChoiceFormats;
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fCount = count;
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fChoiceLimits  = newLimits;
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fClosures      = newClosures;
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fChoiceFormats = newFormats;
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return;
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)error:
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    status = U_ILLEGAL_ARGUMENT_ERROR;
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    syntaxError(pattern,i,parseError);
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(newLimits);
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(newClosures);
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete[] newFormats;
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return;
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Reconstruct the original input pattern.
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::toPattern(UnicodeString& result) const
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    result.remove();
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int32_t i = 0; i < fCount; ++i) {
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (i != 0) {
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += VERTICAL_BAR;
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString buf;
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (uprv_isPositiveInfinity(fChoiceLimits[i])) {
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += INFINITY;
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (uprv_isNegativeInfinity(fChoiceLimits[i])) {
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += MINUS;
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += INFINITY;
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += dtos(fChoiceLimits[i], buf);
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fClosures[i]) {
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += LESS_THAN;
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += LESS_EQUAL;
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Append fChoiceFormats[i], using quotes if there are special
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // characters.  Single quotes themselves must be escaped in
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // either case.
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const UnicodeString& text = fChoiceFormats[i];
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UBool needQuote = text.indexOf(LESS_THAN) >= 0
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            || text.indexOf(LESS_EQUAL) >= 0
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            || text.indexOf(LESS_EQUAL2) >= 0
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            || text.indexOf(VERTICAL_BAR) >= 0;
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (needQuote) {
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += SINGLE_QUOTE;
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (text.indexOf(SINGLE_QUOTE) < 0) {
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += text;
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for (int32_t j = 0; j < text.length(); ++j) {
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                UChar c = text[j];
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                result += c;
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (c == SINGLE_QUOTE) {
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    result += c;
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (needQuote) {
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result += SINGLE_QUOTE;
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return result;
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Sets the limit and format arrays.
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::setChoices(  const double* limits,
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           const UnicodeString* formats,
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           int32_t cnt )
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    setChoices(limits, 0, formats, cnt);
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Sets the limit and format arrays.
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::setChoices(  const double* limits,
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           const UBool* closures,
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           const UnicodeString* formats,
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           int32_t cnt )
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(limits == 0 || formats == 0)
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fChoiceLimits) {
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(fChoiceLimits);
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fClosures) {
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(fClosures);
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fChoiceFormats) {
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete [] fChoiceFormats;
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Note that the old arrays are deleted and this owns
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the created array.
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fCount = cnt;
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fChoiceLimits = (double*) uprv_malloc( sizeof(double) * fCount);
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fClosures = (UBool*) uprv_malloc( sizeof(UBool) * fCount);
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fChoiceFormats = new UnicodeString[fCount];
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //check for memory allocation error
553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (!fChoiceLimits || !fClosures || !fChoiceFormats) {
554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fChoiceLimits) {
555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_free(fChoiceLimits);
556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fChoiceLimits = NULL;
557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fClosures) {
559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_free(fClosures);
560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fClosures = NULL;
561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fChoiceFormats) {
563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            delete[] fChoiceFormats;
564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fChoiceFormats = NULL;
565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_arrayCopy(limits, fChoiceLimits, fCount);
570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_arrayCopy(formats, fChoiceFormats, fCount);
571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (closures != 0) {
573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_arrayCopy(closures, fClosures, fCount);
574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t i;
576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (i=0; i<fCount; ++i) {
577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fClosures[i] = FALSE;
578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Gets the limit array.
584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const double*
586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::getLimits(int32_t& cnt) const
587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cnt = fCount;
589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fChoiceLimits;
590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Gets the closures array.
594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UBool*
596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::getClosures(int32_t& cnt) const
597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cnt = fCount;
599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fClosures;
600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Gets the format array.
604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UnicodeString*
606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::getFormats(int32_t& cnt) const
607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cnt = fCount;
609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fChoiceFormats;
610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Formats an int64 number, it's actually formatted as
614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// a double.  The returned format string may differ
615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// from the input number because of this.
616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::format(int64_t number,
619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UnicodeString& appendTo,
620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     FieldPosition& status) const
621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return format((double) number, appendTo, status);
623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Formats a long number, it's actually formatted as
627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// a double.  The returned format string may differ
628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// from the input number because of this.
629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::format(int32_t number,
632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UnicodeString& appendTo,
633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     FieldPosition& status) const
634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return format((double) number, appendTo, status);
636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Formats a double number.
640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::format(double number,
643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UnicodeString& appendTo,
644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     FieldPosition& /*pos*/) const
645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // find the number
647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i;
648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (i = 0; i < fCount; ++i) {
649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fClosures[i]) {
650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (!(number > fChoiceLimits[i])) {
651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // same as number <= fChoiceLimits, except catches NaN
652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (!(number >= fChoiceLimits[i])) {
655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // same as number < fChoiceLimits, except catches NaN
656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    --i;
660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (i < 0) {
661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        i = 0;
662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // return either a formatted number, or a string
664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    appendTo += fChoiceFormats[i];
665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return appendTo;
666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Formats an array of objects. Checks if the data type of the objects
670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// to get the right value for formatting.
671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::format(const Formattable* objs,
674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     int32_t cnt,
675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UnicodeString& appendTo,
676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     FieldPosition& pos,
677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UErrorCode& status) const
678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(cnt < 0) {
680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_ILLEGAL_ARGUMENT_ERROR;
681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return appendTo;
682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString buffer;
685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int32_t i = 0; i < cnt; i++) {
686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        double objDouble = objs[i].getDouble(status);
687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_SUCCESS(status)) {
688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            buffer.remove();
689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            appendTo += format(objDouble, buffer, pos);
690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return appendTo;
694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Formats an array of objects. Checks if the data type of the objects
698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// to get the right value for formatting.
699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::format(const Formattable& obj,
702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UnicodeString& appendTo,
703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     FieldPosition& pos,
704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UErrorCode& status) const
705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return NumberFormat::format(obj, appendTo, pos, status);
707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::parse(const UnicodeString& text,
712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    Formattable& result,
713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ParsePosition& status) const
714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // find the best number (defined as the one with the longest parse)
716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t start = status.getIndex();
717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t furthest = start;
718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    double bestNumber = uprv_getNaN();
719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    double tempNumber = 0.0;
720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int i = 0; i < fCount; ++i) {
721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t len = fChoiceFormats[i].length();
722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (text.compare(start, len, fChoiceFormats[i]) == 0) {
723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status.setIndex(start + len);
724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            tempNumber = fChoiceLimits[i];
725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (status.getIndex() > furthest) {
726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                furthest = status.getIndex();
727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                bestNumber = tempNumber;
728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (furthest == text.length())
729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    status.setIndex(furthest);
734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (status.getIndex() == start) {
735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status.setErrorIndex(furthest);
736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    result.setDouble(bestNumber);
738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Parses the text and return the Formattable object.
742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::parse(const UnicodeString& text,
745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    Formattable& result,
746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    UErrorCode& status) const
747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    NumberFormat::parse(text, result, status);
749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------
752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Format*
754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ChoiceFormat::clone() const
755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ChoiceFormat *aCopy = new ChoiceFormat(*this);
757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return aCopy;
758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END
761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */
763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//eof
765