]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/decfmtst.cpp
ICU-400.39.tar.gz
[apple/icu.git] / icuSources / i18n / decfmtst.cpp
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 gDashEquivalentsPattern[] = {
49 // [ \ - HYPHEN F_DASH N_DASH MINUS ]
50 0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
51
52 static const UChar gStrictDotEquivalentsPattern[] = {
53 // [ . \u2024 \uFE52 \uFF0E \uFF61 ]
54 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
55
56 static const UChar gStrictCommaEquivalentsPattern[] = {
57 // [ , \u066B \uFE10 \uFE50 \uFF0C ]
58 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
59
60 static const UChar gStrictOtherGroupingSeparatorsPattern[] = {
61 // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ]
62 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
63
64 static const UChar gStrictDashEquivalentsPattern[] = {
65 // [ \ - MINUS ]
66 0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
67
68
69 DecimalFormatStaticSets *DecimalFormatStaticSets::gStaticSets = NULL;
70
71 DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode *status)
72 : fDotEquivalents(NULL),
73 fCommaEquivalents(NULL),
74 fOtherGroupingSeparators(NULL),
75 fDashEquivalents(NULL),
76 fStrictDotEquivalents(NULL),
77 fStrictCommaEquivalents(NULL),
78 fStrictOtherGroupingSeparators(NULL),
79 fStrictDashEquivalents(NULL),
80 fDefaultGroupingSeparators(NULL),
81 fStrictDefaultGroupingSeparators(NULL)
82 {
83 fDotEquivalents = new UnicodeSet(UnicodeString(TRUE, gDotEquivalentsPattern, -1), *status);
84 fCommaEquivalents = new UnicodeSet(UnicodeString(TRUE, gCommaEquivalentsPattern, -1), *status);
85 fOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gOtherGroupingSeparatorsPattern, -1), *status);
86 fDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gDashEquivalentsPattern, -1), *status);
87
88 fStrictDotEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictDotEquivalentsPattern, -1), *status);
89 fStrictCommaEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictCommaEquivalentsPattern, -1), *status);
90 fStrictOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gStrictOtherGroupingSeparatorsPattern, -1), *status);
91 fStrictDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictDashEquivalentsPattern, -1), *status);
92
93
94 fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents);
95 fDefaultGroupingSeparators->addAll(*fCommaEquivalents);
96 fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators);
97
98 fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents);
99 fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents);
100 fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators);
101
102 // Check for null pointers
103 if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL || fDashEquivalents == NULL ||
104 fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL || fStrictDashEquivalents == NULL ||
105 fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL) {
106 goto ExitConstrDeleteAll;
107 }
108
109 // Freeze all the sets
110 fDotEquivalents->freeze();
111 fCommaEquivalents->freeze();
112 fOtherGroupingSeparators->freeze();
113 fDashEquivalents->freeze();
114 fStrictDotEquivalents->freeze();
115 fStrictCommaEquivalents->freeze();
116 fStrictOtherGroupingSeparators->freeze();
117 fStrictDashEquivalents->freeze();
118 fDefaultGroupingSeparators->freeze();
119 fStrictDefaultGroupingSeparators->freeze();
120
121 return; // If we reached this point, everything is fine so just exit
122
123 ExitConstrDeleteAll: // Remove fPropSets and fRuleSets and return error
124 delete fDotEquivalents; fDotEquivalents = NULL;
125 delete fCommaEquivalents; fCommaEquivalents = NULL;
126 delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
127 delete fDashEquivalents; fDashEquivalents = NULL;
128 delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
129 delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
130 delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
131 delete fStrictDashEquivalents; fStrictDashEquivalents = NULL;
132 delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
133 delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
134
135 *status = U_MEMORY_ALLOCATION_ERROR;
136 }
137
138
139 DecimalFormatStaticSets::~DecimalFormatStaticSets() {
140 delete fDotEquivalents; fDotEquivalents = NULL;
141 delete fCommaEquivalents; fCommaEquivalents = NULL;
142 delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
143 delete fDashEquivalents; fDashEquivalents = NULL;
144 delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
145 delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
146 delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
147 delete fStrictDashEquivalents; fStrictDashEquivalents = NULL;
148 delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
149 delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
150 }
151
152
153 //------------------------------------------------------------------------------
154 //
155 // decfmt_cleanup Memory cleanup function, free/delete all
156 // cached memory. Called by ICU's u_cleanup() function.
157 //
158 //------------------------------------------------------------------------------
159 UBool
160 DecimalFormatStaticSets::cleanup(void)
161 {
162 delete DecimalFormatStaticSets::gStaticSets;
163 DecimalFormatStaticSets::gStaticSets = NULL;
164
165 return TRUE;
166 }
167
168 U_CDECL_BEGIN
169 static UBool U_CALLCONV
170 decimfmt_cleanup(void)
171 {
172 return DecimalFormatStaticSets::cleanup();
173 }
174 U_CDECL_END
175
176 void DecimalFormatStaticSets::initSets(UErrorCode *status)
177 {
178 DecimalFormatStaticSets *p;
179
180 UMTX_CHECK(NULL, gStaticSets, p);
181 if (p == NULL) {
182 p = new DecimalFormatStaticSets(status);
183
184 if (p == NULL) {
185 *status = U_MEMORY_ALLOCATION_ERROR;
186 return;
187 }
188
189 if (U_FAILURE(*status)) {
190 delete p;
191 return;
192 }
193
194 umtx_lock(NULL);
195 if (gStaticSets == NULL) {
196 gStaticSets = p;
197 p = NULL;
198 }
199
200 umtx_unlock(NULL);
201 if (p != NULL) {
202 delete p;
203 }
204
205 ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup);
206 }
207 }
208
209 UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse, UnicodeSet *fallback)
210 {
211 UErrorCode status = U_ZERO_ERROR;
212
213 initSets(&status);
214
215 if (U_FAILURE(status)) {
216 fallback->set(decimal, decimal);
217 return fallback;
218 }
219
220 if (gStaticSets->fDotEquivalents->contains(decimal)) {
221 return strictParse ? gStaticSets->fStrictDotEquivalents : gStaticSets->fDotEquivalents;
222 }
223
224 if (gStaticSets->fCommaEquivalents->contains(decimal)) {
225 return strictParse ? gStaticSets->fStrictCommaEquivalents : gStaticSets->fCommaEquivalents;
226 }
227
228 // if there is no match, return the character itself
229 fallback->set(decimal, decimal);
230 return fallback;
231 }
232
233
234 U_NAMESPACE_END