• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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