]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/decfmtst.cpp
ICU-400.40.tar.gz
[apple/icu.git] / icuSources / i18n / decfmtst.cpp
CommitLineData
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
25U_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
36static const UChar gDotEquivalentsPattern[] = {
37 // [ . \u2024 \u3002 \uFE12 \uFE52 \uFF0E \uFF61 ]
38 0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
39
40static 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
44static 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
7393aa2f
A
48static const UChar gDashEquivalentsPattern[] = {
49 // [ \ - HYPHEN F_DASH N_DASH MINUS ]
50 0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
51
46f4442e
A
52static const UChar gStrictDotEquivalentsPattern[] = {
53 // [ . \u2024 \uFE52 \uFF0E \uFF61 ]
54 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
55
56static const UChar gStrictCommaEquivalentsPattern[] = {
57 // [ , \u066B \uFE10 \uFE50 \uFF0C ]
58 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
59
60static 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
7393aa2f
A
64static const UChar gStrictDashEquivalentsPattern[] = {
65 // [ \ - MINUS ]
66 0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
67
46f4442e
A
68
69DecimalFormatStaticSets *DecimalFormatStaticSets::gStaticSets = NULL;
70
71DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode *status)
72: fDotEquivalents(NULL),
73 fCommaEquivalents(NULL),
74 fOtherGroupingSeparators(NULL),
7393aa2f 75 fDashEquivalents(NULL),
46f4442e
A
76 fStrictDotEquivalents(NULL),
77 fStrictCommaEquivalents(NULL),
78 fStrictOtherGroupingSeparators(NULL),
7393aa2f 79 fStrictDashEquivalents(NULL),
46f4442e
A
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);
7393aa2f
A
86 fDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gDashEquivalentsPattern, -1), *status);
87
46f4442e
A
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);
7393aa2f 91 fStrictDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictDashEquivalentsPattern, -1), *status);
46f4442e
A
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
7393aa2f
A
103 if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL || fDashEquivalents == NULL ||
104 fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL || fStrictDashEquivalents == NULL ||
46f4442e
A
105 fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL) {
106 goto ExitConstrDeleteAll;
107 }
108
109 // Freeze all the sets
110 fDotEquivalents->freeze();
111 fCommaEquivalents->freeze();
112 fOtherGroupingSeparators->freeze();
7393aa2f 113 fDashEquivalents->freeze();
46f4442e
A
114 fStrictDotEquivalents->freeze();
115 fStrictCommaEquivalents->freeze();
116 fStrictOtherGroupingSeparators->freeze();
7393aa2f 117 fStrictDashEquivalents->freeze();
46f4442e
A
118 fDefaultGroupingSeparators->freeze();
119 fStrictDefaultGroupingSeparators->freeze();
120
121 return; // If we reached this point, everything is fine so just exit
122
123ExitConstrDeleteAll: // Remove fPropSets and fRuleSets and return error
124 delete fDotEquivalents; fDotEquivalents = NULL;
125 delete fCommaEquivalents; fCommaEquivalents = NULL;
126 delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
7393aa2f 127 delete fDashEquivalents; fDashEquivalents = NULL;
46f4442e
A
128 delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
129 delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
130 delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
7393aa2f 131 delete fStrictDashEquivalents; fStrictDashEquivalents = NULL;
46f4442e
A
132 delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
133 delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
134
135 *status = U_MEMORY_ALLOCATION_ERROR;
136}
137
138
139DecimalFormatStaticSets::~DecimalFormatStaticSets() {
140 delete fDotEquivalents; fDotEquivalents = NULL;
141 delete fCommaEquivalents; fCommaEquivalents = NULL;
142 delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
7393aa2f 143 delete fDashEquivalents; fDashEquivalents = NULL;
46f4442e
A
144 delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
145 delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
146 delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
7393aa2f 147 delete fStrictDashEquivalents; fStrictDashEquivalents = NULL;
46f4442e
A
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//------------------------------------------------------------------------------
159UBool
160DecimalFormatStaticSets::cleanup(void)
161{
162 delete DecimalFormatStaticSets::gStaticSets;
163 DecimalFormatStaticSets::gStaticSets = NULL;
164
165 return TRUE;
166}
167
168U_CDECL_BEGIN
169static UBool U_CALLCONV
170decimfmt_cleanup(void)
171{
172 return DecimalFormatStaticSets::cleanup();
173}
174U_CDECL_END
175
176void 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
209UnicodeSet *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
234U_NAMESPACE_END