diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /intl/icu/source/i18n/quantityformatter.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'intl/icu/source/i18n/quantityformatter.cpp')
-rw-r--r-- | intl/icu/source/i18n/quantityformatter.cpp | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/intl/icu/source/i18n/quantityformatter.cpp b/intl/icu/source/i18n/quantityformatter.cpp new file mode 100644 index 000000000..c44357a53 --- /dev/null +++ b/intl/icu/source/i18n/quantityformatter.cpp @@ -0,0 +1,203 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +****************************************************************************** +* Copyright (C) 2014-2016, International Business Machines +* Corporation and others. All Rights Reserved. +****************************************************************************** +* quantityformatter.cpp +*/ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +#include "unicode/simpleformatter.h" +#include "quantityformatter.h" +#include "uassert.h" +#include "unicode/unistr.h" +#include "unicode/decimfmt.h" +#include "cstring.h" +#include "unicode/plurrule.h" +#include "charstr.h" +#include "unicode/fmtable.h" +#include "unicode/fieldpos.h" +#include "standardplural.h" +#include "visibledigits.h" +#include "uassert.h" + +U_NAMESPACE_BEGIN + +QuantityFormatter::QuantityFormatter() { + for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { + formatters[i] = NULL; + } +} + +QuantityFormatter::QuantityFormatter(const QuantityFormatter &other) { + for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { + if (other.formatters[i] == NULL) { + formatters[i] = NULL; + } else { + formatters[i] = new SimpleFormatter(*other.formatters[i]); + } + } +} + +QuantityFormatter &QuantityFormatter::operator=( + const QuantityFormatter& other) { + if (this == &other) { + return *this; + } + for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { + delete formatters[i]; + if (other.formatters[i] == NULL) { + formatters[i] = NULL; + } else { + formatters[i] = new SimpleFormatter(*other.formatters[i]); + } + } + return *this; +} + +QuantityFormatter::~QuantityFormatter() { + for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { + delete formatters[i]; + } +} + +void QuantityFormatter::reset() { + for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { + delete formatters[i]; + formatters[i] = NULL; + } +} + +UBool QuantityFormatter::addIfAbsent( + const char *variant, + const UnicodeString &rawPattern, + UErrorCode &status) { + int32_t pluralIndex = StandardPlural::indexFromString(variant, status); + if (U_FAILURE(status)) { + return FALSE; + } + if (formatters[pluralIndex] != NULL) { + return TRUE; + } + SimpleFormatter *newFmt = new SimpleFormatter(rawPattern, 0, 1, status); + if (newFmt == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return FALSE; + } + if (U_FAILURE(status)) { + delete newFmt; + return FALSE; + } + formatters[pluralIndex] = newFmt; + return TRUE; +} + +UBool QuantityFormatter::isValid() const { + return formatters[StandardPlural::OTHER] != NULL; +} + +const SimpleFormatter *QuantityFormatter::getByVariant( + const char *variant) const { + U_ASSERT(isValid()); + int32_t pluralIndex = StandardPlural::indexOrOtherIndexFromString(variant); + const SimpleFormatter *pattern = formatters[pluralIndex]; + if (pattern == NULL) { + pattern = formatters[StandardPlural::OTHER]; + } + return pattern; +} + +UnicodeString &QuantityFormatter::format( + const Formattable &number, + const NumberFormat &fmt, + const PluralRules &rules, + UnicodeString &appendTo, + FieldPosition &pos, + UErrorCode &status) const { + UnicodeString formattedNumber; + StandardPlural::Form p = selectPlural(number, fmt, rules, formattedNumber, pos, status); + if (U_FAILURE(status)) { + return appendTo; + } + const SimpleFormatter *pattern = formatters[p]; + if (pattern == NULL) { + pattern = formatters[StandardPlural::OTHER]; + if (pattern == NULL) { + status = U_INVALID_STATE_ERROR; + return appendTo; + } + } + return format(*pattern, formattedNumber, appendTo, pos, status); +} + +// The following methods live here so that class PluralRules does not depend on number formatting, +// and the SimpleFormatter does not depend on FieldPosition. + +StandardPlural::Form QuantityFormatter::selectPlural( + const Formattable &number, + const NumberFormat &fmt, + const PluralRules &rules, + UnicodeString &formattedNumber, + FieldPosition &pos, + UErrorCode &status) { + if (U_FAILURE(status)) { + return StandardPlural::OTHER; + } + UnicodeString pluralKeyword; + VisibleDigitsWithExponent digits; + const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt); + if (decFmt != NULL) { + decFmt->initVisibleDigitsWithExponent(number, digits, status); + if (U_FAILURE(status)) { + return StandardPlural::OTHER; + } + pluralKeyword = rules.select(digits); + decFmt->format(digits, formattedNumber, pos, status); + } else { + if (number.getType() == Formattable::kDouble) { + pluralKeyword = rules.select(number.getDouble()); + } else if (number.getType() == Formattable::kLong) { + pluralKeyword = rules.select(number.getLong()); + } else if (number.getType() == Formattable::kInt64) { + pluralKeyword = rules.select((double) number.getInt64()); + } else { + status = U_ILLEGAL_ARGUMENT_ERROR; + return StandardPlural::OTHER; + } + fmt.format(number, formattedNumber, pos, status); + } + return StandardPlural::orOtherFromString(pluralKeyword); +} + +UnicodeString &QuantityFormatter::format( + const SimpleFormatter &pattern, + const UnicodeString &value, + UnicodeString &appendTo, + FieldPosition &pos, + UErrorCode &status) { + if (U_FAILURE(status)) { + return appendTo; + } + const UnicodeString *param = &value; + int32_t offset; + pattern.formatAndAppend(¶m, 1, appendTo, &offset, 1, status); + if (pos.getBeginIndex() != 0 || pos.getEndIndex() != 0) { + if (offset >= 0) { + pos.setBeginIndex(pos.getBeginIndex() + offset); + pos.setEndIndex(pos.getEndIndex() + offset); + } else { + pos.setBeginIndex(0); + pos.setEndIndex(0); + } + } + return appendTo; +} + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_FORMATTING */ |