2 ******************************************************************************
4 * Copyright (C) 2003-2016, International Business Machines *
5 * Corporation and others. All Rights Reserved. *
7 ******************************************************************************
8 * file name: ulocdata.c
10 * tab size: 8 (not used)
13 * created on: 2003Oct21
14 * created by: Ram Viswanadha,John Emmons
18 #include "unicode/ustring.h"
19 #include "unicode/ures.h"
20 #include "unicode/uloc.h"
21 #include "unicode/ulocdata.h"
26 #define MEASUREMENT_SYSTEM "MeasurementSystem"
27 #define PAPER_SIZE "PaperSize"
29 /** A locale data object.
30 * For usage in C programs.
35 * Controls the "No Substitute" behavior of this locale data object
40 * Pointer to the resource bundle associated with this locale data object
42 UResourceBundle
*bundle
;
45 * Pointer to the lang resource bundle associated with this locale data object
47 UResourceBundle
*langBundle
;
50 U_CAPI ULocaleData
* U_EXPORT2
51 ulocdata_open(const char *localeID
, UErrorCode
*status
)
55 if (U_FAILURE(*status
)) {
59 uld
= (ULocaleData
*)uprv_malloc(sizeof(ULocaleData
));
61 *status
= U_MEMORY_ALLOCATION_ERROR
;
65 uld
->langBundle
= NULL
;
67 uld
->noSubstitute
= FALSE
;
68 uld
->bundle
= ures_open(NULL
, localeID
, status
);
69 uld
->langBundle
= ures_open(U_ICUDATA_LANG
, localeID
, status
);
71 if (U_FAILURE(*status
)) {
80 ulocdata_close(ULocaleData
*uld
)
83 ures_close(uld
->langBundle
);
84 ures_close(uld
->bundle
);
90 ulocdata_setNoSubstitute(ULocaleData
*uld
, UBool setting
)
92 uld
->noSubstitute
= setting
;
95 U_CAPI UBool U_EXPORT2
96 ulocdata_getNoSubstitute(ULocaleData
*uld
)
98 return uld
->noSubstitute
;
101 U_CAPI USet
* U_EXPORT2
102 ulocdata_getExemplarSet(ULocaleData
*uld
, USet
*fillIn
,
103 uint32_t options
, ULocaleDataExemplarSetType extype
, UErrorCode
*status
){
105 static const char* const exemplarSetTypes
[] = { "ExemplarCharacters",
106 "AuxExemplarCharacters",
107 "ExemplarCharactersIndex",
108 "ExemplarCharactersPunctuation"};
109 const UChar
*exemplarChars
= NULL
;
111 UErrorCode localStatus
= U_ZERO_ERROR
;
113 if (U_FAILURE(*status
))
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
;
121 if (localStatus
!= U_ZERO_ERROR
) {
122 *status
= localStatus
;
125 if (U_FAILURE(*status
))
129 uset_applyPattern(fillIn
, exemplarChars
, len
,
130 USET_IGNORE_SPACE
| options
, status
);
132 fillIn
= uset_openPatternOptions(exemplarChars
, len
,
133 USET_IGNORE_SPACE
| options
, status
);
139 U_CAPI
int32_t U_EXPORT2
140 ulocdata_getDelimiter(ULocaleData
*uld
, ULocaleDataDelimiterType type
,
141 UChar
*result
, int32_t resultLength
, UErrorCode
*status
){
143 static const char* const delimiterKeys
[] = {
146 "alternateQuotationStart",
147 "alternateQuotationEnd"
150 UResourceBundle
*delimiterBundle
;
152 const UChar
*delimiter
= NULL
;
153 UErrorCode localStatus
= U_ZERO_ERROR
;
155 if (U_FAILURE(*status
))
158 delimiterBundle
= ures_getByKey(uld
->bundle
, "delimiters", NULL
, &localStatus
);
160 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
161 localStatus
= U_MISSING_RESOURCE_ERROR
;
164 if (localStatus
!= U_ZERO_ERROR
) {
165 *status
= localStatus
;
168 if (U_FAILURE(*status
)){
169 ures_close(delimiterBundle
);
173 delimiter
= ures_getStringByKey(delimiterBundle
, delimiterKeys
[type
], &len
, &localStatus
);
174 ures_close(delimiterBundle
);
176 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
177 localStatus
= U_MISSING_RESOURCE_ERROR
;
180 if (localStatus
!= U_ZERO_ERROR
) {
181 *status
= localStatus
;
184 if (U_FAILURE(*status
)){
188 u_strncpy(result
,delimiter
, resultLength
);
192 static UResourceBundle
* measurementTypeBundleForLocale(const char *localeID
, const char *measurementType
, UErrorCode
*status
){
193 char region
[ULOC_COUNTRY_CAPACITY
];
195 UResourceBundle
*measTypeBundle
= NULL
;
197 ulocimp_getRegionForSupplementalData(localeID
, TRUE
, region
, ULOC_COUNTRY_CAPACITY
, status
);
199 rb
= ures_openDirect(NULL
, "supplementalData", status
);
200 ures_getByKey(rb
, "measurementData", rb
, status
);
202 UResourceBundle
*measDataBundle
= ures_getByKey(rb
, region
, NULL
, status
);
203 if (U_SUCCESS(*status
)) {
204 measTypeBundle
= ures_getByKey(measDataBundle
, measurementType
, NULL
, status
);
206 if (*status
== U_MISSING_RESOURCE_ERROR
) {
207 *status
= U_ZERO_ERROR
;
208 if (measDataBundle
!= NULL
) {
209 ures_close(measDataBundle
);
211 measDataBundle
= ures_getByKey(rb
, "001", NULL
, status
);
212 measTypeBundle
= ures_getByKey(measDataBundle
, measurementType
, NULL
, status
);
214 ures_close(measDataBundle
);
217 return measTypeBundle
;
220 U_CAPI UMeasurementSystem U_EXPORT2
221 ulocdata_getMeasurementSystem(const char *localeID
, UErrorCode
*status
){
223 UResourceBundle
* measurement
=NULL
;
224 UMeasurementSystem system
= UMS_LIMIT
;
226 if(status
== NULL
|| U_FAILURE(*status
)){
230 measurement
= measurementTypeBundleForLocale(localeID
, MEASUREMENT_SYSTEM
, status
);
231 system
= (UMeasurementSystem
) ures_getInt(measurement
, status
);
233 ures_close(measurement
);
239 U_CAPI
void U_EXPORT2
240 ulocdata_getPaperSize(const char* localeID
, int32_t *height
, int32_t *width
, UErrorCode
*status
){
241 UResourceBundle
* paperSizeBundle
= NULL
;
242 const int32_t* paperSize
=NULL
;
245 if(status
== NULL
|| U_FAILURE(*status
)){
249 paperSizeBundle
= measurementTypeBundleForLocale(localeID
, PAPER_SIZE
, status
);
250 paperSize
= ures_getIntVector(paperSizeBundle
, &len
, status
);
252 if(U_SUCCESS(*status
)){
254 *status
= U_INTERNAL_PROGRAM_ERROR
;
256 *height
= paperSize
[0];
257 *width
= paperSize
[1];
261 ures_close(paperSizeBundle
);
265 U_CAPI
void U_EXPORT2
266 ulocdata_getCLDRVersion(UVersionInfo versionArray
, UErrorCode
*status
) {
267 UResourceBundle
*rb
= NULL
;
268 rb
= ures_openDirect(NULL
, "supplementalData", status
);
269 ures_getVersionByKey(rb
, "cldrVersion", versionArray
, status
);
273 U_CAPI
int32_t U_EXPORT2
274 ulocdata_getLocaleDisplayPattern(ULocaleData
*uld
,
276 int32_t resultCapacity
,
277 UErrorCode
*status
) {
278 UResourceBundle
*patternBundle
;
280 const UChar
*pattern
= NULL
;
281 UErrorCode localStatus
= U_ZERO_ERROR
;
283 if (U_FAILURE(*status
))
286 patternBundle
= ures_getByKey(uld
->langBundle
, "localeDisplayPattern", NULL
, &localStatus
);
288 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
289 localStatus
= U_MISSING_RESOURCE_ERROR
;
292 if (localStatus
!= U_ZERO_ERROR
) {
293 *status
= localStatus
;
296 if (U_FAILURE(*status
)){
297 ures_close(patternBundle
);
301 pattern
= ures_getStringByKey(patternBundle
, "pattern", &len
, &localStatus
);
302 ures_close(patternBundle
);
304 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
305 localStatus
= U_MISSING_RESOURCE_ERROR
;
308 if (localStatus
!= U_ZERO_ERROR
) {
309 *status
= localStatus
;
312 if (U_FAILURE(*status
)){
316 u_strncpy(result
, pattern
, resultCapacity
);
321 U_CAPI
int32_t U_EXPORT2
322 ulocdata_getLocaleSeparator(ULocaleData
*uld
,
324 int32_t resultCapacity
,
325 UErrorCode
*status
) {
326 UResourceBundle
*separatorBundle
;
328 const UChar
*separator
= NULL
;
329 UErrorCode localStatus
= U_ZERO_ERROR
;
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;
335 if (U_FAILURE(*status
))
338 separatorBundle
= ures_getByKey(uld
->langBundle
, "localeDisplayPattern", NULL
, &localStatus
);
340 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
341 localStatus
= U_MISSING_RESOURCE_ERROR
;
344 if (localStatus
!= U_ZERO_ERROR
) {
345 *status
= localStatus
;
348 if (U_FAILURE(*status
)){
349 ures_close(separatorBundle
);
353 separator
= ures_getStringByKey(separatorBundle
, "separator", &len
, &localStatus
);
354 ures_close(separatorBundle
);
356 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
357 localStatus
= U_MISSING_RESOURCE_ERROR
;
360 if (localStatus
!= U_ZERO_ERROR
) {
361 *status
= localStatus
;
364 if (U_FAILURE(*status
)){
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
);
382 u_strncpy(result
, separator
, resultCapacity
);