2 ******************************************************************************
4 * Copyright (C) 2003-2013, 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"
25 #define MEASUREMENT_SYSTEM "MeasurementSystem"
26 #define PAPER_SIZE "PaperSize"
28 /** A locale data object.
29 * For usage in C programs.
34 * Controls the "No Substitute" behavior of this locale data object
39 * Pointer to the resource bundle associated with this locale data object
41 UResourceBundle
*bundle
;
44 * Pointer to the lang resource bundle associated with this locale data object
46 UResourceBundle
*langBundle
;
49 U_CAPI ULocaleData
* U_EXPORT2
50 ulocdata_open(const char *localeID
, UErrorCode
*status
)
54 if (U_FAILURE(*status
)) {
58 uld
= (ULocaleData
*)uprv_malloc(sizeof(ULocaleData
));
60 *status
= U_MEMORY_ALLOCATION_ERROR
;
64 uld
->langBundle
= NULL
;
66 uld
->noSubstitute
= FALSE
;
67 uld
->bundle
= ures_open(NULL
, localeID
, status
);
68 uld
->langBundle
= ures_open(U_ICUDATA_LANG
, localeID
, status
);
70 if (U_FAILURE(*status
)) {
79 ulocdata_close(ULocaleData
*uld
)
82 ures_close(uld
->langBundle
);
83 ures_close(uld
->bundle
);
89 ulocdata_setNoSubstitute(ULocaleData
*uld
, UBool setting
)
91 uld
->noSubstitute
= setting
;
94 U_CAPI UBool U_EXPORT2
95 ulocdata_getNoSubstitute(ULocaleData
*uld
)
97 return uld
->noSubstitute
;
100 U_CAPI USet
* U_EXPORT2
101 ulocdata_getExemplarSet(ULocaleData
*uld
, USet
*fillIn
,
102 uint32_t options
, ULocaleDataExemplarSetType extype
, UErrorCode
*status
){
104 static const char* const exemplarSetTypes
[] = { "ExemplarCharacters",
105 "AuxExemplarCharacters",
106 "ExemplarCharactersIndex",
107 "ExemplarCharactersPunctuation"};
108 const UChar
*exemplarChars
= NULL
;
110 UErrorCode localStatus
= U_ZERO_ERROR
;
112 if (U_FAILURE(*status
))
115 exemplarChars
= ures_getStringByKey(uld
->bundle
, exemplarSetTypes
[extype
], &len
, &localStatus
);
116 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
117 localStatus
= U_MISSING_RESOURCE_ERROR
;
120 if (localStatus
!= U_ZERO_ERROR
) {
121 *status
= localStatus
;
124 if (U_FAILURE(*status
))
128 uset_applyPattern(fillIn
, exemplarChars
, len
,
129 USET_IGNORE_SPACE
| options
, status
);
131 fillIn
= uset_openPatternOptions(exemplarChars
, len
,
132 USET_IGNORE_SPACE
| options
, status
);
138 U_CAPI
int32_t U_EXPORT2
139 ulocdata_getDelimiter(ULocaleData
*uld
, ULocaleDataDelimiterType type
,
140 UChar
*result
, int32_t resultLength
, UErrorCode
*status
){
142 static const char* const delimiterKeys
[] = {
145 "alternateQuotationStart",
146 "alternateQuotationEnd"
149 UResourceBundle
*delimiterBundle
;
151 const UChar
*delimiter
= NULL
;
152 UErrorCode localStatus
= U_ZERO_ERROR
;
154 if (U_FAILURE(*status
))
157 delimiterBundle
= ures_getByKey(uld
->bundle
, "delimiters", NULL
, &localStatus
);
159 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
160 localStatus
= U_MISSING_RESOURCE_ERROR
;
163 if (localStatus
!= U_ZERO_ERROR
) {
164 *status
= localStatus
;
167 if (U_FAILURE(*status
)){
168 ures_close(delimiterBundle
);
172 delimiter
= ures_getStringByKey(delimiterBundle
, delimiterKeys
[type
], &len
, &localStatus
);
173 ures_close(delimiterBundle
);
175 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
176 localStatus
= U_MISSING_RESOURCE_ERROR
;
179 if (localStatus
!= U_ZERO_ERROR
) {
180 *status
= localStatus
;
183 if (U_FAILURE(*status
)){
187 u_strncpy(result
,delimiter
, resultLength
);
191 static UResourceBundle
* measurementTypeBundleForLocale(const char *localeID
, const char *measurementType
, UErrorCode
*status
){
192 char fullLoc
[ULOC_FULLNAME_CAPACITY
];
193 char region
[ULOC_COUNTRY_CAPACITY
];
195 UResourceBundle
*measTypeBundle
= NULL
;
197 /* The following code is basically copied from Calendar::setWeekData and
198 * Calendar::getCalendarTypeForLocale with adjustments for resource name
200 uloc_addLikelySubtags(localeID
, fullLoc
, ULOC_FULLNAME_CAPACITY
, status
);
201 uloc_getCountry(fullLoc
, region
, ULOC_COUNTRY_CAPACITY
, status
);
203 rb
= ures_openDirect(NULL
, "supplementalData", status
);
204 ures_getByKey(rb
, "measurementData", rb
, status
);
206 UResourceBundle
*measDataBundle
= ures_getByKey(rb
, region
, NULL
, status
);
207 if (U_SUCCESS(*status
)) {
208 measTypeBundle
= ures_getByKey(measDataBundle
, measurementType
, NULL
, status
);
210 if (*status
== U_MISSING_RESOURCE_ERROR
) {
211 *status
= U_ZERO_ERROR
;
212 if (measDataBundle
!= NULL
) {
213 ures_close(measDataBundle
);
215 measDataBundle
= ures_getByKey(rb
, "001", NULL
, status
);
216 measTypeBundle
= ures_getByKey(measDataBundle
, measurementType
, NULL
, status
);
218 ures_close(measDataBundle
);
221 return measTypeBundle
;
224 U_CAPI UMeasurementSystem U_EXPORT2
225 ulocdata_getMeasurementSystem(const char *localeID
, UErrorCode
*status
){
227 UResourceBundle
* measurement
=NULL
;
228 UMeasurementSystem system
= UMS_LIMIT
;
230 if(status
== NULL
|| U_FAILURE(*status
)){
234 measurement
= measurementTypeBundleForLocale(localeID
, MEASUREMENT_SYSTEM
, status
);
235 system
= (UMeasurementSystem
) ures_getInt(measurement
, status
);
237 ures_close(measurement
);
243 U_CAPI
void U_EXPORT2
244 ulocdata_getPaperSize(const char* localeID
, int32_t *height
, int32_t *width
, UErrorCode
*status
){
245 UResourceBundle
* paperSizeBundle
= NULL
;
246 const int32_t* paperSize
=NULL
;
249 if(status
== NULL
|| U_FAILURE(*status
)){
253 paperSizeBundle
= measurementTypeBundleForLocale(localeID
, PAPER_SIZE
, status
);
254 paperSize
= ures_getIntVector(paperSizeBundle
, &len
, status
);
256 if(U_SUCCESS(*status
)){
258 *status
= U_INTERNAL_PROGRAM_ERROR
;
260 *height
= paperSize
[0];
261 *width
= paperSize
[1];
265 ures_close(paperSizeBundle
);
269 U_CAPI
void U_EXPORT2
270 ulocdata_getCLDRVersion(UVersionInfo versionArray
, UErrorCode
*status
) {
271 UResourceBundle
*rb
= NULL
;
272 rb
= ures_openDirect(NULL
, "supplementalData", status
);
273 ures_getVersionByKey(rb
, "cldrVersion", versionArray
, status
);
277 U_CAPI
int32_t U_EXPORT2
278 ulocdata_getLocaleDisplayPattern(ULocaleData
*uld
,
280 int32_t resultCapacity
,
281 UErrorCode
*status
) {
282 UResourceBundle
*patternBundle
;
284 const UChar
*pattern
= NULL
;
285 UErrorCode localStatus
= U_ZERO_ERROR
;
287 if (U_FAILURE(*status
))
290 patternBundle
= ures_getByKey(uld
->langBundle
, "localeDisplayPattern", NULL
, &localStatus
);
292 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
293 localStatus
= U_MISSING_RESOURCE_ERROR
;
296 if (localStatus
!= U_ZERO_ERROR
) {
297 *status
= localStatus
;
300 if (U_FAILURE(*status
)){
301 ures_close(patternBundle
);
305 pattern
= ures_getStringByKey(patternBundle
, "pattern", &len
, &localStatus
);
306 ures_close(patternBundle
);
308 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
309 localStatus
= U_MISSING_RESOURCE_ERROR
;
312 if (localStatus
!= U_ZERO_ERROR
) {
313 *status
= localStatus
;
316 if (U_FAILURE(*status
)){
320 u_strncpy(result
, pattern
, resultCapacity
);
325 U_CAPI
int32_t U_EXPORT2
326 ulocdata_getLocaleSeparator(ULocaleData
*uld
,
328 int32_t resultCapacity
,
329 UErrorCode
*status
) {
330 UResourceBundle
*separatorBundle
;
332 const UChar
*separator
= NULL
;
333 UErrorCode localStatus
= U_ZERO_ERROR
;
335 static const UChar sub0
[4] = { 0x007b, 0x0030, 0x007d , 0x0000 }; /* {0} */
336 static const UChar sub1
[4] = { 0x007b, 0x0031, 0x007d , 0x0000 }; /* {1} */
337 static const int32_t subLen
= 3;
339 if (U_FAILURE(*status
))
342 separatorBundle
= ures_getByKey(uld
->langBundle
, "localeDisplayPattern", NULL
, &localStatus
);
344 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
345 localStatus
= U_MISSING_RESOURCE_ERROR
;
348 if (localStatus
!= U_ZERO_ERROR
) {
349 *status
= localStatus
;
352 if (U_FAILURE(*status
)){
353 ures_close(separatorBundle
);
357 separator
= ures_getStringByKey(separatorBundle
, "separator", &len
, &localStatus
);
358 ures_close(separatorBundle
);
360 if ( (localStatus
== U_USING_DEFAULT_WARNING
) && uld
->noSubstitute
) {
361 localStatus
= U_MISSING_RESOURCE_ERROR
;
364 if (localStatus
!= U_ZERO_ERROR
) {
365 *status
= localStatus
;
368 if (U_FAILURE(*status
)){
372 /* For backwards compatibility, if we have a pattern, return the portion between {0} and {1} */
373 p0
=u_strstr(separator
, sub0
);
374 p1
=u_strstr(separator
, sub1
);
375 if (p0
!=NULL
&& p1
!=NULL
&& p0
<=p1
) {
376 separator
= (const UChar
*)p0
+ subLen
;
377 len
= p1
- separator
;
378 /* Desired separator is no longer zero-terminated; handle that if necessary */
379 if (len
< resultCapacity
) {
380 u_strncpy(result
, separator
, len
);
386 u_strncpy(result
, separator
, resultCapacity
);