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