2 *******************************************************************************
3 * Copyright (C) 2009-2013, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 * This file contains the class DecimalFormatStaticSets
9 * DecimalFormatStaticSets holds the UnicodeSets that are needed for lenient
10 * parsing of decimal and group separators.
11 ********************************************************************************
14 #include "unicode/utypes.h"
16 #if !UCONFIG_NO_FORMATTING
18 #include "unicode/unistr.h"
19 #include "unicode/uniset.h"
20 #include "unicode/uchar.h"
32 //------------------------------------------------------------------------------
34 // Unicode Set pattern strings for all of the required constant sets.
35 // Initialized with hex values for portability to EBCDIC based machines.
36 // Really ugly, but there's no good way to avoid it.
38 //------------------------------------------------------------------------------
40 static const UChar gDotEquivalentsPattern
[] = {
41 // [ . \u2024 \u3002 \uFE12 \uFE52 \uFF0E \uFF61 ]
42 0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
44 static const UChar gCommaEquivalentsPattern
[] = {
45 // [ , \u060C \u066B \u3001 \uFE10 \uFE11 \uFE50 \uFE51 \uFF0C \uFF64 ]
46 0x005B, 0x002C, 0x060C, 0x066B, 0x3001, 0xFE10, 0xFE11, 0xFE50, 0xFE51, 0xFF0C, 0xFF64, 0x005D, 0x0000};
48 static const UChar gOtherGroupingSeparatorsPattern
[] = {
49 // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ]
50 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
52 static const UChar gDashEquivalentsPattern
[] = {
53 // [ \ - HYPHEN F_DASH N_DASH MINUS ]
54 0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
56 static const UChar gStrictDotEquivalentsPattern
[] = {
57 // [ . \u2024 \uFE52 \uFF0E \uFF61 ]
58 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
60 static const UChar gStrictCommaEquivalentsPattern
[] = {
61 // [ , \u066B \uFE10 \uFE50 \uFF0C ]
62 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
64 static const UChar gStrictOtherGroupingSeparatorsPattern
[] = {
65 // [ \ SPACE ' NBSP \u066C \u2000 - \u200A \u2018 \u2019 \u202F \u205F \u3000 \uFF07 ]
66 0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
68 static const UChar gStrictDashEquivalentsPattern
[] = {
70 0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
72 static UChar32 gMinusSigns
[] = {
81 static UChar32 gPlusSigns
[] = {
90 static void initUnicodeSet(const UChar32
*raw
, int32_t len
, UnicodeSet
*s
) {
91 for (int32_t i
= 0; i
< len
; ++i
) {
96 DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode
&status
)
97 : fDotEquivalents(NULL
),
98 fCommaEquivalents(NULL
),
99 fOtherGroupingSeparators(NULL
),
100 fDashEquivalents(NULL
),
101 fStrictDotEquivalents(NULL
),
102 fStrictCommaEquivalents(NULL
),
103 fStrictOtherGroupingSeparators(NULL
),
104 fStrictDashEquivalents(NULL
),
105 fDefaultGroupingSeparators(NULL
),
106 fStrictDefaultGroupingSeparators(NULL
),
110 fDotEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gDotEquivalentsPattern
, -1), status
);
111 fCommaEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gCommaEquivalentsPattern
, -1), status
);
112 fOtherGroupingSeparators
= new UnicodeSet(UnicodeString(TRUE
, gOtherGroupingSeparatorsPattern
, -1), status
);
113 fDashEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gDashEquivalentsPattern
, -1), status
);
115 fStrictDotEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gStrictDotEquivalentsPattern
, -1), status
);
116 fStrictCommaEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gStrictCommaEquivalentsPattern
, -1), status
);
117 fStrictOtherGroupingSeparators
= new UnicodeSet(UnicodeString(TRUE
, gStrictOtherGroupingSeparatorsPattern
, -1), status
);
118 fStrictDashEquivalents
= new UnicodeSet(UnicodeString(TRUE
, gStrictDashEquivalentsPattern
, -1), status
);
121 fDefaultGroupingSeparators
= new UnicodeSet(*fDotEquivalents
);
122 fDefaultGroupingSeparators
->addAll(*fCommaEquivalents
);
123 fDefaultGroupingSeparators
->addAll(*fOtherGroupingSeparators
);
125 fStrictDefaultGroupingSeparators
= new UnicodeSet(*fStrictDotEquivalents
);
126 fStrictDefaultGroupingSeparators
->addAll(*fStrictCommaEquivalents
);
127 fStrictDefaultGroupingSeparators
->addAll(*fStrictOtherGroupingSeparators
);
129 fMinusSigns
= new UnicodeSet();
130 fPlusSigns
= new UnicodeSet();
132 // Check for null pointers
133 if (fDotEquivalents
== NULL
|| fCommaEquivalents
== NULL
|| fOtherGroupingSeparators
== NULL
|| fDashEquivalents
== NULL
||
134 fStrictDotEquivalents
== NULL
|| fStrictCommaEquivalents
== NULL
|| fStrictOtherGroupingSeparators
== NULL
|| fStrictDashEquivalents
== NULL
||
135 fDefaultGroupingSeparators
== NULL
|| fStrictOtherGroupingSeparators
== NULL
||
136 fMinusSigns
== NULL
|| fPlusSigns
== NULL
) {
138 status
= U_MEMORY_ALLOCATION_ERROR
;
144 sizeof(gMinusSigns
) / sizeof(gMinusSigns
[0]),
148 sizeof(gPlusSigns
) / sizeof(gPlusSigns
[0]),
151 // Freeze all the sets
152 fDotEquivalents
->freeze();
153 fCommaEquivalents
->freeze();
154 fOtherGroupingSeparators
->freeze();
155 fDashEquivalents
->freeze();
156 fStrictDotEquivalents
->freeze();
157 fStrictCommaEquivalents
->freeze();
158 fStrictOtherGroupingSeparators
->freeze();
159 fStrictDashEquivalents
->freeze();
160 fDefaultGroupingSeparators
->freeze();
161 fStrictDefaultGroupingSeparators
->freeze();
162 fMinusSigns
->freeze();
163 fPlusSigns
->freeze();
166 DecimalFormatStaticSets::~DecimalFormatStaticSets() {
170 void DecimalFormatStaticSets::cleanup() { // Be sure to clean up newly added fields!
171 delete fDotEquivalents
; fDotEquivalents
= NULL
;
172 delete fCommaEquivalents
; fCommaEquivalents
= NULL
;
173 delete fOtherGroupingSeparators
; fOtherGroupingSeparators
= NULL
;
174 delete fDashEquivalents
; fDashEquivalents
= NULL
;
175 delete fStrictDotEquivalents
; fStrictDotEquivalents
= NULL
;
176 delete fStrictCommaEquivalents
; fStrictCommaEquivalents
= NULL
;
177 delete fStrictOtherGroupingSeparators
; fStrictOtherGroupingSeparators
= NULL
;
178 delete fStrictDashEquivalents
; fStrictDashEquivalents
= NULL
;
179 delete fDefaultGroupingSeparators
; fDefaultGroupingSeparators
= NULL
;
180 delete fStrictDefaultGroupingSeparators
; fStrictDefaultGroupingSeparators
= NULL
;
181 delete fStrictOtherGroupingSeparators
; fStrictOtherGroupingSeparators
= NULL
;
182 delete fMinusSigns
; fMinusSigns
= NULL
;
183 delete fPlusSigns
; fPlusSigns
= NULL
;
186 static DecimalFormatStaticSets
*gStaticSets
;
187 static icu::UInitOnce gStaticSetsInitOnce
= U_INITONCE_INITIALIZER
;
190 //------------------------------------------------------------------------------
192 // decfmt_cleanup Memory cleanup function, free/delete all
193 // cached memory. Called by ICU's u_cleanup() function.
195 //------------------------------------------------------------------------------
197 static UBool U_CALLCONV
198 decimfmt_cleanup(void)
202 gStaticSetsInitOnce
.reset();
206 static void U_CALLCONV
initSets(UErrorCode
&status
) {
207 U_ASSERT(gStaticSets
== NULL
);
208 ucln_i18n_registerCleanup(UCLN_I18N_DECFMT
, decimfmt_cleanup
);
209 gStaticSets
= new DecimalFormatStaticSets(status
);
210 if (U_FAILURE(status
)) {
215 if (gStaticSets
== NULL
) {
216 status
= U_MEMORY_ALLOCATION_ERROR
;
221 const DecimalFormatStaticSets
*DecimalFormatStaticSets::getStaticSets(UErrorCode
&status
) {
222 umtx_initOnce(gStaticSetsInitOnce
, initSets
, status
);
227 const UnicodeSet
*DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal
, UBool strictParse
)
229 UErrorCode status
= U_ZERO_ERROR
;
230 umtx_initOnce(gStaticSetsInitOnce
, initSets
, status
);
231 if (U_FAILURE(status
)) {
235 if (gStaticSets
->fDotEquivalents
->contains(decimal
)) {
236 return strictParse
? gStaticSets
->fStrictDotEquivalents
: gStaticSets
->fDotEquivalents
;
239 if (gStaticSets
->fCommaEquivalents
->contains(decimal
)) {
240 return strictParse
? gStaticSets
->fStrictCommaEquivalents
: gStaticSets
->fCommaEquivalents
;
243 // if there is no match, return NULL
249 #endif // !UCONFIG_NO_FORMATTING