OLD | NEW |
(Empty) | |
| 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 |
| 30 U_NAMESPACE_BEGIN |
| 31 |
| 32 // Useful constants |
| 33 |
| 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"; |
| 42 |
| 43 |
| 44 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumberingSystem) |
| 45 |
| 46 /** |
| 47 * Default Constructor. |
| 48 * |
| 49 * @draft ICU 4.2 |
| 50 */ |
| 51 |
| 52 NumberingSystem::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 |
| 65 NumberingSystem::NumberingSystem(const NumberingSystem& other) |
| 66 : UObject(other) { |
| 67 *this=other; |
| 68 } |
| 69 |
| 70 NumberingSystem* U_EXPORT2 |
| 71 NumberingSystem::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 |
| 100 NumberingSystem* U_EXPORT2 |
| 101 NumberingSystem::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),st
atus); |
| 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,gNumberEleme
nts,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 numberin
g 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 |
| 139 NumberingSystem* U_EXPORT2 |
| 140 NumberingSystem::createInstance(UErrorCode& status) { |
| 141 return NumberingSystem::createInstance(Locale::getDefault(), status); |
| 142 } |
| 143 |
| 144 NumberingSystem* U_EXPORT2 |
| 145 NumberingSystem::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,&stat
us); |
| 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,n
sd,status); |
| 179 ns->setName(name); |
| 180 return ns; |
| 181 } |
| 182 |
| 183 /** |
| 184 * Destructor. |
| 185 * @draft ICU 4.2 |
| 186 */ |
| 187 NumberingSystem::~NumberingSystem() { |
| 188 } |
| 189 |
| 190 int32_t NumberingSystem::getRadix() { |
| 191 return radix; |
| 192 } |
| 193 |
| 194 UnicodeString NumberingSystem::getDescription() { |
| 195 return desc; |
| 196 } |
| 197 |
| 198 const char * NumberingSystem::getName() { |
| 199 return name; |
| 200 } |
| 201 |
| 202 void NumberingSystem::setRadix(int32_t r) { |
| 203 radix = r; |
| 204 } |
| 205 |
| 206 void NumberingSystem::setAlgorithmic(UBool c) { |
| 207 algorithmic = c; |
| 208 } |
| 209 |
| 210 void NumberingSystem::setDesc(UnicodeString d) { |
| 211 desc.setTo(d); |
| 212 } |
| 213 void 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 } |
| 221 UBool NumberingSystem::isAlgorithmic() const { |
| 222 return ( algorithmic ); |
| 223 } |
| 224 |
| 225 |
| 226 UBool 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 } |
| 243 U_NAMESPACE_END |
| 244 |
| 245 #endif /* #if !UCONFIG_NO_FORMATTING */ |
| 246 |
| 247 //eof |
OLD | NEW |