From 1c11ee4838e666faddb61d2491cbdddf03c893d0 Mon Sep 17 00:00:00 2001 From: Yoshito Umaoka Date: Fri, 3 Feb 2012 18:40:03 +0000 Subject: [PATCH] ICU-7964 Merging ucurr_getNumericCode from the work branch to the trunk. X-SVN-Rev: 31320 --- icu4c/source/i18n/ucurr.cpp | 47 ++++++++++++++++++++------- icu4c/source/i18n/unicode/ucurr.h | 15 ++++++++- icu4c/source/test/cintltst/currtest.c | 34 ++++++++++++++++++- 3 files changed, 82 insertions(+), 14 deletions(-) diff --git a/icu4c/source/i18n/ucurr.cpp b/icu4c/source/i18n/ucurr.cpp index 152af95fbd9..60024c1df04 100644 --- a/icu4c/source/i18n/ucurr.cpp +++ b/icu4c/source/i18n/ucurr.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (c) 2002-2011, International Business Machines +* Copyright (c) 2002-2012, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -53,7 +53,7 @@ static const int32_t POW10[] = { 1, 10, 100, 1000, 10000, 100000, static const int32_t MAX_POW10 = (sizeof(POW10)/sizeof(POW10[0])) - 1; -#define ISO_COUNTRY_CODE_LENGTH 3 +#define ISO_CURRENCY_CODE_LENGTH 3 //------------------------------------------------------------ // Resource tags @@ -141,8 +141,8 @@ deleteIsoCodeEntry(void *obj) { */ static inline char* myUCharsToChars(char* resultOfLen4, const UChar* currency) { - u_UCharsToChars(currency, resultOfLen4, ISO_COUNTRY_CODE_LENGTH); - resultOfLen4[ISO_COUNTRY_CODE_LENGTH] = 0; + u_UCharsToChars(currency, resultOfLen4, ISO_CURRENCY_CODE_LENGTH); + resultOfLen4[ISO_CURRENCY_CODE_LENGTH] = 0; return resultOfLen4; } @@ -175,7 +175,7 @@ _findMetaData(const UChar* currency, UErrorCode& ec) { } // Look up our currency, or if that's not available, then DEFAULT - char buf[ISO_COUNTRY_CODE_LENGTH+1]; + char buf[ISO_CURRENCY_CODE_LENGTH+1]; UErrorCode ec2 = U_ZERO_ERROR; // local error code: soft failure UResourceBundle* rb = ures_getByKey(currencyMeta, myUCharsToChars(buf, currency), NULL, &ec2); if (U_FAILURE(ec2)) { @@ -254,7 +254,7 @@ static CReg* gCRegHead = 0; struct CReg : public icu::UMemory { CReg *next; - UChar iso[ISO_COUNTRY_CODE_LENGTH+1]; + UChar iso[ISO_CURRENCY_CODE_LENGTH+1]; char id[ULOC_FULLNAME_CAPACITY]; CReg(const UChar* _iso, const char* _id) @@ -266,8 +266,8 @@ struct CReg : public icu::UMemory { } uprv_strncpy(id, _id, len); id[len] = 0; - uprv_memcpy(iso, _iso, ISO_COUNTRY_CODE_LENGTH * sizeof(const UChar)); - iso[ISO_COUNTRY_CODE_LENGTH] = 0; + uprv_memcpy(iso, _iso, ISO_CURRENCY_CODE_LENGTH * sizeof(const UChar)); + iso[ISO_CURRENCY_CODE_LENGTH] = 0; } static UCurrRegistryKey reg(const UChar* _iso, const char* _id, UErrorCode* status) @@ -559,7 +559,7 @@ ucurr_getName(const UChar* currency, return 0; } - char buf[ISO_COUNTRY_CODE_LENGTH+1]; + char buf[ISO_CURRENCY_CODE_LENGTH+1]; myUCharsToChars(buf, currency); /* Normalize the keyword value to uppercase */ @@ -604,7 +604,7 @@ ucurr_getName(const UChar* currency, } // If we fail to find a match, use the ISO 4217 code - *len = u_strlen(currency); // Should == ISO_COUNTRY_CODE_LENGTH, but maybe not...? + *len = u_strlen(currency); // Should == ISO_CURRENCY_CODE_LENGTH, but maybe not...? *ec = U_USING_DEFAULT_WARNING; return currency; } @@ -642,7 +642,7 @@ ucurr_getPluralName(const UChar* currency, return 0; } - char buf[ISO_COUNTRY_CODE_LENGTH+1]; + char buf[ISO_CURRENCY_CODE_LENGTH+1]; myUCharsToChars(buf, currency); const UChar* s = NULL; @@ -680,7 +680,7 @@ ucurr_getPluralName(const UChar* currency, } // If we fail to find a match, use the ISO 4217 code - *len = u_strlen(currency); // Should == ISO_COUNTRY_CODE_LENGTH, but maybe not...? + *len = u_strlen(currency); // Should == ISO_CURRENCY_CODE_LENGTH, but maybe not...? *ec = U_USING_DEFAULT_WARNING; return currency; } @@ -2415,6 +2415,29 @@ U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key, return en; } + +U_CAPI int32_t U_EXPORT2 +ucurr_getNumericCode(const UChar* currency) { + int32_t code = 0; + if (currency && u_strlen(currency) == ISO_CURRENCY_CODE_LENGTH) { + UErrorCode status = U_ZERO_ERROR; + + UResourceBundle *bundle = ures_openDirect(0, "currencyNumericCodes", &status); + ures_getByKey(bundle, "codeMap", bundle, &status); + if (U_SUCCESS(status)) { + char alphaCode[ISO_CURRENCY_CODE_LENGTH+1]; + myUCharsToChars(alphaCode, currency); + T_CString_toUpperCase(alphaCode); + ures_getByKey(bundle, alphaCode, bundle, &status); + int tmpCode = ures_getInt(bundle, &status); + if (U_SUCCESS(status)) { + code = tmpCode; + } + } + ures_close(bundle); + } + return code; +} #endif /* #if !UCONFIG_NO_FORMATTING */ //eof diff --git a/icu4c/source/i18n/unicode/ucurr.h b/icu4c/source/i18n/unicode/ucurr.h index cedad07daf5..fd28b63f717 100644 --- a/icu4c/source/i18n/unicode/ucurr.h +++ b/icu4c/source/i18n/unicode/ucurr.h @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (c) 2002-2011, International Business Machines +* Copyright (c) 2002-2012, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -345,6 +345,19 @@ ucurr_getKeywordValuesForLocale(const char* key, UBool commonlyUsed, UErrorCode* status); + +/** + * Returns the ISO 4217 numeric code for the currency. + *

Note: If the ISO 4217 numeric code is not assigned for the currency or + * the currency is unknown, this function returns 0. + * + * @param currency null-terminated 3-letter ISO 4217 code + * @return The ISO 4217 numeric code of the currency + * @draft ICU 49 + */ +U_DRAFT int32_t U_EXPORT2 +ucurr_getNumericCode(const UChar* currency); + #endif /* #if !UCONFIG_NO_FORMATTING */ #endif diff --git a/icu4c/source/test/cintltst/currtest.c b/icu4c/source/test/cintltst/currtest.c index 7bcc8040f35..633dbd27307 100644 --- a/icu4c/source/test/cintltst/currtest.c +++ b/icu4c/source/test/cintltst/currtest.c @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 2005-2009, International Business Machines Corporation and + * Copyright (c) 2005-2012, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ #include "unicode/utypes.h" @@ -227,6 +227,37 @@ static void TestPrefixSuffix(void) { unum_close(parser); } +typedef struct { + const char* alphaCode; + int32_t numericCode; +} NumCodeTestEntry; + +static const NumCodeTestEntry NUMCODE_TESTDATA[] = { + {"USD", 840}, + {"Usd", 840}, /* mixed casing */ + {"EUR", 978}, + {"JPY", 392}, + {"XFU", 0}, /* XFU: no numeric code */ + {"ZZZ", 0}, /* ZZZ: undefined ISO currency code */ + {"bogus", 0}, /* bogus code */ + {0, 0}, +}; + +static void TestNumericCode(void) { + UChar code[4]; + int32_t i; + int32_t numCode; + + for (i = 0; NUMCODE_TESTDATA[i].alphaCode; i++) { + u_charsToUChars(NUMCODE_TESTDATA[i].alphaCode, code, sizeof(code)/sizeof(code[0])); + numCode = ucurr_getNumericCode(code); + if (numCode != NUMCODE_TESTDATA[i].numericCode) { + log_err("Error: ucurr_getNumericCode returned %d for currency %s, expected - %d\n", + numCode, NUMCODE_TESTDATA[i].alphaCode, NUMCODE_TESTDATA[i].numericCode); + } + } +} + void addCurrencyTest(TestNode** root); #define TESTCASE(x) addTest(root, &x, "tsformat/currtest/" #x) @@ -238,6 +269,7 @@ void addCurrencyTest(TestNode** root) TESTCASE(TestEnumListCount); TESTCASE(TestFractionDigitOverride); TESTCASE(TestPrefixSuffix); + TESTCASE(TestNumericCode); } #endif /* #if !UCONFIG_NO_FORMATTING */