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