|
1 /* |
|
2 ******************************************************************************* |
|
3 * |
|
4 * Copyright (C) 1997-2012, International Business Machines |
|
5 * Corporation and others. All Rights Reserved. |
|
6 * |
|
7 ******************************************************************************* |
|
8 * file name: loclikely.cpp |
|
9 * encoding: US-ASCII |
|
10 * tab size: 8 (not used) |
|
11 * indentation:4 |
|
12 * |
|
13 * created on: 2010feb25 |
|
14 * created by: Markus W. Scherer |
|
15 * |
|
16 * Code for miscellaneous locale-related resource bundle data access, |
|
17 * separated out from other .cpp files |
|
18 * that then do not depend on resource bundle code and this data. |
|
19 */ |
|
20 |
|
21 #include "unicode/utypes.h" |
|
22 #include "unicode/putil.h" |
|
23 #include "unicode/uloc.h" |
|
24 #include "unicode/ures.h" |
|
25 #include "cstring.h" |
|
26 #include "ulocimp.h" |
|
27 #include "uresimp.h" |
|
28 |
|
29 /* |
|
30 * Lookup a resource bundle table item with fallback on the table level. |
|
31 * Regular resource bundle lookups perform fallback to parent locale bundles |
|
32 * and eventually the root bundle, but only for top-level items. |
|
33 * This function takes the name of a top-level table and of an item in that table |
|
34 * and performs a lookup of both, falling back until a bundle contains a table |
|
35 * with this item. |
|
36 * |
|
37 * Note: Only the opening of entire bundles falls back through the default locale |
|
38 * before root. Once a bundle is open, item lookups do not go through the |
|
39 * default locale because that would result in a mix of languages that is |
|
40 * unpredictable to the programmer and most likely useless. |
|
41 */ |
|
42 U_CAPI const UChar * U_EXPORT2 |
|
43 uloc_getTableStringWithFallback(const char *path, const char *locale, |
|
44 const char *tableKey, const char *subTableKey, |
|
45 const char *itemKey, |
|
46 int32_t *pLength, |
|
47 UErrorCode *pErrorCode) |
|
48 { |
|
49 /* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/ |
|
50 UResourceBundle *rb=NULL, table, subTable; |
|
51 const UChar *item=NULL; |
|
52 UErrorCode errorCode; |
|
53 char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0}; |
|
54 |
|
55 /* |
|
56 * open the bundle for the current locale |
|
57 * this falls back through the locale's chain to root |
|
58 */ |
|
59 errorCode=U_ZERO_ERROR; |
|
60 rb=ures_open(path, locale, &errorCode); |
|
61 |
|
62 if(U_FAILURE(errorCode)) { |
|
63 /* total failure, not even root could be opened */ |
|
64 *pErrorCode=errorCode; |
|
65 return NULL; |
|
66 } else if(errorCode==U_USING_DEFAULT_WARNING || |
|
67 (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING) |
|
68 ) { |
|
69 /* set the "strongest" error code (success->fallback->default->failure) */ |
|
70 *pErrorCode=errorCode; |
|
71 } |
|
72 |
|
73 for(;;){ |
|
74 ures_initStackObject(&table); |
|
75 ures_initStackObject(&subTable); |
|
76 ures_getByKeyWithFallback(rb, tableKey, &table, &errorCode); |
|
77 |
|
78 if (subTableKey != NULL) { |
|
79 /* |
|
80 ures_getByKeyWithFallback(&table,subTableKey, &subTable, &errorCode); |
|
81 item = ures_getStringByKeyWithFallback(&subTable, itemKey, pLength, &errorCode); |
|
82 if(U_FAILURE(errorCode)){ |
|
83 *pErrorCode = errorCode; |
|
84 } |
|
85 |
|
86 break;*/ |
|
87 |
|
88 ures_getByKeyWithFallback(&table,subTableKey, &table, &errorCode); |
|
89 } |
|
90 if(U_SUCCESS(errorCode)){ |
|
91 item = ures_getStringByKeyWithFallback(&table, itemKey, pLength, &errorCode); |
|
92 if(U_FAILURE(errorCode)){ |
|
93 const char* replacement = NULL; |
|
94 *pErrorCode = errorCode; /*save the errorCode*/ |
|
95 errorCode = U_ZERO_ERROR; |
|
96 /* may be a deprecated code */ |
|
97 if(uprv_strcmp(tableKey, "Countries")==0){ |
|
98 replacement = uloc_getCurrentCountryID(itemKey); |
|
99 }else if(uprv_strcmp(tableKey, "Languages")==0){ |
|
100 replacement = uloc_getCurrentLanguageID(itemKey); |
|
101 } |
|
102 /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/ |
|
103 if(replacement!=NULL && itemKey != replacement){ |
|
104 item = ures_getStringByKeyWithFallback(&table, replacement, pLength, &errorCode); |
|
105 if(U_SUCCESS(errorCode)){ |
|
106 *pErrorCode = errorCode; |
|
107 break; |
|
108 } |
|
109 } |
|
110 }else{ |
|
111 break; |
|
112 } |
|
113 } |
|
114 |
|
115 if(U_FAILURE(errorCode)){ |
|
116 |
|
117 /* still can't figure out ?.. try the fallback mechanism */ |
|
118 int32_t len = 0; |
|
119 const UChar* fallbackLocale = NULL; |
|
120 *pErrorCode = errorCode; |
|
121 errorCode = U_ZERO_ERROR; |
|
122 |
|
123 fallbackLocale = ures_getStringByKeyWithFallback(&table, "Fallback", &len, &errorCode); |
|
124 if(U_FAILURE(errorCode)){ |
|
125 *pErrorCode = errorCode; |
|
126 break; |
|
127 } |
|
128 |
|
129 u_UCharsToChars(fallbackLocale, explicitFallbackName, len); |
|
130 |
|
131 /* guard against recursive fallback */ |
|
132 if(uprv_strcmp(explicitFallbackName, locale)==0){ |
|
133 *pErrorCode = U_INTERNAL_PROGRAM_ERROR; |
|
134 break; |
|
135 } |
|
136 ures_close(rb); |
|
137 rb = ures_open(path, explicitFallbackName, &errorCode); |
|
138 if(U_FAILURE(errorCode)){ |
|
139 *pErrorCode = errorCode; |
|
140 break; |
|
141 } |
|
142 /* succeeded in opening the fallback bundle .. continue and try to fetch the item */ |
|
143 }else{ |
|
144 break; |
|
145 } |
|
146 } |
|
147 /* done with the locale string - ready to close table and rb */ |
|
148 ures_close(&subTable); |
|
149 ures_close(&table); |
|
150 ures_close(rb); |
|
151 return item; |
|
152 } |
|
153 |
|
154 static ULayoutType |
|
155 _uloc_getOrientationHelper(const char* localeId, |
|
156 const char* key, |
|
157 UErrorCode *status) |
|
158 { |
|
159 ULayoutType result = ULOC_LAYOUT_UNKNOWN; |
|
160 |
|
161 if (!U_FAILURE(*status)) { |
|
162 int32_t length = 0; |
|
163 char localeBuffer[ULOC_FULLNAME_CAPACITY]; |
|
164 |
|
165 uloc_canonicalize(localeId, localeBuffer, sizeof(localeBuffer), status); |
|
166 |
|
167 if (!U_FAILURE(*status)) { |
|
168 const UChar* const value = |
|
169 uloc_getTableStringWithFallback( |
|
170 NULL, |
|
171 localeBuffer, |
|
172 "layout", |
|
173 NULL, |
|
174 key, |
|
175 &length, |
|
176 status); |
|
177 |
|
178 if (!U_FAILURE(*status) && length != 0) { |
|
179 switch(value[0]) |
|
180 { |
|
181 case 0x0062: /* 'b' */ |
|
182 result = ULOC_LAYOUT_BTT; |
|
183 break; |
|
184 case 0x006C: /* 'l' */ |
|
185 result = ULOC_LAYOUT_LTR; |
|
186 break; |
|
187 case 0x0072: /* 'r' */ |
|
188 result = ULOC_LAYOUT_RTL; |
|
189 break; |
|
190 case 0x0074: /* 't' */ |
|
191 result = ULOC_LAYOUT_TTB; |
|
192 break; |
|
193 default: |
|
194 *status = U_INTERNAL_PROGRAM_ERROR; |
|
195 break; |
|
196 } |
|
197 } |
|
198 } |
|
199 } |
|
200 |
|
201 return result; |
|
202 } |
|
203 |
|
204 U_CAPI ULayoutType U_EXPORT2 |
|
205 uloc_getCharacterOrientation(const char* localeId, |
|
206 UErrorCode *status) |
|
207 { |
|
208 return _uloc_getOrientationHelper(localeId, "characters", status); |
|
209 } |
|
210 |
|
211 /** |
|
212 * Get the layout line orientation for the specified locale. |
|
213 * |
|
214 * @param localeID locale name |
|
215 * @param status Error status |
|
216 * @return an enum indicating the layout orientation for lines. |
|
217 */ |
|
218 U_CAPI ULayoutType U_EXPORT2 |
|
219 uloc_getLineOrientation(const char* localeId, |
|
220 UErrorCode *status) |
|
221 { |
|
222 return _uloc_getOrientationHelper(localeId, "lines", status); |
|
223 } |