]> git.saurik.com Git - apple/icu.git/blame_incremental - icuSources/i18n/ulocdata.c
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / ulocdata.c
... / ...
CommitLineData
1/*
2******************************************************************************
3* *
4* Copyright (C) 2003-2016, 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 "uresimp.h"
23#include "ureslocs.h"
24#include "ulocimp.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 */
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;
43
44 /**
45 * Pointer to the lang resource bundle associated with this locale data object
46 */
47 UResourceBundle *langBundle;
48};
49
50U_CAPI ULocaleData* U_EXPORT2
51ulocdata_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
79U_CAPI void U_EXPORT2
80ulocdata_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
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
102ulocdata_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
139U_CAPI int32_t U_EXPORT2
140ulocdata_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
192static UResourceBundle * measurementTypeBundleForLocale(const char *localeID, const char *measurementType, UErrorCode *status){
193 char region[ULOC_COUNTRY_CAPACITY];
194 UResourceBundle *rb;
195 UResourceBundle *measTypeBundle = NULL;
196
197 ulocimp_getRegionForSupplementalData(localeID, TRUE, region, ULOC_COUNTRY_CAPACITY, status);
198
199 rb = ures_openDirect(NULL, "supplementalData", status);
200 ures_getByKey(rb, "measurementData", rb, status);
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);
215 }
216 ures_close(rb);
217 return measTypeBundle;
218}
219
220U_CAPI UMeasurementSystem U_EXPORT2
221ulocdata_getMeasurementSystem(const char *localeID, UErrorCode *status){
222
223 UResourceBundle* measurement=NULL;
224 UMeasurementSystem system = UMS_LIMIT;
225
226 if(status == NULL || U_FAILURE(*status)){
227 return system;
228 }
229
230 measurement = measurementTypeBundleForLocale(localeID, MEASUREMENT_SYSTEM, status);
231 system = (UMeasurementSystem) ures_getInt(measurement, status);
232
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){
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 }
248
249 paperSizeBundle = measurementTypeBundleForLocale(localeID, PAPER_SIZE, status);
250 paperSize = ures_getIntVector(paperSizeBundle, &len, status);
251
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 }
260
261 ures_close(paperSizeBundle);
262
263}
264
265U_CAPI void U_EXPORT2
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
273U_CAPI int32_t U_EXPORT2
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
321U_CAPI int32_t U_EXPORT2
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;
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;
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
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
382 u_strncpy(result, separator, resultCapacity);
383 return len;
384}