NumberingSystem* U_EXPORT2 NumberingSystem::createInstance(const Locale & inLocale, UErrorCode& status) { char buffer[ULOC_KEYWORDS_CAPACITY]; int32_t count = inLocale.getKeywordValue("numbers",buffer, sizeof(buffer),status); if ( count > 0 ) { // @numbers keyword was specified in the locale buffer[count] = '\0'; // Make sure it is null terminated. return NumberingSystem::createInstanceByName(buffer,status); } else { // Find the default numbering system for this locale. LocalUResourceBundlePointer resource(ures_open(NULL, inLocale.getName(), &status)); if (U_FAILURE(status)) { status = U_USING_FALLBACK_WARNING; NumberingSystem *ns = new NumberingSystem(); return ns; } const UChar *defaultNSName = ures_getStringByKeyWithFallback(resource.getAlias(), gDefaultNumberingSystem, &count, &status); if (U_FAILURE(status)) { return NULL; } if ( count > 0 && count < ULOC_KEYWORDS_CAPACITY ) { // Default numbering system found u_UCharsToChars(defaultNSName,buffer,count); buffer[count] = '\0'; // Make sure it is null terminated. return NumberingSystem::createInstanceByName(buffer,status); } else { status = U_USING_FALLBACK_WARNING; NumberingSystem *ns = new NumberingSystem(); return ns; } } }
NumberingSystem* U_EXPORT2 NumberingSystem::createInstance(const Locale & inLocale, UErrorCode& status) { if (U_FAILURE(status)) { return NULL; } UBool nsResolved = TRUE; UBool usingFallback = FALSE; char buffer[ULOC_KEYWORDS_CAPACITY]; int32_t count = inLocale.getKeywordValue("numbers",buffer, sizeof(buffer),status); if ( count > 0 ) { // @numbers keyword was specified in the locale buffer[count] = '\0'; // Make sure it is null terminated. if ( !uprv_strcmp(buffer,gDefault) || !uprv_strcmp(buffer,gNative) || !uprv_strcmp(buffer,gTraditional) || !uprv_strcmp(buffer,gFinance)) { nsResolved = FALSE; } } else { uprv_strcpy(buffer,gDefault); nsResolved = FALSE; } if (!nsResolved) { // Resolve the numbering system ( default, native, traditional or finance ) into a "real" numbering system UErrorCode localStatus = U_ZERO_ERROR; UResourceBundle *resource = ures_open(NULL, inLocale.getName(), &localStatus); UResourceBundle *numberElementsRes = ures_getByKey(resource,gNumberElements,NULL,&localStatus); while (!nsResolved) { localStatus = U_ZERO_ERROR; count = 0; const UChar *nsName = ures_getStringByKeyWithFallback(numberElementsRes, buffer, &count, &localStatus); if ( count > 0 && count < ULOC_KEYWORDS_CAPACITY ) { // numbering system found u_UCharsToChars(nsName,buffer,count); buffer[count] = '\0'; // Make sure it is null terminated. nsResolved = TRUE; } if (!nsResolved) { // Fallback behavior per TR35 - traditional falls back to native, finance and native fall back to default if (!uprv_strcmp(buffer,gNative) || !uprv_strcmp(buffer,gFinance)) { uprv_strcpy(buffer,gDefault); } else if (!uprv_strcmp(buffer,gTraditional)) { uprv_strcpy(buffer,gNative); } else { // If we get here we couldn't find even the default numbering system usingFallback = TRUE; nsResolved = TRUE; } } } ures_close(numberElementsRes); ures_close(resource); } if (usingFallback) { status = U_USING_FALLBACK_WARNING; NumberingSystem *ns = new NumberingSystem(); return ns; } else { return NumberingSystem::createInstanceByName(buffer,status); } }
DateFormat* U_EXPORT2 DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale) { UErrorCode status = U_ZERO_ERROR; #if U_PLATFORM_HAS_WIN32_API char buffer[8]; int32_t count = locale.getKeywordValue("compat", buffer, sizeof(buffer), status); // if the locale has "@compat=host", create a host-specific DateFormat... if (count > 0 && uprv_strcmp(buffer, "host") == 0) { Win32DateFormat *f = new Win32DateFormat(timeStyle, dateStyle, locale, status); if (U_SUCCESS(status)) { return f; } delete f; } #endif // is it relative? if(/*((timeStyle!=UDAT_NONE)&&(timeStyle & UDAT_RELATIVE)) || */((dateStyle!=kNone)&&((dateStyle-kDateOffset) & UDAT_RELATIVE))) { RelativeDateFormat *r = new RelativeDateFormat((UDateFormatStyle)timeStyle, (UDateFormatStyle)(dateStyle-kDateOffset), locale, status); if(U_SUCCESS(status)) return r; delete r; status = U_ZERO_ERROR; } // Try to create a SimpleDateFormat of the desired style. SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status); if (U_SUCCESS(status)) return f; delete f; // If that fails, try to create a format using the default pattern and // the DateFormatSymbols for this locale. status = U_ZERO_ERROR; f = new SimpleDateFormat(locale, status); if (U_SUCCESS(status)) return f; delete f; // This should never really happen, because the preceding constructor // should always succeed. If the resource data is unavailable, a last // resort object should be returned. return 0; }
GLUE_SYM ( Collator ) :: create (const Locale &loc, const char */*ver*/) { // TODO: save 'ver' off. UErrorCode status = U_ZERO_ERROR; char locBuf[200]; char kwvBuf[200]; int32_t len = loc.getKeywordValue("collation", kwvBuf, 200, status); strcpy(locBuf,loc.getBaseName()); if(len>0) { strcat(locBuf,"@collator="); strcat(locBuf,kwvBuf); } UCollator * uc = OICU_ucol_open( locBuf, status); if(U_FAILURE(status)) return NULL; // TODO: ERR? Collator *c = new GLUE_SYM( Collator ) ( uc ); #if COLL_FE_DEBUG fprintf(stderr, "VCF " ICUGLUE_VER_STR " ucol_open=%s ->> %p\n", locBuf, c); #endif return c; }
DateFormat* U_EXPORT2 DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale) { UErrorCode status = U_ZERO_ERROR; #ifdef U_WINDOWS char buffer[8]; int32_t count = locale.getKeywordValue("compat", buffer, sizeof(buffer), status); // if the locale has "@compat=host", create a host-specific DateFormat... if (count > 0 && uprv_strcmp(buffer, "host") == 0) { Win32DateFormat *f = new Win32DateFormat(timeStyle, dateStyle, locale, status); if (U_SUCCESS(status)) { return f; } delete f; } #endif // Try to create a SimpleDateFormat of the desired style. SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status); if (U_SUCCESS(status)) return f; delete f; // If that fails, try to create a format using the default pattern and // the DateFormatSymbols for this locale. status = U_ZERO_ERROR; f = new SimpleDateFormat(locale, status); if (U_SUCCESS(status)) return f; delete f; // This should never really happen, because the preceding constructor // should always succeed. If the resource data is unavailable, a last // resort object should be returned. return 0; }
/** List Localizable Date-Time Formatting Data * * @param locale single string or NULL * @param context single string * @param width single string * @return list * * @version 0.5-1 (Marek Gagolewski, 2014-12-25) * * @version 0.5-1 (Marek Gagolewski, 2015-01-01) * use calendar keyword in locale */ SEXP stri_datetime_symbols(SEXP locale, SEXP context, SEXP width) { const char* qloc = stri__prepare_arg_locale(locale, "locale", true); /* this is R_alloc'ed */ const char* context_str = stri__prepare_arg_string_1_notNA(context, "context"); const char* context_opts[] = {"format", "standalone", NULL}; int context_cur = stri__match_arg(context_str, context_opts); const char* width_str = stri__prepare_arg_string_1_notNA(width, "width"); const char* width_opts[] = {"abbreviated", "wide", "narrow", NULL}; int width_cur = stri__match_arg(width_str, width_opts); DateFormatSymbols::DtContextType context_val; if (context_cur == 0) context_val = DateFormatSymbols::FORMAT; else if (context_cur == 1) context_val = DateFormatSymbols::STANDALONE; else Rf_error(MSG__INCORRECT_MATCH_OPTION, "context"); DateFormatSymbols::DtWidthType width_val; if (width_cur == 0) width_val = DateFormatSymbols::ABBREVIATED; else if (width_cur == 1) width_val = DateFormatSymbols::WIDE; else if (width_cur == 2) width_val = DateFormatSymbols::NARROW; else Rf_error(MSG__INCORRECT_MATCH_OPTION, "width"); UErrorCode status = U_ZERO_ERROR; String8buf calendar_type(128); Locale loc = Locale::createFromName(qloc); int32_t kvlen = loc.getKeywordValue("calendar", calendar_type.data(), calendar_type.size(), status); STRI__CHECKICUSTATUS_RFERROR(status, {/* do nothing special on err */}) status = U_ZERO_ERROR; DateFormatSymbols sym(status); status = U_ZERO_ERROR; if (kvlen == 0) sym = DateFormatSymbols(loc, status); else sym = DateFormatSymbols(loc, calendar_type.data(), status); STRI__CHECKICUSTATUS_RFERROR(status, {/* do nothing special on err */})
UnicodeString& LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale, UnicodeString& result) const { if (locale.isBogus()) { result.setToBogus(); return result; } UnicodeString resultName; const char* lang = locale.getLanguage(); if (uprv_strlen(lang) == 0) { lang = "root"; } const char* script = locale.getScript(); const char* country = locale.getCountry(); const char* variant = locale.getVariant(); UBool hasScript = uprv_strlen(script) > 0; UBool hasCountry = uprv_strlen(country) > 0; UBool hasVariant = uprv_strlen(variant) > 0; if (dialectHandling == ULDN_DIALECT_NAMES) { char buffer[ULOC_FULLNAME_CAPACITY]; do { // loop construct is so we can break early out of search if (hasScript && hasCountry) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasScript = FALSE; hasCountry = FALSE; break; } } if (hasScript) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasScript = FALSE; break; } } if (hasCountry) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasCountry = FALSE; break; } } } while (FALSE); } if (resultName.isBogus() || resultName.isEmpty()) { localeIdName(lang, resultName); } UnicodeString resultRemainder; UnicodeString temp; UErrorCode status = U_ZERO_ERROR; if (hasScript) { resultRemainder.append(scriptDisplayName(script, temp, TRUE)); } if (hasCountry) { appendWithSep(resultRemainder, regionDisplayName(country, temp, TRUE)); } if (hasVariant) { appendWithSep(resultRemainder, variantDisplayName(variant, temp, TRUE)); } resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen); resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen); LocalPointer<StringEnumeration> e(locale.createKeywords(status)); if (e.isValid() && U_SUCCESS(status)) { UnicodeString temp2; char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY const char* key; while ((key = e->next((int32_t *)0, status)) != NULL) { locale.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status); if (U_FAILURE(status)) { return result; } keyDisplayName(key, temp, TRUE); temp.findAndReplace(formatOpenParen, formatReplaceOpenParen); temp.findAndReplace(formatCloseParen, formatReplaceCloseParen); keyValueDisplayName(key, value, temp2, TRUE); temp2.findAndReplace(formatOpenParen, formatReplaceOpenParen); temp2.findAndReplace(formatCloseParen, formatReplaceCloseParen); if (temp2 != UnicodeString(value, -1, US_INV)) { appendWithSep(resultRemainder, temp2); } else if (temp != UnicodeString(key, -1, US_INV)) { UnicodeString temp3; keyTypeFormat.format(temp, temp2, temp3, status); appendWithSep(resultRemainder, temp3); } else { appendWithSep(resultRemainder, temp) .append((UChar)0x3d /* = */) .append(temp2); } } } if (!resultRemainder.isEmpty()) { format.format(resultName, resultRemainder, result.remove(), status); return adjustForUsageAndContext(kCapContextUsageLanguage, result); } result = resultName; return adjustForUsageAndContext(kCapContextUsageLanguage, result); }
UnicodeString& LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale, UnicodeString& result) const { UnicodeString resultName; const char* lang = locale.getLanguage(); if (uprv_strlen(lang) == 0) { lang = "root"; } const char* script = locale.getScript(); const char* country = locale.getCountry(); const char* variant = locale.getVariant(); UBool hasScript = uprv_strlen(script) > 0; UBool hasCountry = uprv_strlen(country) > 0; UBool hasVariant = uprv_strlen(variant) > 0; if (dialectHandling == ULDN_DIALECT_NAMES) { char buffer[ULOC_FULLNAME_CAPACITY]; do { // loop construct is so we can break early out of search if (hasScript && hasCountry) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasScript = FALSE; hasCountry = FALSE; break; } } if (hasScript) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasScript = FALSE; break; } } if (hasCountry) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasCountry = FALSE; break; } } } while (FALSE); } if (resultName.isBogus() || resultName.isEmpty()) { localeIdName(lang, resultName); } UnicodeString resultRemainder; UnicodeString temp; StringEnumeration *e = NULL; UErrorCode status = U_ZERO_ERROR; if (hasScript) { resultRemainder.append(scriptDisplayName(script, temp)); } if (hasCountry) { appendWithSep(resultRemainder, regionDisplayName(country, temp)); } if (hasVariant) { appendWithSep(resultRemainder, variantDisplayName(variant, temp)); } e = locale.createKeywords(status); if (e && U_SUCCESS(status)) { UnicodeString temp2; char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY const char* key; while ((key = e->next((int32_t *)0, status)) != NULL) { locale.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status); keyDisplayName(key, temp); keyValueDisplayName(key, value, temp2); if (temp2 != UnicodeString(value, -1, US_INV)) { appendWithSep(resultRemainder, temp2); } else if (temp != UnicodeString(key, -1, US_INV)) { UnicodeString temp3; Formattable data[] = { temp, temp2 }; FieldPosition fpos; status = U_ZERO_ERROR; keyTypeFormat->format(data, 2, temp3, fpos, status); appendWithSep(resultRemainder, temp3); } else { appendWithSep(resultRemainder, temp) .append((UChar)0x3d /* = */) .append(temp2); } } delete e; } if (!resultRemainder.isEmpty()) { Formattable data[] = { resultName, resultRemainder }; FieldPosition fpos; status = U_ZERO_ERROR; format->format(data, 2, result, fpos, status); return result; } return result = resultName; }