1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/ulocdata.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,388 @@ 1.4 +/* 1.5 +****************************************************************************** 1.6 +* * 1.7 +* Copyright (C) 2003-2013, International Business Machines * 1.8 +* Corporation and others. All Rights Reserved. * 1.9 +* * 1.10 +****************************************************************************** 1.11 +* file name: ulocdata.c 1.12 +* encoding: US-ASCII 1.13 +* tab size: 8 (not used) 1.14 +* indentation:4 1.15 +* 1.16 +* created on: 2003Oct21 1.17 +* created by: Ram Viswanadha,John Emmons 1.18 +*/ 1.19 + 1.20 +#include "cmemory.h" 1.21 +#include "unicode/ustring.h" 1.22 +#include "unicode/ures.h" 1.23 +#include "unicode/uloc.h" 1.24 +#include "unicode/ulocdata.h" 1.25 +#include "uresimp.h" 1.26 +#include "ureslocs.h" 1.27 + 1.28 +#define MEASUREMENT_SYSTEM "MeasurementSystem" 1.29 +#define PAPER_SIZE "PaperSize" 1.30 + 1.31 +/** A locale data object. 1.32 + * For usage in C programs. 1.33 + * @draft ICU 3.4 1.34 + */ 1.35 +struct ULocaleData { 1.36 + /** 1.37 + * Controls the "No Substitute" behavior of this locale data object 1.38 + */ 1.39 + UBool noSubstitute; 1.40 + 1.41 + /** 1.42 + * Pointer to the resource bundle associated with this locale data object 1.43 + */ 1.44 + UResourceBundle *bundle; 1.45 + 1.46 + /** 1.47 + * Pointer to the lang resource bundle associated with this locale data object 1.48 + */ 1.49 + UResourceBundle *langBundle; 1.50 +}; 1.51 + 1.52 +U_CAPI ULocaleData* U_EXPORT2 1.53 +ulocdata_open(const char *localeID, UErrorCode *status) 1.54 +{ 1.55 + ULocaleData *uld; 1.56 + 1.57 + if (U_FAILURE(*status)) { 1.58 + return NULL; 1.59 + } 1.60 + 1.61 + uld = (ULocaleData *)uprv_malloc(sizeof(ULocaleData)); 1.62 + if (uld == NULL) { 1.63 + *status = U_MEMORY_ALLOCATION_ERROR; 1.64 + return(NULL); 1.65 + } 1.66 + 1.67 + uld->langBundle = NULL; 1.68 + 1.69 + uld->noSubstitute = FALSE; 1.70 + uld->bundle = ures_open(NULL, localeID, status); 1.71 + uld->langBundle = ures_open(U_ICUDATA_LANG, localeID, status); 1.72 + 1.73 + if (U_FAILURE(*status)) { 1.74 + uprv_free(uld); 1.75 + return NULL; 1.76 + } 1.77 + 1.78 + return uld; 1.79 +} 1.80 + 1.81 +U_CAPI void U_EXPORT2 1.82 +ulocdata_close(ULocaleData *uld) 1.83 +{ 1.84 + if ( uld != NULL ) { 1.85 + ures_close(uld->langBundle); 1.86 + ures_close(uld->bundle); 1.87 + uprv_free(uld); 1.88 + } 1.89 +} 1.90 + 1.91 +U_CAPI void U_EXPORT2 1.92 +ulocdata_setNoSubstitute(ULocaleData *uld, UBool setting) 1.93 +{ 1.94 + uld->noSubstitute = setting; 1.95 +} 1.96 + 1.97 +U_CAPI UBool U_EXPORT2 1.98 +ulocdata_getNoSubstitute(ULocaleData *uld) 1.99 +{ 1.100 + return uld->noSubstitute; 1.101 +} 1.102 + 1.103 +U_CAPI USet* U_EXPORT2 1.104 +ulocdata_getExemplarSet(ULocaleData *uld, USet *fillIn, 1.105 + uint32_t options, ULocaleDataExemplarSetType extype, UErrorCode *status){ 1.106 + 1.107 + static const char* const exemplarSetTypes[] = { "ExemplarCharacters", 1.108 + "AuxExemplarCharacters", 1.109 + "ExemplarCharactersIndex", 1.110 + "ExemplarCharactersPunctuation"}; 1.111 + const UChar *exemplarChars = NULL; 1.112 + int32_t len = 0; 1.113 + UErrorCode localStatus = U_ZERO_ERROR; 1.114 + 1.115 + if (U_FAILURE(*status)) 1.116 + return NULL; 1.117 + 1.118 + exemplarChars = ures_getStringByKey(uld->bundle, exemplarSetTypes[extype], &len, &localStatus); 1.119 + if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 1.120 + localStatus = U_MISSING_RESOURCE_ERROR; 1.121 + } 1.122 + 1.123 + if (localStatus != U_ZERO_ERROR) { 1.124 + *status = localStatus; 1.125 + } 1.126 + 1.127 + if (U_FAILURE(*status)) 1.128 + return NULL; 1.129 + 1.130 + if(fillIn != NULL) 1.131 + uset_applyPattern(fillIn, exemplarChars, len, 1.132 + USET_IGNORE_SPACE | options, status); 1.133 + else 1.134 + fillIn = uset_openPatternOptions(exemplarChars, len, 1.135 + USET_IGNORE_SPACE | options, status); 1.136 + 1.137 + return fillIn; 1.138 + 1.139 +} 1.140 + 1.141 +U_CAPI int32_t U_EXPORT2 1.142 +ulocdata_getDelimiter(ULocaleData *uld, ULocaleDataDelimiterType type, 1.143 + UChar *result, int32_t resultLength, UErrorCode *status){ 1.144 + 1.145 + static const char* const delimiterKeys[] = { 1.146 + "quotationStart", 1.147 + "quotationEnd", 1.148 + "alternateQuotationStart", 1.149 + "alternateQuotationEnd" 1.150 + }; 1.151 + 1.152 + UResourceBundle *delimiterBundle; 1.153 + int32_t len = 0; 1.154 + const UChar *delimiter = NULL; 1.155 + UErrorCode localStatus = U_ZERO_ERROR; 1.156 + 1.157 + if (U_FAILURE(*status)) 1.158 + return 0; 1.159 + 1.160 + delimiterBundle = ures_getByKey(uld->bundle, "delimiters", NULL, &localStatus); 1.161 + 1.162 + if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 1.163 + localStatus = U_MISSING_RESOURCE_ERROR; 1.164 + } 1.165 + 1.166 + if (localStatus != U_ZERO_ERROR) { 1.167 + *status = localStatus; 1.168 + } 1.169 + 1.170 + if (U_FAILURE(*status)){ 1.171 + ures_close(delimiterBundle); 1.172 + return 0; 1.173 + } 1.174 + 1.175 + delimiter = ures_getStringByKey(delimiterBundle, delimiterKeys[type], &len, &localStatus); 1.176 + ures_close(delimiterBundle); 1.177 + 1.178 + if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 1.179 + localStatus = U_MISSING_RESOURCE_ERROR; 1.180 + } 1.181 + 1.182 + if (localStatus != U_ZERO_ERROR) { 1.183 + *status = localStatus; 1.184 + } 1.185 + 1.186 + if (U_FAILURE(*status)){ 1.187 + return 0; 1.188 + } 1.189 + 1.190 + u_strncpy(result,delimiter, resultLength); 1.191 + return len; 1.192 +} 1.193 + 1.194 +static UResourceBundle * measurementTypeBundleForLocale(const char *localeID, const char *measurementType, UErrorCode *status){ 1.195 + char fullLoc[ULOC_FULLNAME_CAPACITY]; 1.196 + char region[ULOC_COUNTRY_CAPACITY]; 1.197 + UResourceBundle *rb; 1.198 + UResourceBundle *measTypeBundle = NULL; 1.199 + 1.200 + /* The following code is basically copied from Calendar::setWeekData and 1.201 + * Calendar::getCalendarTypeForLocale with adjustments for resource name 1.202 + */ 1.203 + uloc_addLikelySubtags(localeID, fullLoc, ULOC_FULLNAME_CAPACITY, status); 1.204 + uloc_getCountry(fullLoc, region, ULOC_COUNTRY_CAPACITY, status); 1.205 + 1.206 + rb = ures_openDirect(NULL, "supplementalData", status); 1.207 + ures_getByKey(rb, "measurementData", rb, status); 1.208 + if (rb != NULL) { 1.209 + UResourceBundle *measDataBundle = ures_getByKey(rb, region, NULL, status); 1.210 + if (U_SUCCESS(*status)) { 1.211 + measTypeBundle = ures_getByKey(measDataBundle, measurementType, NULL, status); 1.212 + } 1.213 + if (*status == U_MISSING_RESOURCE_ERROR) { 1.214 + *status = U_ZERO_ERROR; 1.215 + if (measDataBundle != NULL) { 1.216 + ures_close(measDataBundle); 1.217 + } 1.218 + measDataBundle = ures_getByKey(rb, "001", NULL, status); 1.219 + measTypeBundle = ures_getByKey(measDataBundle, measurementType, NULL, status); 1.220 + } 1.221 + ures_close(measDataBundle); 1.222 + } 1.223 + ures_close(rb); 1.224 + return measTypeBundle; 1.225 +} 1.226 + 1.227 +U_CAPI UMeasurementSystem U_EXPORT2 1.228 +ulocdata_getMeasurementSystem(const char *localeID, UErrorCode *status){ 1.229 + 1.230 + UResourceBundle* measurement=NULL; 1.231 + UMeasurementSystem system = UMS_LIMIT; 1.232 + 1.233 + if(status == NULL || U_FAILURE(*status)){ 1.234 + return system; 1.235 + } 1.236 + 1.237 + measurement = measurementTypeBundleForLocale(localeID, MEASUREMENT_SYSTEM, status); 1.238 + system = (UMeasurementSystem) ures_getInt(measurement, status); 1.239 + 1.240 + ures_close(measurement); 1.241 + 1.242 + return system; 1.243 + 1.244 +} 1.245 + 1.246 +U_CAPI void U_EXPORT2 1.247 +ulocdata_getPaperSize(const char* localeID, int32_t *height, int32_t *width, UErrorCode *status){ 1.248 + UResourceBundle* paperSizeBundle = NULL; 1.249 + const int32_t* paperSize=NULL; 1.250 + int32_t len = 0; 1.251 + 1.252 + if(status == NULL || U_FAILURE(*status)){ 1.253 + return; 1.254 + } 1.255 + 1.256 + paperSizeBundle = measurementTypeBundleForLocale(localeID, PAPER_SIZE, status); 1.257 + paperSize = ures_getIntVector(paperSizeBundle, &len, status); 1.258 + 1.259 + if(U_SUCCESS(*status)){ 1.260 + if(len < 2){ 1.261 + *status = U_INTERNAL_PROGRAM_ERROR; 1.262 + }else{ 1.263 + *height = paperSize[0]; 1.264 + *width = paperSize[1]; 1.265 + } 1.266 + } 1.267 + 1.268 + ures_close(paperSizeBundle); 1.269 + 1.270 +} 1.271 + 1.272 +U_CAPI void U_EXPORT2 1.273 +ulocdata_getCLDRVersion(UVersionInfo versionArray, UErrorCode *status) { 1.274 + UResourceBundle *rb = NULL; 1.275 + rb = ures_openDirect(NULL, "supplementalData", status); 1.276 + ures_getVersionByKey(rb, "cldrVersion", versionArray, status); 1.277 + ures_close(rb); 1.278 +} 1.279 + 1.280 +U_CAPI int32_t U_EXPORT2 1.281 +ulocdata_getLocaleDisplayPattern(ULocaleData *uld, 1.282 + UChar *result, 1.283 + int32_t resultCapacity, 1.284 + UErrorCode *status) { 1.285 + UResourceBundle *patternBundle; 1.286 + int32_t len = 0; 1.287 + const UChar *pattern = NULL; 1.288 + UErrorCode localStatus = U_ZERO_ERROR; 1.289 + 1.290 + if (U_FAILURE(*status)) 1.291 + return 0; 1.292 + 1.293 + patternBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus); 1.294 + 1.295 + if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 1.296 + localStatus = U_MISSING_RESOURCE_ERROR; 1.297 + } 1.298 + 1.299 + if (localStatus != U_ZERO_ERROR) { 1.300 + *status = localStatus; 1.301 + } 1.302 + 1.303 + if (U_FAILURE(*status)){ 1.304 + ures_close(patternBundle); 1.305 + return 0; 1.306 + } 1.307 + 1.308 + pattern = ures_getStringByKey(patternBundle, "pattern", &len, &localStatus); 1.309 + ures_close(patternBundle); 1.310 + 1.311 + if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 1.312 + localStatus = U_MISSING_RESOURCE_ERROR; 1.313 + } 1.314 + 1.315 + if (localStatus != U_ZERO_ERROR) { 1.316 + *status = localStatus; 1.317 + } 1.318 + 1.319 + if (U_FAILURE(*status)){ 1.320 + return 0; 1.321 + } 1.322 + 1.323 + u_strncpy(result, pattern, resultCapacity); 1.324 + return len; 1.325 +} 1.326 + 1.327 + 1.328 +U_CAPI int32_t U_EXPORT2 1.329 +ulocdata_getLocaleSeparator(ULocaleData *uld, 1.330 + UChar *result, 1.331 + int32_t resultCapacity, 1.332 + UErrorCode *status) { 1.333 + UResourceBundle *separatorBundle; 1.334 + int32_t len = 0; 1.335 + const UChar *separator = NULL; 1.336 + UErrorCode localStatus = U_ZERO_ERROR; 1.337 + UChar *p0, *p1; 1.338 + static const UChar sub0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 }; /* {0} */ 1.339 + static const UChar sub1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 }; /* {1} */ 1.340 + static const int32_t subLen = 3; 1.341 + 1.342 + if (U_FAILURE(*status)) 1.343 + return 0; 1.344 + 1.345 + separatorBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus); 1.346 + 1.347 + if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 1.348 + localStatus = U_MISSING_RESOURCE_ERROR; 1.349 + } 1.350 + 1.351 + if (localStatus != U_ZERO_ERROR) { 1.352 + *status = localStatus; 1.353 + } 1.354 + 1.355 + if (U_FAILURE(*status)){ 1.356 + ures_close(separatorBundle); 1.357 + return 0; 1.358 + } 1.359 + 1.360 + separator = ures_getStringByKey(separatorBundle, "separator", &len, &localStatus); 1.361 + ures_close(separatorBundle); 1.362 + 1.363 + if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { 1.364 + localStatus = U_MISSING_RESOURCE_ERROR; 1.365 + } 1.366 + 1.367 + if (localStatus != U_ZERO_ERROR) { 1.368 + *status = localStatus; 1.369 + } 1.370 + 1.371 + if (U_FAILURE(*status)){ 1.372 + return 0; 1.373 + } 1.374 + 1.375 + /* For backwards compatibility, if we have a pattern, return the portion between {0} and {1} */ 1.376 + p0=u_strstr(separator, sub0); 1.377 + p1=u_strstr(separator, sub1); 1.378 + if (p0!=NULL && p1!=NULL && p0<=p1) { 1.379 + separator = (const UChar *)p0 + subLen; 1.380 + len = p1 - separator; 1.381 + /* Desired separator is no longer zero-terminated; handle that if necessary */ 1.382 + if (len < resultCapacity) { 1.383 + u_strncpy(result, separator, len); 1.384 + result[len] = 0; 1.385 + return len; 1.386 + } 1.387 + } 1.388 + 1.389 + u_strncpy(result, separator, resultCapacity); 1.390 + return len; 1.391 +}