| Index: icu46/source/i18n/currpinf.cpp
|
| ===================================================================
|
| --- icu46/source/i18n/currpinf.cpp (revision 0)
|
| +++ icu46/source/i18n/currpinf.cpp (revision 0)
|
| @@ -0,0 +1,384 @@
|
| +/*
|
| + *******************************************************************************
|
| + * Copyright (C) 2009-2010, International Business Machines Corporation and
|
| + * others. All Rights Reserved.
|
| + *******************************************************************************
|
| + */
|
| +
|
| +#include "unicode/currpinf.h"
|
| +
|
| +#if !UCONFIG_NO_FORMATTING
|
| +
|
| +//#define CURRENCY_PLURAL_INFO_DEBUG 1
|
| +
|
| +#ifdef CURRENCY_PLURAL_INFO_DEBUG
|
| +#include <iostream>
|
| +#endif
|
| +
|
| +
|
| +#include "unicode/locid.h"
|
| +#include "unicode/plurrule.h"
|
| +#include "unicode/ures.h"
|
| +#include "cstring.h"
|
| +#include "hash.h"
|
| +#include "uresimp.h"
|
| +#include "ureslocs.h"
|
| +
|
| +U_NAMESPACE_BEGIN
|
| +
|
| +
|
| +static const UChar gNumberPatternSeparator = 0x3B; // ;
|
| +
|
| +U_CDECL_BEGIN
|
| +
|
| +/**
|
| + * @internal ICU 4.2
|
| + */
|
| +static UBool U_CALLCONV ValueComparator(UHashTok val1, UHashTok val2);
|
| +
|
| +UBool
|
| +U_CALLCONV ValueComparator(UHashTok val1, UHashTok val2) {
|
| + const UnicodeString* affix_1 = (UnicodeString*)val1.pointer;
|
| + const UnicodeString* affix_2 = (UnicodeString*)val2.pointer;
|
| + return *affix_1 == *affix_2;
|
| +}
|
| +
|
| +U_CDECL_END
|
| +
|
| +
|
| +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CurrencyPluralInfo)
|
| +
|
| +static const UChar gDefaultCurrencyPluralPattern[] = {'0', '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4, 0};
|
| +static const UChar gTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
|
| +static const UChar gPluralCountOther[] = {0x6F, 0x74, 0x68, 0x65, 0x72, 0};
|
| +static const UChar gPart0[] = {0x7B, 0x30, 0x7D, 0};
|
| +static const UChar gPart1[] = {0x7B, 0x31, 0x7D, 0};
|
| +
|
| +static const char gNumberElementsTag[]="NumberElements";
|
| +static const char gLatnTag[]="latn";
|
| +static const char gPatternsTag[]="patterns";
|
| +static const char gDecimalFormatTag[]="decimalFormat";
|
| +static const char gCurrUnitPtnTag[]="CurrencyUnitPatterns";
|
| +
|
| +CurrencyPluralInfo::CurrencyPluralInfo(UErrorCode& status)
|
| +: fPluralCountToCurrencyUnitPattern(NULL),
|
| + fPluralRules(NULL),
|
| + fLocale(NULL) {
|
| + initialize(Locale::getDefault(), status);
|
| +}
|
| +
|
| +CurrencyPluralInfo::CurrencyPluralInfo(const Locale& locale, UErrorCode& status)
|
| +: fPluralCountToCurrencyUnitPattern(NULL),
|
| + fPluralRules(NULL),
|
| + fLocale(NULL) {
|
| + initialize(locale, status);
|
| +}
|
| +
|
| +CurrencyPluralInfo::CurrencyPluralInfo(const CurrencyPluralInfo& info)
|
| +: UObject(info),
|
| + fPluralCountToCurrencyUnitPattern(NULL),
|
| + fPluralRules(NULL),
|
| + fLocale(NULL) {
|
| + *this = info;
|
| +}
|
| +
|
| +
|
| +CurrencyPluralInfo&
|
| +CurrencyPluralInfo::operator=(const CurrencyPluralInfo& info) {
|
| + if (this == &info) {
|
| + return *this;
|
| + }
|
| +
|
| + deleteHash(fPluralCountToCurrencyUnitPattern);
|
| + UErrorCode status = U_ZERO_ERROR;
|
| + fPluralCountToCurrencyUnitPattern = initHash(status);
|
| + copyHash(info.fPluralCountToCurrencyUnitPattern,
|
| + fPluralCountToCurrencyUnitPattern, status);
|
| + if ( U_FAILURE(status) ) {
|
| + return *this;
|
| + }
|
| +
|
| + delete fPluralRules;
|
| + delete fLocale;
|
| + if (info.fPluralRules) {
|
| + fPluralRules = info.fPluralRules->clone();
|
| + } else {
|
| + fPluralRules = NULL;
|
| + }
|
| + if (info.fLocale) {
|
| + fLocale = info.fLocale->clone();
|
| + } else {
|
| + fLocale = NULL;
|
| + }
|
| + return *this;
|
| +}
|
| +
|
| +
|
| +CurrencyPluralInfo::~CurrencyPluralInfo() {
|
| + deleteHash(fPluralCountToCurrencyUnitPattern);
|
| + fPluralCountToCurrencyUnitPattern = NULL;
|
| + delete fPluralRules;
|
| + delete fLocale;
|
| + fPluralRules = NULL;
|
| + fLocale = NULL;
|
| +}
|
| +
|
| +UBool
|
| +CurrencyPluralInfo::operator==(const CurrencyPluralInfo& info) const {
|
| +#ifdef CURRENCY_PLURAL_INFO_DEBUG
|
| + if (*fPluralRules == *info.fPluralRules) {
|
| + std::cout << "same plural rules\n";
|
| + }
|
| + if (*fLocale == *info.fLocale) {
|
| + std::cout << "same locale\n";
|
| + }
|
| + if (fPluralCountToCurrencyUnitPattern->equals(*info.fPluralCountToCurrencyUnitPattern)) {
|
| + std::cout << "same pattern\n";
|
| + }
|
| +#endif
|
| + return *fPluralRules == *info.fPluralRules &&
|
| + *fLocale == *info.fLocale &&
|
| + fPluralCountToCurrencyUnitPattern->equals(*info.fPluralCountToCurrencyUnitPattern);
|
| +}
|
| +
|
| +
|
| +CurrencyPluralInfo*
|
| +CurrencyPluralInfo::clone() const {
|
| + return new CurrencyPluralInfo(*this);
|
| +}
|
| +
|
| +const PluralRules*
|
| +CurrencyPluralInfo::getPluralRules() const {
|
| + return fPluralRules;
|
| +}
|
| +
|
| +UnicodeString&
|
| +CurrencyPluralInfo::getCurrencyPluralPattern(const UnicodeString& pluralCount,
|
| + UnicodeString& result) const {
|
| + const UnicodeString* currencyPluralPattern =
|
| + (UnicodeString*)fPluralCountToCurrencyUnitPattern->get(pluralCount);
|
| + if (currencyPluralPattern == NULL) {
|
| + // fall back to "other"
|
| + if (pluralCount.compare(gPluralCountOther)) {
|
| + currencyPluralPattern =
|
| + (UnicodeString*)fPluralCountToCurrencyUnitPattern->get(gPluralCountOther);
|
| + }
|
| + if (currencyPluralPattern == NULL) {
|
| + // no currencyUnitPatterns defined,
|
| + // fallback to predefined defult.
|
| + // This should never happen when ICU resource files are
|
| + // available, since currencyUnitPattern of "other" is always
|
| + // defined in root.
|
| + result = UnicodeString(gDefaultCurrencyPluralPattern);
|
| + return result;
|
| + }
|
| + }
|
| + result = *currencyPluralPattern;
|
| + return result;
|
| +}
|
| +
|
| +const Locale&
|
| +CurrencyPluralInfo::getLocale() const {
|
| + return *fLocale;
|
| +}
|
| +
|
| +void
|
| +CurrencyPluralInfo::setPluralRules(const UnicodeString& ruleDescription,
|
| + UErrorCode& status) {
|
| + if (U_SUCCESS(status)) {
|
| + if (fPluralRules) {
|
| + delete fPluralRules;
|
| + }
|
| + fPluralRules = PluralRules::createRules(ruleDescription, status);
|
| + }
|
| +}
|
| +
|
| +
|
| +void
|
| +CurrencyPluralInfo::setCurrencyPluralPattern(const UnicodeString& pluralCount,
|
| + const UnicodeString& pattern,
|
| + UErrorCode& status) {
|
| + if (U_SUCCESS(status)) {
|
| + fPluralCountToCurrencyUnitPattern->put(pluralCount, new UnicodeString(pattern), status);
|
| + }
|
| +}
|
| +
|
| +
|
| +void
|
| +CurrencyPluralInfo::setLocale(const Locale& loc, UErrorCode& status) {
|
| + initialize(loc, status);
|
| +}
|
| +
|
| +
|
| +void
|
| +CurrencyPluralInfo::initialize(const Locale& loc, UErrorCode& status) {
|
| + if (U_FAILURE(status)) {
|
| + return;
|
| + }
|
| + delete fLocale;
|
| + fLocale = loc.clone();
|
| + if (fPluralRules) {
|
| + delete fPluralRules;
|
| + }
|
| + fPluralRules = PluralRules::forLocale(loc, status);
|
| + setupCurrencyPluralPattern(loc, status);
|
| +}
|
| +
|
| +
|
| +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;
|
| + }
|
| +
|
| + UErrorCode ec = U_ZERO_ERROR;
|
| + UResourceBundle *rb = ures_open(NULL, loc.getName(), &ec);
|
| + rb = ures_getByKey(rb, gNumberElementsTag, rb, &ec);
|
| + rb = ures_getByKey(rb, gLatnTag, rb, &ec);
|
| + rb = ures_getByKey(rb, gPatternsTag, rb, &ec);
|
| + int32_t ptnLen;
|
| + const UChar* 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(rb);
|
| +
|
| + 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(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(currRb);
|
| +}
|
| +
|
| +
|
| +
|
| +void
|
| +CurrencyPluralInfo::deleteHash(Hashtable* hTable)
|
| +{
|
| + if ( hTable == NULL ) {
|
| + return;
|
| + }
|
| + int32_t pos = -1;
|
| + const UHashElement* element = NULL;
|
| + while ( (element = hTable->nextElement(pos)) != NULL ) {
|
| + const UHashTok keyTok = element->key;
|
| + const UHashTok valueTok = element->value;
|
| + const UnicodeString* value = (UnicodeString*)valueTok.pointer;
|
| + delete value;
|
| + }
|
| + delete hTable;
|
| + hTable = NULL;
|
| +}
|
| +
|
| +
|
| +Hashtable*
|
| +CurrencyPluralInfo::initHash(UErrorCode& status) {
|
| + if ( U_FAILURE(status) ) {
|
| + return NULL;
|
| + }
|
| + Hashtable* hTable;
|
| + if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
|
| + status = U_MEMORY_ALLOCATION_ERROR;
|
| + return NULL;
|
| + }
|
| + hTable->setValueComparator(ValueComparator);
|
| + return hTable;
|
| +}
|
| +
|
| +
|
| +void
|
| +CurrencyPluralInfo::copyHash(const Hashtable* source,
|
| + Hashtable* target,
|
| + UErrorCode& status) {
|
| + if ( U_FAILURE(status) ) {
|
| + return;
|
| + }
|
| + int32_t pos = -1;
|
| + const UHashElement* element = NULL;
|
| + if ( source ) {
|
| + while ( (element = source->nextElement(pos)) != NULL ) {
|
| + const UHashTok keyTok = element->key;
|
| + const UnicodeString* key = (UnicodeString*)keyTok.pointer;
|
| + const UHashTok valueTok = element->value;
|
| + const UnicodeString* value = (UnicodeString*)valueTok.pointer;
|
| + UnicodeString* copy = new UnicodeString(*value);
|
| + target->put(UnicodeString(*key), copy, status);
|
| + if ( U_FAILURE(status) ) {
|
| + return;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +U_NAMESPACE_END
|
| +
|
| +#endif
|
|
|
| Property changes on: icu46/source/i18n/currpinf.cpp
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|