mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-7952 ICU4C SelectFormat review feedback. Merge from branches/jinglun.
X-SVN-Rev: 28878
This commit is contained in:
parent
ac89f9ed5b
commit
a1f9c9d8f7
3 changed files with 231 additions and 233 deletions
|
@ -1,5 +1,5 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1997-2010, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************
|
||||
|
@ -16,7 +16,7 @@
|
|||
* 06/17/97 helena Fixed the getPattern to return the correct pattern.
|
||||
* 07/09/97 helena Made ParsePosition into a class.
|
||||
* 02/22/99 stephen Removed character literals for EBCDIC safety
|
||||
* 11/01/09 kirtig Added SelectFormat
|
||||
* 11/01/09 kirtig Added SelectFormat
|
||||
********************************************************************/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
@ -42,10 +42,6 @@
|
|||
#include "ustrfmt.h"
|
||||
#include "uvector.h"
|
||||
|
||||
//Todo:remove stdio
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// class MessageFormat
|
||||
// *****************************************************************************
|
||||
|
@ -94,7 +90,7 @@ static const UChar ID_SELECT[] = {
|
|||
static const UChar * const TYPE_IDS[] = {
|
||||
ID_EMPTY,
|
||||
ID_NUMBER,
|
||||
ID_DATE,
|
||||
ID_DATE,
|
||||
ID_TIME,
|
||||
ID_CHOICE,
|
||||
ID_SPELLOUT,
|
||||
|
@ -104,7 +100,7 @@ static const UChar * const TYPE_IDS[] = {
|
|||
ID_SELECT,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
static const UChar ID_CURRENCY[] = {
|
||||
0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x63, 0x79, 0 /* "currency" */
|
||||
};
|
||||
|
@ -146,7 +142,7 @@ static const UChar * const DATE_STYLE_IDS[] = {
|
|||
ID_FULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
static const U_NAMESPACE_QUALIFIER DateFormat::EStyle DATE_STYLES[] = {
|
||||
U_NAMESPACE_QUALIFIER DateFormat::kDefault,
|
||||
U_NAMESPACE_QUALIFIER DateFormat::kShort,
|
||||
|
@ -209,23 +205,23 @@ static UnicodeString& itos(int32_t i, UnicodeString& appendTo) {
|
|||
class MessageFormat::Subformat : public UMemory {
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
* @internal
|
||||
*/
|
||||
Format* format; // formatter
|
||||
/**
|
||||
* @internal
|
||||
* @internal
|
||||
*/
|
||||
int32_t offset; // offset into fPattern
|
||||
/**
|
||||
* @internal
|
||||
* @internal
|
||||
*/
|
||||
// TODO (claireho) or save the number to argName and use itos to convert to number.=> we need this number
|
||||
int32_t argNum; // 0-based argument number
|
||||
/**
|
||||
* @internal
|
||||
* @internal
|
||||
*/
|
||||
UnicodeString* argName; // argument name or number
|
||||
|
||||
|
||||
/**
|
||||
* Clone that.format and assign it to this.format
|
||||
* Do NOT delete this.format
|
||||
|
@ -242,7 +238,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @internal
|
||||
*/
|
||||
UBool operator==(const Subformat& that) const {
|
||||
// Do cheap comparisons first
|
||||
|
@ -290,7 +286,7 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
|
|||
applyPattern(pattern, success);
|
||||
setLocaleIDs(fLocale.getName(), fLocale.getName());
|
||||
}
|
||||
|
||||
|
||||
MessageFormat::MessageFormat(const UnicodeString& pattern,
|
||||
const Locale& newLocale,
|
||||
UErrorCode& success)
|
||||
|
@ -479,13 +475,13 @@ MessageFormat::operator=(const MessageFormat& that)
|
|||
delete subformats[j].format;
|
||||
}
|
||||
subformatCount = 0;
|
||||
|
||||
|
||||
for (j=0; j<that.subformatCount; ++j) {
|
||||
// Subformat::operator= does NOT delete this.format
|
||||
subformats[j] = that.subformats[j];
|
||||
}
|
||||
subformatCount = that.subformatCount;
|
||||
|
||||
|
||||
for (j=0; j<that.argTypeCount; ++j) {
|
||||
argTypes[j] = that.argTypes[j];
|
||||
}
|
||||
|
@ -495,10 +491,10 @@ MessageFormat::operator=(const MessageFormat& that)
|
|||
}
|
||||
|
||||
UBool
|
||||
MessageFormat::operator==(const Format& rhs) const
|
||||
MessageFormat::operator==(const Format& rhs) const
|
||||
{
|
||||
if (this == &rhs) return TRUE;
|
||||
|
||||
|
||||
MessageFormat& that = (MessageFormat&)rhs;
|
||||
|
||||
// Check class ID before checking MessageFormat members
|
||||
|
@ -515,22 +511,22 @@ MessageFormat::operator==(const Format& rhs) const
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
// Creates a copy of this MessageFormat, the caller owns the copy.
|
||||
|
||||
|
||||
Format*
|
||||
MessageFormat::clone() const
|
||||
{
|
||||
return new MessageFormat(*this);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Sets the locale of this MessageFormat object to theLocale.
|
||||
|
||||
|
||||
void
|
||||
MessageFormat::setLocale(const Locale& theLocale)
|
||||
{
|
||||
|
@ -543,10 +539,10 @@ MessageFormat::setLocale(const Locale& theLocale)
|
|||
fLocale = theLocale;
|
||||
setLocaleIDs(fLocale.getName(), fLocale.getName());
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Gets the locale of this MessageFormat object.
|
||||
|
||||
|
||||
const Locale&
|
||||
MessageFormat::getLocale() const
|
||||
{
|
||||
|
@ -557,7 +553,7 @@ MessageFormat::getLocale() const
|
|||
|
||||
|
||||
void
|
||||
MessageFormat::applyPattern(const UnicodeString& newPattern,
|
||||
MessageFormat::applyPattern(const UnicodeString& newPattern,
|
||||
UErrorCode& status)
|
||||
{
|
||||
UParseError parseError;
|
||||
|
@ -569,10 +565,10 @@ MessageFormat::applyPattern(const UnicodeString& newPattern,
|
|||
// Applies the new pattern and returns an error if the pattern
|
||||
// is not correct.
|
||||
void
|
||||
MessageFormat::applyPattern(const UnicodeString& pattern,
|
||||
MessageFormat::applyPattern(const UnicodeString& pattern,
|
||||
UParseError& parseError,
|
||||
UErrorCode& ec)
|
||||
{
|
||||
{
|
||||
if(U_FAILURE(ec)) {
|
||||
return;
|
||||
}
|
||||
|
@ -611,7 +607,7 @@ MessageFormat::applyPattern(const UnicodeString& pattern,
|
|||
parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
|
||||
int32_t patLen = pattern.length();
|
||||
int32_t i;
|
||||
|
||||
|
||||
for (i=0; i<subformatCount; ++i) {
|
||||
delete subformats[i].format;
|
||||
}
|
||||
|
@ -707,7 +703,7 @@ MessageFormat::applyPattern(const UnicodeString& pattern,
|
|||
argTypeCount = subformatCount = 0;
|
||||
}
|
||||
// -------------------------------------
|
||||
// Converts this MessageFormat instance to a pattern.
|
||||
// Converts this MessageFormat instance to a pattern.
|
||||
|
||||
UnicodeString&
|
||||
MessageFormat::toPattern(UnicodeString& appendTo) const {
|
||||
|
@ -732,7 +728,7 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
|
|||
SelectFormat* selfmt;
|
||||
if (fmt == NULL) {
|
||||
// do nothing, string format
|
||||
}
|
||||
}
|
||||
else if ((decfmt = dynamic_cast<DecimalFormat*>(fmt)) != NULL) {
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
NumberFormat& formatAlias = *decfmt;
|
||||
|
@ -740,31 +736,31 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
|
|||
NumberFormat *currencyTemplate = NumberFormat::createCurrencyInstance(fLocale, ec);
|
||||
NumberFormat *percentTemplate = NumberFormat::createPercentInstance(fLocale, ec);
|
||||
NumberFormat *integerTemplate = createIntegerFormat(fLocale, ec);
|
||||
|
||||
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_NUMBER;
|
||||
if (formatAlias != *defaultTemplate) {
|
||||
appendTo += COMMA;
|
||||
if (formatAlias == *currencyTemplate) {
|
||||
appendTo += ID_CURRENCY;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *percentTemplate) {
|
||||
appendTo += ID_PERCENT;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *integerTemplate) {
|
||||
appendTo += ID_INTEGER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
UnicodeString buffer;
|
||||
appendTo += decfmt->toPattern(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete defaultTemplate;
|
||||
delete currencyTemplate;
|
||||
delete percentTemplate;
|
||||
delete integerTemplate;
|
||||
}
|
||||
}
|
||||
else if ((sdtfmt = dynamic_cast<SimpleDateFormat*>(fmt)) != NULL) {
|
||||
DateFormat& formatAlias = *sdtfmt;
|
||||
DateFormat *defaultDateTemplate = DateFormat::createDateInstance(DateFormat::kDefault, fLocale);
|
||||
|
@ -775,62 +771,62 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
|
|||
DateFormat *shortTimeTemplate = DateFormat::createTimeInstance(DateFormat::kShort, fLocale);
|
||||
DateFormat *longTimeTemplate = DateFormat::createTimeInstance(DateFormat::kLong, fLocale);
|
||||
DateFormat *fullTimeTemplate = DateFormat::createTimeInstance(DateFormat::kFull, fLocale);
|
||||
|
||||
|
||||
|
||||
|
||||
appendTo += COMMA;
|
||||
if (formatAlias == *defaultDateTemplate) {
|
||||
appendTo += ID_DATE;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *shortDateTemplate) {
|
||||
appendTo += ID_DATE;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_SHORT;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *defaultDateTemplate) {
|
||||
appendTo += ID_DATE;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_MEDIUM;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *longDateTemplate) {
|
||||
appendTo += ID_DATE;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_LONG;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *fullDateTemplate) {
|
||||
appendTo += ID_DATE;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_FULL;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *defaultTimeTemplate) {
|
||||
appendTo += ID_TIME;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *shortTimeTemplate) {
|
||||
appendTo += ID_TIME;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_SHORT;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *defaultTimeTemplate) {
|
||||
appendTo += ID_TIME;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_MEDIUM;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *longTimeTemplate) {
|
||||
appendTo += ID_TIME;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_LONG;
|
||||
}
|
||||
}
|
||||
else if (formatAlias == *fullTimeTemplate) {
|
||||
appendTo += ID_TIME;
|
||||
appendTo += COMMA;
|
||||
appendTo += ID_FULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
UnicodeString buffer;
|
||||
appendTo += ID_DATE;
|
||||
appendTo += COMMA;
|
||||
appendTo += sdtfmt->toPattern(buffer);
|
||||
}
|
||||
|
||||
|
||||
delete defaultDateTemplate;
|
||||
delete shortDateTemplate;
|
||||
delete longDateTemplate;
|
||||
|
@ -840,7 +836,7 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
|
|||
delete longTimeTemplate;
|
||||
delete fullTimeTemplate;
|
||||
// {sfb} there should be a more efficient way to do this!
|
||||
}
|
||||
}
|
||||
else if ((chcfmt = dynamic_cast<ChoiceFormat*>(fmt)) != NULL) {
|
||||
UnicodeString buffer;
|
||||
appendTo += COMMA;
|
||||
|
@ -851,11 +847,11 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
|
|||
else if ((plfmt = dynamic_cast<PluralFormat*>(fmt)) != NULL) {
|
||||
UnicodeString buffer;
|
||||
appendTo += plfmt->toPattern(buffer);
|
||||
}
|
||||
}
|
||||
else if ((selfmt = dynamic_cast<SelectFormat*>(fmt)) != NULL) {
|
||||
UnicodeString buffer;
|
||||
appendTo += ((SelectFormat*)fmt)->toPattern(buffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//appendTo += ", unknown";
|
||||
}
|
||||
|
@ -864,18 +860,18 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
|
|||
copyAndFixQuotes(fPattern, lastOffset, fPattern.length(), appendTo);
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Adopts the new formats array and updates the array count.
|
||||
// This MessageFormat instance owns the new formats.
|
||||
|
||||
|
||||
void
|
||||
MessageFormat::adoptFormats(Format** newFormats,
|
||||
int32_t count) {
|
||||
if (newFormats == NULL || count < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int32_t i;
|
||||
if (allocateSubformats(count)) {
|
||||
for (i=0; i<subformatCount; ++i) {
|
||||
|
@ -894,12 +890,12 @@ MessageFormat::adoptFormats(Format** newFormats,
|
|||
}
|
||||
|
||||
// TODO: What about the .offset and .argNum fields?
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
// Sets the new formats array and updates the array count.
|
||||
// This MessageFormat instance maks a copy of the new formats.
|
||||
|
||||
|
||||
void
|
||||
MessageFormat::setFormats(const Format** newFormats,
|
||||
int32_t count) {
|
||||
|
@ -908,7 +904,7 @@ MessageFormat::setFormats(const Format** newFormats,
|
|||
}
|
||||
|
||||
if (allocateSubformats(count)) {
|
||||
int32_t i;
|
||||
int32_t i;
|
||||
for (i=0; i<subformatCount; ++i) {
|
||||
delete subformats[i].format;
|
||||
}
|
||||
|
@ -921,12 +917,12 @@ MessageFormat::setFormats(const Format** newFormats,
|
|||
}
|
||||
|
||||
// TODO: What about the .offset and .arg fields?
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
// Adopt a single format by format number.
|
||||
// Do nothing if the format number is not less than the array count.
|
||||
|
||||
|
||||
void
|
||||
MessageFormat::adoptFormat(int32_t n, Format *newFormat) {
|
||||
if (n < 0 || n >= subformatCount) {
|
||||
|
@ -941,14 +937,14 @@ MessageFormat::adoptFormat(int32_t n, Format *newFormat) {
|
|||
// Adopt a single format by format name.
|
||||
// Do nothing if there is no match of formatName.
|
||||
void
|
||||
MessageFormat::adoptFormat(const UnicodeString& formatName,
|
||||
MessageFormat::adoptFormat(const UnicodeString& formatName,
|
||||
Format* formatToAdopt,
|
||||
UErrorCode& status) {
|
||||
if (isArgNumeric ) {
|
||||
int32_t argumentNumber = stou(formatName);
|
||||
if (argumentNumber<0) {
|
||||
status = U_ARGUMENT_TYPE_MISMATCH;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
adoptFormat(argumentNumber, formatToAdopt);
|
||||
return;
|
||||
|
@ -969,7 +965,7 @@ MessageFormat::adoptFormat(const UnicodeString& formatName,
|
|||
// -------------------------------------
|
||||
// Set a single format.
|
||||
// Do nothing if the variable is not less than the array count.
|
||||
|
||||
|
||||
void
|
||||
MessageFormat::setFormat(int32_t n, const Format& newFormat) {
|
||||
if (n >= 0 && n < subformatCount) {
|
||||
|
@ -990,12 +986,12 @@ Format *
|
|||
MessageFormat::getFormat(const UnicodeString& formatName, UErrorCode& status) {
|
||||
|
||||
if (U_FAILURE(status)) return NULL;
|
||||
|
||||
|
||||
if (isArgNumeric ) {
|
||||
int32_t argumentNumber = stou(formatName);
|
||||
if (argumentNumber<0) {
|
||||
status = U_ARGUMENT_TYPE_MISMATCH;
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
if (argumentNumber < 0 || argumentNumber >= subformatCount) {
|
||||
return subformats[argumentNumber].format;
|
||||
|
@ -1004,7 +1000,7 @@ MessageFormat::getFormat(const UnicodeString& formatName, UErrorCode& status) {
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int32_t i=0; i<subformatCount; ++i) {
|
||||
if (formatName==*subformats[i].argName)
|
||||
{
|
||||
|
@ -1042,7 +1038,7 @@ MessageFormat::setFormat(const UnicodeString& formatName,
|
|||
|
||||
// -------------------------------------
|
||||
// Gets the format array.
|
||||
|
||||
|
||||
const Format**
|
||||
MessageFormat::getFormats(int32_t& cnt) const
|
||||
{
|
||||
|
@ -1060,7 +1056,7 @@ MessageFormat::getFormats(int32_t& cnt) const
|
|||
if (a == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
t->formatAliases = a;
|
||||
t->formatAliases = a;
|
||||
} else if (subformatCount > formatAliasesCapacity) {
|
||||
Format** a = (Format**)
|
||||
uprv_realloc(formatAliases, sizeof(Format*) * subformatCount);
|
||||
|
@ -1076,16 +1072,16 @@ MessageFormat::getFormats(int32_t& cnt) const
|
|||
cnt = subformatCount;
|
||||
return (const Format**)formatAliases;
|
||||
}
|
||||
|
||||
|
||||
|
||||
StringEnumeration*
|
||||
MessageFormat::getFormatNames(UErrorCode& status) {
|
||||
if (U_FAILURE(status)) return NULL;
|
||||
|
||||
|
||||
if (isArgNumeric) {
|
||||
status = U_ARGUMENT_TYPE_MISMATCH;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
UVector *fFormatNames = new UVector(status);
|
||||
if (U_FAILURE(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
|
@ -1102,30 +1098,30 @@ MessageFormat::getFormatNames(UErrorCode& status) {
|
|||
// -------------------------------------
|
||||
// Formats the source Formattable array and copy into the result buffer.
|
||||
// Ignore the FieldPosition result for error checking.
|
||||
|
||||
|
||||
UnicodeString&
|
||||
MessageFormat::format(const Formattable* source,
|
||||
int32_t cnt,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& ignore,
|
||||
int32_t cnt,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& ignore,
|
||||
UErrorCode& success) const
|
||||
{
|
||||
if (U_FAILURE(success))
|
||||
if (U_FAILURE(success))
|
||||
return appendTo;
|
||||
|
||||
|
||||
return format(source, cnt, appendTo, ignore, 0, success);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Internally creates a MessageFormat instance based on the
|
||||
// pattern and formats the arguments Formattable array and
|
||||
// pattern and formats the arguments Formattable array and
|
||||
// copy into the appendTo buffer.
|
||||
|
||||
|
||||
UnicodeString&
|
||||
MessageFormat::format( const UnicodeString& pattern,
|
||||
const Formattable* arguments,
|
||||
int32_t cnt,
|
||||
UnicodeString& appendTo,
|
||||
UnicodeString& appendTo,
|
||||
UErrorCode& success)
|
||||
{
|
||||
MessageFormat temp(pattern, success);
|
||||
|
@ -1133,28 +1129,28 @@ MessageFormat::format( const UnicodeString& pattern,
|
|||
temp.format(arguments, cnt, appendTo, ignore, success);
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Formats the source Formattable object and copy into the
|
||||
// Formats the source Formattable object and copy into the
|
||||
// appendTo buffer. The Formattable object must be an array
|
||||
// of Formattable instances, returns error otherwise.
|
||||
|
||||
|
||||
UnicodeString&
|
||||
MessageFormat::format(const Formattable& source,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& ignore,
|
||||
MessageFormat::format(const Formattable& source,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& ignore,
|
||||
UErrorCode& success) const
|
||||
{
|
||||
int32_t cnt;
|
||||
|
||||
if (U_FAILURE(success))
|
||||
if (U_FAILURE(success))
|
||||
return appendTo;
|
||||
if (source.getType() != Formattable::kArray) {
|
||||
success = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
const Formattable* tmpPtr = source.getArray(cnt);
|
||||
|
||||
|
||||
return format(tmpPtr, cnt, appendTo, ignore, 0, success);
|
||||
}
|
||||
|
||||
|
@ -1170,12 +1166,12 @@ MessageFormat::format(const UnicodeString* argumentNames,
|
|||
}
|
||||
|
||||
UnicodeString&
|
||||
MessageFormat::format(const Formattable* arguments,
|
||||
int32_t cnt,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& status,
|
||||
MessageFormat::format(const Formattable* arguments,
|
||||
int32_t cnt,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& status,
|
||||
int32_t recursionProtection,
|
||||
UErrorCode& success) const
|
||||
UErrorCode& success) const
|
||||
{
|
||||
return format(arguments, NULL, cnt, appendTo, status, recursionProtection, success);
|
||||
}
|
||||
|
@ -1187,24 +1183,24 @@ MessageFormat::format(const Formattable* arguments,
|
|||
UnicodeString&
|
||||
MessageFormat::format(const Formattable* arguments,
|
||||
const UnicodeString *argumentNames,
|
||||
int32_t cnt,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& status,
|
||||
int32_t cnt,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& status,
|
||||
int32_t recursionProtection,
|
||||
UErrorCode& success) const
|
||||
{
|
||||
UErrorCode& success) const
|
||||
{
|
||||
int32_t lastOffset = 0;
|
||||
int32_t argumentNumber=0;
|
||||
if (cnt < 0 || (cnt && arguments == NULL)) {
|
||||
success = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
|
||||
if ( !isArgNumeric && argumentNames== NULL ) {
|
||||
success = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
|
||||
const Formattable *obj=NULL;
|
||||
for (int32_t i=0; i<subformatCount; ++i) {
|
||||
// Append the prefix of current format element.
|
||||
|
@ -1235,7 +1231,7 @@ MessageFormat::format(const Formattable* arguments,
|
|||
appendTo += *subformats[i].argName;
|
||||
appendTo += RIGHT_CURLY_BRACE;
|
||||
continue;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Formattable::Type type = obj->getType();
|
||||
|
@ -1263,8 +1259,8 @@ MessageFormat::format(const Formattable* arguments,
|
|||
else {
|
||||
temp.format(arguments, argumentNames, cnt, appendTo, status, recursionProtection, success);
|
||||
}
|
||||
if (U_FAILURE(success)) {
|
||||
return appendTo;
|
||||
if (U_FAILURE(success)) {
|
||||
return appendTo;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1272,13 +1268,13 @@ MessageFormat::format(const Formattable* arguments,
|
|||
}
|
||||
}
|
||||
// If the obj data type is a number, use a NumberFormat instance.
|
||||
else if ((type == Formattable::kDouble) ||
|
||||
else if ((type == Formattable::kDouble) ||
|
||||
(type == Formattable::kLong) ||
|
||||
(type == Formattable::kInt64)) {
|
||||
|
||||
const NumberFormat* nf = getDefaultNumberFormat(success);
|
||||
if (nf == NULL) {
|
||||
return appendTo;
|
||||
if (nf == NULL) {
|
||||
return appendTo;
|
||||
}
|
||||
if (type == Formattable::kDouble) {
|
||||
nf->format(obj->getDouble(), appendTo);
|
||||
|
@ -1291,8 +1287,8 @@ MessageFormat::format(const Formattable* arguments,
|
|||
// If the obj data type is a Date instance, use a DateFormat instance.
|
||||
else if (type == Formattable::kDate) {
|
||||
const DateFormat* df = getDefaultDateFormat(success);
|
||||
if (df == NULL) {
|
||||
return appendTo;
|
||||
if (df == NULL) {
|
||||
return appendTo;
|
||||
}
|
||||
df->format(obj->getDate(), appendTo);
|
||||
}
|
||||
|
@ -1312,11 +1308,11 @@ MessageFormat::format(const Formattable* arguments,
|
|||
|
||||
// -------------------------------------
|
||||
// Parses the source pattern and returns the Formattable objects array,
|
||||
// the array count and the ending parse position. The caller of this method
|
||||
// the array count and the ending parse position. The caller of this method
|
||||
// owns the array.
|
||||
|
||||
|
||||
Formattable*
|
||||
MessageFormat::parse(const UnicodeString& source,
|
||||
MessageFormat::parse(const UnicodeString& source,
|
||||
ParsePosition& pos,
|
||||
int32_t& count) const
|
||||
{
|
||||
|
@ -1336,15 +1332,15 @@ MessageFormat::parse(const UnicodeString& source,
|
|||
for (int32_t i = 0; i < subformatCount; ++i) {
|
||||
// match up to format
|
||||
len = subformats[i].offset - patternOffset;
|
||||
if (len == 0 ||
|
||||
if (len == 0 ||
|
||||
fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
|
||||
sourceOffset += len;
|
||||
patternOffset += len;
|
||||
}
|
||||
}
|
||||
else {
|
||||
goto PARSE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// now use format
|
||||
Format* fmt = subformats[i].format;
|
||||
int32_t argNum = subformats[i].argNum;
|
||||
|
@ -1354,7 +1350,7 @@ MessageFormat::parse(const UnicodeString& source,
|
|||
// does NOT recursively try all possibilities
|
||||
int32_t tempLength = (i+1<subformatCount) ?
|
||||
subformats[i+1].offset : fPattern.length();
|
||||
|
||||
|
||||
int32_t next;
|
||||
if (patternOffset >= tempLength) {
|
||||
next = source.length();
|
||||
|
@ -1364,10 +1360,10 @@ MessageFormat::parse(const UnicodeString& source,
|
|||
fPattern.extract(patternOffset,tempLength - patternOffset, buffer);
|
||||
next = source.indexOf(buffer, sourceOffset);
|
||||
}
|
||||
|
||||
|
||||
if (next < 0) {
|
||||
goto PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
UnicodeString buffer;
|
||||
source.extract(sourceOffset,next - sourceOffset, buffer);
|
||||
|
@ -1391,14 +1387,14 @@ MessageFormat::parse(const UnicodeString& source,
|
|||
}
|
||||
sourceOffset = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tempPos.setIndex(sourceOffset);
|
||||
fmt->parseObject(source, resultArray[argNum], tempPos);
|
||||
if (tempPos.getIndex() == sourceOffset) {
|
||||
goto PARSE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if ((argNum + 1) > count) {
|
||||
count = argNum + 1;
|
||||
}
|
||||
|
@ -1406,7 +1402,7 @@ MessageFormat::parse(const UnicodeString& source,
|
|||
}
|
||||
}
|
||||
len = fPattern.length() - patternOffset;
|
||||
if (len == 0 ||
|
||||
if (len == 0 ||
|
||||
fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
|
||||
pos.setIndex(sourceOffset + len);
|
||||
return resultArray;
|
||||
|
@ -1419,20 +1415,20 @@ MessageFormat::parse(const UnicodeString& source,
|
|||
count = 0;
|
||||
return NULL; // leave index as is to signal error
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Parses the source string and returns the array of
|
||||
// Formattable objects and the array count. The caller
|
||||
// Parses the source string and returns the array of
|
||||
// Formattable objects and the array count. The caller
|
||||
// owns the returned array.
|
||||
|
||||
|
||||
Formattable*
|
||||
MessageFormat::parse(const UnicodeString& source,
|
||||
MessageFormat::parse(const UnicodeString& source,
|
||||
int32_t& cnt,
|
||||
UErrorCode& success) const
|
||||
{
|
||||
if (!isArgNumeric ) {
|
||||
success = U_ARGUMENT_TYPE_MISMATCH;
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
ParsePosition status(0);
|
||||
// Calls the actual implementation method and starts
|
||||
|
@ -1445,10 +1441,10 @@ MessageFormat::parse(const UnicodeString& source,
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Parses the source text and copy into the result buffer.
|
||||
|
||||
|
||||
void
|
||||
MessageFormat::parseObject( const UnicodeString& source,
|
||||
Formattable& result,
|
||||
|
@ -1456,11 +1452,11 @@ MessageFormat::parseObject( const UnicodeString& source,
|
|||
{
|
||||
int32_t cnt = 0;
|
||||
Formattable* tmpResult = parse(source, status, cnt);
|
||||
if (tmpResult != NULL)
|
||||
if (tmpResult != NULL)
|
||||
result.adoptArray(tmpResult, cnt);
|
||||
}
|
||||
|
||||
UnicodeString
|
||||
|
||||
UnicodeString
|
||||
MessageFormat::autoQuoteApostrophe(const UnicodeString& pattern, UErrorCode& status) {
|
||||
UnicodeString result;
|
||||
if (U_SUCCESS(status)) {
|
||||
|
@ -1493,7 +1489,7 @@ static Format* makeRBNF(URBNFRuleSetTag tag, const Locale& locale, const Unicode
|
|||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the segments[] array (see applyPattern()) and parses the
|
||||
* segments[1..3] into a Format* object. Stores the format object in
|
||||
|
@ -1506,7 +1502,7 @@ static Format* makeRBNF(URBNFRuleSetTag tag, const Locale& locale, const Unicode
|
|||
* @param ec error code
|
||||
*/
|
||||
void
|
||||
MessageFormat::makeFormat(int32_t formatNumber,
|
||||
MessageFormat::makeFormat(int32_t formatNumber,
|
||||
UnicodeString* segments,
|
||||
UParseError& parseError,
|
||||
UErrorCode& ec) {
|
||||
|
@ -1632,7 +1628,7 @@ MessageFormat::makeFormat(int32_t formatNumber,
|
|||
else {
|
||||
inQuote = !inQuote;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
unquotedPattern += ch;
|
||||
}
|
||||
|
@ -1651,7 +1647,7 @@ MessageFormat::makeFormat(int32_t formatNumber,
|
|||
if (fmt==NULL && argType!=Formattable::kString && U_SUCCESS(ec)) {
|
||||
ec = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (!allocateSubformats(formatNumber+1) ||
|
||||
!allocateArgTypes(argumentNumber+1)) {
|
||||
ec = U_MEMORY_ALLOCATION_ERROR;
|
||||
|
@ -1682,10 +1678,10 @@ MessageFormat::makeFormat(int32_t formatNumber,
|
|||
argTypeCount = argumentNumber+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Finds the string, s, in the string array, list.
|
||||
int32_t MessageFormat::findKeyword(const UnicodeString& s,
|
||||
// Finds the string, s, in the string array, list.
|
||||
int32_t MessageFormat::findKeyword(const UnicodeString& s,
|
||||
const UChar * const *list)
|
||||
{
|
||||
if (s.length() == 0)
|
||||
|
@ -1702,19 +1698,19 @@ int32_t MessageFormat::findKeyword(const UnicodeString& s,
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Checks the range of the source text to quote the special
|
||||
// characters, { and ' and copy to target buffer.
|
||||
|
||||
|
||||
void
|
||||
MessageFormat::copyAndFixQuotes(const UnicodeString& source,
|
||||
int32_t start,
|
||||
int32_t end,
|
||||
MessageFormat::copyAndFixQuotes(const UnicodeString& source,
|
||||
int32_t start,
|
||||
int32_t end,
|
||||
UnicodeString& appendTo)
|
||||
{
|
||||
UBool gotLB = FALSE;
|
||||
|
||||
|
||||
for (int32_t i = start; i < end; ++i) {
|
||||
UChar ch = source[i];
|
||||
if (ch == LEFT_CURLY_BRACE) {
|
||||
|
@ -1722,7 +1718,7 @@ MessageFormat::copyAndFixQuotes(const UnicodeString& source,
|
|||
appendTo += LEFT_CURLY_BRACE;
|
||||
appendTo += SINGLE_QUOTE;
|
||||
gotLB = TRUE;
|
||||
}
|
||||
}
|
||||
else if (ch == RIGHT_CURLY_BRACE) {
|
||||
if(gotLB) {
|
||||
appendTo += RIGHT_CURLY_BRACE;
|
||||
|
@ -1734,11 +1730,11 @@ MessageFormat::copyAndFixQuotes(const UnicodeString& source,
|
|||
appendTo += RIGHT_CURLY_BRACE;
|
||||
appendTo += SINGLE_QUOTE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ch == SINGLE_QUOTE) {
|
||||
appendTo += SINGLE_QUOTE;
|
||||
appendTo += SINGLE_QUOTE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
appendTo += ch;
|
||||
}
|
||||
|
@ -1748,7 +1744,7 @@ MessageFormat::copyAndFixQuotes(const UnicodeString& source,
|
|||
/**
|
||||
* Convenience method that ought to be in NumberFormat
|
||||
*/
|
||||
NumberFormat*
|
||||
NumberFormat*
|
||||
MessageFormat::createIntegerFormat(const Locale& locale, UErrorCode& status) const {
|
||||
NumberFormat *temp = NumberFormat::createInstance(locale, status);
|
||||
DecimalFormat *temp2;
|
||||
|
@ -1772,7 +1768,7 @@ const NumberFormat* MessageFormat::getDefaultNumberFormat(UErrorCode& ec) const
|
|||
if (defaultNumberFormat == NULL) {
|
||||
MessageFormat* t = (MessageFormat*) this;
|
||||
t->defaultNumberFormat = NumberFormat::createInstance(fLocale, ec);
|
||||
if (U_FAILURE(ec)) {
|
||||
if (U_FAILURE(ec)) {
|
||||
delete t->defaultNumberFormat;
|
||||
t->defaultNumberFormat = NULL;
|
||||
} else if (t->defaultNumberFormat == NULL) {
|
||||
|
@ -1818,10 +1814,10 @@ MessageFormat::isLegalArgName(const UnicodeString& argName) const {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
int32_t
|
||||
int32_t
|
||||
MessageFormat::getArgTypeCount() const {
|
||||
return argTypeCount;
|
||||
}
|
||||
return argTypeCount;
|
||||
}
|
||||
|
||||
FormatNameEnumeration::FormatNameEnumeration(UVector *fNameList, UErrorCode& /*status*/) {
|
||||
pos=0;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1997-2010, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
* Copyright (C) 2010 , Yahoo! Inc.
|
||||
* Copyright (C) 2010 , Yahoo! Inc.
|
||||
********************************************************************
|
||||
*
|
||||
* File SELFMT.CPP
|
||||
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
* Date Name Description
|
||||
* 11/11/09 kirtig Finished first cut of implementation.
|
||||
* 11/16/09 kirtig Improved version
|
||||
* 11/16/09 kirtig Improved version
|
||||
********************************************************************/
|
||||
|
||||
#include <typeinfo> // for 'typeid' to work
|
||||
|
@ -40,41 +40,61 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SelectFormat)
|
|||
#define MAX_KEYWORD_SIZE 30
|
||||
static const UChar SELECT_KEYWORD_OTHER[] = {LOW_O, LOW_T, LOW_H, LOW_E, LOW_R, 0};
|
||||
|
||||
SelectFormat::SelectFormat(const UnicodeString& pat, UErrorCode& status) {
|
||||
SelectFormat::SelectFormat(const UnicodeString& pat, UErrorCode& status) : parsedValuesHash(NULL) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
init(status);
|
||||
}
|
||||
initHashTable(status);
|
||||
applyPattern(pat, status);
|
||||
}
|
||||
|
||||
SelectFormat::SelectFormat(const SelectFormat& other) : Format(other) {
|
||||
SelectFormat::SelectFormat(const SelectFormat& other) : Format(other), parsedValuesHash(NULL) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
pattern = other.pattern;
|
||||
copyHashtable(other.parsedValuesHash, status);
|
||||
}
|
||||
|
||||
SelectFormat::~SelectFormat() {
|
||||
delete parsedValuesHash;
|
||||
cleanHashTable();
|
||||
}
|
||||
|
||||
void
|
||||
SelectFormat::init(UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
void SelectFormat::initHashTable(UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
// has inited
|
||||
if (parsedValuesHash != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
parsedValuesHash = new Hashtable(TRUE, status);
|
||||
if (U_FAILURE(status)) {
|
||||
cleanHashTable();
|
||||
return;
|
||||
} else {
|
||||
if (parsedValuesHash == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
parsedValuesHash = NULL;
|
||||
pattern.remove();
|
||||
}
|
||||
}
|
||||
// to use hashtable->equals(), must set Value Compartor.
|
||||
parsedValuesHash->setValueComparator(uhash_compareCaselessUnicodeString);
|
||||
}
|
||||
|
||||
void SelectFormat::cleanHashTable() {
|
||||
if (parsedValuesHash != NULL) {
|
||||
delete parsedValuesHash;
|
||||
parsedValuesHash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->pattern = newPattern;
|
||||
pattern = newPattern;
|
||||
enum State{ startState, keywordState, pastKeywordState, phraseState};
|
||||
|
||||
//Initialization
|
||||
|
@ -83,12 +103,13 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
UnicodeString* ptrPhrase ;
|
||||
int32_t braceCount = 0;
|
||||
|
||||
delete parsedValuesHash;
|
||||
this->parsedValuesHash = NULL;
|
||||
parsedValuesHash = new Hashtable(TRUE, status);
|
||||
if (U_FAILURE(status)) {
|
||||
if (parsedValuesHash == NULL) {
|
||||
initHashTable(status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
parsedValuesHash->removeAll();
|
||||
parsedValuesHash->setValueDeleter(uhash_deleteUnicodeString);
|
||||
|
||||
//Process the state machine
|
||||
|
@ -96,7 +117,7 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
for (int32_t i = 0; i < pattern.length(); ++i) {
|
||||
//Get the character and check its type
|
||||
UChar ch = pattern.charAt(i);
|
||||
CharacterClass type = classifyCharacter(ch);
|
||||
CharacterClass type = classifyCharacter(ch);
|
||||
|
||||
//Allow any character in phrase but nowhere else
|
||||
if ( type == tOther ) {
|
||||
|
@ -105,6 +126,7 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
continue;
|
||||
}else {
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +145,7 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
//If anything else is encountered, it's a syntax error
|
||||
default:
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}//end of switch(type)
|
||||
break;
|
||||
|
@ -143,6 +166,7 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
//If anything else is encountered, it's a syntax error
|
||||
default:
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}//end of switch(type)
|
||||
break;
|
||||
|
@ -158,6 +182,7 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
//If anything else is encountered, it's a syntax error
|
||||
default:
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}//end of switch(type)
|
||||
break;
|
||||
|
@ -175,10 +200,12 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
//Check validity of keyword
|
||||
if (parsedValuesHash->get(keyword) != NULL) {
|
||||
status = U_DUPLICATE_KEYWORD;
|
||||
return;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}
|
||||
if (keyword.length() == 0) {
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -206,6 +233,7 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
//Handle the default case of switch(state)
|
||||
default:
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
cleanHashTable();
|
||||
return;
|
||||
|
||||
}//end of switch(state)
|
||||
|
@ -214,12 +242,14 @@ SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status)
|
|||
//Check if the state machine is back to startState
|
||||
if ( state != startState){
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}
|
||||
|
||||
//Check if "other" keyword is present
|
||||
//Check if "other" keyword is present
|
||||
if ( !checkSufficientDefinition() ) {
|
||||
status = U_DEFAULT_KEYWORD_MISSING;
|
||||
cleanHashTable();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -244,28 +274,28 @@ SelectFormat::format(const Formattable& obj,
|
|||
|
||||
UnicodeString&
|
||||
SelectFormat::format(const UnicodeString& keyword,
|
||||
UnicodeString& appendTo,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& /*pos */,
|
||||
UErrorCode& status) const {
|
||||
|
||||
if (U_FAILURE(status)) return appendTo;
|
||||
|
||||
if (parsedValuesHash == NULL) {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
//Check for the validity of the keyword
|
||||
if ( !checkValidKeyword(keyword) ){
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
if (parsedValuesHash == NULL) {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
UnicodeString *selectedPattern = (UnicodeString *)parsedValuesHash->get(keyword);
|
||||
if (selectedPattern == NULL) {
|
||||
selectedPattern = (UnicodeString *)parsedValuesHash->get(SELECT_KEYWORD_OTHER);
|
||||
}
|
||||
|
||||
|
||||
return appendTo += *selectedPattern;
|
||||
}
|
||||
|
||||
|
@ -289,7 +319,7 @@ SelectFormat::classifyCharacter(UChar ch) const{
|
|||
return tSpace;
|
||||
}
|
||||
switch (ch) {
|
||||
case LEFTBRACE:
|
||||
case LEFTBRACE:
|
||||
return tLeftBrace;
|
||||
case RIGHTBRACE:
|
||||
return tRightBrace;
|
||||
|
@ -314,13 +344,13 @@ SelectFormat::checkValidKeyword(const UnicodeString& argKeyword ) const{
|
|||
if (len < 1){
|
||||
return FALSE;
|
||||
}
|
||||
CharacterClass type = classifyCharacter(argKeyword.charAt(0));
|
||||
CharacterClass type = classifyCharacter(argKeyword.charAt(0));
|
||||
if( type != tStartKeyword ){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < argKeyword.length(); ++i) {
|
||||
type = classifyCharacter(argKeyword.charAt(i));
|
||||
type = classifyCharacter(argKeyword.charAt(i));
|
||||
if( type != tStartKeyword && type != tContinueKeyword ){
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -337,7 +367,6 @@ SelectFormat&
|
|||
SelectFormat::operator=(const SelectFormat& other) {
|
||||
if (this != &other) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
delete parsedValuesHash;
|
||||
pattern = other.pattern;
|
||||
copyHashtable(other.parsedValuesHash, status);
|
||||
}
|
||||
|
@ -358,44 +387,7 @@ SelectFormat::operator==(const Format& other) const {
|
|||
return TRUE;
|
||||
if ( parsedValuesHash == NULL || hashOther == NULL)
|
||||
return FALSE;
|
||||
if ( hashOther->count() != parsedValuesHash->count() ){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const UHashElement* elem = NULL;
|
||||
int32_t pos = -1;
|
||||
while ((elem = hashOther->nextElement(pos)) != NULL) {
|
||||
const UHashTok otherKeyTok = elem->key;
|
||||
UnicodeString* otherKey = (UnicodeString*)otherKeyTok.pointer;
|
||||
const UHashTok otherKeyToVal = elem->value;
|
||||
UnicodeString* otherValue = (UnicodeString*)otherKeyToVal.pointer;
|
||||
|
||||
UnicodeString* thisElemValue = (UnicodeString*)parsedValuesHash->get(*otherKey);
|
||||
if ( thisElemValue == NULL ){
|
||||
return FALSE;
|
||||
}
|
||||
if ( *thisElemValue != *otherValue){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
pos = -1;
|
||||
while ((elem = parsedValuesHash->nextElement(pos)) != NULL) {
|
||||
const UHashTok thisKeyTok = elem->key;
|
||||
UnicodeString* thisKey = (UnicodeString*)thisKeyTok.pointer;
|
||||
const UHashTok thisKeyToVal = elem->value;
|
||||
UnicodeString* thisValue = (UnicodeString*)thisKeyToVal.pointer;
|
||||
|
||||
UnicodeString* otherElemValue = (UnicodeString*)hashOther->get(*thisKey);
|
||||
if ( otherElemValue == NULL ){
|
||||
return FALSE;
|
||||
}
|
||||
if ( *otherElemValue != *thisValue){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
return parsedValuesHash->equals(*hashOther);
|
||||
}
|
||||
|
||||
UBool
|
||||
|
@ -414,14 +406,21 @@ SelectFormat::parseObject(const UnicodeString& /*source*/,
|
|||
|
||||
void
|
||||
SelectFormat::copyHashtable(Hashtable *other, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
if (other == NULL) {
|
||||
parsedValuesHash = NULL;
|
||||
return;
|
||||
cleanHashTable();
|
||||
return;
|
||||
}
|
||||
parsedValuesHash = new Hashtable(TRUE, status);
|
||||
if (U_FAILURE(status)){
|
||||
if (parsedValuesHash == NULL) {
|
||||
initHashTable(status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
parsedValuesHash->removeAll();
|
||||
parsedValuesHash->setValueDeleter(uhash_deleteUnicodeString);
|
||||
|
||||
int32_t pos = -1;
|
||||
|
@ -435,6 +434,7 @@ SelectFormat::copyHashtable(Hashtable *other, UErrorCode& status) {
|
|||
UnicodeString* otherValue = (UnicodeString*)otherKeyToVal.pointer;
|
||||
parsedValuesHash->put(*otherKey, new UnicodeString(*otherValue), status);
|
||||
if (U_FAILURE(status)){
|
||||
cleanHashTable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -356,7 +356,9 @@ private:
|
|||
Hashtable *parsedValuesHash;
|
||||
|
||||
SelectFormat(); // default constructor not implemented.
|
||||
void init(UErrorCode& status);
|
||||
void initHashTable(UErrorCode &status);
|
||||
void cleanHashTable();
|
||||
|
||||
//For the applyPattern , classifies char.s in one of the characterClass.
|
||||
CharacterClass classifyCharacter(UChar ch) const;
|
||||
//Checks if the "other" keyword is present in pattern.
|
||||
|
|
Loading…
Add table
Reference in a new issue