4 // Copyright (C) 20098, International Business Machines Corporation and others.
5 // All Rights Reserved.
7 // This file contains the class DecimalFormatStaticSets
9 // DecimalFormatStaticSets holds the UnicodeSets that are needed for lenient
10 // parsing of decimal and group separators.
12 #include "unicode/utypes.h"
14 #if !UCONFIG_NO_FORMATTING
16 #include "unicode/unistr.h"
17 #include "unicode/uniset.h"
18 #include "unicode/uchar.h"
30 //------------------------------------------------------------------------------
32 // Unicode Set pattern strings for all of the required constant sets.
33 // Initialized with hex values for portability to EBCDIC based machines.
34 // Really ugly, but there's no good way to avoid it.
36 //------------------------------------------------------------------------------
38 static const UChar gDotEquivalentsPattern
[] = {
39 // [ . \u2024 \u3002 \uFE12 \uFE52 \uFF0E \uFF61 ]
40 0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
42 static const UChar gCommaEquivalentsPattern
[] = {
43 // [ , \u060C \u066B \u3001 \uFE10 \uFE11 \uFE50 \uFE51 \uFF0C \uFF64 ]
44 0x005B, 0x002C, 0x060C, 0x066B, 0x3001, 0xFE10, 0xFE11, 0xFE50, 0xFE51, 0xFF0C, 0xFF64, 0x005D, 0x0000};
46 static const UChar gOtherGroupingSeparatorsPattern
[] = {
47 // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ]
48 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
50 static const UChar gDashEquivalentsPattern
[] = {
51 // [ \ - HYPHEN F_DASH N_DASH MINUS ]
52 0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
54 static const UChar gStrictDotEquivalentsPattern
[] = {
55 // [ . \u2024 \uFE52 \uFF0E \uFF61 ]
56 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
58 static const UChar gStrictCommaEquivalentsPattern
[] = {
59 // [ , \u066B \uFE10 \uFE50 \uFF0C ]
60 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
62 static const UChar gStrictOtherGroupingSeparatorsPattern
[] = {
63 // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ]
64 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
66 static const UChar gStrictDashEquivalentsPattern
[] = {
68 0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
71 DecimalFormatStaticSets
*DecimalFormatStaticSets::gStaticSets
= NULL
;
73 DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode
*status
)
74 : fDotEquivalents(NULL
),
75 fCommaEquivalents(NULL
),
76 fOtherGroupingSeparators(NULL
),
77 fDashEquivalents(NULL
),
78 fStrictDotEquivalents(NULL
),
79 fStrictCommaEquivalents(NULL
),
80 fStrictOtherGroupingSeparators(NULL
),
81 fStrictDashEquivalents(NULL
),
82 fDefaultGroupingSeparators(NULL
),
83 fStrictDefaultGroupingSeparators(NULL
)
85 fDotEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gDotEquivalentsPattern
, -1), *status
);
86 fCommaEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gCommaEquivalentsPattern
, -1), *status
);
87 fOtherGroupingSeparators
= new UnicodeSet(UnicodeString(TRUE
, gOtherGroupingSeparatorsPattern
, -1), *status
);
88 fDashEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gDashEquivalentsPattern
, -1), *status
);
90 fStrictDotEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gStrictDotEquivalentsPattern
, -1), *status
);
91 fStrictCommaEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gStrictCommaEquivalentsPattern
, -1), *status
);
92 fStrictOtherGroupingSeparators
= new UnicodeSet(UnicodeString(TRUE
, gStrictOtherGroupingSeparatorsPattern
, -1), *status
);
93 fStrictDashEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gStrictDashEquivalentsPattern
, -1), *status
);
96 fDefaultGroupingSeparators
= new UnicodeSet(*fDotEquivalents
);
97 fDefaultGroupingSeparators
->addAll(*fCommaEquivalents
);
98 fDefaultGroupingSeparators
->addAll(*fOtherGroupingSeparators
);
100 fStrictDefaultGroupingSeparators
= new UnicodeSet(*fStrictDotEquivalents
);
101 fStrictDefaultGroupingSeparators
->addAll(*fStrictCommaEquivalents
);
102 fStrictDefaultGroupingSeparators
->addAll(*fStrictOtherGroupingSeparators
);
104 // Check for null pointers
105 if (fDotEquivalents
== NULL
|| fCommaEquivalents
== NULL
|| fOtherGroupingSeparators
== NULL
|| fDashEquivalents
== NULL
||
106 fStrictDotEquivalents
== NULL
|| fStrictCommaEquivalents
== NULL
|| fStrictOtherGroupingSeparators
== NULL
|| fStrictDashEquivalents
== NULL
||
107 fDefaultGroupingSeparators
== NULL
|| fStrictOtherGroupingSeparators
== NULL
) {
108 goto ExitConstrDeleteAll
;
111 // Freeze all the sets
112 fDotEquivalents
->freeze();
113 fCommaEquivalents
->freeze();
114 fOtherGroupingSeparators
->freeze();
115 fDashEquivalents
->freeze();
116 fStrictDotEquivalents
->freeze();
117 fStrictCommaEquivalents
->freeze();
118 fStrictOtherGroupingSeparators
->freeze();
119 fStrictDashEquivalents
->freeze();
120 fDefaultGroupingSeparators
->freeze();
121 fStrictDefaultGroupingSeparators
->freeze();
123 return; // If we reached this point, everything is fine so just exit
125 ExitConstrDeleteAll
: // Remove fPropSets and fRuleSets and return error
126 delete fDotEquivalents
; fDotEquivalents
= NULL
;
127 delete fCommaEquivalents
; fCommaEquivalents
= NULL
;
128 delete fOtherGroupingSeparators
; fOtherGroupingSeparators
= NULL
;
129 delete fDashEquivalents
; fDashEquivalents
= NULL
;
130 delete fStrictDotEquivalents
; fStrictDotEquivalents
= NULL
;
131 delete fStrictCommaEquivalents
; fStrictCommaEquivalents
= NULL
;
132 delete fStrictOtherGroupingSeparators
; fStrictOtherGroupingSeparators
= NULL
;
133 delete fStrictDashEquivalents
; fStrictDashEquivalents
= NULL
;
134 delete fDefaultGroupingSeparators
; fDefaultGroupingSeparators
= NULL
;
135 delete fStrictOtherGroupingSeparators
; fStrictOtherGroupingSeparators
= NULL
;
137 *status
= U_MEMORY_ALLOCATION_ERROR
;
141 DecimalFormatStaticSets::~DecimalFormatStaticSets() {
142 delete fDotEquivalents
; fDotEquivalents
= NULL
;
143 delete fCommaEquivalents
; fCommaEquivalents
= NULL
;
144 delete fOtherGroupingSeparators
; fOtherGroupingSeparators
= NULL
;
145 delete fDashEquivalents
; fDashEquivalents
= NULL
;
146 delete fStrictDotEquivalents
; fStrictDotEquivalents
= NULL
;
147 delete fStrictCommaEquivalents
; fStrictCommaEquivalents
= NULL
;
148 delete fStrictOtherGroupingSeparators
; fStrictOtherGroupingSeparators
= NULL
;
149 delete fStrictDashEquivalents
; fStrictDashEquivalents
= NULL
;
150 delete fDefaultGroupingSeparators
; fDefaultGroupingSeparators
= NULL
;
151 delete fStrictOtherGroupingSeparators
; fStrictOtherGroupingSeparators
= NULL
;
155 //------------------------------------------------------------------------------
157 // decfmt_cleanup Memory cleanup function, free/delete all
158 // cached memory. Called by ICU's u_cleanup() function.
160 //------------------------------------------------------------------------------
162 DecimalFormatStaticSets::cleanup(void)
164 delete DecimalFormatStaticSets::gStaticSets
;
165 DecimalFormatStaticSets::gStaticSets
= NULL
;
171 static UBool U_CALLCONV
172 decimfmt_cleanup(void)
174 return DecimalFormatStaticSets::cleanup();
178 void DecimalFormatStaticSets::initSets(UErrorCode
*status
)
180 DecimalFormatStaticSets
*p
;
182 UMTX_CHECK(NULL
, gStaticSets
, p
);
184 p
= new DecimalFormatStaticSets(status
);
187 *status
= U_MEMORY_ALLOCATION_ERROR
;
191 if (U_FAILURE(*status
)) {
197 if (gStaticSets
== NULL
) {
207 ucln_i18n_registerCleanup(UCLN_I18N_DECFMT
, decimfmt_cleanup
);
211 UnicodeSet
*DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal
, UBool strictParse
, UnicodeSet
*fallback
)
213 UErrorCode status
= U_ZERO_ERROR
;
217 if (U_FAILURE(status
)) {
218 fallback
->set(decimal
, decimal
);
222 if (gStaticSets
->fDotEquivalents
->contains(decimal
)) {
223 return strictParse
? gStaticSets
->fStrictDotEquivalents
: gStaticSets
->fDotEquivalents
;
226 if (gStaticSets
->fCommaEquivalents
->contains(decimal
)) {
227 return strictParse
? gStaticSets
->fStrictCommaEquivalents
: gStaticSets
->fCommaEquivalents
;
230 // if there is no match, return the character itself
231 fallback
->set(decimal
, decimal
);
237 #endif // !UCONFIG_NO_FORMATTING