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