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