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.
175 lines
5.5 KiB
175 lines
5.5 KiB
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
/*
|
|
* 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 */
|
|
|