]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/numsys.cpp
ICU-461.12.tar.gz
[apple/icu.git] / icuSources / i18n / numsys.cpp
CommitLineData
729e4ab9
A
1/*
2*******************************************************************************
3* Copyright (C) 2010, International Business Machines Corporation and
4* others. All Rights Reserved.
5*******************************************************************************
6*
7*
8* File NUMSYS.CPP
9*
10* Modification History:*
11* Date Name Description
12*
13********************************************************************************
14*/
15
16#include "unicode/utypes.h"
17#include "unicode/localpointer.h"
18#include "unicode/uchar.h"
19#include "unicode/unistr.h"
20#include "unicode/ures.h"
21#include "unicode/ustring.h"
22#include "unicode/uloc.h"
23#include "unicode/schriter.h"
24#include "unicode/numsys.h"
25#include "cstring.h"
26#include "uresimp.h"
27
28#if !UCONFIG_NO_FORMATTING
29
30U_NAMESPACE_BEGIN
31
32// Useful constants
33
34#define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789");
35static const char gNumberingSystems[] = "numberingSystems";
36static const char gNumberElements[] = "NumberElements";
37static const char gDefault[] = "default";
38static const char gDesc[] = "desc";
39static const char gRadix[] = "radix";
40static const char gAlgorithmic[] = "algorithmic";
41static const char gLatn[] = "latn";
42
43
44UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumberingSystem)
45
46 /**
47 * Default Constructor.
48 *
49 * @draft ICU 4.2
50 */
51
52NumberingSystem::NumberingSystem() {
53 radix = 10;
54 algorithmic = FALSE;
55 UnicodeString defaultDigits = DEFAULT_DIGITS;
56 desc.setTo(defaultDigits);
57 uprv_strcpy(name,gLatn);
58}
59
60 /**
61 * Copy constructor.
62 * @draft ICU 4.2
63 */
64
65NumberingSystem::NumberingSystem(const NumberingSystem& other)
66: UObject(other) {
67 *this=other;
68}
69
70NumberingSystem* U_EXPORT2
71NumberingSystem::createInstance(int32_t radix_in, UBool isAlgorithmic_in, const UnicodeString & desc_in, UErrorCode &status) {
72
73 if (U_FAILURE(status)) {
74 return NULL;
75 }
76
77 if ( radix_in < 2 ) {
78 status = U_ILLEGAL_ARGUMENT_ERROR;
79 return NULL;
80 }
81
82 if ( !isAlgorithmic_in ) {
83 if ( desc_in.countChar32() != radix_in || !isValidDigitString(desc_in)) {
84 status = U_ILLEGAL_ARGUMENT_ERROR;
85 return NULL;
86 }
87 }
88
89 NumberingSystem *ns = new NumberingSystem();
90
91 ns->setRadix(radix_in);
92 ns->setDesc(desc_in);
93 ns->setAlgorithmic(isAlgorithmic_in);
94 ns->setName(NULL);
95 return ns;
96
97}
98
99
100NumberingSystem* U_EXPORT2
101NumberingSystem::createInstance(const Locale & inLocale, UErrorCode& status) {
102
103 if (U_FAILURE(status)) {
104 return NULL;
105 }
106
107 char buffer[ULOC_KEYWORDS_CAPACITY];
108 int32_t count = inLocale.getKeywordValue("numbers",buffer, sizeof(buffer),status);
109 if ( count > 0 ) { // @numbers keyword was specified in the locale
110 buffer[count] = '\0'; // Make sure it is null terminated.
111 return NumberingSystem::createInstanceByName(buffer,status);
112 } else { // Find the default numbering system for this locale.
113 UResourceBundle *resource = ures_open(NULL, inLocale.getName(), &status);
114 UResourceBundle *numberElementsRes = ures_getByKey(resource,gNumberElements,NULL,&status);
115 const UChar *defaultNSName =
116 ures_getStringByKeyWithFallback(numberElementsRes, gDefault, &count, &status);
117 ures_close(numberElementsRes);
118 ures_close(resource);
119
120 if (U_FAILURE(status)) {
121 status = U_USING_FALLBACK_WARNING;
122 NumberingSystem *ns = new NumberingSystem();
123 return ns;
124 }
125
126 if ( count > 0 && count < ULOC_KEYWORDS_CAPACITY ) { // Default numbering system found
127 u_UCharsToChars(defaultNSName,buffer,count);
128 buffer[count] = '\0'; // Make sure it is null terminated.
129 return NumberingSystem::createInstanceByName(buffer,status);
130 } else {
131 status = U_USING_FALLBACK_WARNING;
132 NumberingSystem *ns = new NumberingSystem();
133 return ns;
134 }
135
136 }
137}
138
139NumberingSystem* U_EXPORT2
140NumberingSystem::createInstance(UErrorCode& status) {
141 return NumberingSystem::createInstance(Locale::getDefault(), status);
142}
143
144NumberingSystem* U_EXPORT2
145NumberingSystem::createInstanceByName(const char *name, UErrorCode& status) {
146
147 UResourceBundle *numberingSystemsInfo = NULL;
148 UResourceBundle *nsTop, *nsCurrent;
149 const UChar* description = NULL;
150 int32_t radix = 10;
151 int32_t algorithmic = 0;
152 int32_t len;
153
154 numberingSystemsInfo = ures_openDirect(NULL,gNumberingSystems, &status);
155 nsCurrent = ures_getByKey(numberingSystemsInfo,gNumberingSystems,NULL,&status);
156 nsTop = ures_getByKey(nsCurrent,name,NULL,&status);
157 description = ures_getStringByKey(nsTop,gDesc,&len,&status);
158
159 ures_getByKey(nsTop,gRadix,nsCurrent,&status);
160 radix = ures_getInt(nsCurrent,&status);
161
162 ures_getByKey(nsTop,gAlgorithmic,nsCurrent,&status);
163 algorithmic = ures_getInt(nsCurrent,&status);
164
165 UBool isAlgorithmic = ( algorithmic == 1 );
166 UnicodeString nsd;
167 nsd.setTo(description);
168
169 ures_close(nsCurrent);
170 ures_close(nsTop);
171 ures_close(numberingSystemsInfo);
172
173 if (U_FAILURE(status)) {
174 status = U_UNSUPPORTED_ERROR;
175 return NULL;
176 }
177
178 NumberingSystem* ns = NumberingSystem::createInstance(radix,isAlgorithmic,nsd,status);
179 ns->setName(name);
180 return ns;
181}
182
183 /**
184 * Destructor.
185 * @draft ICU 4.2
186 */
187NumberingSystem::~NumberingSystem() {
188}
189
190int32_t NumberingSystem::getRadix() {
191 return radix;
192}
193
194UnicodeString NumberingSystem::getDescription() {
195 return desc;
196}
197
198const char * NumberingSystem::getName() {
199 return name;
200}
201
202void NumberingSystem::setRadix(int32_t r) {
203 radix = r;
204}
205
206void NumberingSystem::setAlgorithmic(UBool c) {
207 algorithmic = c;
208}
209
210void NumberingSystem::setDesc(UnicodeString d) {
211 desc.setTo(d);
212}
213void NumberingSystem::setName(const char *n) {
214 if ( n == NULL ) {
215 name[0] = (char) 0;
216 } else {
217 uprv_strncpy(name,n,NUMSYS_NAME_CAPACITY);
218 name[NUMSYS_NAME_CAPACITY] = (char)0; // Make sure it is null terminated.
219 }
220}
221UBool NumberingSystem::isAlgorithmic() const {
222 return ( algorithmic );
223}
224
225
226UBool NumberingSystem::isValidDigitString(const UnicodeString& str) {
227
228 StringCharacterIterator it(str);
229 UChar32 c;
230 UChar32 prev = 0;
231 int32_t i = 0;
232
233 for ( it.setToStart(); it.hasNext(); ) {
234 c = it.next32PostInc();
235 if ( c > 0xFFFF ) { // Digits outside the BMP are not currently supported
236 return FALSE;
237 }
238 i++;
239 prev = c;
240 }
241 return TRUE;
242}
243U_NAMESPACE_END
244
245#endif /* #if !UCONFIG_NO_FORMATTING */
246
247//eof