]>
Commit | Line | Data |
---|---|---|
4388f060 A |
1 | /* |
2 | ******************************************************************************* | |
57a6839d | 3 | * Copyright (C) 2009-2013, International Business Machines Corporation and * |
4388f060 A |
4 | * others. All Rights Reserved. * |
5 | ******************************************************************************* | |
6 | * | |
7 | * This file contains the class DecimalFormatStaticSets | |
8 | * | |
9 | * DecimalFormatStaticSets holds the UnicodeSets that are needed for lenient | |
10 | * parsing of decimal and group separators. | |
11 | ******************************************************************************** | |
12 | */ | |
13 | ||
46f4442e A |
14 | #include "unicode/utypes.h" |
15 | ||
729e4ab9 A |
16 | #if !UCONFIG_NO_FORMATTING |
17 | ||
46f4442e A |
18 | #include "unicode/unistr.h" |
19 | #include "unicode/uniset.h" | |
20 | #include "unicode/uchar.h" | |
21 | #include "cmemory.h" | |
22 | #include "cstring.h" | |
23 | #include "uassert.h" | |
24 | #include "ucln_in.h" | |
25 | #include "umutex.h" | |
26 | ||
27 | #include "decfmtst.h" | |
28 | ||
29 | U_NAMESPACE_BEGIN | |
30 | ||
31 | ||
32 | //------------------------------------------------------------------------------ | |
33 | // | |
34 | // Unicode Set pattern strings for all of the required constant sets. | |
35 | // Initialized with hex values for portability to EBCDIC based machines. | |
36 | // Really ugly, but there's no good way to avoid it. | |
37 | // | |
38 | //------------------------------------------------------------------------------ | |
39 | ||
40 | static const UChar gDotEquivalentsPattern[] = { | |
4388f060 A |
41 | // [ . \u2024 \u3002 \uFE12 \uFE52 \uFF0E \uFF61 ] |
42 | 0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000}; | |
46f4442e A |
43 | |
44 | static const UChar gCommaEquivalentsPattern[] = { | |
4388f060 | 45 | // [ , \u060C \u066B \u3001 \uFE10 \uFE11 \uFE50 \uFE51 \uFF0C \uFF64 ] |
46f4442e A |
46 | 0x005B, 0x002C, 0x060C, 0x066B, 0x3001, 0xFE10, 0xFE11, 0xFE50, 0xFE51, 0xFF0C, 0xFF64, 0x005D, 0x0000}; |
47 | ||
48 | static const UChar gOtherGroupingSeparatorsPattern[] = { | |
4388f060 | 49 | // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ] |
46f4442e A |
50 | 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000}; |
51 | ||
7393aa2f | 52 | static const UChar gDashEquivalentsPattern[] = { |
729e4ab9 A |
53 | // [ \ - HYPHEN F_DASH N_DASH MINUS ] |
54 | 0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000}; | |
7393aa2f | 55 | |
46f4442e | 56 | static const UChar gStrictDotEquivalentsPattern[] = { |
4388f060 | 57 | // [ . \u2024 \uFE52 \uFF0E \uFF61 ] |
46f4442e A |
58 | 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000}; |
59 | ||
60 | static const UChar gStrictCommaEquivalentsPattern[] = { | |
4388f060 | 61 | // [ , \u066B \uFE10 \uFE50 \uFF0C ] |
46f4442e A |
62 | 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000}; |
63 | ||
64 | static const UChar gStrictOtherGroupingSeparatorsPattern[] = { | |
4388f060 | 65 | // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ] |
46f4442e A |
66 | 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000}; |
67 | ||
7393aa2f | 68 | static const UChar gStrictDashEquivalentsPattern[] = { |
4388f060 A |
69 | // [ \ - MINUS ] |
70 | 0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000}; | |
7393aa2f | 71 | |
57a6839d A |
72 | static UChar32 gMinusSigns[] = { |
73 | 0x002D, | |
74 | 0x207B, | |
75 | 0x208B, | |
76 | 0x2212, | |
77 | 0x2796, | |
78 | 0xFE63, | |
79 | 0xFF0D}; | |
80 | ||
81 | static UChar32 gPlusSigns[] = { | |
82 | 0x002B, | |
83 | 0x207A, | |
84 | 0x208A, | |
85 | 0x2795, | |
86 | 0xfB29, | |
87 | 0xFE62, | |
88 | 0xFF0B}; | |
89 | ||
90 | static void initUnicodeSet(const UChar32 *raw, int32_t len, UnicodeSet *s) { | |
91 | for (int32_t i = 0; i < len; ++i) { | |
92 | s->add(raw[i]); | |
93 | } | |
94 | } | |
46f4442e | 95 | |
57a6839d | 96 | DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode &status) |
46f4442e A |
97 | : fDotEquivalents(NULL), |
98 | fCommaEquivalents(NULL), | |
99 | fOtherGroupingSeparators(NULL), | |
7393aa2f | 100 | fDashEquivalents(NULL), |
46f4442e A |
101 | fStrictDotEquivalents(NULL), |
102 | fStrictCommaEquivalents(NULL), | |
103 | fStrictOtherGroupingSeparators(NULL), | |
7393aa2f | 104 | fStrictDashEquivalents(NULL), |
46f4442e | 105 | fDefaultGroupingSeparators(NULL), |
57a6839d A |
106 | fStrictDefaultGroupingSeparators(NULL), |
107 | fMinusSigns(NULL), | |
108 | fPlusSigns(NULL) | |
46f4442e | 109 | { |
57a6839d A |
110 | fDotEquivalents = new UnicodeSet(UnicodeString(TRUE, gDotEquivalentsPattern, -1), status); |
111 | fCommaEquivalents = new UnicodeSet(UnicodeString(TRUE, gCommaEquivalentsPattern, -1), status); | |
112 | fOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gOtherGroupingSeparatorsPattern, -1), status); | |
113 | fDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gDashEquivalentsPattern, -1), status); | |
7393aa2f | 114 | |
57a6839d A |
115 | fStrictDotEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictDotEquivalentsPattern, -1), status); |
116 | fStrictCommaEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictCommaEquivalentsPattern, -1), status); | |
117 | fStrictOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gStrictOtherGroupingSeparatorsPattern, -1), status); | |
118 | fStrictDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictDashEquivalentsPattern, -1), status); | |
46f4442e A |
119 | |
120 | ||
121 | fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents); | |
122 | fDefaultGroupingSeparators->addAll(*fCommaEquivalents); | |
123 | fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators); | |
124 | ||
125 | fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents); | |
126 | fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents); | |
127 | fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators); | |
128 | ||
57a6839d A |
129 | fMinusSigns = new UnicodeSet(); |
130 | fPlusSigns = new UnicodeSet(); | |
131 | ||
46f4442e | 132 | // Check for null pointers |
7393aa2f | 133 | if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL || fDashEquivalents == NULL || |
4388f060 | 134 | fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL || fStrictDashEquivalents == NULL || |
57a6839d A |
135 | fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL || |
136 | fMinusSigns == NULL || fPlusSigns == NULL) { | |
137 | cleanup(); | |
138 | status = U_MEMORY_ALLOCATION_ERROR; | |
139 | return; | |
46f4442e A |
140 | } |
141 | ||
57a6839d A |
142 | initUnicodeSet( |
143 | gMinusSigns, | |
144 | sizeof(gMinusSigns) / sizeof(gMinusSigns[0]), | |
145 | fMinusSigns); | |
146 | initUnicodeSet( | |
147 | gPlusSigns, | |
148 | sizeof(gPlusSigns) / sizeof(gPlusSigns[0]), | |
149 | fPlusSigns); | |
150 | ||
46f4442e A |
151 | // Freeze all the sets |
152 | fDotEquivalents->freeze(); | |
153 | fCommaEquivalents->freeze(); | |
154 | fOtherGroupingSeparators->freeze(); | |
7393aa2f | 155 | fDashEquivalents->freeze(); |
46f4442e A |
156 | fStrictDotEquivalents->freeze(); |
157 | fStrictCommaEquivalents->freeze(); | |
158 | fStrictOtherGroupingSeparators->freeze(); | |
7393aa2f | 159 | fStrictDashEquivalents->freeze(); |
46f4442e A |
160 | fDefaultGroupingSeparators->freeze(); |
161 | fStrictDefaultGroupingSeparators->freeze(); | |
57a6839d A |
162 | fMinusSigns->freeze(); |
163 | fPlusSigns->freeze(); | |
46f4442e A |
164 | } |
165 | ||
46f4442e | 166 | DecimalFormatStaticSets::~DecimalFormatStaticSets() { |
57a6839d A |
167 | cleanup(); |
168 | } | |
169 | ||
170 | void DecimalFormatStaticSets::cleanup() { // Be sure to clean up newly added fields! | |
46f4442e A |
171 | delete fDotEquivalents; fDotEquivalents = NULL; |
172 | delete fCommaEquivalents; fCommaEquivalents = NULL; | |
173 | delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL; | |
7393aa2f | 174 | delete fDashEquivalents; fDashEquivalents = NULL; |
46f4442e A |
175 | delete fStrictDotEquivalents; fStrictDotEquivalents = NULL; |
176 | delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL; | |
177 | delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL; | |
7393aa2f | 178 | delete fStrictDashEquivalents; fStrictDashEquivalents = NULL; |
46f4442e | 179 | delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL; |
4388f060 | 180 | delete fStrictDefaultGroupingSeparators; fStrictDefaultGroupingSeparators = NULL; |
46f4442e | 181 | delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL; |
57a6839d A |
182 | delete fMinusSigns; fMinusSigns = NULL; |
183 | delete fPlusSigns; fPlusSigns = NULL; | |
46f4442e A |
184 | } |
185 | ||
57a6839d A |
186 | static DecimalFormatStaticSets *gStaticSets; |
187 | static icu::UInitOnce gStaticSetsInitOnce = U_INITONCE_INITIALIZER; | |
188 | ||
46f4442e A |
189 | |
190 | //------------------------------------------------------------------------------ | |
191 | // | |
192 | // decfmt_cleanup Memory cleanup function, free/delete all | |
193 | // cached memory. Called by ICU's u_cleanup() function. | |
194 | // | |
195 | //------------------------------------------------------------------------------ | |
46f4442e A |
196 | U_CDECL_BEGIN |
197 | static UBool U_CALLCONV | |
198 | decimfmt_cleanup(void) | |
199 | { | |
57a6839d A |
200 | delete gStaticSets; |
201 | gStaticSets = NULL; | |
202 | gStaticSetsInitOnce.reset(); | |
203 | return TRUE; | |
46f4442e | 204 | } |
46f4442e | 205 | |
57a6839d A |
206 | static void U_CALLCONV initSets(UErrorCode &status) { |
207 | U_ASSERT(gStaticSets == NULL); | |
208 | ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup); | |
209 | gStaticSets = new DecimalFormatStaticSets(status); | |
210 | if (U_FAILURE(status)) { | |
211 | delete gStaticSets; | |
212 | gStaticSets = NULL; | |
213 | return; | |
214 | } | |
215 | if (gStaticSets == NULL) { | |
216 | status = U_MEMORY_ALLOCATION_ERROR; | |
46f4442e A |
217 | } |
218 | } | |
57a6839d A |
219 | U_CDECL_END |
220 | ||
221 | const DecimalFormatStaticSets *DecimalFormatStaticSets::getStaticSets(UErrorCode &status) { | |
222 | umtx_initOnce(gStaticSetsInitOnce, initSets, status); | |
223 | return gStaticSets; | |
224 | } | |
225 | ||
46f4442e | 226 | |
4388f060 | 227 | const UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse) |
46f4442e | 228 | { |
4388f060 | 229 | UErrorCode status = U_ZERO_ERROR; |
57a6839d | 230 | umtx_initOnce(gStaticSetsInitOnce, initSets, status); |
4388f060 A |
231 | if (U_FAILURE(status)) { |
232 | return NULL; | |
233 | } | |
46f4442e A |
234 | |
235 | if (gStaticSets->fDotEquivalents->contains(decimal)) { | |
236 | return strictParse ? gStaticSets->fStrictDotEquivalents : gStaticSets->fDotEquivalents; | |
237 | } | |
238 | ||
239 | if (gStaticSets->fCommaEquivalents->contains(decimal)) { | |
240 | return strictParse ? gStaticSets->fStrictCommaEquivalents : gStaticSets->fCommaEquivalents; | |
241 | } | |
242 | ||
4388f060 A |
243 | // if there is no match, return NULL |
244 | return NULL; | |
46f4442e A |
245 | } |
246 | ||
247 | ||
248 | U_NAMESPACE_END | |
729e4ab9 | 249 | #endif // !UCONFIG_NO_FORMATTING |