ICU-3832 Add support for monetary grouping separator

X-SVN-Rev: 18960
This commit is contained in:
Ram Viswanadha 2006-01-09 23:03:31 +00:00
parent 2aee23b0eb
commit 0bdf064c1d
7 changed files with 100 additions and 45 deletions

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2004, International Business Machines Corporation and *
* Copyright (C) 1997-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@ -29,7 +29,7 @@
#include "ucurrimp.h"
#include "cstring.h"
#include "locbased.h"
#include "uresimp.h"
// *****************************************************************************
// class DecimalFormatSymbols
// *****************************************************************************
@ -120,13 +120,13 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status,
UBool useLastResortData)
{
*validLocale = *actualLocale = 0;
currPattern = NULL;
if (U_FAILURE(status))
return;
const char* locStr = loc.getName();
UResourceBundle *resource = ures_open((char *)0, locStr, &status);
UResourceBundle *numberElementsRes = ures_getByKey(resource, gNumberElements, resource, &status);
UResourceBundle *numberElementsRes = ures_getByKey(resource, gNumberElements, NULL, &status);
if (U_FAILURE(status))
{
// Initializes with last resort data if necessary.
@ -183,7 +183,40 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status,
ures_getLocaleByType(numberElementsRes,
ULOC_ACTUAL_LOCALE, &status));
}
//load the currency data
UChar ucc[4]={0}; //Currency Codes are always 3 chars long
int32_t uccLen = 4;
const char* locName = loc.getName();
uccLen = ucurr_forLocale(locName, ucc, uccLen, &status);
if(U_SUCCESS(status) && uccLen > 0) {
char cc[4]={0};
u_UCharsToChars(ucc, cc, uccLen);
/* An explicit currency was requested */
UErrorCode localStatus = U_ZERO_ERROR;
UResourceBundle *currency = ures_getByKeyWithFallback(resource, "Currencies", NULL, &localStatus);
currency = ures_getByKeyWithFallback(currency, cc, currency, &localStatus);
if(U_SUCCESS(localStatus) && ures_getSize(currency)>2) { // the length is 3 if more data is present
currency = ures_getByIndex(currency, 2, currency, &localStatus);
int32_t currPatternLen = 0;
currPattern = ures_getStringByIndex(currency, (int32_t)0, &currPatternLen, &localStatus);
UnicodeString decimalSep = ures_getStringByIndex(currency, (int32_t)1, NULL, &localStatus);
UnicodeString groupingSep = ures_getStringByIndex(currency, (int32_t)2, NULL, &localStatus);
if(U_SUCCESS(localStatus)){
fSymbols[kMonetaryGroupingSeparatorSymbol] = groupingSep;
fSymbols[kMonetarySeparatorSymbol] = decimalSep;
//pattern.setTo(TRUE, currPattern, currPatternLen);
status = localStatus;
}
}
ures_close(currency);
/* else An explicit currency was requested and is unknown or locale data is malformed. */
/* ucurr_* API will get the correct value later on. */
}else{
// ignore the error if no currency
status = U_ZERO_ERROR;
}
}
ures_close(resource);
ures_close(numberElementsRes);
}
@ -222,6 +255,7 @@ DecimalFormatSymbols::initialize(const UChar** numberElements, int32_t *numberEl
// TODO: read from locale data, if this makes it into CLDR
fSymbols[kSignificantDigitSymbol] = (UChar)0x0040; // '@' significant digit
fSymbols[kPadEscapeSymbol] = (UChar)0x002a; // TODO: '*' Hard coded for now; get from resource later
fSymbols[kMonetaryGroupingSeparatorSymbol] = fSymbols[kGroupingSeparatorSymbol];
}
// initialize with default values

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2005, International Business Machines Corporation and *
* Copyright (C) 1997-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@ -832,7 +832,12 @@ DecimalFormat::subformat(UnicodeString& appendTo,
// Gets the localized zero Unicode character.
UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
int32_t zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
const UnicodeString *grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
const UnicodeString *grouping ;
if(fIsCurrencyFormat) {
grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
}else{
grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
}
const UnicodeString *decimal;
if(fIsCurrencyFormat) {
decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2005, International Business Machines Corporation and *
* Copyright (C) 1997-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@ -859,37 +859,11 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
if (U_FAILURE(status) || symbolsToAdopt == NULL) {
goto cleanup;
}
// Here we assume that the locale passed in is in the canonical
// form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO
if(style==kCurrencyStyle){
char currencyCode[8]={0};
int32_t currencyCodeCap = sizeof(currencyCode);
const char* locName = desiredLocale.getName();
currencyCodeCap = uloc_getKeywordValue(locName, "currency", currencyCode, currencyCodeCap, &status);
if(U_SUCCESS(status) && currencyCodeCap > 0) {
/* An explicit currency was requested */
UErrorCode localStatus = U_ZERO_ERROR;
UResourceBundle *currency = ures_getByKeyWithFallback(resource, "Currencies", NULL, &localStatus);
currency = ures_getByKeyWithFallback(currency, currencyCode, currency, &localStatus);
if(U_SUCCESS(localStatus) && ures_getSize(currency)>2) {
currency = ures_getByIndex(currency, 2, currency, &localStatus);
int32_t currPatternLen = 0;
const UChar *currPattern = ures_getStringByIndex(currency, (int32_t)0, &currPatternLen, &localStatus);
UnicodeString decimalSep = ures_getStringByIndex(currency, (int32_t)1, NULL, &localStatus);
UnicodeString groupingSep = ures_getStringByIndex(currency, (int32_t)2, NULL, &localStatus);
if(U_SUCCESS(localStatus)){
symbolsToAdopt->setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, groupingSep);
symbolsToAdopt->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, decimalSep);
pattern.setTo(TRUE, currPattern, currPatternLen);
status = localStatus;
}
}
ures_close(currency);
/* else An explicit currency was requested and is unknown or locale data is malformed. */
/* ucurr_* API will get the correct value later on. */
const UChar* currPattern = symbolsToAdopt->getCurrencyPattern();
if(currPattern!=NULL){
pattern.setTo(currPattern, u_strlen(currPattern));
}
/* else no currency keyword used. */
}
f = new DecimalFormat(pattern, symbolsToAdopt, status);
if (U_FAILURE(status) || f == NULL) {

View File

@ -1,6 +1,6 @@
/*
********************************************************************************
* Copyright (C) 1997-2005, International Business Machines
* Copyright (C) 1997-2006, International Business Machines
* Corporation and others. All Rights Reserved.
********************************************************************************
*
@ -121,6 +121,10 @@ public:
/** Significant digit symbol
* @draft ICU 3.0 */
kSignificantDigitSymbol,
/** The monetary grouping separator
* @draft ICU 3.6
*/
kMonetaryGroupingSeparatorSymbol,
/** count symbol constants */
kFormatSymbolCount
};
@ -277,6 +281,12 @@ public:
*/
inline const UnicodeString &getConstSymbol(ENumberFormatSymbol symbol) const;
/**
* Returns that pattern stored in currecy info. Internal API for use by NumberFormat API.
* @internal
*/
inline const UChar* getCurrencyPattern(void) const;
private:
/**
* Private symbol strings.
@ -305,6 +315,7 @@ private:
char actualLocale[ULOC_FULLNAME_CAPACITY];
char validLocale[ULOC_FULLNAME_CAPACITY];
const UChar* currPattern;
};
// -------------------------------------
@ -347,7 +358,10 @@ DecimalFormatSymbols::getLocale() const {
return locale;
}
inline const UChar*
DecimalFormatSymbols::getCurrencyPattern() const {
return currPattern;
}
U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2005, International Business Machines Corporation and others. All Rights Reserved.
* Copyright (C) 1997-2006, International Business Machines Corporation and others. All Rights Reserved.
* Modification History:
*
* Date Name Description
@ -790,6 +790,10 @@ typedef enum UNumberFormatSymbol {
/** Significant digit symbol
* @draft ICU 3.0 */
UNUM_SIGNIFICANT_DIGIT_SYMBOL,
/** The monetary grouping separator
* @draft ICU 3.6
*/
UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL,
/** count symbol constants */
UNUM_FORMAT_SYMBOL_COUNT
} UNumberFormatSymbol;

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2005, International Business Machines Corporation and
* Copyright (c) 1997-2006, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/* Modification History:
@ -79,7 +79,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
CASE(29,TestCurrencyAmount);
CASE(30,TestCurrencyUnit);
CASE(31,TestCoverage);
CASE(32,TestJB3832);
default: name = ""; break;
}
}
@ -1583,7 +1583,8 @@ void NumberFormatTest::TestSymbolsWithBadLocale(void) {
+ prettify(mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum)));
if (mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum).length() == 0
&& symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol)
&& symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
&& symbolEnum != (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol)
{
errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum);
}
@ -2171,5 +2172,27 @@ void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
", expected " + pos + " " + width + " " + pad);
}
}
void NumberFormatTest::TestJB3832(){
const char* localeID = "pt_PT@currency=PTE";
Locale loc(localeID);
UErrorCode status = U_ZERO_ERROR;
UnicodeString expected("1,150$50 Esc.");
UnicodeString s;
NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status);
if(U_FAILURE(status)){
errln("Could not create currency formatter for locale %s", localeID);
return;
}
currencyFmt->format(1150.50, s);
if(s!=expected){
errln(UnicodeString("FAIL: Expected: ")+expected
+ UnicodeString(" Got: ") + s
+ UnicodeString( " for locale: ")+ UnicodeString(localeID) );
}
if (U_FAILURE(status)){
errln((UnicodeString)"FAIL: Status " + (int32_t)status);
}
delete currencyFmt;
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2005, International Business Machines Corporation and
* Copyright (c) 1997-2006, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -116,9 +116,10 @@ class NumberFormatTest: public CalendarTimeZoneTest {
void TestPerMill(void);
void TestIllegalPatterns(void);
void TestCases(void);
void TestJB3832(void);
private:
static UBool equalValue(const Formattable& a, const Formattable& b);