Line data Source code
1 : // © 2016 and later: Unicode, Inc. and others.
2 : // License & terms of use: http://www.unicode.org/copyright.html
3 : /*
4 : * Copyright (C) 2015, International Business Machines
5 : * Corporation and others. All Rights Reserved.
6 : *
7 : * file name: digitaffixesandpadding.cpp
8 : */
9 :
10 : #include "unicode/utypes.h"
11 :
12 : #if !UCONFIG_NO_FORMATTING
13 :
14 : #include "unicode/plurrule.h"
15 : #include "charstr.h"
16 : #include "digitaffix.h"
17 : #include "digitaffixesandpadding.h"
18 : #include "digitlst.h"
19 : #include "uassert.h"
20 : #include "valueformatter.h"
21 : #include "visibledigits.h"
22 :
23 : U_NAMESPACE_BEGIN
24 :
25 : UBool
26 0 : DigitAffixesAndPadding::needsPluralRules() const {
27 : return (
28 0 : fPositivePrefix.hasMultipleVariants() ||
29 0 : fPositiveSuffix.hasMultipleVariants() ||
30 0 : fNegativePrefix.hasMultipleVariants() ||
31 0 : fNegativeSuffix.hasMultipleVariants());
32 : }
33 :
34 : UnicodeString &
35 0 : DigitAffixesAndPadding::formatInt32(
36 : int32_t value,
37 : const ValueFormatter &formatter,
38 : FieldPositionHandler &handler,
39 : const PluralRules *optPluralRules,
40 : UnicodeString &appendTo,
41 : UErrorCode &status) const {
42 0 : if (U_FAILURE(status)) {
43 0 : return appendTo;
44 : }
45 0 : if (optPluralRules != NULL || fWidth > 0 || !formatter.isFastFormattable(value)) {
46 0 : VisibleDigitsWithExponent digits;
47 : formatter.toVisibleDigitsWithExponent(
48 0 : (int64_t) value, digits, status);
49 : return format(
50 : digits,
51 : formatter,
52 : handler,
53 : optPluralRules,
54 : appendTo,
55 0 : status);
56 : }
57 0 : UBool bPositive = value >= 0;
58 0 : const DigitAffix *prefix = bPositive ? &fPositivePrefix.getOtherVariant() : &fNegativePrefix.getOtherVariant();
59 0 : const DigitAffix *suffix = bPositive ? &fPositiveSuffix.getOtherVariant() : &fNegativeSuffix.getOtherVariant();
60 0 : if (value < 0) {
61 0 : value = -value;
62 : }
63 0 : prefix->format(handler, appendTo);
64 0 : formatter.formatInt32(value, handler, appendTo);
65 0 : return suffix->format(handler, appendTo);
66 : }
67 :
68 : static UnicodeString &
69 0 : formatAffix(
70 : const DigitAffix *affix,
71 : FieldPositionHandler &handler,
72 : UnicodeString &appendTo) {
73 0 : if (affix) {
74 0 : affix->format(handler, appendTo);
75 : }
76 0 : return appendTo;
77 : }
78 :
79 : static int32_t
80 0 : countAffixChar32(const DigitAffix *affix) {
81 0 : if (affix) {
82 0 : return affix->countChar32();
83 : }
84 0 : return 0;
85 : }
86 :
87 : UnicodeString &
88 0 : DigitAffixesAndPadding::format(
89 : const VisibleDigitsWithExponent &digits,
90 : const ValueFormatter &formatter,
91 : FieldPositionHandler &handler,
92 : const PluralRules *optPluralRules,
93 : UnicodeString &appendTo,
94 : UErrorCode &status) const {
95 0 : if (U_FAILURE(status)) {
96 0 : return appendTo;
97 : }
98 0 : const DigitAffix *prefix = NULL;
99 0 : const DigitAffix *suffix = NULL;
100 0 : if (!digits.isNaN()) {
101 0 : UBool bPositive = !digits.isNegative();
102 0 : const PluralAffix *pluralPrefix = bPositive ? &fPositivePrefix : &fNegativePrefix;
103 0 : const PluralAffix *pluralSuffix = bPositive ? &fPositiveSuffix : &fNegativeSuffix;
104 0 : if (optPluralRules == NULL || digits.isInfinite()) {
105 0 : prefix = &pluralPrefix->getOtherVariant();
106 0 : suffix = &pluralSuffix->getOtherVariant();
107 : } else {
108 0 : UnicodeString count(optPluralRules->select(digits));
109 0 : prefix = &pluralPrefix->getByCategory(count);
110 0 : suffix = &pluralSuffix->getByCategory(count);
111 : }
112 : }
113 0 : if (fWidth <= 0) {
114 0 : formatAffix(prefix, handler, appendTo);
115 0 : formatter.format(digits, handler, appendTo);
116 0 : return formatAffix(suffix, handler, appendTo);
117 : }
118 0 : int32_t codePointCount = countAffixChar32(prefix) + formatter.countChar32(digits) + countAffixChar32(suffix);
119 0 : int32_t paddingCount = fWidth - codePointCount;
120 0 : switch (fPadPosition) {
121 : case kPadBeforePrefix:
122 0 : appendPadding(paddingCount, appendTo);
123 0 : formatAffix(prefix, handler, appendTo);
124 0 : formatter.format(digits, handler, appendTo);
125 0 : return formatAffix(suffix, handler, appendTo);
126 : case kPadAfterPrefix:
127 0 : formatAffix(prefix, handler, appendTo);
128 0 : appendPadding(paddingCount, appendTo);
129 0 : formatter.format(digits, handler, appendTo);
130 0 : return formatAffix(suffix, handler, appendTo);
131 : case kPadBeforeSuffix:
132 0 : formatAffix(prefix, handler, appendTo);
133 0 : formatter.format(digits, handler, appendTo);
134 0 : appendPadding(paddingCount, appendTo);
135 0 : return formatAffix(suffix, handler, appendTo);
136 : case kPadAfterSuffix:
137 0 : formatAffix(prefix, handler, appendTo);
138 0 : formatter.format(digits, handler, appendTo);
139 0 : formatAffix(suffix, handler, appendTo);
140 0 : return appendPadding(paddingCount, appendTo);
141 : default:
142 0 : U_ASSERT(FALSE);
143 : return appendTo;
144 : }
145 : }
146 :
147 : UnicodeString &
148 0 : DigitAffixesAndPadding::format(
149 : DigitList &value,
150 : const ValueFormatter &formatter,
151 : FieldPositionHandler &handler,
152 : const PluralRules *optPluralRules,
153 : UnicodeString &appendTo,
154 : UErrorCode &status) const {
155 0 : VisibleDigitsWithExponent digits;
156 : formatter.toVisibleDigitsWithExponent(
157 0 : value, digits, status);
158 0 : if (U_FAILURE(status)) {
159 0 : return appendTo;
160 : }
161 : return format(
162 0 : digits, formatter, handler, optPluralRules, appendTo, status);
163 : }
164 :
165 : UnicodeString &
166 0 : DigitAffixesAndPadding::appendPadding(int32_t paddingCount, UnicodeString &appendTo) const {
167 0 : for (int32_t i = 0; i < paddingCount; ++i) {
168 0 : appendTo.append(fPadChar);
169 : }
170 0 : return appendTo;
171 : }
172 :
173 :
174 : U_NAMESPACE_END
175 : #endif /* #if !UCONFIG_NO_FORMATTING */
|