result_type operator() (const result_type& str) const { UnicodeString input = str.c_str(); // 「ン」をマーキング input.findAndReplace("ン", "[ン]"); // カタカナ --> Latin 変換 UErrorCode error = U_ZERO_ERROR; boost::shared_ptr<Transliterator> t( Transliterator::createInstance("Katakana-Latin", UTRANS_FORWARD, error) ); t->transliterate(input); // 伸ばす音の表記変更 + マーキングしたンをNにする + 「つ」を「q」にする std::map<UnicodeString, UnicodeString> long_map = { {"\u0101","a:"}, {"\u0113","i:"}, {"\u012B","u:"}, {"\u014D","e:"}, {"\u014D","o:"}, {"[n]", "N"}, {"~", "q"} }; for (const auto& x : long_map) { input.findAndReplace(x.first, x.second); } // 変換結果取得 size_t length = input.length(); char* result = new char[length + 1]; input.extract(0, length, result, "utf8"); return result; }
UnicodeString& U_EXPORT2 TimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) { if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen) || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) { name.setToBogus(); return name; } int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */); if (sep > 0 && sep + 1 < tzID.length()) { name.setTo(tzID, sep + 1); name.findAndReplace(UnicodeString((UChar)0x5f /* _ */), UnicodeString((UChar)0x20 /* space */)); } else { name.setToBogus(); } return name; }
void CurrencyPluralInfo::setupCurrencyPluralPattern(const Locale& loc, UErrorCode& status) { if (U_FAILURE(status)) { return; } fPluralCountToCurrencyUnitPattern = initHash(status); if (U_FAILURE(status)) { return; } UErrorCode ec = U_ZERO_ERROR; UResourceBundle *rb = ures_open(NULL, loc.getName(), &ec); UResourceBundle *numberPatterns = ures_getByKey(rb, gNumberPatternsTag, NULL, &ec); int32_t ptnLen; // TODO: 0 to be NumberFormat::fNumberStyle const UChar* numberStylePattern = ures_getStringByIndex(numberPatterns, 0, &ptnLen, &ec); int32_t numberStylePatternLen = ptnLen; const UChar* negNumberStylePattern = NULL; int32_t negNumberStylePatternLen = 0; // TODO: Java // parse to check whether there is ";" separator in the numberStylePattern UBool hasSeparator = false; if (U_SUCCESS(ec)) { for (int32_t styleCharIndex = 0; styleCharIndex < ptnLen; ++styleCharIndex) { if (numberStylePattern[styleCharIndex] == gNumberPatternSeparator) { hasSeparator = true; // split the number style pattern into positive and negative negNumberStylePattern = numberStylePattern + styleCharIndex + 1; negNumberStylePatternLen = ptnLen - styleCharIndex - 1; numberStylePatternLen = styleCharIndex; } } } ures_close(numberPatterns); if (U_FAILURE(ec)) { ures_close(rb); return; } UResourceBundle *currencyRes = ures_getByKeyWithFallback(rb, gCurrUnitPtnTag, NULL, &ec); #ifdef CURRENCY_PLURAL_INFO_DEBUG std::cout << "in set up\n"; #endif StringEnumeration* keywords = fPluralRules->getKeywords(ec); if (U_SUCCESS(ec)) { const char* pluralCount; while ((pluralCount = keywords->next(NULL, ec)) != NULL) { if ( U_SUCCESS(ec) ) { int32_t ptnLen; UErrorCode err = U_ZERO_ERROR; const UChar* patternChars = ures_getStringByKeyWithFallback( currencyRes, pluralCount, &ptnLen, &err); if (U_SUCCESS(err) && ptnLen > 0) { UnicodeString* pattern = new UnicodeString(patternChars, ptnLen); #ifdef CURRENCY_PLURAL_INFO_DEBUG char result_1[1000]; pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif pattern->findAndReplace(gPart0, UnicodeString(numberStylePattern, numberStylePatternLen)); pattern->findAndReplace(gPart1, gTripleCurrencySign); if (hasSeparator) { UnicodeString negPattern(patternChars, ptnLen); negPattern.findAndReplace(gPart0, UnicodeString(negNumberStylePattern, negNumberStylePatternLen)); negPattern.findAndReplace(gPart1, gTripleCurrencySign); pattern->append(gNumberPatternSeparator); pattern->append(negPattern); } #ifdef CURRENCY_PLURAL_INFO_DEBUG pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif fPluralCountToCurrencyUnitPattern->put(UnicodeString(pluralCount), pattern, status); } } } } delete keywords; ures_close(currencyRes); ures_close(rb); }
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& RelativeDateFormat::format( Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const { UErrorCode status = U_ZERO_ERROR; UnicodeString relativeDayString; UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status); // calculate the difference, in days, between 'cal' and now. int dayDiff = dayDifference(cal, status); // look up string int32_t len = 0; const UChar *theString = getStringForDay(dayDiff, len, status); if(U_SUCCESS(status) && (theString!=NULL)) { // found a relative string relativeDayString.setTo(theString, len); } if ( relativeDayString.length() > 0 && !fDatePattern.isEmpty() && (fTimePattern.isEmpty() || fCombinedFormat == NULL || fCombinedHasDateAtStart)) { #if !UCONFIG_NO_BREAK_ITERATION // capitalize relativeDayString according to context for relative, set formatter no context if ( u_islower(relativeDayString.char32At(0)) && fCapitalizationBrkIter!= NULL && ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && fCapitalizationOfRelativeUnitsForUIListMenu) || (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_STANDALONE && fCapitalizationOfRelativeUnitsForStandAlone) ) ) { // titlecase first word of relativeDayString relativeDayString.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT); } #endif fDateTimeFormatter->setContext(UDISPCTX_CAPITALIZATION_NONE, status); } else { // set our context for the formatter fDateTimeFormatter->setContext(capitalizationContext, status); } if (fDatePattern.isEmpty()) { fDateTimeFormatter->applyPattern(fTimePattern); fDateTimeFormatter->format(cal,appendTo,pos); } else if (fTimePattern.isEmpty() || fCombinedFormat == NULL) { if (relativeDayString.length() > 0) { appendTo.append(relativeDayString); } else { fDateTimeFormatter->applyPattern(fDatePattern); fDateTimeFormatter->format(cal,appendTo,pos); } } else { UnicodeString datePattern; if (relativeDayString.length() > 0) { // Need to quote the relativeDayString to make it a legal date pattern relativeDayString.findAndReplace(UNICODE_STRING("'", 1), UNICODE_STRING("''", 2)); // double any existing APOSTROPHE relativeDayString.insert(0, APOSTROPHE); // add APOSTROPHE at beginning... relativeDayString.append(APOSTROPHE); // and at end datePattern.setTo(relativeDayString); } else { datePattern.setTo(fDatePattern); } UnicodeString combinedPattern; fCombinedFormat->format(fTimePattern, datePattern, combinedPattern, status); fDateTimeFormatter->applyPattern(combinedPattern); fDateTimeFormatter->format(cal,appendTo,pos); } return appendTo; }
void CurrencyPluralInfo::setupCurrencyPluralPattern(const Locale& loc, UErrorCode& status) { if (U_FAILURE(status)) { return; } if (fPluralCountToCurrencyUnitPattern) { deleteHash(fPluralCountToCurrencyUnitPattern); } fPluralCountToCurrencyUnitPattern = initHash(status); if (U_FAILURE(status)) { return; } NumberingSystem *ns = NumberingSystem::createInstance(loc,status); UErrorCode ec = U_ZERO_ERROR; UResourceBundle *rb = ures_open(NULL, loc.getName(), &ec); UResourceBundle *numElements = ures_getByKeyWithFallback(rb, gNumberElementsTag, NULL, &ec); rb = ures_getByKeyWithFallback(numElements, ns->getName(), rb, &ec); rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec); int32_t ptnLen; const UChar* numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec); // Fall back to "latn" if num sys specific pattern isn't there. if ( ec == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),gLatnTag)) { ec = U_ZERO_ERROR; rb = ures_getByKeyWithFallback(numElements, gLatnTag, rb, &ec); rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec); numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec); } int32_t numberStylePatternLen = ptnLen; const UChar* negNumberStylePattern = NULL; int32_t negNumberStylePatternLen = 0; // TODO: Java // parse to check whether there is ";" separator in the numberStylePattern UBool hasSeparator = false; if (U_SUCCESS(ec)) { for (int32_t styleCharIndex = 0; styleCharIndex < ptnLen; ++styleCharIndex) { if (numberStylePattern[styleCharIndex] == gNumberPatternSeparator) { hasSeparator = true; // split the number style pattern into positive and negative negNumberStylePattern = numberStylePattern + styleCharIndex + 1; negNumberStylePatternLen = ptnLen - styleCharIndex - 1; numberStylePatternLen = styleCharIndex; } } } ures_close(numElements); ures_close(rb); delete ns; if (U_FAILURE(ec)) { return; } UResourceBundle *currRb = ures_open(U_ICUDATA_CURR, loc.getName(), &ec); UResourceBundle *currencyRes = ures_getByKeyWithFallback(currRb, gCurrUnitPtnTag, NULL, &ec); #ifdef CURRENCY_PLURAL_INFO_DEBUG std::cout << "in set up\n"; #endif StringEnumeration* keywords = fPluralRules->getKeywords(ec); if (U_SUCCESS(ec)) { const char* pluralCount; while ((pluralCount = keywords->next(NULL, ec)) != NULL) { if ( U_SUCCESS(ec) ) { int32_t ptnLen; UErrorCode err = U_ZERO_ERROR; const UChar* patternChars = ures_getStringByKeyWithFallback( currencyRes, pluralCount, &ptnLen, &err); if (U_SUCCESS(err) && ptnLen > 0) { UnicodeString* pattern = new UnicodeString(patternChars, ptnLen); #ifdef CURRENCY_PLURAL_INFO_DEBUG char result_1[1000]; pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif pattern->findAndReplace(UnicodeString(TRUE, gPart0, 3), UnicodeString(numberStylePattern, numberStylePatternLen)); pattern->findAndReplace(UnicodeString(TRUE, gPart1, 3), UnicodeString(TRUE, gTripleCurrencySign, 3)); if (hasSeparator) { UnicodeString negPattern(patternChars, ptnLen); negPattern.findAndReplace(UnicodeString(TRUE, gPart0, 3), UnicodeString(negNumberStylePattern, negNumberStylePatternLen)); negPattern.findAndReplace(UnicodeString(TRUE, gPart1, 3), UnicodeString(TRUE, gTripleCurrencySign, 3)); pattern->append(gNumberPatternSeparator); pattern->append(negPattern); } #ifdef CURRENCY_PLURAL_INFO_DEBUG pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif fPluralCountToCurrencyUnitPattern->put(UnicodeString(pluralCount, -1, US_INV), pattern, status); } } } } delete keywords; ures_close(currencyRes); ures_close(currRb); }
void t4p::FinderClass::EscapeRegEx(UnicodeString& regEx) { UnicodeString symbols = UNICODE_STRING_SIMPLE("!@#$%^&*()[]{}\\-+?.,\"|"); // there's got to be a batter way of escaping all regex symbols regEx.findAndReplace(UNICODE_STRING_SIMPLE("\\"), UNICODE_STRING_SIMPLE("\\\\")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("!"), UNICODE_STRING_SIMPLE("\\!")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("@"), UNICODE_STRING_SIMPLE("\\@")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("#"), UNICODE_STRING_SIMPLE("\\#")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("$"), UNICODE_STRING_SIMPLE("\\$")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("%"), UNICODE_STRING_SIMPLE("\\%")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("^"), UNICODE_STRING_SIMPLE("\\^")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("&"), UNICODE_STRING_SIMPLE("\\&")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("*"), UNICODE_STRING_SIMPLE("\\*")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("("), UNICODE_STRING_SIMPLE("\\(")); regEx.findAndReplace(UNICODE_STRING_SIMPLE(")"), UNICODE_STRING_SIMPLE("\\)")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("["), UNICODE_STRING_SIMPLE("\\[")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("]"), UNICODE_STRING_SIMPLE("\\]")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("{"), UNICODE_STRING_SIMPLE("\\{")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("}"), UNICODE_STRING_SIMPLE("\\}")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("-"), UNICODE_STRING_SIMPLE("\\-")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("+"), UNICODE_STRING_SIMPLE("\\+")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("?"), UNICODE_STRING_SIMPLE("\\?")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("."), UNICODE_STRING_SIMPLE("\\.")); regEx.findAndReplace(UNICODE_STRING_SIMPLE(","), UNICODE_STRING_SIMPLE("\\,")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("\""), UNICODE_STRING_SIMPLE("\\\"")); regEx.findAndReplace(UNICODE_STRING_SIMPLE("|"), UNICODE_STRING_SIMPLE("\\|")); }
NumberFormat* NumberFormat::makeInstance(const Locale& desiredLocale, EStyles style, UErrorCode& status) { if (U_FAILURE(status)) return NULL; if (style < 0 || style >= kStyleCount) { status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } #ifdef U_WINDOWS char buffer[8]; int32_t count = desiredLocale.getKeywordValue("compat", buffer, sizeof(buffer), status); // if the locale has "@compat=host", create a host-specific NumberFormat if (count > 0 && uprv_strcmp(buffer, "host") == 0) { Win32NumberFormat *f = NULL; UBool curr = TRUE; switch (style) { case kNumberStyle: curr = FALSE; // fall-through case kCurrencyStyle: case kIsoCurrencyStyle: // do not support plural formatting here case kPluralCurrencyStyle: f = new Win32NumberFormat(desiredLocale, curr, status); if (U_SUCCESS(status)) { return f; } delete f; break; default: break; } } #endif NumberFormat* f = NULL; DecimalFormatSymbols* symbolsToAdopt = NULL; UnicodeString pattern; UResourceBundle *resource = ures_open((char *)0, desiredLocale.getName(), &status); UResourceBundle *numberPatterns = ures_getByKey(resource, DecimalFormat::fgNumberPatterns, NULL, &status); NumberingSystem *ns = NULL; UBool deleteSymbols = TRUE; UHashtable * cache = NULL; int32_t hashKey; UBool getCache = FALSE; UBool deleteNS = FALSE; if (U_FAILURE(status)) { // We don't appear to have resource data available -- use the last-resort data status = U_USING_FALLBACK_WARNING; // When the data is unavailable, and locale isn't passed in, last resort data is used. symbolsToAdopt = new DecimalFormatSymbols(status); // Creates a DecimalFormat instance with the last resort number patterns. pattern.setTo(TRUE, gLastResortNumberPatterns[style], -1); } else { // If not all the styled patterns exists for the NumberFormat in this locale, // sets the status code to failure and returns nil. if (ures_getSize(numberPatterns) < (int32_t)(sizeof(gLastResortNumberPatterns)/sizeof(gLastResortNumberPatterns[0])) -2 ) { //minus 2: ISO and plural status = U_INVALID_FORMAT_ERROR; goto cleanup; } // Loads the decimal symbols of the desired locale. symbolsToAdopt = new DecimalFormatSymbols(desiredLocale, status); int32_t patLen = 0; /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE, * the pattern is the same as the pattern of CURRENCYSTYLE * but by replacing the single currency sign with * double currency sign or triple currency sign. */ int styleInNumberPattern = ((style == kIsoCurrencyStyle || style == kPluralCurrencyStyle) ? kCurrencyStyle : style); const UChar *patResStr = ures_getStringByIndex(numberPatterns, (int32_t)styleInNumberPattern, &patLen, &status); // Creates the specified decimal format style of the desired locale. pattern.setTo(TRUE, patResStr, patLen); } if (U_FAILURE(status) || symbolsToAdopt == NULL) { goto cleanup; } if(style==kCurrencyStyle || style == kIsoCurrencyStyle){ const UChar* currPattern = symbolsToAdopt->getCurrencyPattern(); if(currPattern!=NULL){ pattern.setTo(currPattern, u_strlen(currPattern)); } } // Use numbering system cache hashtable UMTX_CHECK(&nscacheMutex, (UBool)(cache != NumberingSystem_cache), getCache); if (getCache) { umtx_lock(&nscacheMutex); cache = NumberingSystem_cache; umtx_unlock(&nscacheMutex); } // Check cache we got, create if non-existant status = U_ZERO_ERROR; if (cache == NULL) { cache = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &status); if (cache == NULL || U_FAILURE(status)) { // cache not created - out of memory cache = NULL; } else { // cache created uhash_setValueDeleter(cache, deleteNumberingSystem); // set final NumberingSystem_cache value UHashtable* h = NULL; UMTX_CHECK(&nscacheMutex, (UBool)(h != NumberingSystem_cache), getCache); if (getCache) { umtx_lock(&nscacheMutex); h = NumberingSystem_cache; umtx_unlock(&nscacheMutex); } if (h == NULL) { umtx_lock(&nscacheMutex); NumberingSystem_cache = h = cache; cache = NULL; ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup); umtx_unlock(&nscacheMutex); } if(cache != NULL) { uhash_close(cache); } cache = h; } } // Get cached numbering system if (cache != NULL) { hashKey = desiredLocale.hashCode(); umtx_lock(&nscacheMutex); ns = (NumberingSystem *)uhash_iget(cache, hashKey); if (ns == NULL) { ns = NumberingSystem::createInstance(desiredLocale,status); uhash_iput(cache, hashKey, (void*)ns, &status); } umtx_unlock(&nscacheMutex); } else { ns = NumberingSystem::createInstance(desiredLocale,status); deleteNS = TRUE; } // check results of getting a numbering system if ((ns == NULL) || (U_FAILURE(status))) { goto cleanup; } if (ns->isAlgorithmic()) { UnicodeString nsDesc; UnicodeString nsRuleSetGroup; UnicodeString nsRuleSetName; Locale nsLoc; URBNFRuleSetTag desiredRulesType = URBNF_NUMBERING_SYSTEM; nsDesc.setTo(ns->getDescription()); int32_t firstSlash = nsDesc.indexOf(gSlash); int32_t lastSlash = nsDesc.lastIndexOf(gSlash); if ( lastSlash > firstSlash ) { char nsLocID[ULOC_FULLNAME_CAPACITY]; nsDesc.extract(0,firstSlash,nsLocID,ULOC_FULLNAME_CAPACITY,US_INV); nsRuleSetGroup.setTo(nsDesc,firstSlash+1,lastSlash-firstSlash-1); nsRuleSetName.setTo(nsDesc,lastSlash+1); nsLoc = Locale::createFromName(nsLocID); UnicodeString SpelloutRules = UNICODE_STRING_SIMPLE("SpelloutRules"); if ( nsRuleSetGroup.compare(SpelloutRules) == 0 ) { desiredRulesType = URBNF_SPELLOUT; } } else { nsLoc = desiredLocale; nsRuleSetName.setTo(nsDesc); } RuleBasedNumberFormat *r = new RuleBasedNumberFormat(desiredRulesType,nsLoc,status); if (U_FAILURE(status) || r == NULL) { goto cleanup; } r->setDefaultRuleSet(nsRuleSetName,status); f = (NumberFormat *) r; } else { // replace single currency sign in the pattern with double currency sign // if the style is kIsoCurrencyStyle if (style == kIsoCurrencyStyle) { pattern.findAndReplace(gSingleCurrencySign, gDoubleCurrencySign); } f = new DecimalFormat(pattern, symbolsToAdopt, style, status); if (U_FAILURE(status) || f == NULL) { goto cleanup; } deleteSymbols = FALSE; } f->setLocaleIDs(ures_getLocaleByType(numberPatterns, ULOC_VALID_LOCALE, &status), ures_getLocaleByType(numberPatterns, ULOC_ACTUAL_LOCALE, &status)); cleanup: ures_close(numberPatterns); ures_close(resource); if (deleteNS && ns) { delete ns; } if (U_FAILURE(status)) { /* If f exists, then it will delete the symbols */ if (f==NULL) { delete symbolsToAdopt; } else { delete f; } return NULL; } if (f == NULL || symbolsToAdopt == NULL) { status = U_MEMORY_ALLOCATION_ERROR; f = NULL; } if (deleteSymbols && symbolsToAdopt != NULL) { delete symbolsToAdopt; } return f; }
NumberFormat* NumberFormat::makeInstance(const Locale& desiredLocale, UNumberFormatStyle style, UBool mustBeDecimalFormat, UErrorCode& status) { if (U_FAILURE(status)) return NULL; if (style < 0 || style >= UNUM_FORMAT_STYLE_COUNT) { status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } // Some styles are not supported. This is a result of merging // the @draft ICU 4.2 NumberFormat::EStyles into the long-existing UNumberFormatStyle. // Ticket #8503 is for reviewing/fixing/merging the two relevant implementations: // this one and unum_open(). // The UNUM_PATTERN_ styles are not supported here // because this method does not take a pattern string. if (!isStyleSupported(style)) { status = U_UNSUPPORTED_ERROR; return NULL; } #if U_PLATFORM_USES_ONLY_WIN32_API if (!mustBeDecimalFormat) { char buffer[8]; int32_t count = desiredLocale.getKeywordValue("compat", buffer, sizeof(buffer), status); // if the locale has "@compat=host", create a host-specific NumberFormat if (U_SUCCESS(status) && count > 0 && uprv_strcmp(buffer, "host") == 0) { Win32NumberFormat *f = NULL; UBool curr = TRUE; switch (style) { case UNUM_DECIMAL: curr = FALSE; // fall-through case UNUM_CURRENCY: case UNUM_CURRENCY_ISO: // do not support plural formatting here case UNUM_CURRENCY_PLURAL: f = new Win32NumberFormat(desiredLocale, curr, status); if (U_SUCCESS(status)) { return f; } delete f; break; default: break; } } } #endif // Use numbering system cache hashtable umtx_initOnce(gNSCacheInitOnce, &nscacheInit); // Get cached numbering system LocalPointer<NumberingSystem> ownedNs; NumberingSystem *ns = NULL; if (NumberingSystem_cache != NULL) { // TODO: Bad hash key usage, see ticket #8504. int32_t hashKey = desiredLocale.hashCode(); Mutex lock(&nscacheMutex); ns = (NumberingSystem *)uhash_iget(NumberingSystem_cache, hashKey); if (ns == NULL) { ns = NumberingSystem::createInstance(desiredLocale,status); uhash_iput(NumberingSystem_cache, hashKey, (void*)ns, &status); } } else { ownedNs.adoptInstead(NumberingSystem::createInstance(desiredLocale,status)); ns = ownedNs.getAlias(); } // check results of getting a numbering system if (U_FAILURE(status)) { return NULL; } if (mustBeDecimalFormat && ns->isAlgorithmic()) { status = U_UNSUPPORTED_ERROR; return NULL; } LocalPointer<DecimalFormatSymbols> symbolsToAdopt; UnicodeString pattern; LocalUResourceBundlePointer ownedResource(ures_open(NULL, desiredLocale.getName(), &status)); if (U_FAILURE(status)) { // We don't appear to have resource data available -- use the last-resort data status = U_USING_FALLBACK_WARNING; // When the data is unavailable, and locale isn't passed in, last resort data is used. symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(status)); if (symbolsToAdopt.isNull()) { status = U_MEMORY_ALLOCATION_ERROR; return NULL; } // Creates a DecimalFormat instance with the last resort number patterns. pattern.setTo(TRUE, gLastResortNumberPatterns[style], -1); } else { // Loads the decimal symbols of the desired locale. symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(desiredLocale, status)); if (symbolsToAdopt.isNull()) { status = U_MEMORY_ALLOCATION_ERROR; return NULL; } UResourceBundle *resource = ownedResource.orphan(); UResourceBundle *numElements = ures_getByKeyWithFallback(resource, gNumberElements, NULL, &status); resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &status); resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status); ownedResource.adoptInstead(resource); int32_t patLen = 0; const UChar *patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status); // Didn't find a pattern specific to the numbering system, so fall back to "latn" if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(gLatn,ns->getName())) { status = U_ZERO_ERROR; resource = ures_getByKeyWithFallback(numElements, gLatn, resource, &status); resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status); patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status); } ures_close(numElements); // Creates the specified decimal format style of the desired locale. pattern.setTo(TRUE, patResStr, patLen); } if (U_FAILURE(status)) { return NULL; } if(style==UNUM_CURRENCY || style == UNUM_CURRENCY_ISO){ const UChar* currPattern = symbolsToAdopt->getCurrencyPattern(); if(currPattern!=NULL){ pattern.setTo(currPattern, u_strlen(currPattern)); } } NumberFormat *f; if (ns->isAlgorithmic()) { UnicodeString nsDesc; UnicodeString nsRuleSetGroup; UnicodeString nsRuleSetName; Locale nsLoc; URBNFRuleSetTag desiredRulesType = URBNF_NUMBERING_SYSTEM; nsDesc.setTo(ns->getDescription()); int32_t firstSlash = nsDesc.indexOf(gSlash); int32_t lastSlash = nsDesc.lastIndexOf(gSlash); if ( lastSlash > firstSlash ) { CharString nsLocID; nsLocID.appendInvariantChars(nsDesc.tempSubString(0, firstSlash), status); nsRuleSetGroup.setTo(nsDesc,firstSlash+1,lastSlash-firstSlash-1); nsRuleSetName.setTo(nsDesc,lastSlash+1); nsLoc = Locale::createFromName(nsLocID.data()); UnicodeString SpelloutRules = UNICODE_STRING_SIMPLE("SpelloutRules"); if ( nsRuleSetGroup.compare(SpelloutRules) == 0 ) { desiredRulesType = URBNF_SPELLOUT; } } else { nsLoc = desiredLocale; nsRuleSetName.setTo(nsDesc); } RuleBasedNumberFormat *r = new RuleBasedNumberFormat(desiredRulesType,nsLoc,status); if (r == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return NULL; } r->setDefaultRuleSet(nsRuleSetName,status); f = r; } else { // replace single currency sign in the pattern with double currency sign // if the style is UNUM_CURRENCY_ISO if (style == UNUM_CURRENCY_ISO) { pattern.findAndReplace(UnicodeString(TRUE, gSingleCurrencySign, 1), UnicodeString(TRUE, gDoubleCurrencySign, 2)); } // "new DecimalFormat()" does not adopt the symbols if its memory allocation fails. DecimalFormatSymbols *syms = symbolsToAdopt.orphan(); f = new DecimalFormat(pattern, syms, style, status); if (f == NULL) { delete syms; status = U_MEMORY_ALLOCATION_ERROR; return NULL; } } f->setLocaleIDs(ures_getLocaleByType(ownedResource.getAlias(), ULOC_VALID_LOCALE, &status), ures_getLocaleByType(ownedResource.getAlias(), ULOC_ACTUAL_LOCALE, &status)); if (U_FAILURE(status)) { delete f; return NULL; } return f; }
extern int main(int argc, char *argv[]) { int32_t low = 1902; int32_t high = 2038; UBool bAll = FALSE; const char *dir = NULL; const char *linesep = NULL; U_MAIN_INIT_ARGS(argc, argv); argc = u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); if (argc < 0) { cerr << "Illegal command line argument(s)" << endl << endl; } if (argc < 0 || options[kOptHelpH].doesOccur || options[kOptHelpQuestionMark].doesOccur) { cerr << "Usage: icuzdump [-options] [zoneid1 zoneid2 ...]" << endl << endl << "\tDump all offset transitions for the specified zones." << endl << endl << "Options:" << endl << "\t-a : Dump all available zones." << endl << "\t-d <dir> : When specified, write transitions in a file under" << endl << "\t the directory for each zone." << endl << "\t-l <sep> : New line code type used in file outputs. CR or LF (default)" << "\t or CRLF." << endl << "\t-c [<low_year>,]<high_year>" << endl << "\t : When specified, dump transitions starting <low_year>" << endl << "\t (inclusive) up to <high_year> (exclusive). The default" << endl << "\t values are 1902(low) and 2038(high)." << endl; return argc < 0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; } bAll = options[kOptAllZones].doesOccur; if (options[kOptDestDir].doesOccur) { dir = options[kOptDestDir].value; } if (options[kOptLineSep].doesOccur) { if (strcmp(options[kOptLineSep].value, "CR") == 0) { linesep = "\r"; } else if (strcmp(options[kOptLineSep].value, "CRLF") == 0) { linesep = "\r\n"; } else if (strcmp(options[kOptLineSep].value, "LF") == 0) { linesep = "\n"; } } if (options[kOptCutover].doesOccur) { char* comma = (char*)strchr(options[kOptCutover].value, ','); if (comma == NULL) { high = atoi(options[kOptCutover].value); } else { *comma = 0; low = atoi(options[kOptCutover].value); high = atoi(comma + 1); } } ICUZDump dumper; dumper.setLowYear(low); dumper.setHighYear(high); if (dir != NULL && linesep != NULL) { // use the specified line separator only for file output dumper.setLineSeparator((const char*)linesep); } ZoneIterator* zit; if (bAll) { zit = new ZoneIterator(TRUE); } else { if (argc <= 1) { zit = new ZoneIterator(); } else { zit = new ZoneIterator((const char**)&argv[1], argc - 1); } } UnicodeString id; if (dir != NULL) { // file output ostringstream path; ios::openmode mode = ios::out; if (linesep != NULL) { mode |= ios::binary; } for (;;) { TimeZone* tz = zit->next(); if (tz == NULL) { break; } dumper.setTimeZone(tz); tz->getID(id); // target file path path.str(""); path << dir << U_FILE_SEP_CHAR; id = id.findAndReplace("/", "-"); path << id; ofstream* fout = new ofstream(path.str().c_str(), mode); if (fout->fail()) { cerr << "Cannot open file " << path << endl; delete fout; delete tz; break; } dumper.dump(*fout); fout->close(); delete fout; delete tz; } } else { // stdout UBool bFirst = TRUE; for (;;) { TimeZone* tz = zit->next(); if (tz == NULL) { break; } dumper.setTimeZone(tz); tz->getID(id); if (bFirst) { bFirst = FALSE; } else { cout << endl; } cout << "ZONE: " << id << endl; dumper.dump(cout); delete tz; } } delete zit; }
void U_EXPORT2 DateIntervalFormat::adjustFieldWidth(const UnicodeString& inputSkeleton, const UnicodeString& bestMatchSkeleton, const UnicodeString& bestIntervalPattern, int8_t differenceInfo, UnicodeString& adjustedPtn) { adjustedPtn = bestIntervalPattern; int32_t inputSkeletonFieldWidth[] = { // A B C D E F G H I J K L M N O 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // P Q R S T U V W X Y Z 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a b c d e f g h i j k l m n o 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // p q r s t u v w x y z 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int32_t bestMatchSkeletonFieldWidth[] = { // A B C D E F G H I J K L M N O 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // P Q R S T U V W X Y Z 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a b c d e f g h i j k l m n o 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // p q r s t u v w x y z 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; DateIntervalInfo::parseSkeleton(inputSkeleton, inputSkeletonFieldWidth); DateIntervalInfo::parseSkeleton(bestMatchSkeleton, bestMatchSkeletonFieldWidth); if ( differenceInfo == 2 ) { adjustedPtn.findAndReplace("v", "z"); } UBool inQuote = false; UChar prevCh = 0; int32_t count = 0; const int8_t PATTERN_CHAR_BASE = 0x41; // loop through the pattern string character by character int32_t adjustedPtnLength = adjustedPtn.length(); int32_t i; for (i = 0; i < adjustedPtnLength; ++i) { UChar ch = adjustedPtn.charAt(i); if (ch != prevCh && count > 0) { // check the repeativeness of pattern letter UChar skeletonChar = prevCh; if ( skeletonChar == CAP_L ) { // there is no "L" (always be "M") in skeleton, // but there is "L" in pattern. // for skeleton "M+", the pattern might be "...L..." skeletonChar = CAP_M; } int32_t fieldCount = bestMatchSkeletonFieldWidth[(int)(skeletonChar - PATTERN_CHAR_BASE)]; int32_t inputFieldCount = inputSkeletonFieldWidth[(int)(skeletonChar - PATTERN_CHAR_BASE)]; if ( fieldCount == count && inputFieldCount > fieldCount ) { count = inputFieldCount - fieldCount; int32_t j; for ( j = 0; j < count; ++j ) { adjustedPtn.insert(i, prevCh); } i += count; adjustedPtnLength += count; } count = 0; } if (ch == '\'') { // Consecutive single quotes are a single quote literal, // either outside of quotes or between quotes if ((i+1) < adjustedPtn.length() && adjustedPtn.charAt(i+1) == '\'') { ++i; } else { inQuote = ! inQuote; } } else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/) || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) { // ch is a date-time pattern character prevCh = ch; ++count; } } if ( count > 0 ) { // last item // check the repeativeness of pattern letter UChar skeletonChar = prevCh; if ( skeletonChar == CAP_L ) { // there is no "L" (always be "M") in skeleton, // but there is "L" in pattern. // for skeleton "M+", the pattern might be "...L..." skeletonChar = CAP_M; } int32_t fieldCount = bestMatchSkeletonFieldWidth[(int)(skeletonChar - PATTERN_CHAR_BASE)]; int32_t inputFieldCount = inputSkeletonFieldWidth[(int)(skeletonChar - PATTERN_CHAR_BASE)]; if ( fieldCount == count && inputFieldCount > fieldCount ) { count = inputFieldCount - fieldCount; int32_t j; for ( j = 0; j < count; ++j ) { adjustedPtn.append(prevCh); } } } }