Line data Source code
1 : // © 2016 and later: Unicode, Inc. and others.
2 : // License & terms of use: http://www.unicode.org/copyright.html
3 : /*
4 : *******************************************************************************
5 : *
6 : * Copyright (C) 1997-2012, International Business Machines
7 : * Corporation and others. All Rights Reserved.
8 : *
9 : *******************************************************************************
10 : * file name: loclikely.cpp
11 : * encoding: UTF-8
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 0 : 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 0 : UResourceBundle *rb=NULL, table, subTable;
53 0 : const UChar *item=NULL;
54 : UErrorCode errorCode;
55 0 : 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 0 : errorCode=U_ZERO_ERROR;
62 0 : rb=ures_open(path, locale, &errorCode);
63 :
64 0 : if(U_FAILURE(errorCode)) {
65 : /* total failure, not even root could be opened */
66 0 : *pErrorCode=errorCode;
67 0 : return NULL;
68 0 : } else if(errorCode==U_USING_DEFAULT_WARNING ||
69 0 : (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING)
70 : ) {
71 : /* set the "strongest" error code (success->fallback->default->failure) */
72 0 : *pErrorCode=errorCode;
73 : }
74 :
75 : for(;;){
76 0 : ures_initStackObject(&table);
77 0 : ures_initStackObject(&subTable);
78 0 : ures_getByKeyWithFallback(rb, tableKey, &table, &errorCode);
79 :
80 0 : 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 0 : ures_getByKeyWithFallback(&table,subTableKey, &table, &errorCode);
91 : }
92 0 : if(U_SUCCESS(errorCode)){
93 0 : item = ures_getStringByKeyWithFallback(&table, itemKey, pLength, &errorCode);
94 0 : if(U_FAILURE(errorCode)){
95 0 : const char* replacement = NULL;
96 0 : *pErrorCode = errorCode; /*save the errorCode*/
97 0 : errorCode = U_ZERO_ERROR;
98 : /* may be a deprecated code */
99 0 : if(uprv_strcmp(tableKey, "Countries")==0){
100 0 : replacement = uloc_getCurrentCountryID(itemKey);
101 0 : }else if(uprv_strcmp(tableKey, "Languages")==0){
102 0 : 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 0 : if(replacement!=NULL && itemKey != replacement){
106 0 : item = ures_getStringByKeyWithFallback(&table, replacement, pLength, &errorCode);
107 0 : if(U_SUCCESS(errorCode)){
108 0 : *pErrorCode = errorCode;
109 0 : break;
110 : }
111 : }
112 : }else{
113 0 : break;
114 : }
115 : }
116 :
117 0 : if(U_FAILURE(errorCode)){
118 :
119 : /* still can't figure out ?.. try the fallback mechanism */
120 0 : int32_t len = 0;
121 0 : const UChar* fallbackLocale = NULL;
122 0 : *pErrorCode = errorCode;
123 0 : errorCode = U_ZERO_ERROR;
124 :
125 0 : fallbackLocale = ures_getStringByKeyWithFallback(&table, "Fallback", &len, &errorCode);
126 0 : if(U_FAILURE(errorCode)){
127 0 : *pErrorCode = errorCode;
128 0 : break;
129 : }
130 :
131 0 : u_UCharsToChars(fallbackLocale, explicitFallbackName, len);
132 :
133 : /* guard against recursive fallback */
134 0 : if(uprv_strcmp(explicitFallbackName, locale)==0){
135 0 : *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
136 0 : break;
137 : }
138 0 : ures_close(rb);
139 0 : rb = ures_open(path, explicitFallbackName, &errorCode);
140 0 : if(U_FAILURE(errorCode)){
141 0 : *pErrorCode = errorCode;
142 0 : break;
143 : }
144 : /* succeeded in opening the fallback bundle .. continue and try to fetch the item */
145 : }else{
146 0 : break;
147 : }
148 0 : }
149 : /* done with the locale string - ready to close table and rb */
150 0 : ures_close(&subTable);
151 0 : ures_close(&table);
152 0 : ures_close(rb);
153 0 : return item;
154 : }
155 :
156 : static ULayoutType
157 0 : _uloc_getOrientationHelper(const char* localeId,
158 : const char* key,
159 : UErrorCode *status)
160 : {
161 0 : ULayoutType result = ULOC_LAYOUT_UNKNOWN;
162 :
163 0 : if (!U_FAILURE(*status)) {
164 0 : int32_t length = 0;
165 : char localeBuffer[ULOC_FULLNAME_CAPACITY];
166 :
167 0 : uloc_canonicalize(localeId, localeBuffer, sizeof(localeBuffer), status);
168 :
169 0 : 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 0 : status);
179 :
180 0 : if (!U_FAILURE(*status) && length != 0) {
181 0 : switch(value[0])
182 : {
183 : case 0x0062: /* 'b' */
184 0 : result = ULOC_LAYOUT_BTT;
185 0 : break;
186 : case 0x006C: /* 'l' */
187 0 : result = ULOC_LAYOUT_LTR;
188 0 : break;
189 : case 0x0072: /* 'r' */
190 0 : result = ULOC_LAYOUT_RTL;
191 0 : break;
192 : case 0x0074: /* 't' */
193 0 : result = ULOC_LAYOUT_TTB;
194 0 : break;
195 : default:
196 0 : *status = U_INTERNAL_PROGRAM_ERROR;
197 0 : break;
198 : }
199 : }
200 : }
201 : }
202 :
203 0 : return result;
204 : }
205 :
206 : U_CAPI ULayoutType U_EXPORT2
207 0 : uloc_getCharacterOrientation(const char* localeId,
208 : UErrorCode *status)
209 : {
210 0 : 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.
219 : */
220 : U_CAPI ULayoutType U_EXPORT2
221 0 : uloc_getLineOrientation(const char* localeId,
222 : UErrorCode *status)
223 : {
224 0 : return _uloc_getOrientationHelper(localeId, "lines", status);
225 : }
|