//static void NativeDecimalFormat_setRoundingMode(JNIEnv*, jclass, jint addr, jint mode, jdouble increment) { JNIEXPORT void JNICALL Java_com_ibm_icu4jni_text_NativeDecimalFormat_setRoundingMode(JNIEnv*, jclass, jint addr, jint mode, jdouble increment) { DecimalFormat* fmt = toDecimalFormat(addr); fmt->setRoundingMode(static_cast<DecimalFormat::ERoundingMode> (mode)); fmt->setRoundingIncrement(increment); }
/** * Returns a pointer to a Region using the given numeric region code. If the numeric region code is not recognized, * the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ). */ const Region* U_EXPORT2 Region::getInstance (int32_t code, UErrorCode &status) { loadRegionData(); Region *r = (Region *)uhash_iget(numericCodeMap,code); if ( !r ) { // Just in case there's an alias that's numeric, try to find it. UErrorCode fs = U_ZERO_ERROR; UnicodeString pat = UNICODE_STRING_SIMPLE("00#"); DecimalFormat *df = new DecimalFormat(pat,fs); UnicodeString id; id.remove(); df->format(code,id); delete df; r = (Region *)uhash_get(regionAliases,&id); } if ( !r ) { status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } if ( r->type == URGN_DEPRECATED && r->preferredValues->size() == 1) { StringEnumeration *pv = r->getPreferredValues(); pv->reset(status); const UnicodeString *ustr = pv->snext(status); r = (Region *)uhash_get(regionIDMap,(void *)ustr); delete pv; } return r; }
bool BCountry::MonGrouping(BString& grouping) const { UErrorCode err; NumberFormat* numberFormatter = NumberFormat::createCurrencyInstance(*fICULocale, err); assert(err == U_ZERO_ERROR); DecimalFormat* decimalFormatter = dynamic_cast<DecimalFormat*>(numberFormatter); assert(decimalFormatter != NULL); const DecimalFormatSymbols* syms = decimalFormatter->getDecimalFormatSymbols(); UnicodeString ICUString; ICUString = syms->getSymbol( DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol); BStringByteSink stringConverter(&grouping); ICUString.toUTF8(stringConverter); return true; }
U_CAPI void U_EXPORT2 unum_setSymbol(UNumberFormat *fmt, UNumberFormatSymbol symbol, const UChar *value, int32_t length, UErrorCode *status) { if(status==NULL || U_FAILURE(*status)) { return; } if(fmt==NULL || symbol< 0 || symbol>=UNUM_FORMAT_SYMBOL_COUNT || value==NULL || length<-1) { *status=U_ILLEGAL_ARGUMENT_ERROR; return; } NumberFormat *nf = reinterpret_cast<NumberFormat *>(fmt); DecimalFormat *dcf = dynamic_cast<DecimalFormat *>(nf); if (dcf == NULL) { *status = U_UNSUPPORTED_ERROR; return; } DecimalFormatSymbols symbols(*dcf->getDecimalFormatSymbols()); symbols.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol, UnicodeString(value, length)); /* UnicodeString can handle the case when length = -1. */ dcf->setDecimalFormatSymbols(symbols); }
static jcharArray format(JNIEnv* env, jint addr, jobject fpIter, T val) { UErrorCode status = U_ZERO_ERROR; UnicodeString str; DecimalFormat* fmt = toDecimalFormat(addr); FieldPositionIterator fpi; FieldPositionIterator* pfpi = fpIter ? &fpi : NULL; fmt->format(reinterpret_cast<const Formattable&>(val), str, pfpi, status); return formatResult(env, str, pfpi, fpIter); }
static jobject NativeDecimalFormat_parse(JNIEnv* env, jclass, jlong addr, jstring text, jobject position, jboolean parseBigDecimal) { static jmethodID gPP_getIndex = env->GetMethodID(JniConstants::parsePositionClass, "getIndex", "()I"); static jmethodID gPP_setIndex = env->GetMethodID(JniConstants::parsePositionClass, "setIndex", "(I)V"); static jmethodID gPP_setErrorIndex = env->GetMethodID(JniConstants::parsePositionClass, "setErrorIndex", "(I)V"); ScopedJavaUnicodeString src(env, text); if (!src.valid()) { return NULL; } // make sure the ParsePosition is valid. Actually icu4c would parse a number // correctly even if the parsePosition is set to -1, but since the RI fails // for that case we have to fail too int parsePos = env->CallIntMethod(position, gPP_getIndex, NULL); if (parsePos < 0 || parsePos > env->GetStringLength(text)) { return NULL; } Formattable res; ParsePosition pp(parsePos); DecimalFormat* fmt = toDecimalFormat(addr); fmt->parse(src.unicodeString(), res, pp); if (pp.getErrorIndex() == -1) { env->CallVoidMethod(position, gPP_setIndex, pp.getIndex()); } else { env->CallVoidMethod(position, gPP_setErrorIndex, pp.getErrorIndex()); return NULL; } if (parseBigDecimal) { UErrorCode status = U_ZERO_ERROR; StringPiece str = res.getDecimalNumber(status); if (U_SUCCESS(status)) { int len = str.length(); const char* data = str.data(); if (strncmp(data, "NaN", 3) == 0 || strncmp(data, "Inf", 3) == 0 || strncmp(data, "-Inf", 4) == 0) { double resultDouble = res.getDouble(status); return doubleValueOf(env, resultDouble); } return newBigDecimal(env, data, len); } return NULL; } switch (res.getType()) { case Formattable::kDouble: return doubleValueOf(env, res.getDouble()); case Formattable::kLong: return longValueOf(env, res.getLong()); case Formattable::kInt64: return longValueOf(env, res.getInt64()); default: return NULL; } }
static jstring NativeDecimalFormat_toPatternImpl(JNIEnv* env, jclass, jlong addr, jboolean localized) { DecimalFormat* fmt = toDecimalFormat(addr); UnicodeString pattern; if (localized) { fmt->toLocalizedPattern(pattern); } else { fmt->toPattern(pattern); } return env->NewString(pattern.getBuffer(), pattern.length()); }
U_CAPI void U_EXPORT2 unum_setDoubleAttribute( UNumberFormat* fmt, UNumberFormatAttribute attr, double newValue) { NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); if (df != NULL && attr == UNUM_ROUNDING_INCREMENT) { df->setRoundingIncrement(newValue); } }
static jcharArray format(JNIEnv* env, jlong addr, jobject javaFieldPositionIterator, T value) { UErrorCode status = U_ZERO_ERROR; UnicodeString s; DecimalFormat* fmt = toDecimalFormat(addr); FieldPositionIterator nativeFieldPositionIterator; FieldPositionIterator* fpi = javaFieldPositionIterator ? &nativeFieldPositionIterator : NULL; fmt->format(value, s, fpi, status); if (maybeThrowIcuException(env, "DecimalFormat::format", status)) { return NULL; } return formatResult(env, s, fpi, javaFieldPositionIterator); }
//static jstring NativeDecimalFormat_toPatternImpl(JNIEnv* env, jclass, jint addr, jboolean localized) { JNIEXPORT jstring JNICALL Java_com_ibm_icu4jni_text_NativeDecimalFormat_toPatternImpl(JNIEnv* env, jclass, jint addr, jboolean localized) { DecimalFormat* fmt = toDecimalFormat(addr); UnicodeString pattern; if (localized) { fmt->toLocalizedPattern(pattern); } else { fmt->toPattern(pattern); } return env->NewString((const jchar*) pattern.getBuffer(), pattern.length()); }
void ParsePositionTest::TestFieldPosition_example() { //***** no error detection yet !!!!!!! //***** this test is for compiler checks and visual verification only. double doubleNum[] = { 123456789.0, -12345678.9, 1234567.89, -123456.789, 12345.6789, -1234.56789, 123.456789, -12.3456789, 1.23456789}; int dNumSize = 9; UErrorCode status = U_ZERO_ERROR; NumberFormat *nf = NumberFormat::createInstance(status); if (failure(status, "NumberFormat::createInstance", TRUE)){ delete nf; return; }; DecimalFormat *fmt = dynamic_cast<DecimalFormat *>(nf); if(fmt == NULL) { errln("NumberFormat::createInstance returned unexpected class type"); return; } fmt->setDecimalSeparatorAlwaysShown(TRUE); const int tempLen = 20; UnicodeString temp; for (int i=0; i < dNumSize; i++) { temp.remove(); //temp = new StringBuffer(); // Get new buffer FieldPosition pos(NumberFormat::INTEGER_FIELD); UnicodeString buf;// = new StringBuffer(); //char fmtText[tempLen]; //ToCharString(fmt->format(doubleNum[i], buf, pos), fmtText); UnicodeString res; res = fmt->format(doubleNum[i], buf, pos); int tempOffset = (tempLen <= (tempLen - pos.getEndIndex())) ? tempLen : (tempLen - pos.getEndIndex()); for (int j=0; j<tempOffset; j++) temp += UnicodeString("="/*'='*/); // initialize logln("FP " + temp + res); } logln(""); delete nf; }
template<> U_I18N_API const MeasureFormatCacheData *LocaleCacheKey<MeasureFormatCacheData>::createObject( const void * /*unused*/, UErrorCode &status) const { const char *localeId = fLoc.getName(); LocalUResourceBundlePointer unitsBundle(ures_open(U_ICUDATA_UNIT, localeId, &status)); static UNumberFormatStyle currencyStyles[] = { UNUM_CURRENCY_PLURAL, UNUM_CURRENCY_ISO, UNUM_CURRENCY}; LocalPointer<MeasureFormatCacheData> result(new MeasureFormatCacheData(), status); if (U_FAILURE(status)) { return NULL; } if (!loadMeasureUnitData( unitsBundle.getAlias(), *result, status)) { return NULL; } result->adoptNumericDateFormatters(loadNumericDateFormatters( unitsBundle.getAlias(), status)); if (U_FAILURE(status)) { return NULL; } for (int32_t i = 0; i < WIDTH_INDEX_COUNT; ++i) { // NumberFormat::createInstance can erase warning codes from status, so pass it // a separate status instance UErrorCode localStatus = U_ZERO_ERROR; result->adoptCurrencyFormat(i, NumberFormat::createInstance( localeId, currencyStyles[i], localStatus)); if (localStatus != U_ZERO_ERROR) { status = localStatus; } if (U_FAILURE(status)) { return NULL; } } NumberFormat *inf = NumberFormat::createInstance( localeId, UNUM_DECIMAL, status); if (U_FAILURE(status)) { return NULL; } inf->setMaximumFractionDigits(0); DecimalFormat *decfmt = dynamic_cast<DecimalFormat *>(inf); if (decfmt != NULL) { decfmt->setRoundingMode(DecimalFormat::kRoundDown); } result->adoptIntegerFormat(inf); result->addRef(); return result.orphan(); }
static void NativeDecimalFormat_applyPatternImpl(JNIEnv* env, jclass, jlong addr, jboolean localized, jstring pattern0) { ScopedJavaUnicodeString pattern(env, pattern0); if (!pattern.valid()) { return; } DecimalFormat* fmt = toDecimalFormat(addr); UErrorCode status = U_ZERO_ERROR; const char* function; if (localized) { function = "DecimalFormat::applyLocalizedPattern"; fmt->applyLocalizedPattern(pattern.unicodeString(), status); } else { function = "DecimalFormat::applyPattern"; fmt->applyPattern(pattern.unicodeString(), status); } maybeThrowIcuException(env, function, status); }
//static void NativeDecimalFormat_applyPatternImpl(JNIEnv* env, jclass, jint addr, jboolean localized, jstring pattern0) { JNIEXPORT void JNICALL Java_com_ibm_icu4jni_text_NativeDecimalFormat_applyPatternImpl(JNIEnv* env, jclass, jint addr, jboolean localized, jstring pattern0) { if (pattern0 == NULL) { jniThrowNullPointerException(env, NULL); return; } ScopedJavaUnicodeString pattern(env, pattern0); DecimalFormat* fmt = toDecimalFormat(addr); UErrorCode status = U_ZERO_ERROR; if (localized) { fmt->applyLocalizedPattern(pattern.unicodeString(), status); } else { fmt->applyPattern(pattern.unicodeString(), status); } icu4jni_error(env, status); }
U_CAPI void U_EXPORT2 unum_setAttribute( UNumberFormat* fmt, UNumberFormatAttribute attr, int32_t newValue) { NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); if ( attr == UNUM_LENIENT_PARSE ) { // Supported for all subclasses // keep this here as the class may not be a DecimalFormat return nf->setLenient(newValue != 0); } // The remaining attributea are only supported for DecimalFormat DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); if (df != NULL) { UErrorCode ignoredStatus = U_ZERO_ERROR; df->setAttribute(attr, newValue, ignoredStatus); } }
std::string AbstractModel::getAllOutcomes(double ocs[]) { if (sizeof(ocs) / sizeof(ocs[0]) != outcomeNames->length) { return "The double array sent as a parameter to GISModel.getAllOutcomes() must not have been produced by this model."; } else { DecimalFormat *df = new DecimalFormat("0.0000"); StringBuffer *sb = new StringBuffer(sizeof(ocs) / sizeof(ocs[0])*2); sb->append(outcomeNames[0])->append("[")->append(df->format(ocs[0]))->append("]"); for (int i = 1; i < sizeof(ocs) / sizeof(ocs[0]); i++) { sb->append(" ")->append(outcomeNames[i])->append("[")->append(df->format(ocs[i]))->append("]"); } //JAVA TO C++ CONVERTER TODO TASK: There is no native C++ equivalent to 'toString': return sb->toString(); } }
void IntlTestDecimalFormatAPI::TestCurrencyPluralInfo(){ UErrorCode status = U_ZERO_ERROR; CurrencyPluralInfo *cpi = new CurrencyPluralInfo(status); if(U_FAILURE(status)) { errln((UnicodeString)"ERROR: CurrencyPluralInfo(UErrorCode) could not be created"); } CurrencyPluralInfo cpi1 = *cpi; if(cpi->getDynamicClassID() != CurrencyPluralInfo::getStaticClassID()){ errln((UnicodeString)"ERROR: CurrencyPluralInfo::getDynamicClassID() didn't return the expected value"); } cpi->setCurrencyPluralPattern("","",status); if(U_FAILURE(status)) { errln((UnicodeString)"ERROR: CurrencyPluralInfo::setCurrencyPluralPattern"); } cpi->setLocale(Locale::getCanada(), status); if(U_FAILURE(status)) { errln((UnicodeString)"ERROR: CurrencyPluralInfo::setLocale"); } cpi->setPluralRules("",status); if(U_FAILURE(status)) { errln((UnicodeString)"ERROR: CurrencyPluralInfo::setPluralRules"); } DecimalFormat *df = new DecimalFormat(status); if(U_FAILURE(status)) { errcheckln(status, "ERROR: Could not create DecimalFormat - %s", u_errorName(status)); } df->adoptCurrencyPluralInfo(cpi); df->getCurrencyPluralInfo(); df->setCurrencyPluralInfo(cpi1); delete df; }
U_CAPI void U_EXPORT2 unum_setTextAttribute( UNumberFormat* fmt, UNumberFormatTextAttribute tag, const UChar* newValue, int32_t newValueLength, UErrorCode *status) { if(U_FAILURE(*status)) return; int32_t len = (newValueLength == -1 ? u_strlen(newValue) : newValueLength); const UnicodeString val((UChar*)newValue, len, len); NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); if (df != NULL) { switch(tag) { case UNUM_POSITIVE_PREFIX: df->setPositivePrefix(val); break; case UNUM_POSITIVE_SUFFIX: df->setPositiveSuffix(val); break; case UNUM_NEGATIVE_PREFIX: df->setNegativePrefix(val); break; case UNUM_NEGATIVE_SUFFIX: df->setNegativeSuffix(val); break; case UNUM_PADDING_CHARACTER: df->setPadCharacter(*newValue); break; case UNUM_CURRENCY_CODE: df->setCurrency(newValue, *status); break; default: *status = U_UNSUPPORTED_ERROR; break; } } else { RuleBasedNumberFormat* rbnf = dynamic_cast<RuleBasedNumberFormat*>(nf); U_ASSERT(rbnf != NULL); if (tag == UNUM_DEFAULT_RULESET) { rbnf->setDefaultRuleSet(newValue, *status); } else { *status = U_UNSUPPORTED_ERROR; } } }
U_CAPI void U_EXPORT2 unum_setTextAttribute( UNumberFormat* fmt, UNumberFormatTextAttribute tag, const UChar* newValue, int32_t newValueLength, UErrorCode *status) { if(U_FAILURE(*status)) return; int32_t len = (newValueLength == -1 ? u_strlen(newValue) : newValueLength); const UnicodeString val((UChar*)newValue, len, len); if (((NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) { DecimalFormat* df = (DecimalFormat*) fmt; switch(tag) { case UNUM_POSITIVE_PREFIX: df->setPositivePrefix(val); break; case UNUM_POSITIVE_SUFFIX: df->setPositiveSuffix(val); break; case UNUM_NEGATIVE_PREFIX: df->setNegativePrefix(val); break; case UNUM_NEGATIVE_SUFFIX: df->setNegativeSuffix(val); break; case UNUM_PADDING_CHARACTER: df->setPadCharacter(*newValue); break; case UNUM_CURRENCY_CODE: df->setCurrency(newValue, *status); break; default: *status = U_UNSUPPORTED_ERROR; break; } } else { U_ASSERT(((NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID()); if (tag == UNUM_DEFAULT_RULESET) { ((RuleBasedNumberFormat*)fmt)->setDefaultRuleSet(newValue, *status); } else { *status = U_UNSUPPORTED_ERROR; } } }
bool BCountry::NegativeSign(BString& sign) const { UErrorCode err; NumberFormat* numberFormatter = NumberFormat::createInstance(*fICULocale, err); assert(err == U_ZERO_ERROR); DecimalFormat* decimalFormatter = dynamic_cast<DecimalFormat*>(numberFormatter); assert(decimalFormatter != NULL); const DecimalFormatSymbols* syms = decimalFormatter->getDecimalFormatSymbols(); UnicodeString ICUString; ICUString = syms->getSymbol(DecimalFormatSymbols::kMinusSignSymbol); BStringByteSink stringConverter(&sign); ICUString.toUTF8(stringConverter); return true; }
void test_FieldPosition_example( void ) { //***** no error detection yet !!!!!!! //***** this test is for compiler checks and visual verification only. double doubleNum[] = { 123456789.0, -12345678.9, 1234567.89, -123456.789, 12345.6789, -1234.56789, 123.456789, -12.3456789, 1.23456789}; int32_t dNumSize = (int32_t)(sizeof(doubleNum)/sizeof(double)); UErrorCode status = U_ZERO_ERROR; DecimalFormat* fmt = (DecimalFormat*) NumberFormat::createInstance(status); if (U_FAILURE(status)) { it_dataerrln("NumberFormat::createInstance() error"); return; } fmt->setDecimalSeparatorAlwaysShown(TRUE); const int32_t tempLen = 20; char temp[tempLen]; for (int32_t i=0; i<dNumSize; i++) { FieldPosition pos(NumberFormat::INTEGER_FIELD); UnicodeString buf; //char fmtText[tempLen]; //ToCharString(fmt->format(doubleNum[i], buf, pos), fmtText); UnicodeString res = fmt->format(doubleNum[i], buf, pos); for (int32_t j=0; j<tempLen; j++) temp[j] = '='; // clear with spaces int32_t tempOffset = (tempLen <= (tempLen - pos.getEndIndex())) ? tempLen : (tempLen - pos.getEndIndex()); temp[tempOffset] = '\0'; it_logln(UnicodeString("FP ") + UnicodeString(temp) + res); } delete fmt; it_logln(""); }
U_CAPI void U_EXPORT2 unum_applyPattern( UNumberFormat *fmt, UBool localized, const UChar *pattern, int32_t patternLength, UParseError *parseError, UErrorCode* status) { UErrorCode tStatus = U_ZERO_ERROR; UParseError tParseError; if(parseError == NULL){ parseError = &tParseError; } if(status==NULL){ status = &tStatus; } int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength); const UnicodeString pat((UChar*)pattern, len, len); // Verify if the object passed is a DecimalFormat object NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); if (df != NULL) { if(localized) { df->applyLocalizedPattern(pat,*parseError, *status); } else { df->applyPattern(pat,*parseError, *status); } } else { *status = U_UNSUPPORTED_ERROR; return; } }
UnicodeString& PluralFormat::format(const Formattable& numberObject, double number, UnicodeString& appendTo, FieldPosition& pos, UErrorCode& status) const { if (U_FAILURE(status)) { return appendTo; } if (msgPattern.countParts() == 0) { return numberFormat->format(numberObject, appendTo, pos, status); } // Get the appropriate sub-message. // Select it based on the formatted number-offset. double numberMinusOffset = number - offset; UnicodeString numberString; FieldPosition ignorePos; FixedPrecision fp; VisibleDigitsWithExponent dec; fp.initVisibleDigitsWithExponent(numberMinusOffset, dec, status); if (U_FAILURE(status)) { return appendTo; } if (offset == 0) { DecimalFormat *decFmt = dynamic_cast<DecimalFormat *>(numberFormat); if(decFmt != NULL) { decFmt->initVisibleDigitsWithExponent( numberObject, dec, status); if (U_FAILURE(status)) { return appendTo; } decFmt->format(dec, numberString, ignorePos, status); } else { numberFormat->format( numberObject, numberString, ignorePos, status); // could be BigDecimal etc. } } else { DecimalFormat *decFmt = dynamic_cast<DecimalFormat *>(numberFormat); if(decFmt != NULL) { decFmt->initVisibleDigitsWithExponent( numberMinusOffset, dec, status); if (U_FAILURE(status)) { return appendTo; } decFmt->format(dec, numberString, ignorePos, status); } else { numberFormat->format( numberMinusOffset, numberString, ignorePos, status); } } int32_t partIndex = findSubMessage(msgPattern, 0, pluralRulesWrapper, &dec, number, status); if (U_FAILURE(status)) { return appendTo; } // Replace syntactic # signs in the top level of this sub-message // (not in nested arguments) with the formatted number-offset. const UnicodeString& pattern = msgPattern.getPatternString(); int32_t prevIndex = msgPattern.getPart(partIndex).getLimit(); for (;;) { const MessagePattern::Part& part = msgPattern.getPart(++partIndex); const UMessagePatternPartType type = part.getType(); int32_t index = part.getIndex(); if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) { return appendTo.append(pattern, prevIndex, index - prevIndex); } else if ((type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) || (type == UMSGPAT_PART_TYPE_SKIP_SYNTAX && MessageImpl::jdkAposMode(msgPattern))) { appendTo.append(pattern, prevIndex, index - prevIndex); if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) { appendTo.append(numberString); } prevIndex = part.getLimit(); } else if (type == UMSGPAT_PART_TYPE_ARG_START) { appendTo.append(pattern, prevIndex, index - prevIndex); prevIndex = index; partIndex = msgPattern.getLimitPartIndex(partIndex); index = msgPattern.getPart(partIndex).getLimit(); MessageImpl::appendReducedApostrophes(pattern, prevIndex, index, appendTo); prevIndex = index; } } }
static void NativeDecimalFormat_setRoundingMode(JNIEnv*, jclass, jlong addr, jint mode, jdouble increment) { DecimalFormat* fmt = toDecimalFormat(addr); fmt->setRoundingMode(static_cast<DecimalFormat::ERoundingMode>(mode)); fmt->setRoundingIncrement(increment); }
static jlong NativeDecimalFormat_cloneImpl(JNIEnv*, jclass, jlong addr) { DecimalFormat* fmt = toDecimalFormat(addr); return reinterpret_cast<uintptr_t>(fmt->clone()); }
/* * Initializes the region data from the ICU resource bundles. The region data * contains the basic relationships such as which regions are known, what the numeric * codes are, any known aliases, and the territory containment data. * * If the region data has already loaded, then this method simply returns without doing * anything meaningful. */ void Region::loadRegionData() { if (regionDataIsLoaded) { return; } umtx_lock(&gRegionDataLock); if (regionDataIsLoaded) { // In case another thread gets to it before we do... umtx_unlock(&gRegionDataLock); return; } UErrorCode status = U_ZERO_ERROR; UResourceBundle* regionCodes = NULL; UResourceBundle* territoryAlias = NULL; UResourceBundle* codeMappings = NULL; UResourceBundle* worldContainment = NULL; UResourceBundle* territoryContainment = NULL; UResourceBundle* groupingContainment = NULL; DecimalFormat *df = new DecimalFormat(status); df->setParseIntegerOnly(TRUE); regionIDMap = uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString,NULL,&status); uhash_setValueDeleter(regionIDMap, deleteRegion); numericCodeMap = uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status); regionAliases = uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString,NULL,&status); uhash_setKeyDeleter(regionAliases,uprv_deleteUObject); UResourceBundle *rb = ures_openDirect(NULL,"metadata",&status); regionCodes = ures_getByKey(rb,"regionCodes",NULL,&status); territoryAlias = ures_getByKey(rb,"territoryAlias",NULL,&status); UResourceBundle *rb2 = ures_openDirect(NULL,"supplementalData",&status); codeMappings = ures_getByKey(rb2,"codeMappings",NULL,&status); territoryContainment = ures_getByKey(rb2,"territoryContainment",NULL,&status); worldContainment = ures_getByKey(territoryContainment,"001",NULL,&status); groupingContainment = ures_getByKey(territoryContainment,"grouping",NULL,&status); UVector *continents = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status); while ( ures_hasNext(worldContainment) ) { UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeString(worldContainment,NULL,&status)); continents->addElement(continentName,status); } UVector *groupings = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status); while ( ures_hasNext(groupingContainment) ) { UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeString(groupingContainment,NULL,&status)); groupings->addElement(groupingName,status); } while ( ures_hasNext(regionCodes) ) { UnicodeString regionID = ures_getNextUnicodeString(regionCodes,NULL,&status); Region *r = new Region(); r->idStr = regionID; r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV); r->type = URGN_TERRITORY; // Only temporary - figure out the real type later once the aliases are known. uhash_put(regionIDMap,(void *)&(r->idStr),(void *)r,&status); Formattable result; UErrorCode ps = U_ZERO_ERROR; df->parse(r->idStr,result,ps); if ( U_SUCCESS(ps) ) { r->code = result.getLong(); // Convert string to number uhash_iput(numericCodeMap,r->code,(void *)r,&status); r->type = URGN_SUBCONTINENT; } else { r->code = Region::UNDEFINED_NUMERIC_CODE; } } // Process the territory aliases while ( ures_hasNext(territoryAlias) ) { UResourceBundle *res = ures_getNextResource(territoryAlias,NULL,&status); const char *aliasFrom = ures_getKey(res); UnicodeString* aliasFromStr = new UnicodeString(aliasFrom); UnicodeString aliasTo = ures_getUnicodeString(res,&status); ures_close(res); Region *aliasToRegion = (Region *) uhash_get(regionIDMap,&aliasTo); Region *aliasFromRegion = (Region *)uhash_get(regionIDMap,aliasFromStr); if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is just an alias from some string to a region uhash_put(regionAliases,(void *)aliasFromStr, (void *)aliasToRegion,&status); } else { if ( aliasFromRegion == NULL ) { // Deprecated region code not in the master codes list - so need to create a deprecated region for it. aliasFromRegion = new Region(); aliasFromRegion->idStr.setTo(*aliasFromStr); aliasFromRegion->idStr.extract(0,aliasFromRegion->idStr.length(),aliasFromRegion->id,sizeof(aliasFromRegion->id),US_INV); uhash_put(regionIDMap,(void *)&(aliasFromRegion->idStr),(void *)aliasFromRegion,&status); Formattable result; UErrorCode ps = U_ZERO_ERROR; df->parse(aliasFromRegion->idStr,result,ps); if ( U_SUCCESS(ps) ) { aliasFromRegion->code = result.getLong(); // Convert string to number uhash_iput(numericCodeMap,aliasFromRegion->code,(void *)aliasFromRegion,&status); } else { aliasFromRegion->code = Region::UNDEFINED_NUMERIC_CODE; } aliasFromRegion->type = URGN_DEPRECATED; } else { aliasFromRegion->type = URGN_DEPRECATED; } delete aliasFromStr; aliasFromRegion->preferredValues = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status); UnicodeString currentRegion; currentRegion.remove(); for (int32_t i = 0 ; i < aliasTo.length() ; i++ ) { if ( aliasTo.charAt(i) != 0x0020 ) { currentRegion.append(aliasTo.charAt(i)); } if ( aliasTo.charAt(i) == 0x0020 || i+1 == aliasTo.length() ) { Region *target = (Region *)uhash_get(regionIDMap,(void *)¤tRegion); if (target) { UnicodeString *preferredValue = new UnicodeString(target->idStr); aliasFromRegion->preferredValues->addElement((void *)preferredValue,status); } currentRegion.remove(); } } } } // Process the code mappings - This will allow us to assign numeric codes to most of the territories. while ( ures_hasNext(codeMappings) ) { UResourceBundle *mapping = ures_getNextResource(codeMappings,NULL,&status); if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3) { UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0,&status); UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mapping,1,&status); UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapping,2,&status); Region *r = (Region *)uhash_get(regionIDMap,(void *)&codeMappingID); if ( r ) { Formattable result; UErrorCode ps = U_ZERO_ERROR; df->parse(codeMappingNumber,result,ps); if ( U_SUCCESS(ps) ) { r->code = result.getLong(); // Convert string to number uhash_iput(numericCodeMap,r->code,(void *)r,&status); } UnicodeString *code3 = new UnicodeString(codeMapping3Letter); uhash_put(regionAliases,(void *)code3, (void *)r,&status); } } ures_close(mapping); } // Now fill in the special cases for WORLD, UNKNOWN, CONTINENTS, and GROUPINGS Region *r; r = (Region *) uhash_get(regionIDMap,(void *)&WORLD_ID); if ( r ) { r->type = URGN_WORLD; } r = (Region *) uhash_get(regionIDMap,(void *)&UNKNOWN_REGION_ID); if ( r ) { r->type = URGN_UNKNOWN; } for ( int32_t i = 0 ; i < continents->size() ; i++ ) { r = (Region *) uhash_get(regionIDMap,(void *)continents->elementAt(i)); if ( r ) { r->type = URGN_CONTINENT; } } delete continents; for ( int32_t i = 0 ; i < groupings->size() ; i++ ) { r = (Region *) uhash_get(regionIDMap,(void *)groupings->elementAt(i)); if ( r ) { r->type = URGN_GROUPING; } } delete groupings; // Special case: The region code "QO" (Outlying Oceania) is a subcontinent code added by CLDR // even though it looks like a territory code. Need to handle it here. r = (Region *) uhash_get(regionIDMap,(void *)&OUTLYING_OCEANIA_REGION_ID); if ( r ) { r->type = URGN_SUBCONTINENT; } // Load territory containment info from the supplemental data. while ( ures_hasNext(territoryContainment) ) { UResourceBundle *mapping = ures_getNextResource(territoryContainment,NULL,&status); const char *parent = ures_getKey(mapping); UnicodeString parentStr = UnicodeString(parent); Region *parentRegion = (Region *) uhash_get(regionIDMap,(void *)&parentStr); for ( int j = 0 ; j < ures_getSize(mapping); j++ ) { UnicodeString child = ures_getUnicodeStringByIndex(mapping,j,&status); Region *childRegion = (Region *) uhash_get(regionIDMap,(void *)&child); if ( parentRegion != NULL && childRegion != NULL ) { // Add the child region to the set of regions contained by the parent if (parentRegion->containedRegions == NULL) { parentRegion->containedRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status); } UnicodeString *childStr = new UnicodeString(status); childStr->fastCopyFrom(childRegion->idStr); parentRegion->containedRegions->addElement((void *)childStr,status); // Set the parent region to be the containing region of the child. // Regions of type GROUPING can't be set as the parent, since another region // such as a SUBCONTINENT, CONTINENT, or WORLD must always be the parent. if ( parentRegion->type != URGN_GROUPING) { childRegion->containingRegion = parentRegion; } } } ures_close(mapping); } // Create the availableRegions lists int32_t pos = -1; while ( const UHashElement* element = uhash_nextElement(regionIDMap,&pos)) { Region *ar = (Region *)element->value.pointer; if ( availableRegions[ar->type] == NULL ) { availableRegions[ar->type] = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status); } UnicodeString *arString = new UnicodeString(ar->idStr); availableRegions[ar->type]->addElement((void *)arString,status); } ures_close(territoryContainment); ures_close(worldContainment); ures_close(groupingContainment); ures_close(codeMappings); ures_close(rb2); ures_close(territoryAlias); ures_close(regionCodes); ures_close(rb); delete df; ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup); regionDataIsLoaded = true; umtx_unlock(&gRegionDataLock); }
void TestMessageFormat::testBug3() { double myNumber = -123456; DecimalFormat *form = 0; Locale locale[] = { Locale("ar", "", ""), Locale("be", "", ""), Locale("bg", "", ""), Locale("ca", "", ""), Locale("cs", "", ""), Locale("da", "", ""), Locale("de", "", ""), Locale("de", "AT", ""), Locale("de", "CH", ""), Locale("el", "", ""), // 10 Locale("en", "CA", ""), Locale("en", "GB", ""), Locale("en", "IE", ""), Locale("en", "US", ""), Locale("es", "", ""), Locale("et", "", ""), Locale("fi", "", ""), Locale("fr", "", ""), Locale("fr", "BE", ""), Locale("fr", "CA", ""), // 20 Locale("fr", "CH", ""), Locale("he", "", ""), Locale("hr", "", ""), Locale("hu", "", ""), Locale("is", "", ""), Locale("it", "", ""), Locale("it", "CH", ""), Locale("ja", "", ""), Locale("ko", "", ""), Locale("lt", "", ""), // 30 Locale("lv", "", ""), Locale("mk", "", ""), Locale("nl", "", ""), Locale("nl", "BE", ""), Locale("no", "", ""), Locale("pl", "", ""), Locale("pt", "", ""), Locale("ro", "", ""), Locale("ru", "", ""), Locale("sh", "", ""), // 40 Locale("sk", "", ""), Locale("sl", "", ""), Locale("sq", "", ""), Locale("sr", "", ""), Locale("sv", "", ""), Locale("tr", "", ""), Locale("uk", "", ""), Locale("zh", "", ""), Locale("zh", "TW", "") // 49 }; int32_t i; for (i= 0; i < 49; i++) { UnicodeString buffer; logln(locale[i].getDisplayName(buffer)); UErrorCode success = U_ZERO_ERROR; // form = (DecimalFormat*)NumberFormat::createCurrencyInstance(locale[i], success); form = (DecimalFormat*)NumberFormat::createInstance(locale[i], success); if (U_FAILURE(success)) { errln("Err: Number Format "); logln("Number format creation failed."); continue; } Formattable result; FieldPosition pos(0); buffer.remove(); form->format(myNumber, buffer, pos); success = U_ZERO_ERROR; ParsePosition parsePos; form->parse(buffer, result, parsePos); logln(UnicodeString(" -> ") /* + << dec*/ + toString(result) + UnicodeString("[supposed output for result]")); if (U_FAILURE(success)) { errln("Err: Number Format parse"); logln("Number format parse failed."); } delete form; } }
U_CAPI void U_EXPORT2 unum_setAttribute( UNumberFormat* fmt, UNumberFormatAttribute attr, int32_t newValue) { if (((NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) { DecimalFormat* df = (DecimalFormat*) fmt; switch(attr) { case UNUM_PARSE_INT_ONLY: df->setParseIntegerOnly(newValue!=0); break; case UNUM_GROUPING_USED: df->setGroupingUsed(newValue!=0); break; case UNUM_DECIMAL_ALWAYS_SHOWN: df->setDecimalSeparatorAlwaysShown(newValue!=0); break; case UNUM_MAX_INTEGER_DIGITS: df->setMaximumIntegerDigits(newValue); break; case UNUM_MIN_INTEGER_DIGITS: df->setMinimumIntegerDigits(newValue); break; case UNUM_INTEGER_DIGITS: df->setMinimumIntegerDigits(newValue); df->setMaximumIntegerDigits(newValue); break; case UNUM_MAX_FRACTION_DIGITS: df->setMaximumFractionDigits(newValue); break; case UNUM_MIN_FRACTION_DIGITS: df->setMinimumFractionDigits(newValue); break; case UNUM_FRACTION_DIGITS: df->setMinimumFractionDigits(newValue); df->setMaximumFractionDigits(newValue); break; case UNUM_SIGNIFICANT_DIGITS_USED: df->setSignificantDigitsUsed(newValue!=0); break; case UNUM_MAX_SIGNIFICANT_DIGITS: df->setMaximumSignificantDigits(newValue); break; case UNUM_MIN_SIGNIFICANT_DIGITS: df->setMinimumSignificantDigits(newValue); break; case UNUM_MULTIPLIER: df->setMultiplier(newValue); break; case UNUM_GROUPING_SIZE: df->setGroupingSize(newValue); break; case UNUM_ROUNDING_MODE: df->setRoundingMode((DecimalFormat::ERoundingMode)newValue); break; case UNUM_FORMAT_WIDTH: df->setFormatWidth(newValue); break; case UNUM_PADDING_POSITION: /** The position at which padding will take place. */ df->setPadPosition((DecimalFormat::EPadPosition)newValue); break; case UNUM_SECONDARY_GROUPING_SIZE: df->setSecondaryGroupingSize(newValue); break; default: /* Shouldn't get here anyway */ break; } } else { U_ASSERT(((NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID()); if (attr == UNUM_LENIENT_PARSE) { #if !UCONFIG_NO_COLLATION ((RuleBasedNumberFormat*)fmt)->setLenient((UBool)newValue); #endif } } }
void NumberFormatRoundTripTest::test(NumberFormat *fmt, const Formattable& value) { fmt->setMaximumFractionDigits(999); DecimalFormat *df = dynamic_cast<DecimalFormat *>(fmt); if(df != NULL) { df->setRoundingIncrement(0.0); } UErrorCode status = U_ZERO_ERROR; UnicodeString s, s2, temp; if(isDouble(value)) s = fmt->format(value.getDouble(), s); else s = fmt->format(value.getLong(), s); Formattable n; UBool show = verbose; if(DEBUG_VAR) logln(/*value.getString(temp) +*/ " F> " + escape(s)); fmt->parse(s, n, status); failure(status, "fmt->parse"); if(DEBUG_VAR) logln(escape(s) + " P> " /*+ n.getString(temp)*/); if(isDouble(n)) s2 = fmt->format(n.getDouble(), s2); else s2 = fmt->format(n.getLong(), s2); if(DEBUG_VAR) logln(/*n.getString(temp) +*/ " F> " + escape(s2)); if(STRING_COMPARE) { if (s != s2) { errln("*** STRING ERROR \"" + escape(s) + "\" != \"" + escape(s2) + "\""); show = TRUE; } } if(EXACT_NUMERIC_COMPARE) { if(value != n) { errln("*** NUMERIC ERROR"); show = TRUE; } } else { // Compute proportional error double error = proportionalError(value, n); if(error > MAX_ERROR) { errln(UnicodeString("*** NUMERIC ERROR ") + error); show = TRUE; } if (error > max_numeric_error) max_numeric_error = error; if (error < min_numeric_error) min_numeric_error = error; } if (show) { errln(/*value.getString(temp) +*/ typeOf(value, temp) + " F> " + escape(s) + " P> " + (n.getType() == Formattable::kDouble ? n.getDouble() : (double)n.getLong()) /*n.getString(temp) */ + typeOf(n, temp) + " F> " + escape(s2)); } }
void NumberFormatRoundTripTest::test(NumberFormat *fmt) { #if IEEE_754 && U_PLATFORM != U_PF_OS400 test(fmt, uprv_getNaN()); test(fmt, uprv_getInfinity()); test(fmt, -uprv_getInfinity()); #endif test(fmt, (int32_t)500); test(fmt, (int32_t)0); test(fmt, (int32_t)-0); test(fmt, 0.0); double negZero = 0.0; negZero /= -1.0; test(fmt, negZero); test(fmt, 9223372036854775808.0); test(fmt, -9223372036854775809.0); for(int i = 0; i < 10; ++i) { test(fmt, randomDouble(1)); test(fmt, randomDouble(10000)); test(fmt, uprv_floor((randomDouble(10000)))); test(fmt, randomDouble(1e50)); test(fmt, randomDouble(1e-50)); #if !(U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400) test(fmt, randomDouble(1e100)); #elif IEEE_754 test(fmt, randomDouble(1e75)); #endif /* OS390 and OS400 */ // {sfb} When formatting with a percent instance, numbers very close to // DBL_MAX will fail the round trip. This is because: // 1) Format the double into a string --> INF% (since 100 * double > DBL_MAX) // 2) Parse the string into a double --> INF // 3) Re-format the double --> INF% // 4) The strings are equal, so that works. // 5) Calculate the proportional error --> INF, so the test will fail // I'll get around this by dividing by the multiplier to make sure // the double will stay in range. //if(fmt->getMultipler() == 1) DecimalFormat *df = dynamic_cast<DecimalFormat *>(fmt); if(df != NULL) { #if !(U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400) /* DBL_MAX/2 is here because randomDouble does a *2 in the math */ test(fmt, randomDouble(DBL_MAX/2.0) / df->getMultiplier()); #elif IEEE_754 test(fmt, randomDouble(1e75) / df->getMultiplier()); #else test(fmt, randomDouble(1e65) / df->getMultiplier()); #endif } #if (defined(_MSC_VER) && _MSC_VER < 1400) || defined(__alpha__) || defined(U_OSF) // These machines and compilers don't fully support denormalized doubles, test(fmt, randomDouble(1e-292)); test(fmt, randomDouble(1e-100)); #elif U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400 // i5/OS (OS/400) throws exceptions on denormalized numbers # if IEEE_754 test(fmt, randomDouble(1e-78)); test(fmt, randomDouble(1e-78)); // #else we're using something like the old z/OS floating point. # endif #else // This is a normal machine that can support IEEE754 denormalized doubles without throwing an error. test(fmt, randomDouble(DBL_MIN)); /* Usually 2.2250738585072014e-308 */ test(fmt, randomDouble(1e-100)); #endif } }