]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/digitaffixesandpadding.cpp
ICU-59117.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / digitaffixesandpadding.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
2ca993e8
A
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
23U_NAMESPACE_BEGIN
24
25UBool
26DigitAffixesAndPadding::needsPluralRules() const {
27 return (
28 fPositivePrefix.hasMultipleVariants() ||
29 fPositiveSuffix.hasMultipleVariants() ||
30 fNegativePrefix.hasMultipleVariants() ||
31 fNegativeSuffix.hasMultipleVariants());
32}
33
34UnicodeString &
35DigitAffixesAndPadding::formatInt32(
36 int32_t value,
37 const ValueFormatter &formatter,
38 FieldPositionHandler &handler,
39 const PluralRules *optPluralRules,
40 UnicodeString &appendTo,
41 UErrorCode &status) const {
42 if (U_FAILURE(status)) {
43 return appendTo;
44 }
45 if (optPluralRules != NULL || fWidth > 0 || !formatter.isFastFormattable(value)) {
46 VisibleDigitsWithExponent digits;
47 formatter.toVisibleDigitsWithExponent(
48 (int64_t) value, digits, status);
49 return format(
50 digits,
51 formatter,
52 handler,
53 optPluralRules,
54 appendTo,
55 status);
56 }
57 UBool bPositive = value >= 0;
58 const DigitAffix *prefix = bPositive ? &fPositivePrefix.getOtherVariant() : &fNegativePrefix.getOtherVariant();
59 const DigitAffix *suffix = bPositive ? &fPositiveSuffix.getOtherVariant() : &fNegativeSuffix.getOtherVariant();
60 if (value < 0) {
61 value = -value;
62 }
63 prefix->format(handler, appendTo);
64 formatter.formatInt32(value, handler, appendTo);
65 return suffix->format(handler, appendTo);
66}
67
68static UnicodeString &
69formatAffix(
70 const DigitAffix *affix,
71 FieldPositionHandler &handler,
72 UnicodeString &appendTo) {
73 if (affix) {
74 affix->format(handler, appendTo);
75 }
76 return appendTo;
77}
78
79static int32_t
80countAffixChar32(const DigitAffix *affix) {
81 if (affix) {
82 return affix->countChar32();
83 }
84 return 0;
85}
86
87UnicodeString &
88DigitAffixesAndPadding::format(
89 const VisibleDigitsWithExponent &digits,
90 const ValueFormatter &formatter,
91 FieldPositionHandler &handler,
92 const PluralRules *optPluralRules,
93 UnicodeString &appendTo,
94 UErrorCode &status) const {
95 if (U_FAILURE(status)) {
96 return appendTo;
97 }
98 const DigitAffix *prefix = NULL;
99 const DigitAffix *suffix = NULL;
100 if (!digits.isNaN()) {
101 UBool bPositive = !digits.isNegative();
102 const PluralAffix *pluralPrefix = bPositive ? &fPositivePrefix : &fNegativePrefix;
103 const PluralAffix *pluralSuffix = bPositive ? &fPositiveSuffix : &fNegativeSuffix;
104 if (optPluralRules == NULL || digits.isInfinite()) {
105 prefix = &pluralPrefix->getOtherVariant();
106 suffix = &pluralSuffix->getOtherVariant();
107 } else {
108 UnicodeString count(optPluralRules->select(digits));
109 prefix = &pluralPrefix->getByCategory(count);
110 suffix = &pluralSuffix->getByCategory(count);
111 }
112 }
113 if (fWidth <= 0) {
114 formatAffix(prefix, handler, appendTo);
115 formatter.format(digits, handler, appendTo);
116 return formatAffix(suffix, handler, appendTo);
117 }
118 int32_t codePointCount = countAffixChar32(prefix) + formatter.countChar32(digits) + countAffixChar32(suffix);
119 int32_t paddingCount = fWidth - codePointCount;
120 switch (fPadPosition) {
121 case kPadBeforePrefix:
122 appendPadding(paddingCount, appendTo);
123 formatAffix(prefix, handler, appendTo);
124 formatter.format(digits, handler, appendTo);
125 return formatAffix(suffix, handler, appendTo);
126 case kPadAfterPrefix:
127 formatAffix(prefix, handler, appendTo);
128 appendPadding(paddingCount, appendTo);
129 formatter.format(digits, handler, appendTo);
130 return formatAffix(suffix, handler, appendTo);
131 case kPadBeforeSuffix:
132 formatAffix(prefix, handler, appendTo);
133 formatter.format(digits, handler, appendTo);
134 appendPadding(paddingCount, appendTo);
135 return formatAffix(suffix, handler, appendTo);
136 case kPadAfterSuffix:
137 formatAffix(prefix, handler, appendTo);
138 formatter.format(digits, handler, appendTo);
139 formatAffix(suffix, handler, appendTo);
140 return appendPadding(paddingCount, appendTo);
141 default:
142 U_ASSERT(FALSE);
143 return appendTo;
144 }
145}
146
147UnicodeString &
148DigitAffixesAndPadding::format(
149 DigitList &value,
150 const ValueFormatter &formatter,
151 FieldPositionHandler &handler,
152 const PluralRules *optPluralRules,
153 UnicodeString &appendTo,
154 UErrorCode &status) const {
155 VisibleDigitsWithExponent digits;
156 formatter.toVisibleDigitsWithExponent(
157 value, digits, status);
158 if (U_FAILURE(status)) {
159 return appendTo;
160 }
161 return format(
162 digits, formatter, handler, optPluralRules, appendTo, status);
163}
164
165UnicodeString &
166DigitAffixesAndPadding::appendPadding(int32_t paddingCount, UnicodeString &appendTo) const {
167 for (int32_t i = 0; i < paddingCount; ++i) {
168 appendTo.append(fPadChar);
169 }
170 return appendTo;
171}
172
173
174U_NAMESPACE_END
175#endif /* #if !UCONFIG_NO_FORMATTING */