ICU-13634 Filling in more methods in decimfmt.cpp

X-SVN-Rev: 41100
This commit is contained in:
Shane Carr 2018-03-13 10:11:36 +00:00
parent 8a50c335fa
commit b30a6f0df1
6 changed files with 372 additions and 40 deletions

View File

@ -71,18 +71,229 @@ DecimalFormat::DecimalFormat(const DecimalFormatSymbols* symbolsToAdopt, UErrorC
}
}
void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {}
#if UCONFIG_HAVE_PARSEALLINPUT
void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {
properties->parseAllInput = value;
}
#endif
DecimalFormat&
DecimalFormat::setAttribute(UNumberFormatAttribute attr, int32_t newvalue, UErrorCode& status) {}
DecimalFormat::setAttribute(UNumberFormatAttribute attr, int32_t newValue, UErrorCode& status) {
if (U_FAILURE(status)) { return *this; }
int32_t DecimalFormat::getAttribute(UNumberFormatAttribute attr, UErrorCode& status) const {}
switch (attr) {
case UNUM_LENIENT_PARSE:
setLenient(newValue != 0);
break;
void DecimalFormat::setGroupingUsed(UBool newValue) {}
case UNUM_PARSE_INT_ONLY:
setParseIntegerOnly(newValue != 0);
break;
void DecimalFormat::setParseIntegerOnly(UBool value) {}
case UNUM_GROUPING_USED:
setGroupingUsed(newValue != 0);
break;
void DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) {}
case UNUM_DECIMAL_ALWAYS_SHOWN:
setDecimalSeparatorAlwaysShown(newValue != 0);
break;
case UNUM_MAX_INTEGER_DIGITS:
setMaximumIntegerDigits(newValue);
break;
case UNUM_MIN_INTEGER_DIGITS:
setMinimumIntegerDigits(newValue);
break;
case UNUM_INTEGER_DIGITS:
setMinimumIntegerDigits(newValue);
setMaximumIntegerDigits(newValue);
break;
case UNUM_MAX_FRACTION_DIGITS:
setMaximumFractionDigits(newValue);
break;
case UNUM_MIN_FRACTION_DIGITS:
setMinimumFractionDigits(newValue);
break;
case UNUM_FRACTION_DIGITS:
setMinimumFractionDigits(newValue);
setMaximumFractionDigits(newValue);
break;
case UNUM_SIGNIFICANT_DIGITS_USED:
setSignificantDigitsUsed(newValue != 0);
break;
case UNUM_MAX_SIGNIFICANT_DIGITS:
setMaximumSignificantDigits(newValue);
break;
case UNUM_MIN_SIGNIFICANT_DIGITS:
setMinimumSignificantDigits(newValue);
break;
case UNUM_MULTIPLIER:
setMultiplier(newValue);
break;
case UNUM_GROUPING_SIZE:
setGroupingSize(newValue);
break;
case UNUM_ROUNDING_MODE:
setRoundingMode((DecimalFormat::ERoundingMode) newValue);
break;
case UNUM_FORMAT_WIDTH:
setFormatWidth(newValue);
break;
case UNUM_PADDING_POSITION:
/** The position at which padding will take place. */
setPadPosition((DecimalFormat::EPadPosition) newValue);
break;
case UNUM_SECONDARY_GROUPING_SIZE:
setSecondaryGroupingSize(newValue);
break;
#if UCONFIG_HAVE_PARSEALLINPUT
case UNUM_PARSE_ALL_INPUT:
setParseAllInput((UNumberFormatAttributeValue) newValue);
break;
#endif
case UNUM_PARSE_NO_EXPONENT:
setParseNoExponent((UBool) newValue);
break;
case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
setDecimalPatternMatchRequired((UBool) newValue);
break;
case UNUM_CURRENCY_USAGE:
setCurrencyUsage((UCurrencyUsage) newValue, &status);
break;
case UNUM_MINIMUM_GROUPING_DIGITS:
setMinimumGroupingDigits(newValue);
break;
default:
status = U_UNSUPPORTED_ERROR;
break;
}
// TODO: UNUM_SCALE?
// TODO: UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS?
return *this;
}
int32_t DecimalFormat::getAttribute(UNumberFormatAttribute attr, UErrorCode& status) const {
if (U_FAILURE(status)) { return -1; }
switch (attr) {
case UNUM_LENIENT_PARSE:
return isLenient();
case UNUM_PARSE_INT_ONLY:
return isParseIntegerOnly();
case UNUM_GROUPING_USED:
return isGroupingUsed();
case UNUM_DECIMAL_ALWAYS_SHOWN:
return isDecimalSeparatorAlwaysShown();
case UNUM_MAX_INTEGER_DIGITS:
return getMaximumIntegerDigits();
case UNUM_MIN_INTEGER_DIGITS:
return getMinimumIntegerDigits();
case UNUM_INTEGER_DIGITS:
// TBD: what should this return?
return getMinimumIntegerDigits();
case UNUM_MAX_FRACTION_DIGITS:
return getMaximumFractionDigits();
case UNUM_MIN_FRACTION_DIGITS:
return getMinimumFractionDigits();
case UNUM_FRACTION_DIGITS:
// TBD: what should this return?
return getMinimumFractionDigits();
case UNUM_SIGNIFICANT_DIGITS_USED:
return areSignificantDigitsUsed();
case UNUM_MAX_SIGNIFICANT_DIGITS:
return getMaximumSignificantDigits();
case UNUM_MIN_SIGNIFICANT_DIGITS:
return getMinimumSignificantDigits();
case UNUM_MULTIPLIER:
return getMultiplier();
case UNUM_GROUPING_SIZE:
return getGroupingSize();
case UNUM_ROUNDING_MODE:
return getRoundingMode();
case UNUM_FORMAT_WIDTH:
return getFormatWidth();
case UNUM_PADDING_POSITION:
return getPadPosition();
case UNUM_SECONDARY_GROUPING_SIZE:
return getSecondaryGroupingSize();
case UNUM_PARSE_NO_EXPONENT:
return getParseNoExponent();
case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
return isDecimalPatternMatchRequired();
case UNUM_CURRENCY_USAGE:
return getCurrencyUsage();
case UNUM_MINIMUM_GROUPING_DIGITS:
return getMinimumGroupingDigits();
default:
status = U_UNSUPPORTED_ERROR;
break;
}
// TODO: UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS?
// TODO: UNUM_SCALE?
return -1; /* undefined */
}
void DecimalFormat::setGroupingUsed(UBool enabled) {
if (enabled) {
// Set to a reasonable default value
properties->groupingSize = 3;
properties->secondaryGroupingSize = 3;
} else {
properties->groupingSize = 0;
properties->secondaryGroupingSize = 0;
}
refreshFormatterNoError();
}
void DecimalFormat::setParseIntegerOnly(UBool value) {
properties->parseIntegerOnly = value;
refreshFormatterNoError();
}
DecimalFormat::DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* symbolsToAdopt,
UParseError& parseError, UErrorCode& status)
@ -106,60 +317,139 @@ DecimalFormat::DecimalFormat(const DecimalFormat& source) {
if (properties == nullptr || exportedProperties == nullptr || symbols == nullptr) {
return;
}
ErrorCode localStatus;
refreshFormatter(localStatus);
refreshFormatterNoError();
}
DecimalFormat& DecimalFormat::operator=(const DecimalFormat& rhs) {}
DecimalFormat& DecimalFormat::operator=(const DecimalFormat& rhs) {
*properties = *rhs.properties;
exportedProperties->clear();
symbols = new DecimalFormatSymbols(*rhs.symbols);
refreshFormatterNoError();
}
DecimalFormat::~DecimalFormat() = default;
Format* DecimalFormat::clone() const {}
Format* DecimalFormat::clone() const {
return new DecimalFormat(*this);
}
UBool DecimalFormat::operator==(const Format& other) const {}
UBool DecimalFormat::operator==(const Format& other) const {
const DecimalFormat* otherDF = dynamic_cast<const DecimalFormat*>(&other);
if (otherDF == nullptr) {
return false;
}
return *properties == *otherDF->properties && *symbols == *otherDF->symbols;
}
UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, FieldPosition& pos) const {}
UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, FieldPosition& pos) const {
ErrorCode localStatus;
FormattedNumber output = formatter->formatDouble(number, localStatus);
output.populateFieldPosition(pos, localStatus);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, FieldPosition& pos,
UErrorCode& status) const {}
UErrorCode& status) const {
FormattedNumber output = formatter->formatDouble(number, status);
output.populateFieldPosition(pos, status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString&
DecimalFormat::format(double number, UnicodeString& appendTo, FieldPositionIterator* posIter,
UErrorCode& status) const {}
UErrorCode& status) const {
FormattedNumber output = formatter->formatDouble(number, status);
output.populateFieldPositionIterator(*posIter, status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString& DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPosition& pos) const {}
UnicodeString& DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPosition& pos) const {
return format(static_cast<int64_t> (number), appendTo, pos);
}
UnicodeString& DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPosition& pos,
UErrorCode& status) const {}
UErrorCode& status) const {
return format(static_cast<int64_t> (number), appendTo, pos, status);
}
UnicodeString&
DecimalFormat::format(int32_t number, UnicodeString& appendTo, FieldPositionIterator* posIter,
UErrorCode& status) const {}
UErrorCode& status) const {
return format(static_cast<int64_t> (number), appendTo, posIter, status);
}
UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPosition& pos) const {}
UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPosition& pos) const {
ErrorCode localStatus;
FormattedNumber output = formatter->formatInt(number, localStatus);
output.populateFieldPosition(pos, localStatus);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPosition& pos,
UErrorCode& status) const {}
UErrorCode& status) const {
FormattedNumber output = formatter->formatInt(number, status);
output.populateFieldPosition(pos, status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString&
DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPositionIterator* posIter,
UErrorCode& status) const {}
UErrorCode& status) const {
FormattedNumber output = formatter->formatInt(number, status);
output.populateFieldPositionIterator(*posIter, status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString&
DecimalFormat::format(StringPiece number, UnicodeString& appendTo, FieldPositionIterator* posIter,
UErrorCode& status) const {}
UErrorCode& status) const {
ErrorCode localStatus;
FormattedNumber output = formatter->formatDecimal(number, localStatus);
output.populateFieldPositionIterator(*posIter, status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString& DecimalFormat::format(const DecimalQuantity& number, UnicodeString& appendTo,
FieldPositionIterator* posIter, UErrorCode& status) const {}
FieldPositionIterator* posIter, UErrorCode& status) const {
FormattedNumber output = formatter->formatDecimalQuantity(number, status);
output.populateFieldPositionIterator(*posIter, status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
UnicodeString&
DecimalFormat::format(const DecimalQuantity& number, UnicodeString& appendTo, FieldPosition& pos,
UErrorCode& status) const {}
UErrorCode& status) const {
FormattedNumber output = formatter->formatDecimalQuantity(number, status);
output.populateFieldPosition(pos, status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable);
return appendTo;
}
void
DecimalFormat::parse(const UnicodeString& text, Formattable& result, ParsePosition& parsePosition) const {}
DecimalFormat::parse(const UnicodeString& text, Formattable& result, ParsePosition& parsePosition) const {
// FIXME
}
CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text, ParsePosition& pos) const {}
CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text, ParsePosition& pos) const {
// FIXME
}
const DecimalFormatSymbols* DecimalFormat::getDecimalFormatSymbols(void) const {}
@ -326,6 +616,11 @@ void DecimalFormat::refreshFormatter(UErrorCode& status) {
*properties, *symbols, true, false, status);
}
void DecimalFormat::refreshFormatterNoError() {
ErrorCode localStatus;
refreshFormatter(localStatus);
}
void DecimalFormat::setPropertiesFromPattern(const UnicodeString& pattern, int32_t ignoreRounding,
UErrorCode& status) {
// Cast workaround to get around putting the enum in the public header file

View File

@ -35,12 +35,20 @@ namespace impl {
struct U_I18N_API CurrencyPluralInfoWrapper {
LocalPointer<CurrencyPluralInfo> fPtr;
CurrencyPluralInfoWrapper() {}
CurrencyPluralInfoWrapper() = default;
CurrencyPluralInfoWrapper(const CurrencyPluralInfoWrapper& other) {
if (!other.fPtr.isNull()) {
fPtr.adoptInstead(new CurrencyPluralInfo(*other.fPtr));
}
}
CurrencyPluralInfoWrapper& operator=(const CurrencyPluralInfoWrapper& other) {
if (!other.fPtr.isNull()) {
fPtr.adoptInstead(new CurrencyPluralInfo(*other.fPtr));
}
return *this;
}
};
// Exported as U_I18N_API because it is needed for the unit test PatternStringTest
@ -77,6 +85,7 @@ struct U_I18N_API DecimalFormatProperties {
bool parseLenient;
bool parseNoExponent;
bool parseToBigDecimal;
UNumberFormatAttributeValue parseAllInput; // ICU4C-only
//PluralRules pluralRules;
UnicodeString positivePrefix;
UnicodeString positivePrefixPattern;

View File

@ -309,6 +309,17 @@ FormattedNumber LocalizedNumberFormatter::formatDecimal(StringPiece value, UErro
return formatImpl(results, status);
}
FormattedNumber LocalizedNumberFormatter::formatDecimalQuantity(const DecimalQuantity& dq, UErrorCode &status) const {
if (U_FAILURE(status)) { return FormattedNumber(U_ILLEGAL_ARGUMENT_ERROR); }
auto results = new NumberFormatterResults();
if (results == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return FormattedNumber(status);
}
results->quantity = dq;
return formatImpl(results, status);
}
FormattedNumber
LocalizedNumberFormatter::formatImpl(impl::NumberFormatterResults *results, UErrorCode &status) const {
// fUnsafeCallCount contains memory to be interpreted as an atomic int, most commonly

View File

@ -792,7 +792,7 @@ class U_I18N_API DecimalFormat : public NumberFormat {
* @return *this - for chaining (example: format.setAttribute(...).setAttribute(...) )
* @stable ICU 51
*/
virtual DecimalFormat& setAttribute(UNumberFormatAttribute attr, int32_t newvalue, UErrorCode& status);
virtual DecimalFormat& setAttribute(UNumberFormatAttribute attr, int32_t newValue, UErrorCode& status);
/**
* Get an integer
@ -823,17 +823,6 @@ class U_I18N_API DecimalFormat : public NumberFormat {
*/
void setParseIntegerOnly(UBool value) U_OVERRIDE;
/**
* Set a particular UDisplayContext value in the formatter, such as
* UDISPCTX_CAPITALIZATION_FOR_STANDALONE.
* @param value The UDisplayContext value to set.
* @param status Input/output status. If at entry this indicates a failure
* status, the function will do nothing; otherwise this will be
* updated with any new status from the function.
* @stable ICU 53
*/
void setContext(UDisplayContext value, UErrorCode& status) U_OVERRIDE;
/**
* Create a DecimalFormat from the given pattern and symbols.
* Use this constructor when you need to completely customize the
@ -1651,7 +1640,7 @@ class U_I18N_API DecimalFormat : public NumberFormat {
UBool isDecimalPatternMatchRequired(void) const;
/**
* Allows you to set the behavior of the pattern decimal mark.
* Allows you to set the parse behavior of the pattern decimal mark.
*
* if TRUE, the input must have a decimal mark if one was specified in the pattern. When
* FALSE the decimal mark may be omitted from the input.
@ -1661,6 +1650,24 @@ class U_I18N_API DecimalFormat : public NumberFormat {
*/
virtual void setDecimalPatternMatchRequired(UBool newValue);
/**
* {@icu} Returns whether to ignore exponents when parsing.
*
* @see #setParseNoExponent
* @internal This API is a technical preview. It may change in an upcoming release.
*/
UBool getParseNoExponent() const;
/**
* {@icu} Specifies whether to stop parsing when an exponent separator is encountered. For
* example, parses "123E4" to 123 (with parse position 3) instead of 1230000 (with parse position
* 5).
*
* @param value true to prevent exponents from being parsed; false to allow them to be parsed.
* @internal This API is a technical preview. It may change in an upcoming release.
*/
void setParseNoExponent(UBool value);
/**
* Synthesizes a pattern string that represents the current state
@ -1974,6 +1981,9 @@ class U_I18N_API DecimalFormat : public NumberFormat {
/** Rebuilds the formatter object from the property bag. */
void refreshFormatter(UErrorCode& status);
/** Rebuilds the formatter object, hiding the error code. */
void refreshFormatterNoError();
/**
* Updates the property bag with settings from the given pattern.
*

View File

@ -2027,6 +2027,13 @@ class U_I18N_API LocalizedNumberFormatter
*/
FormattedNumber formatDecimal(StringPiece value, UErrorCode &status) const;
#ifndef U_HIDE_INTERNAL_API
/** Internal method.
* @internal
*/
FormattedNumber formatDecimalQuantity(const impl::DecimalQuantity& dq, UErrorCode& status) const;
#endif
// Make default copy constructor call the NumberFormatterSettings copy constructor.
/**
* Returns a copy of this LocalizedNumberFormatter.