2 *******************************************************************************
3 * Copyright (C) 2010, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 *******************************************************************************
10 * Modification History:*
11 * Date Name Description
13 ********************************************************************************
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"
28 #if !UCONFIG_NO_FORMATTING
34 #define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789");
35 static const char gNumberingSystems
[] = "numberingSystems";
36 static const char gNumberElements
[] = "NumberElements";
37 static const char gDefault
[] = "default";
38 static const char gDesc
[] = "desc";
39 static const char gRadix
[] = "radix";
40 static const char gAlgorithmic
[] = "algorithmic";
41 static const char gLatn
[] = "latn";
44 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumberingSystem
)
47 * Default Constructor.
52 NumberingSystem::NumberingSystem() {
55 UnicodeString defaultDigits
= DEFAULT_DIGITS
;
56 desc
.setTo(defaultDigits
);
57 uprv_strcpy(name
,gLatn
);
65 NumberingSystem::NumberingSystem(const NumberingSystem
& other
)
70 NumberingSystem
* U_EXPORT2
71 NumberingSystem::createInstance(int32_t radix_in
, UBool isAlgorithmic_in
, const UnicodeString
& desc_in
, UErrorCode
&status
) {
73 if (U_FAILURE(status
)) {
78 status
= U_ILLEGAL_ARGUMENT_ERROR
;
82 if ( !isAlgorithmic_in
) {
83 if ( desc_in
.countChar32() != radix_in
|| !isValidDigitString(desc_in
)) {
84 status
= U_ILLEGAL_ARGUMENT_ERROR
;
89 NumberingSystem
*ns
= new NumberingSystem();
91 ns
->setRadix(radix_in
);
93 ns
->setAlgorithmic(isAlgorithmic_in
);
100 NumberingSystem
* U_EXPORT2
101 NumberingSystem::createInstance(const Locale
& inLocale
, UErrorCode
& status
) {
103 if (U_FAILURE(status
)) {
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
);
120 if (U_FAILURE(status
)) {
121 status
= U_USING_FALLBACK_WARNING
;
122 NumberingSystem
*ns
= new NumberingSystem();
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
);
131 status
= U_USING_FALLBACK_WARNING
;
132 NumberingSystem
*ns
= new NumberingSystem();
139 NumberingSystem
* U_EXPORT2
140 NumberingSystem::createInstance(UErrorCode
& status
) {
141 return NumberingSystem::createInstance(Locale::getDefault(), status
);
144 NumberingSystem
* U_EXPORT2
145 NumberingSystem::createInstanceByName(const char *name
, UErrorCode
& status
) {
147 UResourceBundle
*numberingSystemsInfo
= NULL
;
148 UResourceBundle
*nsTop
, *nsCurrent
;
149 const UChar
* description
= NULL
;
151 int32_t algorithmic
= 0;
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
);
159 ures_getByKey(nsTop
,gRadix
,nsCurrent
,&status
);
160 radix
= ures_getInt(nsCurrent
,&status
);
162 ures_getByKey(nsTop
,gAlgorithmic
,nsCurrent
,&status
);
163 algorithmic
= ures_getInt(nsCurrent
,&status
);
165 UBool isAlgorithmic
= ( algorithmic
== 1 );
167 nsd
.setTo(description
);
169 ures_close(nsCurrent
);
171 ures_close(numberingSystemsInfo
);
173 if (U_FAILURE(status
)) {
174 status
= U_UNSUPPORTED_ERROR
;
178 NumberingSystem
* ns
= NumberingSystem::createInstance(radix
,isAlgorithmic
,nsd
,status
);
187 NumberingSystem::~NumberingSystem() {
190 int32_t NumberingSystem::getRadix() {
194 UnicodeString
NumberingSystem::getDescription() {
198 const char * NumberingSystem::getName() {
202 void NumberingSystem::setRadix(int32_t r
) {
206 void NumberingSystem::setAlgorithmic(UBool c
) {
210 void NumberingSystem::setDesc(UnicodeString d
) {
213 void NumberingSystem::setName(const char *n
) {
217 uprv_strncpy(name
,n
,NUMSYS_NAME_CAPACITY
);
218 name
[NUMSYS_NAME_CAPACITY
] = (char)0; // Make sure it is null terminated.
221 UBool
NumberingSystem::isAlgorithmic() const {
222 return ( algorithmic
);
226 UBool
NumberingSystem::isValidDigitString(const UnicodeString
& str
) {
228 StringCharacterIterator
it(str
);
233 for ( it
.setToStart(); it
.hasNext(); ) {
234 c
= it
.next32PostInc();
235 if ( c
> 0xFFFF ) { // Digits outside the BMP are not currently supported
245 #endif /* #if !UCONFIG_NO_FORMATTING */