• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 1997-2010, 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
uloc_getTableStringWithFallback(const char * path,const char * locale,const char * tableKey,const char * subTableKey,const char * itemKey,int32_t * pLength,UErrorCode * pErrorCode)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
_uloc_getOrientationHelper(const char * localeId,const char * key,UErrorCode * status)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_DRAFT ULayoutType U_EXPORT2
uloc_getCharacterOrientation(const char * localeId,UErrorCode * status)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  * @stable ICU 4.0
218  */
219 U_DRAFT ULayoutType U_EXPORT2
uloc_getLineOrientation(const char * localeId,UErrorCode * status)220 uloc_getLineOrientation(const char* localeId,
221                         UErrorCode *status)
222 {
223     return _uloc_getOrientationHelper(localeId, "lines", status);
224 }
225