ICU-3832 Add support for monetary grouping separator
X-SVN-Rev: 18960
This commit is contained in:
parent
2aee23b0eb
commit
0bdf064c1d
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user