]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/decfmtst.cpp
ICU-461.17.tar.gz
[apple/icu.git] / icuSources / i18n / decfmtst.cpp
1 //
2 // decfmtst.cpp
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 #if !UCONFIG_NO_FORMATTING
15
16 #include "unicode/unistr.h"
17 #include "unicode/uniset.h"
18 #include "unicode/uchar.h"
19 #include "cmemory.h"
20 #include "cstring.h"
21 #include "uassert.h"
22 #include "ucln_in.h"
23 #include "umutex.h"
24
25 #include "decfmtst.h"
26
27 U_NAMESPACE_BEGIN
28
29
30 //------------------------------------------------------------------------------
31 //
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.
35 //
36 //------------------------------------------------------------------------------
37
38 static const UChar gDotEquivalentsPattern[] = {
39 // [ . \u2024 \u3002 \uFE12 \uFE52 \uFF0E \uFF61 ]
40 0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
41
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};
45
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};
49
50 static const UChar gDashEquivalentsPattern[] = {
51 // [ \ - HYPHEN F_DASH N_DASH MINUS ]
52 0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
53
54 static const UChar gStrictDotEquivalentsPattern[] = {
55 // [ . \u2024 \uFE52 \uFF0E \uFF61 ]
56 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
57
58 static const UChar gStrictCommaEquivalentsPattern[] = {
59 // [ , \u066B \uFE10 \uFE50 \uFF0C ]
60 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
61
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};
65
66 static const UChar gStrictDashEquivalentsPattern[] = {
67 // [ \ - MINUS ]
68 0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
69
70
71 DecimalFormatStaticSets *DecimalFormatStaticSets::gStaticSets = NULL;
72
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)
84 {
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);
89
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);
94
95
96 fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents);
97 fDefaultGroupingSeparators->addAll(*fCommaEquivalents);
98 fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators);
99
100 fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents);
101 fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents);
102 fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators);
103
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;
109 }
110
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();
122
123 return; // If we reached this point, everything is fine so just exit
124
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;
136
137 *status = U_MEMORY_ALLOCATION_ERROR;
138 }
139
140
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;
152 }
153
154
155 //------------------------------------------------------------------------------
156 //
157 // decfmt_cleanup Memory cleanup function, free/delete all
158 // cached memory. Called by ICU's u_cleanup() function.
159 //
160 //------------------------------------------------------------------------------
161 UBool
162 DecimalFormatStaticSets::cleanup(void)
163 {
164 delete DecimalFormatStaticSets::gStaticSets;
165 DecimalFormatStaticSets::gStaticSets = NULL;
166
167 return TRUE;
168 }
169
170 U_CDECL_BEGIN
171 static UBool U_CALLCONV
172 decimfmt_cleanup(void)
173 {
174 return DecimalFormatStaticSets::cleanup();
175 }
176 U_CDECL_END
177
178 void DecimalFormatStaticSets::initSets(UErrorCode *status)
179 {
180 DecimalFormatStaticSets *p;
181
182 UMTX_CHECK(NULL, gStaticSets, p);
183 if (p == NULL) {
184 p = new DecimalFormatStaticSets(status);
185
186 if (p == NULL) {
187 *status = U_MEMORY_ALLOCATION_ERROR;
188 return;
189 }
190
191 if (U_FAILURE(*status)) {
192 delete p;
193 return;
194 }
195
196 umtx_lock(NULL);
197 if (gStaticSets == NULL) {
198 gStaticSets = p;
199 p = NULL;
200 }
201
202 umtx_unlock(NULL);
203 if (p != NULL) {
204 delete p;
205 }
206
207 ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup);
208 }
209 }
210
211 UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse, UnicodeSet *fallback)
212 {
213 UErrorCode status = U_ZERO_ERROR;
214
215 initSets(&status);
216
217 if (U_FAILURE(status)) {
218 fallback->set(decimal, decimal);
219 return fallback;
220 }
221
222 if (gStaticSets->fDotEquivalents->contains(decimal)) {
223 return strictParse ? gStaticSets->fStrictDotEquivalents : gStaticSets->fDotEquivalents;
224 }
225
226 if (gStaticSets->fCommaEquivalents->contains(decimal)) {
227 return strictParse ? gStaticSets->fStrictCommaEquivalents : gStaticSets->fCommaEquivalents;
228 }
229
230 // if there is no match, return the character itself
231 fallback->set(decimal, decimal);
232 return fallback;
233 }
234
235
236 U_NAMESPACE_END
237 #endif // !UCONFIG_NO_FORMATTING