U_CAPI void U_EXPORT2 ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode) { if(U_FAILURE(*pErrorCode)) { return; } if (locale != NULL && *locale == 0) { csm->locale[0] = 0; csm->caseLocale = UCASE_LOC_ROOT; return; } int32_t length=uloc_getName(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode); if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR || length==sizeof(csm->locale)) { *pErrorCode=U_ZERO_ERROR; /* we only really need the language code for case mappings */ length=uloc_getLanguage(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode); } if(length==sizeof(csm->locale)) { *pErrorCode=U_BUFFER_OVERFLOW_ERROR; } if(U_SUCCESS(*pErrorCode)) { csm->caseLocale=UCASE_LOC_UNKNOWN; csm->caseLocale = ucase_getCaseLocale(csm->locale); } else { csm->locale[0]=0; csm->caseLocale = UCASE_LOC_ROOT; } }
ERL_NIF_TERM locale_name(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { UErrorCode status = U_ZERO_ERROR; int32_t /*value_len,*/ key_len; char value[LOCALE_LEN], key[LOCALE_LEN]; if (argc != 1) return enif_make_badarg(env); key_len = enif_get_atom(env, argv[0], (char*) key, LOCALE_LEN, ERL_NIF_LATIN1); if (!key_len) { return enif_make_badarg(env); } /*value_len =*/ uloc_getName((const char*) key, /* Locale Id */ (char *) value, /* Name */ (int32_t) LOCALE_LEN, &status); CHECK(env, status); return enif_make_atom(env, value); }
U_CDECL_END U_NAMESPACE_BEGIN Locale *locale_set_default_internal(const char *id, UErrorCode& status) { // Synchronize this entire function. Mutex lock(&gDefaultLocaleMutex); UBool canonicalize = FALSE; // If given a NULL string for the locale id, grab the default // name from the system. // (Different from most other locale APIs, where a null name means use // the current ICU default locale.) if (id == NULL) { id = uprv_getDefaultLocaleID(); // This function not thread safe? TODO: verify. canonicalize = TRUE; // always canonicalize host ID } char localeNameBuf[512]; if (canonicalize) { uloc_canonicalize(id, localeNameBuf, sizeof(localeNameBuf)-1, &status); } else { uloc_getName(id, localeNameBuf, sizeof(localeNameBuf)-1, &status); } localeNameBuf[sizeof(localeNameBuf)-1] = 0; // Force null termination in event of // a long name filling the buffer. // (long names are truncated.) // if (U_FAILURE(status)) { return gDefaultLocale; } if (gDefaultLocalesHashT == NULL) { gDefaultLocalesHashT = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status); if (U_FAILURE(status)) { return gDefaultLocale; } uhash_setValueDeleter(gDefaultLocalesHashT, deleteLocale); ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup); } Locale *newDefault = (Locale *)uhash_get(gDefaultLocalesHashT, localeNameBuf); if (newDefault == NULL) { newDefault = new Locale(Locale::eBOGUS); if (newDefault == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return gDefaultLocale; } newDefault->init(localeNameBuf, FALSE); uhash_put(gDefaultLocalesHashT, (char*) newDefault->getName(), newDefault, &status); if (U_FAILURE(status)) { return gDefaultLocale; } } gDefaultLocale = newDefault; return gDefaultLocale; }
int32_t GetLocale( const UChar* localeName, char* localeNameResult, int32_t localeNameResultLength, bool canonicalize, UErrorCode* err) { char localeNameTemp[ULOC_FULLNAME_CAPACITY] = {0}; int32_t localeLength; // Convert ourselves instead of doing u_UCharsToChars as that function considers '@' a variant and stops. for (int i = 0; i < ULOC_FULLNAME_CAPACITY - 1; i++) { UChar c = localeName[i]; if (c > (UChar)0x7F) { *err = U_ILLEGAL_ARGUMENT_ERROR; return ULOC_FULLNAME_CAPACITY; } localeNameTemp[i] = (char)c; if (c == (UChar)0x0) { break; } } if (canonicalize) { localeLength = uloc_canonicalize(localeNameTemp, localeNameResult, localeNameResultLength, err); } else { localeLength = uloc_getName(localeNameTemp, localeNameResult, localeNameResultLength, err); } if (U_SUCCESS(*err)) { // Make sure the "language" part of the locale is reasonable (i.e. we can fetch it and it is within range). // This mimics how the C++ ICU API determines if a locale is "bogus" or not. char language[ULOC_LANG_CAPACITY]; uloc_getLanguage(localeNameTemp, language, ULOC_LANG_CAPACITY, err); if (*err == U_STRING_NOT_TERMINATED_WARNING) { // ULOC_LANG_CAPACITY includes the null terminator, so if we couldn't extract the language with the null // terminator, the language must be invalid. *err = U_ILLEGAL_ARGUMENT_ERROR; } } return localeLength; }
U_CAPI void U_EXPORT2 ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode) { int32_t length; if(U_FAILURE(*pErrorCode)) { return; } length=uloc_getName(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode); if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR || length==sizeof(csm->locale)) { *pErrorCode=U_ZERO_ERROR; /* we only really need the language code for case mappings */ length=uloc_getLanguage(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode); } if(length==sizeof(csm->locale)) { *pErrorCode=U_BUFFER_OVERFLOW_ERROR; } csm->locCache=0; if(U_SUCCESS(*pErrorCode)) { ucase_getCaseLocale(csm->locale, &csm->locCache); } else { csm->locale[0]=0; } }
/*---------------------------------------------------------------------------------------------- Ensure that we have a collator. ----------------------------------------------------------------------------------------------*/ void LgIcuCollator::EnsureCollator() { if (m_pCollator) return; // we already have one. UErrorCode uerr = U_ZERO_ERROR; if (m_stuLocale.Length() == 0) { m_pCollator = Collator::createInstance(uerr); } else { StrAnsi sta(m_stuLocale.Bstr()); char rgchLoc[128]; int32_t cch = uloc_getName(sta.Chars(), rgchLoc, sizeof(rgchLoc), &uerr); Assert(cch < 128); rgchLoc[cch] = 0; if (U_FAILURE(uerr)) ThrowHr(E_FAIL); const Locale loc = Locale::createFromName (rgchLoc); m_pCollator = Collator::createInstance (loc, uerr); } if (U_FAILURE(uerr)) ThrowHr(E_FAIL); }
U_CAPI const UChar* U_EXPORT2 ucurr_getName(const UChar* currency, const char* locale, UCurrNameStyle nameStyle, UBool* isChoiceFormat, // fillin int32_t* len, // fillin UErrorCode* ec) { // Look up the Currencies resource for the given locale. The // Currencies locale data looks like this: //|en { //| Currencies { //| USD { "US$", "US Dollar" } //| CHF { "Sw F", "Swiss Franc" } //| INR { "=0#Rs|1#Re|1<Rs", "=0#Rupees|1#Rupee|1<Rupees" } //| //... //| } //|} if (U_FAILURE(*ec)) { return 0; } int32_t choice = (int32_t) nameStyle; if (choice < 0 || choice > 1) { *ec = U_ILLEGAL_ARGUMENT_ERROR; return 0; } // In the future, resource bundles may implement multi-level // fallback. That is, if a currency is not found in the en_US // Currencies data, then the en Currencies data will be searched. // Currently, if a Currencies datum exists in en_US and en, the // en_US entry hides that in en. // We want multi-level fallback for this resource, so we implement // it manually. // Use a separate UErrorCode here that does not propagate out of // this function. UErrorCode ec2 = U_ZERO_ERROR; char loc[ULOC_FULLNAME_CAPACITY]; uloc_getName(locale, loc, sizeof(loc), &ec2); if (U_FAILURE(ec2) || ec2 == U_STRING_NOT_TERMINATED_WARNING) { *ec = U_ILLEGAL_ARGUMENT_ERROR; return 0; } char buf[ISO_COUNTRY_CODE_LENGTH+1]; myUCharsToChars(buf, currency); const UChar* s = NULL; ec2 = U_ZERO_ERROR; UResourceBundle* rb = ures_open(NULL, loc, &ec2); rb = ures_getByKey(rb, CURRENCIES, rb, &ec2); // Fetch resource with multi-level resource inheritance fallback rb = ures_getByKeyWithFallback(rb, buf, rb, &ec2); s = ures_getStringByIndex(rb, choice, len, &ec2); ures_close(rb); // If we've succeeded we're done. Otherwise, try to fallback. // If that fails (because we are already at root) then exit. if (U_SUCCESS(ec2)) { if (ec2 == U_USING_DEFAULT_WARNING || (ec2 == U_USING_FALLBACK_WARNING && *ec != U_USING_DEFAULT_WARNING)) { *ec = ec2; } } // Determine if this is a ChoiceFormat pattern. One leading mark // indicates a ChoiceFormat. Two indicates a static string that // starts with a mark. In either case, the first mark is ignored, // if present. Marks in the rest of the string have no special // meaning. *isChoiceFormat = FALSE; if (U_SUCCESS(ec2)) { U_ASSERT(s != NULL); int32_t i=0; while (i < *len && s[i] == CHOICE_FORMAT_MARK && i < 2) { ++i; } *isChoiceFormat = (i == 1); if (i != 0) ++s; // Skip over first mark return s; } // If we fail to find a match, use the ISO 4217 code *len = u_strlen(currency); // Should == ISO_COUNTRY_CODE_LENGTH, but maybe not...? *ec = U_USING_DEFAULT_WARNING; return currency; }