]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/ulocdata.c
ICU-511.35.tar.gz
[apple/icu.git] / icuSources / i18n / ulocdata.c
1 /*
2 ******************************************************************************
3 * *
4 * Copyright (C) 2003-2013, 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/ures.h"
20 #include "unicode/uloc.h"
21 #include "unicode/ulocdata.h"
22 #include "umutex.h"
23 #include "uresimp.h"
24 #include "ureslocs.h"
25
26 #define MEASUREMENT_SYSTEM "MeasurementSystem"
27 #define PAPER_SIZE "PaperSize"
28
29 /** A locale data object.
30 * For usage in C programs.
31 * @draft ICU 3.4
32 */
33 struct 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;
43
44 /**
45 * Pointer to the lang resource bundle associated with this locale data object
46 */
47 UResourceBundle *langBundle;
48 };
49
50 U_CAPI ULocaleData* U_EXPORT2
51 ulocdata_open(const char *localeID, UErrorCode *status)
52 {
53 ULocaleData *uld;
54
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
65 uld->langBundle = NULL;
66
67 uld->noSubstitute = FALSE;
68 uld->bundle = ures_open(NULL, localeID, status);
69 uld->langBundle = ures_open(U_ICUDATA_LANG, localeID, status);
70
71 if (U_FAILURE(*status)) {
72 uprv_free(uld);
73 return NULL;
74 }
75
76 return uld;
77 }
78
79 U_CAPI void U_EXPORT2
80 ulocdata_close(ULocaleData *uld)
81 {
82 if ( uld != NULL ) {
83 ures_close(uld->langBundle);
84 ures_close(uld->bundle);
85 uprv_free(uld);
86 }
87 }
88
89 U_CAPI void U_EXPORT2
90 ulocdata_setNoSubstitute(ULocaleData *uld, UBool setting)
91 {
92 uld->noSubstitute = setting;
93 }
94
95 U_CAPI UBool U_EXPORT2
96 ulocdata_getNoSubstitute(ULocaleData *uld)
97 {
98 return uld->noSubstitute;
99 }
100
101 U_CAPI USet* U_EXPORT2
102 ulocdata_getExemplarSet(ULocaleData *uld, USet *fillIn,
103 uint32_t options, ULocaleDataExemplarSetType extype, UErrorCode *status){
104
105 static const char* const exemplarSetTypes[] = { "ExemplarCharacters",
106 "AuxExemplarCharacters",
107 "ExemplarCharactersIndex",
108 "ExemplarCharactersPunctuation"};
109 const UChar *exemplarChars = NULL;
110 int32_t len = 0;
111 UErrorCode localStatus = U_ZERO_ERROR;
112
113 if (U_FAILURE(*status))
114 return NULL;
115
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;
119 }
120
121 if (localStatus != U_ZERO_ERROR) {
122 *status = localStatus;
123 }
124
125 if (U_FAILURE(*status))
126 return NULL;
127
128 if(fillIn != NULL)
129 uset_applyPattern(fillIn, exemplarChars, len,
130 USET_IGNORE_SPACE | options, status);
131 else
132 fillIn = uset_openPatternOptions(exemplarChars, len,
133 USET_IGNORE_SPACE | options, status);
134
135 return fillIn;
136
137 }
138
139 U_CAPI int32_t U_EXPORT2
140 ulocdata_getDelimiter(ULocaleData *uld, ULocaleDataDelimiterType type,
141 UChar *result, int32_t resultLength, UErrorCode *status){
142
143 static const char* const delimiterKeys[] = {
144 "quotationStart",
145 "quotationEnd",
146 "alternateQuotationStart",
147 "alternateQuotationEnd"
148 };
149
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 }
183
184 if (U_FAILURE(*status)){
185 return 0;
186 }
187
188 u_strncpy(result,delimiter, resultLength);
189 return len;
190 }
191
192 static UResourceBundle * measurementDataBundleForLocale(const char *localeID, UErrorCode *status){
193 char fullLoc[ULOC_FULLNAME_CAPACITY];
194 char region[ULOC_COUNTRY_CAPACITY];
195 UResourceBundle *rb;
196 UResourceBundle *measDataBundle = NULL;
197
198 /* The following code is basically copied from Calendar::setWeekData and
199 * Calendar::getCalendarTypeForLocale with adjustments for resource name
200 */
201 uloc_addLikelySubtags(localeID, fullLoc, ULOC_FULLNAME_CAPACITY, status);
202 uloc_getCountry(fullLoc, region, ULOC_COUNTRY_CAPACITY, status);
203
204 rb = ures_openDirect(NULL, "supplementalData", status);
205 ures_getByKey(rb, "measurementData", rb, status);
206 measDataBundle = ures_getByKey(rb, region, NULL, status);
207 if (*status == U_MISSING_RESOURCE_ERROR && rb != NULL) {
208 *status = U_ZERO_ERROR;
209 measDataBundle = ures_getByKey(rb, "001", NULL, status);
210 }
211 ures_close(rb);
212 return measDataBundle;
213 }
214
215 U_CAPI UMeasurementSystem U_EXPORT2
216 ulocdata_getMeasurementSystem(const char *localeID, UErrorCode *status){
217
218 UResourceBundle* bundle=NULL;
219 UResourceBundle* measurement=NULL;
220 UMeasurementSystem system = UMS_LIMIT;
221
222 if(status == NULL || U_FAILURE(*status)){
223 return system;
224 }
225
226 bundle = measurementDataBundleForLocale(localeID, status);
227
228 measurement = ures_getByKeyWithFallback(bundle, MEASUREMENT_SYSTEM, NULL, status);
229
230 system = (UMeasurementSystem) ures_getInt(measurement, status);
231
232 ures_close(bundle);
233 ures_close(measurement);
234
235 return system;
236
237 }
238
239 U_CAPI void U_EXPORT2
240 ulocdata_getPaperSize(const char* localeID, int32_t *height, int32_t *width, UErrorCode *status){
241 UResourceBundle* bundle=NULL;
242 UResourceBundle* paperSizeBundle = NULL;
243 const int32_t* paperSize=NULL;
244 int32_t len = 0;
245
246 if(status == NULL || U_FAILURE(*status)){
247 return;
248 }
249
250 bundle = measurementDataBundleForLocale(localeID, status);
251 paperSizeBundle = ures_getByKeyWithFallback(bundle, PAPER_SIZE, NULL, status);
252 paperSize = ures_getIntVector(paperSizeBundle, &len, status);
253
254 if(U_SUCCESS(*status)){
255 if(len < 2){
256 *status = U_INTERNAL_PROGRAM_ERROR;
257 }else{
258 *height = paperSize[0];
259 *width = paperSize[1];
260 }
261 }
262
263 ures_close(bundle);
264 ures_close(paperSizeBundle);
265
266 }
267
268 U_CAPI void U_EXPORT2
269 ulocdata_getCLDRVersion(UVersionInfo versionArray, UErrorCode *status) {
270 UResourceBundle *rb = NULL;
271 rb = ures_openDirect(NULL, "supplementalData", status);
272 ures_getVersionByKey(rb, "cldrVersion", versionArray, status);
273 ures_close(rb);
274 }
275
276 U_CAPI int32_t U_EXPORT2
277 ulocdata_getLocaleDisplayPattern(ULocaleData *uld,
278 UChar *result,
279 int32_t resultCapacity,
280 UErrorCode *status) {
281 UResourceBundle *patternBundle;
282 int32_t len = 0;
283 const UChar *pattern = NULL;
284 UErrorCode localStatus = U_ZERO_ERROR;
285
286 if (U_FAILURE(*status))
287 return 0;
288
289 patternBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus);
290
291 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
292 localStatus = U_MISSING_RESOURCE_ERROR;
293 }
294
295 if (localStatus != U_ZERO_ERROR) {
296 *status = localStatus;
297 }
298
299 if (U_FAILURE(*status)){
300 ures_close(patternBundle);
301 return 0;
302 }
303
304 pattern = ures_getStringByKey(patternBundle, "pattern", &len, &localStatus);
305 ures_close(patternBundle);
306
307 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
308 localStatus = U_MISSING_RESOURCE_ERROR;
309 }
310
311 if (localStatus != U_ZERO_ERROR) {
312 *status = localStatus;
313 }
314
315 if (U_FAILURE(*status)){
316 return 0;
317 }
318
319 u_strncpy(result, pattern, resultCapacity);
320 return len;
321 }
322
323
324 U_CAPI int32_t U_EXPORT2
325 ulocdata_getLocaleSeparator(ULocaleData *uld,
326 UChar *result,
327 int32_t resultCapacity,
328 UErrorCode *status) {
329 UResourceBundle *separatorBundle;
330 int32_t len = 0;
331 const UChar *separator = NULL;
332 UErrorCode localStatus = U_ZERO_ERROR;
333
334 if (U_FAILURE(*status))
335 return 0;
336
337 separatorBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", NULL, &localStatus);
338
339 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
340 localStatus = U_MISSING_RESOURCE_ERROR;
341 }
342
343 if (localStatus != U_ZERO_ERROR) {
344 *status = localStatus;
345 }
346
347 if (U_FAILURE(*status)){
348 ures_close(separatorBundle);
349 return 0;
350 }
351
352 separator = ures_getStringByKey(separatorBundle, "separator", &len, &localStatus);
353 ures_close(separatorBundle);
354
355 if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
356 localStatus = U_MISSING_RESOURCE_ERROR;
357 }
358
359 if (localStatus != U_ZERO_ERROR) {
360 *status = localStatus;
361 }
362
363 if (U_FAILURE(*status)){
364 return 0;
365 }
366
367 u_strncpy(result, separator, resultCapacity);
368 return len;
369 }