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