Ejemplo n.º 1
0
	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;
	}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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("\\|"));
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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);    
            }                    
        }
    }
}