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