1 /* 2 ****************************************************************************** 3 * * 4 * Copyright (C) 2003-2012, International Business Machines * 5 * Corporation and others. All Rights Reserved. * 6 * * 7 ****************************************************************************** 8 * file name: ulocdata.c 9 * encoding: US-ASCII 10 * tab size: 8 (not used) 11 * indentation:4 12 * 13 * created on: 2003Oct21 14 * created by: Ram Viswanadha,John Emmons 15 */ 16 17 #include "cmemory.h" 18 #include "unicode/ustring.h" 19 #include "unicode/ulocdata.h" 20 #include "umutex.h" 21 #include "uresimp.h" 22 #include "ureslocs.h" 23 24 #define MEASUREMENT_SYSTEM "MeasurementSystem" 25 #define PAPER_SIZE "PaperSize" 26 27 /** A locale data object. 28 * For usage in C programs. 29 * @draft ICU 3.4 30 */ 31 struct ULocaleData { 32 /** 33 * Controls the "No Substitute" behavior of this locale data object 34 */ 35 UBool noSubstitute; 36 37 /** 38 * Pointer to the resource bundle associated with this locale data object 39 */ 40 UResourceBundle *bundle; 41 42 /** 43 * Pointer to the lang resource bundle associated with this locale data object 44 */ 45 UResourceBundle *langBundle; 46 }; 47 48 U_CAPI ULocaleData* U_EXPORT2 49 ulocdata_open(const char *localeID, UErrorCode *status) 50 { 51 ULocaleData *uld; 52 53 if (U_FAILURE(*status)) { 54 return NULL; 55 } 56 57 uld = (ULocaleData *)uprv_malloc(sizeof(ULocaleData)); 58 if (uld == NULL) { 59 *status = U_MEMORY_ALLOCATION_ERROR; 60 return(NULL); 61 } 62 63 uld->langBundle = NULL; 64 65 uld->noSubstitute = FALSE; 66 uld->bundle = ures_open(NULL, localeID, status); 67 uld->langBundle = ures_open(U_ICUDATA_LANG, localeID, status); 68 69 if (U_FAILURE(*status)) { 70 uprv_free(uld); 71 return NULL; 72 } 73 74 return uld; 75 } 76 77 U_CAPI void U_EXPORT2 78 ulocdata_close(ULocaleData *uld) 79 { 80 if ( uld != NULL ) { 81 ures_close(uld->langBundle); 82 ures_close(uld->bundle); 83 uprv_free(uld); 84 } 85 } 86 87 U_CAPI void U_EXPORT2 88 ulocdata_setNoSubstitute(ULocaleData *uld, UBool setting) 89 { 90 uld->noSubstitute = setting; 91 } 92 93 U_CAPI UBool U_EXPORT2 94 ulocdata_getNoSubstitute(ULocaleData *uld) 95 { 96 return uld->noSubstitute; 97 } 98 99 U_CAPI USet* U_EXPORT2 100 ulocdata_getExemplarSet(ULocaleData *uld, USet *fillIn, 101 uint32_t options, ULocaleDataExemplarSetType extype, UErrorCode *status){ 102 103 static const char* const exemplarSetTypes[] = { "ExemplarCharacters", 104 "AuxExemplarCharacters", 105 "ExemplarCharactersIndex"}; 106 const UChar *exemplarChars = NULL; 107 int32_t len = 0; 108 UErrorCode localStatus = U_ZERO_ERROR; 109 110 if (U_FAILURE(*status)) 111 return NULL; 112 113 exemplarChars = ures_getStringByKey(uld->bundle, exemplarSetTypes[extype], &len, &localStatus); 114 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 115 localStatus = U_MISSING_RESOURCE_ERROR; 116 } 117 118 if (localStatus != U_ZERO_ERROR) { 119 *status = localStatus; 120 } 121 122 if (U_FAILURE(*status)) 123 return NULL; 124 125 if(fillIn != NULL) 126 uset_applyPattern(fillIn, exemplarChars, len, 127 USET_IGNORE_SPACE | options, status); 128 else 129 fillIn = uset_openPatternOptions(exemplarChars, len, 130 USET_IGNORE_SPACE | options, status); 131 132 return fillIn; 133 134 } 135 136 U_CAPI int32_t U_EXPORT2 137 ulocdata_getDelimiter(ULocaleData *uld, ULocaleDataDelimiterType type, 138 UChar *result, int32_t resultLength, UErrorCode *status){ 139 140 static const char* const delimiterKeys[] = { 141 "quotationStart", 142 "quotationEnd", 143 "alternateQuotationStart", 144 "alternateQuotationEnd" 145 }; 146 147 UResourceBundle *delimiterBundle; 148 int32_t len = 0; 149 const UChar *delimiter = NULL; 150 UErrorCode localStatus = U_ZERO_ERROR; 151 152 if (U_FAILURE(*status)) 153 return 0; 154 155 delimiterBundle = ures_getByKey(uld->bundle, "delimiters", NULL, &localStatus); 156 157 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 158 localStatus = U_MISSING_RESOURCE_ERROR; 159 } 160 161 if (localStatus != U_ZERO_ERROR) { 162 *status = localStatus; 163 } 164 165 if (U_FAILURE(*status)){ 166 ures_close(delimiterBundle); 167 return 0; 168 } 169 170 delimiter = ures_getStringByKey(delimiterBundle, delimiterKeys[type], &len, &localStatus); 171 ures_close(delimiterBundle); 172 173 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 174 localStatus = U_MISSING_RESOURCE_ERROR; 175 } 176 177 if (localStatus != U_ZERO_ERROR) { 178 *status = localStatus; 179 } 180 181 if (U_FAILURE(*status)){ 182 return 0; 183 } 184 185 u_strncpy(result,delimiter, resultLength); 186 return len; 187 } 188 189 U_CAPI UMeasurementSystem U_EXPORT2 190 ulocdata_getMeasurementSystem(const char *localeID, UErrorCode *status){ 191 192 UResourceBundle* bundle=NULL; 193 UResourceBundle* measurement=NULL; 194 UMeasurementSystem system = UMS_LIMIT; 195 196 if(status == NULL || U_FAILURE(*status)){ 197 return system; 198 } 199 200 bundle = ures_open(NULL, localeID, status); 201 202 measurement = ures_getByKeyWithFallback(bundle, MEASUREMENT_SYSTEM, NULL, status); 203 204 system = (UMeasurementSystem) ures_getInt(measurement, status); 205 206 ures_close(bundle); 207 ures_close(measurement); 208 209 return system; 210 211 } 212 213 U_CAPI void U_EXPORT2 214 ulocdata_getPaperSize(const char* localeID, int32_t *height, int32_t *width, UErrorCode *status){ 215 UResourceBundle* bundle=NULL; 216 UResourceBundle* paperSizeBundle = NULL; 217 const int32_t* paperSize=NULL; 218 int32_t len = 0; 219 220 if(status == NULL || U_FAILURE(*status)){ 221 return; 222 } 223 224 bundle = ures_open(NULL, localeID, status); 225 paperSizeBundle = ures_getByKeyWithFallback(bundle, PAPER_SIZE, NULL, status); 226 paperSize = ures_getIntVector(paperSizeBundle, &len, status); 227 228 if(U_SUCCESS(*status)){ 229 if(len < 2){ 230 *status = U_INTERNAL_PROGRAM_ERROR; 231 }else{ 232 *height = paperSize[0]; 233 *width = paperSize[1]; 234 } 235 } 236 237 ures_close(bundle); 238 ures_close(paperSizeBundle); 239 240 } 241 242 U_CAPI void U_EXPORT2 243 ulocdata_getCLDRVersion(UVersionInfo versionArray, UErrorCode *status) { 244 UResourceBundle *rb = NULL; 245 rb = ures_openDirect(NULL, "supplementalData", status); 246 ures_getVersionByKey(rb, "cldrVersion", versionArray, status); 247 ures_close(rb); 248 } 249 250 U_CAPI int32_t U_EXPORT2 251 ulocdata_getLocaleDisplayPattern(ULocaleData *uld, 252 UChar *result, 253 int32_t resultCapacity, 254 UErrorCode *status) { 255 UResourceBundle *patternBundle; 256 int32_t len = 0; 257 const UChar *pattern = NULL; 258 UErrorCode localStatus = U_ZERO_ERROR; 259 260 if (U_FAILURE(*status)) 261 return 0; 262 263 patternBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus); 264 265 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 266 localStatus = U_MISSING_RESOURCE_ERROR; 267 } 268 269 if (localStatus != U_ZERO_ERROR) { 270 *status = localStatus; 271 } 272 273 if (U_FAILURE(*status)){ 274 ures_close(patternBundle); 275 return 0; 276 } 277 278 pattern = ures_getStringByKey(patternBundle, "pattern", &len, &localStatus); 279 ures_close(patternBundle); 280 281 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 282 localStatus = U_MISSING_RESOURCE_ERROR; 283 } 284 285 if (localStatus != U_ZERO_ERROR) { 286 *status = localStatus; 287 } 288 289 if (U_FAILURE(*status)){ 290 return 0; 291 } 292 293 u_strncpy(result, pattern, resultCapacity); 294 return len; 295 } 296 297 298 U_CAPI int32_t U_EXPORT2 299 ulocdata_getLocaleSeparator(ULocaleData *uld, 300 UChar *result, 301 int32_t resultCapacity, 302 UErrorCode *status) { 303 UResourceBundle *separatorBundle; 304 int32_t len = 0; 305 const UChar *separator = NULL; 306 UErrorCode localStatus = U_ZERO_ERROR; 307 308 if (U_FAILURE(*status)) 309 return 0; 310 311 separatorBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus); 312 313 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 314 localStatus = U_MISSING_RESOURCE_ERROR; 315 } 316 317 if (localStatus != U_ZERO_ERROR) { 318 *status = localStatus; 319 } 320 321 if (U_FAILURE(*status)){ 322 ures_close(separatorBundle); 323 return 0; 324 } 325 326 separator = ures_getStringByKey(separatorBundle, "separator", &len, &localStatus); 327 ures_close(separatorBundle); 328 329 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 330 localStatus = U_MISSING_RESOURCE_ERROR; 331 } 332 333 if (localStatus != U_ZERO_ERROR) { 334 *status = localStatus; 335 } 336 337 if (U_FAILURE(*status)){ 338 return 0; 339 } 340 341 u_strncpy(result, separator, resultCapacity); 342 return len; 343 } 344