Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: source/i18n/quantityformatter.cpp

Issue 1621943002: ICU 56 step 4: Apply post-56 fixes for measure/date format (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@56goog
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/i18n/quantityformatter.h ('k') | source/i18n/rbt_pars.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ****************************************************************************** 2 ******************************************************************************
3 * Copyright (C) 2014-2015, International Business Machines 3 * Copyright (C) 2014-2015, International Business Machines
4 * Corporation and others. All Rights Reserved. 4 * Corporation and others. All Rights Reserved.
5 ****************************************************************************** 5 ******************************************************************************
6 * quantityformatter.cpp 6 * quantityformatter.cpp
7 */ 7 */
8
9 #include "unicode/utypes.h"
10
11 #if !UCONFIG_NO_FORMATTING
12
8 #include "quantityformatter.h" 13 #include "quantityformatter.h"
9 #include "simplepatternformatter.h" 14 #include "simplepatternformatter.h"
10 #include "uassert.h" 15 #include "uassert.h"
11 #include "unicode/unistr.h" 16 #include "unicode/unistr.h"
12 #include "unicode/decimfmt.h" 17 #include "unicode/decimfmt.h"
13 #include "cstring.h" 18 #include "cstring.h"
14 #include "unicode/plurrule.h" 19 #include "unicode/plurrule.h"
15 #include "charstr.h" 20 #include "charstr.h"
16 #include "unicode/fmtable.h" 21 #include "unicode/fmtable.h"
17 #include "unicode/fieldpos.h" 22 #include "unicode/fieldpos.h"
23 #include "standardplural.h"
18 #include "visibledigits.h" 24 #include "visibledigits.h"
19 25 #include "uassert.h"
20 #if !UCONFIG_NO_FORMATTING
21 26
22 U_NAMESPACE_BEGIN 27 U_NAMESPACE_BEGIN
23 28
24 // other must always be first.
25 static const char * const gPluralForms[] = {
26 "other", "zero", "one", "two", "few", "many"};
27
28 static int32_t getPluralIndex(const char *pluralForm) {
29 int32_t len = UPRV_LENGTHOF(gPluralForms);
30 for (int32_t i = 0; i < len; ++i) {
31 if (uprv_strcmp(pluralForm, gPluralForms[i]) == 0) {
32 return i;
33 }
34 }
35 return -1;
36 }
37
38 QuantityFormatter::QuantityFormatter() { 29 QuantityFormatter::QuantityFormatter() {
39 for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { 30 for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) {
40 formatters[i] = NULL; 31 formatters[i] = NULL;
41 } 32 }
42 } 33 }
43 34
44 QuantityFormatter::QuantityFormatter(const QuantityFormatter &other) { 35 QuantityFormatter::QuantityFormatter(const QuantityFormatter &other) {
45 for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { 36 for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) {
46 if (other.formatters[i] == NULL) { 37 if (other.formatters[i] == NULL) {
47 formatters[i] = NULL; 38 formatters[i] = NULL;
(...skipping 25 matching lines...) Expand all
73 } 64 }
74 } 65 }
75 66
76 void QuantityFormatter::reset() { 67 void QuantityFormatter::reset() {
77 for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) { 68 for (int32_t i = 0; i < UPRV_LENGTHOF(formatters); ++i) {
78 delete formatters[i]; 69 delete formatters[i];
79 formatters[i] = NULL; 70 formatters[i] = NULL;
80 } 71 }
81 } 72 }
82 73
83 UBool QuantityFormatter::add( 74 UBool QuantityFormatter::addIfAbsent(
84 const char *variant, 75 const char *variant,
85 const UnicodeString &rawPattern, 76 const UnicodeString &rawPattern,
86 UErrorCode &status) { 77 UErrorCode &status) {
78 int32_t pluralIndex = StandardPlural::indexFromString(variant, status);
87 if (U_FAILURE(status)) { 79 if (U_FAILURE(status)) {
88 return FALSE; 80 return FALSE;
89 } 81 }
90 int32_t pluralIndex = getPluralIndex(variant); 82 if (formatters[pluralIndex] != NULL) {
91 if (pluralIndex == -1) { 83 return TRUE;
92 status = U_ILLEGAL_ARGUMENT_ERROR;
93 return FALSE;
94 } 84 }
95 SimplePatternFormatter *newFmt = 85 SimplePatternFormatter *newFmt = new SimplePatternFormatter(rawPattern, 0, 1 , status);
96 new SimplePatternFormatter(rawPattern);
97 if (newFmt == NULL) { 86 if (newFmt == NULL) {
98 status = U_MEMORY_ALLOCATION_ERROR; 87 status = U_MEMORY_ALLOCATION_ERROR;
99 return FALSE; 88 return FALSE;
100 } 89 }
101 if (newFmt->getPlaceholderCount() > 1) { 90 if (U_FAILURE(status)) {
102 delete newFmt; 91 delete newFmt;
103 status = U_ILLEGAL_ARGUMENT_ERROR;
104 return FALSE; 92 return FALSE;
105 } 93 }
106 delete formatters[pluralIndex];
107 formatters[pluralIndex] = newFmt; 94 formatters[pluralIndex] = newFmt;
108 return TRUE; 95 return TRUE;
109 } 96 }
110 97
111 UBool QuantityFormatter::isValid() const { 98 UBool QuantityFormatter::isValid() const {
112 return formatters[0] != NULL; 99 return formatters[StandardPlural::OTHER] != NULL;
113 } 100 }
114 101
115 const SimplePatternFormatter *QuantityFormatter::getByVariant( 102 const SimplePatternFormatter *QuantityFormatter::getByVariant(
116 const char *variant) const { 103 const char *variant) const {
117 int32_t pluralIndex = getPluralIndex(variant); 104 U_ASSERT(isValid());
118 if (pluralIndex == -1) { 105 int32_t pluralIndex = StandardPlural::indexOrOtherIndexFromString(variant);
119 pluralIndex = 0;
120 }
121 const SimplePatternFormatter *pattern = formatters[pluralIndex]; 106 const SimplePatternFormatter *pattern = formatters[pluralIndex];
122 if (pattern == NULL) { 107 if (pattern == NULL) {
123 pattern = formatters[0]; 108 pattern = formatters[StandardPlural::OTHER];
124 } 109 }
125 return pattern; 110 return pattern;
126 } 111 }
127 112
128 UnicodeString &QuantityFormatter::format( 113 UnicodeString &QuantityFormatter::format(
129 const Formattable& quantity, 114 const Formattable &number,
130 const NumberFormat &fmt, 115 const NumberFormat &fmt,
131 const PluralRules &rules, 116 const PluralRules &rules,
132 UnicodeString &appendTo, 117 UnicodeString &appendTo,
133 FieldPosition &pos, 118 FieldPosition &pos,
134 UErrorCode &status) const { 119 UErrorCode &status) const {
120 UnicodeString formattedNumber;
121 StandardPlural::Form p = selectPlural(number, fmt, rules, formattedNumber, p os, status);
135 if (U_FAILURE(status)) { 122 if (U_FAILURE(status)) {
136 return appendTo; 123 return appendTo;
137 } 124 }
138 UnicodeString count; 125 const SimplePatternFormatter *pattern = formatters[p];
126 if (pattern == NULL) {
127 pattern = formatters[StandardPlural::OTHER];
128 if (pattern == NULL) {
129 status = U_INVALID_STATE_ERROR;
130 return appendTo;
131 }
132 }
133 return format(*pattern, formattedNumber, appendTo, pos, status);
134 }
135
136 // The following methods live here so that class PluralRules does not depend on number formatting,
137 // and the SimplePatternFormatter does not depend on FieldPosition.
138
139 StandardPlural::Form QuantityFormatter::selectPlural(
140 const Formattable &number,
141 const NumberFormat &fmt,
142 const PluralRules &rules,
143 UnicodeString &formattedNumber,
144 FieldPosition &pos,
145 UErrorCode &status) {
146 if (U_FAILURE(status)) {
147 return StandardPlural::OTHER;
148 }
149 UnicodeString pluralKeyword;
139 VisibleDigitsWithExponent digits; 150 VisibleDigitsWithExponent digits;
140 const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt); 151 const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
141 if (decFmt != NULL) { 152 if (decFmt != NULL) {
142 decFmt->initVisibleDigitsWithExponent(quantity, digits, status); 153 decFmt->initVisibleDigitsWithExponent(number, digits, status);
143 if (U_FAILURE(status)) { 154 if (U_FAILURE(status)) {
144 return appendTo; 155 return StandardPlural::OTHER;
145 } 156 }
146 count = rules.select(digits); 157 pluralKeyword = rules.select(digits);
158 decFmt->format(digits, formattedNumber, pos, status);
147 } else { 159 } else {
148 if (quantity.getType() == Formattable::kDouble) { 160 if (number.getType() == Formattable::kDouble) {
149 count = rules.select(quantity.getDouble()); 161 pluralKeyword = rules.select(number.getDouble());
150 } else if (quantity.getType() == Formattable::kLong) { 162 } else if (number.getType() == Formattable::kLong) {
151 count = rules.select(quantity.getLong()); 163 pluralKeyword = rules.select(number.getLong());
152 } else if (quantity.getType() == Formattable::kInt64) { 164 } else if (number.getType() == Formattable::kInt64) {
153 count = rules.select((double) quantity.getInt64()); 165 pluralKeyword = rules.select((double) number.getInt64());
154 } else { 166 } else {
155 status = U_ILLEGAL_ARGUMENT_ERROR; 167 status = U_ILLEGAL_ARGUMENT_ERROR;
156 return appendTo; 168 return StandardPlural::OTHER;
157 } 169 }
170 fmt.format(number, formattedNumber, pos, status);
158 } 171 }
159 CharString buffer; 172 return StandardPlural::orOtherFromString(pluralKeyword);
160 buffer.appendInvariantChars(count, status); 173 }
174
175 UnicodeString &QuantityFormatter::format(
176 const SimplePatternFormatter &pattern,
177 const UnicodeString &value,
178 UnicodeString &appendTo,
179 FieldPosition &pos,
180 UErrorCode &status) {
161 if (U_FAILURE(status)) { 181 if (U_FAILURE(status)) {
162 return appendTo; 182 return appendTo;
163 } 183 }
164 const SimplePatternFormatter *pattern = getByVariant(buffer.data()); 184 const UnicodeString *param = &value;
165 if (pattern == NULL) { 185 int32_t offset;
166 status = U_INVALID_STATE_ERROR; 186 pattern.formatAndAppend(&param, 1, appendTo, &offset, 1, status);
167 return appendTo; 187 if (pos.getBeginIndex() != 0 || pos.getEndIndex() != 0) {
168 } 188 if (offset >= 0) {
169 UnicodeString formattedNumber; 189 pos.setBeginIndex(pos.getBeginIndex() + offset);
170 FieldPosition fpos(pos.getField()); 190 pos.setEndIndex(pos.getEndIndex() + offset);
171 if (decFmt != NULL) { 191 } else {
172 decFmt->format(digits, formattedNumber, fpos, status); 192 pos.setBeginIndex(0);
173 } else { 193 pos.setEndIndex(0);
174 fmt.format(quantity, formattedNumber, fpos, status);
175 }
176 const UnicodeString *params[1] = {&formattedNumber};
177 int32_t offsets[1];
178 pattern->formatAndAppend(
179 params,
180 UPRV_LENGTHOF(params),
181 appendTo,
182 offsets,
183 UPRV_LENGTHOF(offsets),
184 status);
185 if (offsets[0] != -1) {
186 if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
187 pos.setBeginIndex(fpos.getBeginIndex() + offsets[0]);
188 pos.setEndIndex(fpos.getEndIndex() + offsets[0]);
189 } 194 }
190 } 195 }
191 return appendTo; 196 return appendTo;
192 } 197 }
193 198
194 U_NAMESPACE_END 199 U_NAMESPACE_END
195 200
196 #endif /* #if !UCONFIG_NO_FORMATTING */ 201 #endif /* #if !UCONFIG_NO_FORMATTING */
OLDNEW
« no previous file with comments | « source/i18n/quantityformatter.h ('k') | source/i18n/rbt_pars.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698