mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.4 KiB
174 lines
5.4 KiB
9 years ago
|
/*
|
||
|
* Copyright (C) 2015, International Business Machines
|
||
|
* Corporation and others. All Rights Reserved.
|
||
|
*
|
||
|
* file name: digitaffixesandpadding.cpp
|
||
|
*/
|
||
|
|
||
|
#include "unicode/utypes.h"
|
||
|
|
||
|
#if !UCONFIG_NO_FORMATTING
|
||
|
|
||
|
#include "unicode/plurrule.h"
|
||
|
#include "charstr.h"
|
||
|
#include "digitaffix.h"
|
||
|
#include "digitaffixesandpadding.h"
|
||
|
#include "digitlst.h"
|
||
|
#include "uassert.h"
|
||
|
#include "valueformatter.h"
|
||
|
#include "visibledigits.h"
|
||
|
|
||
|
U_NAMESPACE_BEGIN
|
||
|
|
||
|
UBool
|
||
|
DigitAffixesAndPadding::needsPluralRules() const {
|
||
|
return (
|
||
|
fPositivePrefix.hasMultipleVariants() ||
|
||
|
fPositiveSuffix.hasMultipleVariants() ||
|
||
|
fNegativePrefix.hasMultipleVariants() ||
|
||
|
fNegativeSuffix.hasMultipleVariants());
|
||
|
}
|
||
|
|
||
|
UnicodeString &
|
||
|
DigitAffixesAndPadding::formatInt32(
|
||
|
int32_t value,
|
||
|
const ValueFormatter &formatter,
|
||
|
FieldPositionHandler &handler,
|
||
|
const PluralRules *optPluralRules,
|
||
|
UnicodeString &appendTo,
|
||
|
UErrorCode &status) const {
|
||
|
if (U_FAILURE(status)) {
|
||
|
return appendTo;
|
||
|
}
|
||
|
if (optPluralRules != NULL || fWidth > 0 || !formatter.isFastFormattable(value)) {
|
||
|
VisibleDigitsWithExponent digits;
|
||
|
formatter.toVisibleDigitsWithExponent(
|
||
|
(int64_t) value, digits, status);
|
||
|
return format(
|
||
|
digits,
|
||
|
formatter,
|
||
|
handler,
|
||
|
optPluralRules,
|
||
|
appendTo,
|
||
|
status);
|
||
|
}
|
||
|
UBool bPositive = value >= 0;
|
||
|
const DigitAffix *prefix = bPositive ? &fPositivePrefix.getOtherVariant() : &fNegativePrefix.getOtherVariant();
|
||
|
const DigitAffix *suffix = bPositive ? &fPositiveSuffix.getOtherVariant() : &fNegativeSuffix.getOtherVariant();
|
||
|
if (value < 0) {
|
||
|
value = -value;
|
||
|
}
|
||
|
prefix->format(handler, appendTo);
|
||
|
formatter.formatInt32(value, handler, appendTo);
|
||
|
return suffix->format(handler, appendTo);
|
||
|
}
|
||
|
|
||
|
static UnicodeString &
|
||
|
formatAffix(
|
||
|
const DigitAffix *affix,
|
||
|
FieldPositionHandler &handler,
|
||
|
UnicodeString &appendTo) {
|
||
|
if (affix) {
|
||
|
affix->format(handler, appendTo);
|
||
|
}
|
||
|
return appendTo;
|
||
|
}
|
||
|
|
||
|
static int32_t
|
||
|
countAffixChar32(const DigitAffix *affix) {
|
||
|
if (affix) {
|
||
|
return affix->countChar32();
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
UnicodeString &
|
||
|
DigitAffixesAndPadding::format(
|
||
|
const VisibleDigitsWithExponent &digits,
|
||
|
const ValueFormatter &formatter,
|
||
|
FieldPositionHandler &handler,
|
||
|
const PluralRules *optPluralRules,
|
||
|
UnicodeString &appendTo,
|
||
|
UErrorCode &status) const {
|
||
|
if (U_FAILURE(status)) {
|
||
|
return appendTo;
|
||
|
}
|
||
|
const DigitAffix *prefix = NULL;
|
||
|
const DigitAffix *suffix = NULL;
|
||
|
if (!digits.isNaN()) {
|
||
|
UBool bPositive = !digits.isNegative();
|
||
|
const PluralAffix *pluralPrefix = bPositive ? &fPositivePrefix : &fNegativePrefix;
|
||
|
const PluralAffix *pluralSuffix = bPositive ? &fPositiveSuffix : &fNegativeSuffix;
|
||
|
if (optPluralRules == NULL || digits.isInfinite()) {
|
||
|
prefix = &pluralPrefix->getOtherVariant();
|
||
|
suffix = &pluralSuffix->getOtherVariant();
|
||
|
} else {
|
||
|
UnicodeString count(optPluralRules->select(digits));
|
||
|
prefix = &pluralPrefix->getByCategory(count);
|
||
|
suffix = &pluralSuffix->getByCategory(count);
|
||
|
}
|
||
|
}
|
||
|
if (fWidth <= 0) {
|
||
|
formatAffix(prefix, handler, appendTo);
|
||
|
formatter.format(digits, handler, appendTo);
|
||
|
return formatAffix(suffix, handler, appendTo);
|
||
|
}
|
||
|
int32_t codePointCount = countAffixChar32(prefix) + formatter.countChar32(digits) + countAffixChar32(suffix);
|
||
|
int32_t paddingCount = fWidth - codePointCount;
|
||
|
switch (fPadPosition) {
|
||
|
case kPadBeforePrefix:
|
||
|
appendPadding(paddingCount, appendTo);
|
||
|
formatAffix(prefix, handler, appendTo);
|
||
|
formatter.format(digits, handler, appendTo);
|
||
|
return formatAffix(suffix, handler, appendTo);
|
||
|
case kPadAfterPrefix:
|
||
|
formatAffix(prefix, handler, appendTo);
|
||
|
appendPadding(paddingCount, appendTo);
|
||
|
formatter.format(digits, handler, appendTo);
|
||
|
return formatAffix(suffix, handler, appendTo);
|
||
|
case kPadBeforeSuffix:
|
||
|
formatAffix(prefix, handler, appendTo);
|
||
|
formatter.format(digits, handler, appendTo);
|
||
|
appendPadding(paddingCount, appendTo);
|
||
|
return formatAffix(suffix, handler, appendTo);
|
||
|
case kPadAfterSuffix:
|
||
|
formatAffix(prefix, handler, appendTo);
|
||
|
formatter.format(digits, handler, appendTo);
|
||
|
formatAffix(suffix, handler, appendTo);
|
||
|
return appendPadding(paddingCount, appendTo);
|
||
|
default:
|
||
|
U_ASSERT(FALSE);
|
||
|
return appendTo;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UnicodeString &
|
||
|
DigitAffixesAndPadding::format(
|
||
|
DigitList &value,
|
||
|
const ValueFormatter &formatter,
|
||
|
FieldPositionHandler &handler,
|
||
|
const PluralRules *optPluralRules,
|
||
|
UnicodeString &appendTo,
|
||
|
UErrorCode &status) const {
|
||
|
VisibleDigitsWithExponent digits;
|
||
|
formatter.toVisibleDigitsWithExponent(
|
||
|
value, digits, status);
|
||
|
if (U_FAILURE(status)) {
|
||
|
return appendTo;
|
||
|
}
|
||
|
return format(
|
||
|
digits, formatter, handler, optPluralRules, appendTo, status);
|
||
|
}
|
||
|
|
||
|
UnicodeString &
|
||
|
DigitAffixesAndPadding::appendPadding(int32_t paddingCount, UnicodeString &appendTo) const {
|
||
|
for (int32_t i = 0; i < paddingCount; ++i) {
|
||
|
appendTo.append(fPadChar);
|
||
|
}
|
||
|
return appendTo;
|
||
|
}
|
||
|
|
||
|
|
||
|
U_NAMESPACE_END
|
||
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|