intl/icu/source/i18n/ulocdata.c

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial