]>
Commit | Line | Data |
---|---|---|
729e4ab9 A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
51004dcb | 4 | * Copyright (C) 1997-2012, International Business Machines |
729e4ab9 A |
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 | ||
51004dcb | 204 | U_CAPI ULayoutType U_EXPORT2 |
729e4ab9 A |
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. | |
729e4ab9 | 217 | */ |
51004dcb | 218 | U_CAPI ULayoutType U_EXPORT2 |
729e4ab9 A |
219 | uloc_getLineOrientation(const char* localeId, |
220 | UErrorCode *status) | |
221 | { | |
222 | return _uloc_getOrientationHelper(localeId, "lines", status); | |
223 | } |