intl/icu/source/common/locresdata.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/common/locresdata.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,223 @@
     1.4 +/*
     1.5 +*******************************************************************************
     1.6 +*
     1.7 +*   Copyright (C) 1997-2012, International Business Machines
     1.8 +*   Corporation and others.  All Rights Reserved.
     1.9 +*
    1.10 +*******************************************************************************
    1.11 +*   file name:  loclikely.cpp
    1.12 +*   encoding:   US-ASCII
    1.13 +*   tab size:   8 (not used)
    1.14 +*   indentation:4
    1.15 +*
    1.16 +*   created on: 2010feb25
    1.17 +*   created by: Markus W. Scherer
    1.18 +*
    1.19 +*   Code for miscellaneous locale-related resource bundle data access,
    1.20 +*   separated out from other .cpp files
    1.21 +*   that then do not depend on resource bundle code and this data.
    1.22 +*/
    1.23 +
    1.24 +#include "unicode/utypes.h"
    1.25 +#include "unicode/putil.h"
    1.26 +#include "unicode/uloc.h"
    1.27 +#include "unicode/ures.h"
    1.28 +#include "cstring.h"
    1.29 +#include "ulocimp.h"
    1.30 +#include "uresimp.h"
    1.31 +
    1.32 +/*
    1.33 + * Lookup a resource bundle table item with fallback on the table level.
    1.34 + * Regular resource bundle lookups perform fallback to parent locale bundles
    1.35 + * and eventually the root bundle, but only for top-level items.
    1.36 + * This function takes the name of a top-level table and of an item in that table
    1.37 + * and performs a lookup of both, falling back until a bundle contains a table
    1.38 + * with this item.
    1.39 + *
    1.40 + * Note: Only the opening of entire bundles falls back through the default locale
    1.41 + * before root. Once a bundle is open, item lookups do not go through the
    1.42 + * default locale because that would result in a mix of languages that is
    1.43 + * unpredictable to the programmer and most likely useless.
    1.44 + */
    1.45 +U_CAPI const UChar * U_EXPORT2
    1.46 +uloc_getTableStringWithFallback(const char *path, const char *locale,
    1.47 +                              const char *tableKey, const char *subTableKey,
    1.48 +                              const char *itemKey,
    1.49 +                              int32_t *pLength,
    1.50 +                              UErrorCode *pErrorCode)
    1.51 +{
    1.52 +/*    char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
    1.53 +    UResourceBundle *rb=NULL, table, subTable;
    1.54 +    const UChar *item=NULL;
    1.55 +    UErrorCode errorCode;
    1.56 +    char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0};
    1.57 +
    1.58 +    /*
    1.59 +     * open the bundle for the current locale
    1.60 +     * this falls back through the locale's chain to root
    1.61 +     */
    1.62 +    errorCode=U_ZERO_ERROR;
    1.63 +    rb=ures_open(path, locale, &errorCode);
    1.64 +
    1.65 +    if(U_FAILURE(errorCode)) {
    1.66 +        /* total failure, not even root could be opened */
    1.67 +        *pErrorCode=errorCode;
    1.68 +        return NULL;
    1.69 +    } else if(errorCode==U_USING_DEFAULT_WARNING ||
    1.70 +                (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING)
    1.71 +    ) {
    1.72 +        /* set the "strongest" error code (success->fallback->default->failure) */
    1.73 +        *pErrorCode=errorCode;
    1.74 +    }
    1.75 +
    1.76 +    for(;;){
    1.77 +        ures_initStackObject(&table);
    1.78 +        ures_initStackObject(&subTable);
    1.79 +        ures_getByKeyWithFallback(rb, tableKey, &table, &errorCode);
    1.80 +
    1.81 +        if (subTableKey != NULL) {
    1.82 +            /*
    1.83 +            ures_getByKeyWithFallback(&table,subTableKey, &subTable, &errorCode);
    1.84 +            item = ures_getStringByKeyWithFallback(&subTable, itemKey, pLength, &errorCode);
    1.85 +            if(U_FAILURE(errorCode)){
    1.86 +                *pErrorCode = errorCode;
    1.87 +            }
    1.88 +            
    1.89 +            break;*/
    1.90 +            
    1.91 +            ures_getByKeyWithFallback(&table,subTableKey, &table, &errorCode);
    1.92 +        }
    1.93 +        if(U_SUCCESS(errorCode)){
    1.94 +            item = ures_getStringByKeyWithFallback(&table, itemKey, pLength, &errorCode);
    1.95 +            if(U_FAILURE(errorCode)){
    1.96 +                const char* replacement = NULL;
    1.97 +                *pErrorCode = errorCode; /*save the errorCode*/
    1.98 +                errorCode = U_ZERO_ERROR;
    1.99 +                /* may be a deprecated code */
   1.100 +                if(uprv_strcmp(tableKey, "Countries")==0){
   1.101 +                    replacement =  uloc_getCurrentCountryID(itemKey);
   1.102 +                }else if(uprv_strcmp(tableKey, "Languages")==0){
   1.103 +                    replacement =  uloc_getCurrentLanguageID(itemKey);
   1.104 +                }
   1.105 +                /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/
   1.106 +                if(replacement!=NULL && itemKey != replacement){
   1.107 +                    item = ures_getStringByKeyWithFallback(&table, replacement, pLength, &errorCode);
   1.108 +                    if(U_SUCCESS(errorCode)){
   1.109 +                        *pErrorCode = errorCode;
   1.110 +                        break;
   1.111 +                    }
   1.112 +                }
   1.113 +            }else{
   1.114 +                break;
   1.115 +            }
   1.116 +        }
   1.117 +        
   1.118 +        if(U_FAILURE(errorCode)){    
   1.119 +
   1.120 +            /* still can't figure out ?.. try the fallback mechanism */
   1.121 +            int32_t len = 0;
   1.122 +            const UChar* fallbackLocale =  NULL;
   1.123 +            *pErrorCode = errorCode;
   1.124 +            errorCode = U_ZERO_ERROR;
   1.125 +
   1.126 +            fallbackLocale = ures_getStringByKeyWithFallback(&table, "Fallback", &len, &errorCode);
   1.127 +            if(U_FAILURE(errorCode)){
   1.128 +               *pErrorCode = errorCode;
   1.129 +                break;
   1.130 +            }
   1.131 +            
   1.132 +            u_UCharsToChars(fallbackLocale, explicitFallbackName, len);
   1.133 +            
   1.134 +            /* guard against recursive fallback */
   1.135 +            if(uprv_strcmp(explicitFallbackName, locale)==0){
   1.136 +                *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
   1.137 +                break;
   1.138 +            }
   1.139 +            ures_close(rb);
   1.140 +            rb = ures_open(path, explicitFallbackName, &errorCode);
   1.141 +            if(U_FAILURE(errorCode)){
   1.142 +                *pErrorCode = errorCode;
   1.143 +                break;
   1.144 +            }
   1.145 +            /* succeeded in opening the fallback bundle .. continue and try to fetch the item */
   1.146 +        }else{
   1.147 +            break;
   1.148 +        }
   1.149 +    }
   1.150 +    /* done with the locale string - ready to close table and rb */
   1.151 +    ures_close(&subTable);
   1.152 +    ures_close(&table);
   1.153 +    ures_close(rb);
   1.154 +    return item;
   1.155 +}
   1.156 +
   1.157 +static ULayoutType
   1.158 +_uloc_getOrientationHelper(const char* localeId,
   1.159 +                           const char* key,
   1.160 +                           UErrorCode *status)
   1.161 +{
   1.162 +    ULayoutType result = ULOC_LAYOUT_UNKNOWN;
   1.163 +
   1.164 +    if (!U_FAILURE(*status)) {
   1.165 +        int32_t length = 0;
   1.166 +        char localeBuffer[ULOC_FULLNAME_CAPACITY];
   1.167 +
   1.168 +        uloc_canonicalize(localeId, localeBuffer, sizeof(localeBuffer), status);
   1.169 +
   1.170 +        if (!U_FAILURE(*status)) {
   1.171 +            const UChar* const value =
   1.172 +                uloc_getTableStringWithFallback(
   1.173 +                    NULL,
   1.174 +                    localeBuffer,
   1.175 +                    "layout",
   1.176 +                    NULL,
   1.177 +                    key,
   1.178 +                    &length,
   1.179 +                    status);
   1.180 +
   1.181 +            if (!U_FAILURE(*status) && length != 0) {
   1.182 +                switch(value[0])
   1.183 +                {
   1.184 +                case 0x0062: /* 'b' */
   1.185 +                    result = ULOC_LAYOUT_BTT;
   1.186 +                    break;
   1.187 +                case 0x006C: /* 'l' */
   1.188 +                    result = ULOC_LAYOUT_LTR;
   1.189 +                    break;
   1.190 +                case 0x0072: /* 'r' */
   1.191 +                    result = ULOC_LAYOUT_RTL;
   1.192 +                    break;
   1.193 +                case 0x0074: /* 't' */
   1.194 +                    result = ULOC_LAYOUT_TTB;
   1.195 +                    break;
   1.196 +                default:
   1.197 +                    *status = U_INTERNAL_PROGRAM_ERROR;
   1.198 +                    break;
   1.199 +                }
   1.200 +            }
   1.201 +        }
   1.202 +    }
   1.203 +
   1.204 +    return result;
   1.205 +}
   1.206 +
   1.207 +U_CAPI ULayoutType U_EXPORT2
   1.208 +uloc_getCharacterOrientation(const char* localeId,
   1.209 +                             UErrorCode *status)
   1.210 +{
   1.211 +    return _uloc_getOrientationHelper(localeId, "characters", status);
   1.212 +}
   1.213 +
   1.214 +/**
   1.215 + * Get the layout line orientation for the specified locale.
   1.216 + * 
   1.217 + * @param localeID locale name
   1.218 + * @param status Error status
   1.219 + * @return an enum indicating the layout orientation for lines.
   1.220 + */
   1.221 +U_CAPI ULayoutType U_EXPORT2
   1.222 +uloc_getLineOrientation(const char* localeId,
   1.223 +                        UErrorCode *status)
   1.224 +{
   1.225 +    return _uloc_getOrientationHelper(localeId, "lines", status);
   1.226 +}

mercurial