4 // Copyright (C) 20098, International Business Machines Corporation and others.
5 // All Rights Reserved.
7 // This file contains the class DecimalFormatStaticSets
9 // DecimalFormatStaticSets holds the UnicodeSets that are needed for lenient
10 // parsing of decimal and group separators.
12 #include "unicode/utypes.h"
14 #include "unicode/unistr.h"
15 #include "unicode/uniset.h"
16 #include "unicode/uchar.h"
28 //------------------------------------------------------------------------------
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.
34 //------------------------------------------------------------------------------
36 static const UChar gDotEquivalentsPattern
[] = {
37 // [ . \u2024 \u3002 \uFE12 \uFE52 \uFF0E \uFF61 ]
38 0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
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};
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};
48 static const UChar gDashEquivalentsPattern
[] = {
49 // [ \ - HYPHEN F_DASH N_DASH MINUS ]
50 0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
52 static const UChar gStrictDotEquivalentsPattern
[] = {
53 // [ . \u2024 \uFE52 \uFF0E \uFF61 ]
54 0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
56 static const UChar gStrictCommaEquivalentsPattern
[] = {
57 // [ , \u066B \uFE10 \uFE50 \uFF0C ]
58 0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
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};
64 static const UChar gStrictDashEquivalentsPattern
[] = {
66 0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
69 DecimalFormatStaticSets
*DecimalFormatStaticSets::gStaticSets
= NULL
;
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
)
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
);
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
);
94 fDefaultGroupingSeparators
= new UnicodeSet(*fDotEquivalents
);
95 fDefaultGroupingSeparators
->addAll(*fCommaEquivalents
);
96 fDefaultGroupingSeparators
->addAll(*fOtherGroupingSeparators
);
98 fStrictDefaultGroupingSeparators
= new UnicodeSet(*fStrictDotEquivalents
);
99 fStrictDefaultGroupingSeparators
->addAll(*fStrictCommaEquivalents
);
100 fStrictDefaultGroupingSeparators
->addAll(*fStrictOtherGroupingSeparators
);
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
;
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();
121 return; // If we reached this point, everything is fine so just exit
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
;
135 *status
= U_MEMORY_ALLOCATION_ERROR
;
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
;
153 //------------------------------------------------------------------------------
155 // decfmt_cleanup Memory cleanup function, free/delete all
156 // cached memory. Called by ICU's u_cleanup() function.
158 //------------------------------------------------------------------------------
160 DecimalFormatStaticSets::cleanup(void)
162 delete DecimalFormatStaticSets::gStaticSets
;
163 DecimalFormatStaticSets::gStaticSets
= NULL
;
169 static UBool U_CALLCONV
170 decimfmt_cleanup(void)
172 return DecimalFormatStaticSets::cleanup();
176 void DecimalFormatStaticSets::initSets(UErrorCode
*status
)
178 DecimalFormatStaticSets
*p
;
180 UMTX_CHECK(NULL
, gStaticSets
, p
);
182 p
= new DecimalFormatStaticSets(status
);
185 *status
= U_MEMORY_ALLOCATION_ERROR
;
189 if (U_FAILURE(*status
)) {
195 if (gStaticSets
== NULL
) {
205 ucln_i18n_registerCleanup(UCLN_I18N_DECFMT
, decimfmt_cleanup
);
209 UnicodeSet
*DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal
, UBool strictParse
, UnicodeSet
*fallback
)
211 UErrorCode status
= U_ZERO_ERROR
;
215 if (U_FAILURE(status
)) {
216 fallback
->set(decimal
, decimal
);
220 if (gStaticSets
->fDotEquivalents
->contains(decimal
)) {
221 return strictParse
? gStaticSets
->fStrictDotEquivalents
: gStaticSets
->fDotEquivalents
;
224 if (gStaticSets
->fCommaEquivalents
->contains(decimal
)) {
225 return strictParse
? gStaticSets
->fStrictCommaEquivalents
: gStaticSets
->fCommaEquivalents
;
228 // if there is no match, return the character itself
229 fallback
->set(decimal
, decimal
);