tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

locresdata.cpp (7809B)


      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 "charstr.h"
     28 #include "cstring.h"
     29 #include "ulocimp.h"
     30 #include "uresimp.h"
     31 
     32 /*
     33 * Lookup a resource bundle table item with fallback on the table level.
     34 * Regular resource bundle lookups perform fallback to parent locale bundles
     35 * and eventually the root bundle, but only for top-level items.
     36 * This function takes the name of a top-level table and of an item in that table
     37 * and performs a lookup of both, falling back until a bundle contains a table
     38 * with this item.
     39 *
     40 * Note: Only the opening of entire bundles falls back through the default locale
     41 * before root. Once a bundle is open, item lookups do not go through the
     42 * default locale because that would result in a mix of languages that is
     43 * unpredictable to the programmer and most likely useless.
     44 */
     45 U_CAPI const char16_t * U_EXPORT2
     46 uloc_getTableStringWithFallback(const char *path, const char *locale,
     47                              const char *tableKey, const char *subTableKey,
     48                              const char *itemKey,
     49                              int32_t *pLength,
     50                              UErrorCode *pErrorCode)
     51 {
     52    if (U_FAILURE(*pErrorCode)) { return nullptr; }
     53 /*    char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
     54    const char16_t *item=nullptr;
     55    UErrorCode errorCode;
     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    icu::LocalUResourceBundlePointer 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 nullptr;
     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        icu::StackUResourceBundle table;
     77        icu::StackUResourceBundle subTable;
     78        ures_getByKeyWithFallback(rb.getAlias(), tableKey, table.getAlias(), &errorCode);
     79 
     80        if (subTableKey != nullptr) {
     81            /*
     82            ures_getByKeyWithFallback(table.getAlias(), subTableKey, subTable.getAlias(), &errorCode);
     83            item = ures_getStringByKeyWithFallback(subTable.getAlias(), itemKey, pLength, &errorCode);
     84            if(U_FAILURE(errorCode)){
     85                *pErrorCode = errorCode;
     86            }
     87            
     88            break;*/
     89            
     90            ures_getByKeyWithFallback(table.getAlias(), subTableKey, table.getAlias(), &errorCode);
     91        }
     92        if(U_SUCCESS(errorCode)){
     93            item = ures_getStringByKeyWithFallback(table.getAlias(), itemKey, pLength, &errorCode);
     94            if(U_FAILURE(errorCode)){
     95                const char* replacement = nullptr;
     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!=nullptr && itemKey != replacement){
    106                    item = ures_getStringByKeyWithFallback(table.getAlias(), 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 char16_t* fallbackLocale =  nullptr;
    122            *pErrorCode = errorCode;
    123            errorCode = U_ZERO_ERROR;
    124 
    125            fallbackLocale = ures_getStringByKeyWithFallback(table.getAlias(), "Fallback", &len, &errorCode);
    126            if(U_FAILURE(errorCode)){
    127               *pErrorCode = errorCode;
    128                break;
    129            }
    130 
    131            icu::CharString explicitFallbackName;
    132            explicitFallbackName.appendInvariantChars(fallbackLocale, len, errorCode);
    133 
    134            /* guard against recursive fallback */
    135            if (explicitFallbackName == locale) {
    136                *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
    137                break;
    138            }
    139            rb.adoptInstead(ures_open(path, explicitFallbackName.data(), &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 
    150    return item;
    151 }
    152 
    153 namespace {
    154 
    155 ULayoutType
    156 _uloc_getOrientationHelper(const char* localeId,
    157                           const char* key,
    158                           UErrorCode& status)
    159 {
    160    ULayoutType result = ULOC_LAYOUT_UNKNOWN;
    161 
    162    if (U_FAILURE(status)) { return result; }
    163 
    164    if (localeId == nullptr) {
    165        localeId = uloc_getDefault();
    166    }
    167    icu::CharString localeBuffer = ulocimp_canonicalize(localeId, status);
    168 
    169    if (U_FAILURE(status)) { return result; }
    170 
    171    int32_t length = 0;
    172    const char16_t* const value =
    173        uloc_getTableStringWithFallback(
    174            nullptr,
    175            localeBuffer.data(),
    176            "layout",
    177            nullptr,
    178            key,
    179            &length,
    180            &status);
    181 
    182    if (U_FAILURE(status)) { return result; }
    183 
    184    if (length != 0) {
    185        switch(value[0])
    186        {
    187        case 0x0062: /* 'b' */
    188            result = ULOC_LAYOUT_BTT;
    189            break;
    190        case 0x006C: /* 'l' */
    191            result = ULOC_LAYOUT_LTR;
    192            break;
    193        case 0x0072: /* 'r' */
    194            result = ULOC_LAYOUT_RTL;
    195            break;
    196        case 0x0074: /* 't' */
    197            result = ULOC_LAYOUT_TTB;
    198            break;
    199        default:
    200            status = U_INTERNAL_PROGRAM_ERROR;
    201            break;
    202        }
    203    }
    204 
    205    return result;
    206 }
    207 
    208 }  // namespace
    209 
    210 U_CAPI ULayoutType U_EXPORT2
    211 uloc_getCharacterOrientation(const char* localeId,
    212                             UErrorCode *status)
    213 {
    214    return _uloc_getOrientationHelper(localeId, "characters", *status);
    215 }
    216 
    217 /**
    218 * Get the layout line orientation for the specified locale.
    219 * 
    220 * @param localeID locale name
    221 * @param status Error status
    222 * @return an enum indicating the layout orientation for lines.
    223 */
    224 U_CAPI ULayoutType U_EXPORT2
    225 uloc_getLineOrientation(const char* localeId,
    226                        UErrorCode *status)
    227 {
    228    return _uloc_getOrientationHelper(localeId, "lines", *status);
    229 }