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