]>
Commit | Line | Data |
---|---|---|
46f4442e A |
1 | // |
2 | // decfmtst.h | |
3 | // | |
4 | // Copyright (C) 20098, International Business Machines Corporation and others. | |
5 | // All Rights Reserved. | |
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 | #include "unicode/utypes.h" | |
13 | ||
14 | #include "unicode/unistr.h" | |
15 | #include "unicode/uniset.h" | |
16 | #include "unicode/uchar.h" | |
17 | #include "cmemory.h" | |
18 | #include "cstring.h" | |
19 | #include "uassert.h" | |
20 | #include "ucln_in.h" | |
21 | #include "umutex.h" | |
22 | ||
23 | #include "decfmtst.h" | |
24 | ||
25 | U_NAMESPACE_BEGIN | |
26 | ||
27 | ||
28 | //------------------------------------------------------------------------------ | |
29 | // | |
30 | // Unicode Set pattern strings for all of the required constant sets. | |
31 | // Initialized with hex values for portability to EBCDIC based machines. | |
32 | // Really ugly, but there's no good way to avoid it. | |
33 | // | |
34 | //------------------------------------------------------------------------------ | |
35 | ||
36 | static const UChar gDotEquivalentsPattern[] = { | |
37 | // [ . \u2024 \u3002 \uFE12 \uFE52 \uFF0E \uFF61 ] | |
38 | 0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000}; | |
39 | ||
40 | static const UChar gCommaEquivalentsPattern[] = { | |
41 | // [ , \u060C \u066B \u3001 \uFE10 \uFE11 \uFE50 \uFE51 \uFF0C \uFF64 ] | |
42 | 0x005B, 0x002C, 0x060C, 0x066B, 0x3001, 0xFE10, 0xFE11, 0xFE50, 0xFE51, 0xFF0C, 0xFF64, 0x005D, 0x0000}; | |
43 | ||
44 | static const UChar gOtherGroupingSeparatorsPattern[] = { | |
45 | // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ] | |
46 | 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000}; | |
47 | ||
48 | static const UChar gStrictDotEquivalentsPattern[] = { | |
49 | // [ . \u2024 \uFE52 \uFF0E \uFF61 ] | |
50 | 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000}; | |
51 | ||
52 | static const UChar gStrictCommaEquivalentsPattern[] = { | |
53 | // [ , \u066B \uFE10 \uFE50 \uFF0C ] | |
54 | 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000}; | |
55 | ||
56 | static const UChar gStrictOtherGroupingSeparatorsPattern[] = { | |
57 | // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ] | |
58 | 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000}; | |
59 | ||
60 | ||
61 | DecimalFormatStaticSets *DecimalFormatStaticSets::gStaticSets = NULL; | |
62 | ||
63 | DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode *status) | |
64 | : fDotEquivalents(NULL), | |
65 | fCommaEquivalents(NULL), | |
66 | fOtherGroupingSeparators(NULL), | |
67 | fStrictDotEquivalents(NULL), | |
68 | fStrictCommaEquivalents(NULL), | |
69 | fStrictOtherGroupingSeparators(NULL), | |
70 | fDefaultGroupingSeparators(NULL), | |
71 | fStrictDefaultGroupingSeparators(NULL) | |
72 | { | |
73 | fDotEquivalents = new UnicodeSet(UnicodeString(TRUE, gDotEquivalentsPattern, -1), *status); | |
74 | fCommaEquivalents = new UnicodeSet(UnicodeString(TRUE, gCommaEquivalentsPattern, -1), *status); | |
75 | fOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gOtherGroupingSeparatorsPattern, -1), *status); | |
76 | fStrictDotEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictDotEquivalentsPattern, -1), *status); | |
77 | fStrictCommaEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictCommaEquivalentsPattern, -1), *status); | |
78 | fStrictOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gStrictOtherGroupingSeparatorsPattern, -1), *status); | |
79 | ||
80 | ||
81 | fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents); | |
82 | fDefaultGroupingSeparators->addAll(*fCommaEquivalents); | |
83 | fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators); | |
84 | ||
85 | fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents); | |
86 | fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents); | |
87 | fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators); | |
88 | ||
89 | // Check for null pointers | |
90 | if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL || | |
91 | fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL || | |
92 | fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL) { | |
93 | goto ExitConstrDeleteAll; | |
94 | } | |
95 | ||
96 | // Freeze all the sets | |
97 | fDotEquivalents->freeze(); | |
98 | fCommaEquivalents->freeze(); | |
99 | fOtherGroupingSeparators->freeze(); | |
100 | fStrictDotEquivalents->freeze(); | |
101 | fStrictCommaEquivalents->freeze(); | |
102 | fStrictOtherGroupingSeparators->freeze(); | |
103 | fDefaultGroupingSeparators->freeze(); | |
104 | fStrictDefaultGroupingSeparators->freeze(); | |
105 | ||
106 | return; // If we reached this point, everything is fine so just exit | |
107 | ||
108 | ExitConstrDeleteAll: // Remove fPropSets and fRuleSets and return error | |
109 | delete fDotEquivalents; fDotEquivalents = NULL; | |
110 | delete fCommaEquivalents; fCommaEquivalents = NULL; | |
111 | delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL; | |
112 | delete fStrictDotEquivalents; fStrictDotEquivalents = NULL; | |
113 | delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL; | |
114 | delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL; | |
115 | delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL; | |
116 | delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL; | |
117 | ||
118 | *status = U_MEMORY_ALLOCATION_ERROR; | |
119 | } | |
120 | ||
121 | ||
122 | DecimalFormatStaticSets::~DecimalFormatStaticSets() { | |
123 | delete fDotEquivalents; fDotEquivalents = NULL; | |
124 | delete fCommaEquivalents; fCommaEquivalents = NULL; | |
125 | delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL; | |
126 | delete fStrictDotEquivalents; fStrictDotEquivalents = NULL; | |
127 | delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL; | |
128 | delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL; | |
129 | delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL; | |
130 | delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL; | |
131 | } | |
132 | ||
133 | ||
134 | //------------------------------------------------------------------------------ | |
135 | // | |
136 | // decfmt_cleanup Memory cleanup function, free/delete all | |
137 | // cached memory. Called by ICU's u_cleanup() function. | |
138 | // | |
139 | //------------------------------------------------------------------------------ | |
140 | UBool | |
141 | DecimalFormatStaticSets::cleanup(void) | |
142 | { | |
143 | delete DecimalFormatStaticSets::gStaticSets; | |
144 | DecimalFormatStaticSets::gStaticSets = NULL; | |
145 | ||
146 | return TRUE; | |
147 | } | |
148 | ||
149 | U_CDECL_BEGIN | |
150 | static UBool U_CALLCONV | |
151 | decimfmt_cleanup(void) | |
152 | { | |
153 | return DecimalFormatStaticSets::cleanup(); | |
154 | } | |
155 | U_CDECL_END | |
156 | ||
157 | void DecimalFormatStaticSets::initSets(UErrorCode *status) | |
158 | { | |
159 | DecimalFormatStaticSets *p; | |
160 | ||
161 | UMTX_CHECK(NULL, gStaticSets, p); | |
162 | if (p == NULL) { | |
163 | p = new DecimalFormatStaticSets(status); | |
164 | ||
165 | if (p == NULL) { | |
166 | *status = U_MEMORY_ALLOCATION_ERROR; | |
167 | return; | |
168 | } | |
169 | ||
170 | if (U_FAILURE(*status)) { | |
171 | delete p; | |
172 | return; | |
173 | } | |
174 | ||
175 | umtx_lock(NULL); | |
176 | if (gStaticSets == NULL) { | |
177 | gStaticSets = p; | |
178 | p = NULL; | |
179 | } | |
180 | ||
181 | umtx_unlock(NULL); | |
182 | if (p != NULL) { | |
183 | delete p; | |
184 | } | |
185 | ||
186 | ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup); | |
187 | } | |
188 | } | |
189 | ||
190 | UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse, UnicodeSet *fallback) | |
191 | { | |
192 | UErrorCode status = U_ZERO_ERROR; | |
193 | ||
194 | initSets(&status); | |
195 | ||
196 | if (U_FAILURE(status)) { | |
197 | fallback->set(decimal, decimal); | |
198 | return fallback; | |
199 | } | |
200 | ||
201 | if (gStaticSets->fDotEquivalents->contains(decimal)) { | |
202 | return strictParse ? gStaticSets->fStrictDotEquivalents : gStaticSets->fDotEquivalents; | |
203 | } | |
204 | ||
205 | if (gStaticSets->fCommaEquivalents->contains(decimal)) { | |
206 | return strictParse ? gStaticSets->fStrictCommaEquivalents : gStaticSets->fCommaEquivalents; | |
207 | } | |
208 | ||
209 | // if there is no match, return the character itself | |
210 | fallback->set(decimal, decimal); | |
211 | return fallback; | |
212 | } | |
213 | ||
214 | ||
215 | U_NAMESPACE_END |