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

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

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 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/tmunit.cpp ('k') | source/i18n/translit.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) 2008-2013, Google, International Business Machines Corporation 3 * Copyright (C) 2008-2014, Google, International Business Machines Corporation
4 * and others. All Rights Reserved. 4 * and others. All Rights Reserved.
5 ******************************************************************************* 5 *******************************************************************************
6 */ 6 */
7 7
8 #include "utypeinfo.h" // for 'typeid' to work
9
10 #include "unicode/tmutfmt.h" 8 #include "unicode/tmutfmt.h"
11 9
12 #if !UCONFIG_NO_FORMATTING 10 #if !UCONFIG_NO_FORMATTING
13 11
12 #include "unicode/decimfmt.h"
13 #include "plurrule_impl.h"
14 #include "uvector.h" 14 #include "uvector.h"
15 #include "charstr.h" 15 #include "charstr.h"
16 #include "cmemory.h" 16 #include "cmemory.h"
17 #include "cstring.h" 17 #include "cstring.h"
18 #include "hash.h" 18 #include "hash.h"
19 #include "uresimp.h" 19 #include "uresimp.h"
20 #include "ureslocs.h"
20 #include "unicode/msgfmt.h" 21 #include "unicode/msgfmt.h"
21 #include "uassert.h" 22 #include "uassert.h"
22 23
23 #define LEFT_CURLY_BRACKET ((UChar)0x007B) 24 #define LEFT_CURLY_BRACKET ((UChar)0x007B)
24 #define RIGHT_CURLY_BRACKET ((UChar)0x007D) 25 #define RIGHT_CURLY_BRACKET ((UChar)0x007D)
25 #define SPACE ((UChar)0x0020) 26 #define SPACE ((UChar)0x0020)
26 #define DIGIT_ZERO ((UChar)0x0030) 27 #define DIGIT_ZERO ((UChar)0x0030)
27 #define LOW_S ((UChar)0x0073) 28 #define LOW_S ((UChar)0x0073)
28 #define LOW_M ((UChar)0x006D) 29 #define LOW_M ((UChar)0x006D)
29 #define LOW_I ((UChar)0x0069) 30 #define LOW_I ((UChar)0x0069)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 static const UChar DEFAULT_PATTERN_FOR_HOUR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_H, 0}; 70 static const UChar DEFAULT_PATTERN_FOR_HOUR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_H, 0};
70 static const UChar DEFAULT_PATTERN_FOR_WEEK[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_W, 0}; 71 static const UChar DEFAULT_PATTERN_FOR_WEEK[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_W, 0};
71 static const UChar DEFAULT_PATTERN_FOR_DAY[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_D, 0}; 72 static const UChar DEFAULT_PATTERN_FOR_DAY[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_D, 0};
72 static const UChar DEFAULT_PATTERN_FOR_MONTH[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO , RIGHT_CURLY_BRACKET, SPACE, LOW_M, 0}; 73 static const UChar DEFAULT_PATTERN_FOR_MONTH[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO , RIGHT_CURLY_BRACKET, SPACE, LOW_M, 0};
73 static const UChar DEFAULT_PATTERN_FOR_YEAR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_Y, 0}; 74 static const UChar DEFAULT_PATTERN_FOR_YEAR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_Y, 0};
74 75
75 static const UChar PLURAL_COUNT_ZERO[] = {LOW_Z, LOW_E, LOW_R, LOW_O, 0}; 76 static const UChar PLURAL_COUNT_ZERO[] = {LOW_Z, LOW_E, LOW_R, LOW_O, 0};
76 static const UChar PLURAL_COUNT_ONE[] = {LOW_O, LOW_N, LOW_E, 0}; 77 static const UChar PLURAL_COUNT_ONE[] = {LOW_O, LOW_N, LOW_E, 0};
77 static const UChar PLURAL_COUNT_TWO[] = {LOW_T, LOW_W, LOW_O, 0}; 78 static const UChar PLURAL_COUNT_TWO[] = {LOW_T, LOW_W, LOW_O, 0};
78 79
79 TimeUnitFormat::TimeUnitFormat(UErrorCode& status) 80 TimeUnitFormat::TimeUnitFormat(UErrorCode& status) {
80 : fNumberFormat(NULL), 81 initMeasureFormat(Locale::getDefault(), UMEASFMT_WIDTH_WIDE, NULL, status);
81 fPluralRules(NULL) { 82 create(UTMUTFMT_FULL_STYLE, status);
82 create(Locale::getDefault(), UTMUTFMT_FULL_STYLE, status);
83 } 83 }
84 84
85 85
86 TimeUnitFormat::TimeUnitFormat(const Locale& locale, UErrorCode& status) 86 TimeUnitFormat::TimeUnitFormat(const Locale& locale, UErrorCode& status) {
87 : fNumberFormat(NULL), 87 initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
88 fPluralRules(NULL) { 88 create(UTMUTFMT_FULL_STYLE, status);
89 create(locale, UTMUTFMT_FULL_STYLE, status);
90 } 89 }
91 90
92 91
93 TimeUnitFormat::TimeUnitFormat(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status) 92 TimeUnitFormat::TimeUnitFormat(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status) {
94 : fNumberFormat(NULL), 93 switch (style) {
95 fPluralRules(NULL) { 94 case UTMUTFMT_FULL_STYLE:
96 create(locale, style, status); 95 initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
96 break;
97 case UTMUTFMT_ABBREVIATED_STYLE:
98 initMeasureFormat(locale, UMEASFMT_WIDTH_SHORT, NULL, status);
99 break;
100 default:
101 initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
102 break;
103 }
104 create(style, status);
97 } 105 }
98 106
99
100 TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other) 107 TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other)
101 : MeasureFormat(other), 108 : MeasureFormat(other),
102 fNumberFormat(NULL), 109 fStyle(other.fStyle)
103 fPluralRules(NULL),
104 fStyle(UTMUTFMT_FULL_STYLE)
105 { 110 {
106 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR; 111 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
107 i < TimeUnit::UTIMEUNIT_FIELD_COUNT; 112 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
108 i = (TimeUnit::UTimeUnitFields)(i+1)) { 113 i = (TimeUnit::UTimeUnitFields)(i+1)) {
109 fTimeUnitToCountToPatterns[i] = NULL; 114 UErrorCode status = U_ZERO_ERROR;
110 } 115 fTimeUnitToCountToPatterns[i] = initHash(status);
111 *this = other; 116 if (U_SUCCESS(status)) {
117 copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatt erns[i], status);
118 } else {
119 delete fTimeUnitToCountToPatterns[i];
120 fTimeUnitToCountToPatterns[i] = NULL;
121 }
122 }
112 } 123 }
113 124
114 125
115 TimeUnitFormat::~TimeUnitFormat() { 126 TimeUnitFormat::~TimeUnitFormat() {
116 delete fNumberFormat;
117 fNumberFormat = NULL;
118 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR; 127 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
119 i < TimeUnit::UTIMEUNIT_FIELD_COUNT; 128 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
120 i = (TimeUnit::UTimeUnitFields)(i+1)) { 129 i = (TimeUnit::UTimeUnitFields)(i+1)) {
121 deleteHash(fTimeUnitToCountToPatterns[i]); 130 deleteHash(fTimeUnitToCountToPatterns[i]);
122 fTimeUnitToCountToPatterns[i] = NULL; 131 fTimeUnitToCountToPatterns[i] = NULL;
123 } 132 }
124 delete fPluralRules;
125 fPluralRules = NULL;
126 } 133 }
127 134
128 135
129 Format* 136 Format*
130 TimeUnitFormat::clone(void) const { 137 TimeUnitFormat::clone(void) const {
131 return new TimeUnitFormat(*this); 138 return new TimeUnitFormat(*this);
132 } 139 }
133 140
134 141
135 TimeUnitFormat& 142 TimeUnitFormat&
136 TimeUnitFormat::operator=(const TimeUnitFormat& other) { 143 TimeUnitFormat::operator=(const TimeUnitFormat& other) {
137 if (this == &other) { 144 if (this == &other) {
138 return *this; 145 return *this;
139 } 146 }
140 delete fNumberFormat; 147 MeasureFormat::operator=(other);
141 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR; 148 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
142 i < TimeUnit::UTIMEUNIT_FIELD_COUNT; 149 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
143 i = (TimeUnit::UTimeUnitFields)(i+1)) { 150 i = (TimeUnit::UTimeUnitFields)(i+1)) {
144 deleteHash(fTimeUnitToCountToPatterns[i]); 151 deleteHash(fTimeUnitToCountToPatterns[i]);
145 fTimeUnitToCountToPatterns[i] = NULL; 152 fTimeUnitToCountToPatterns[i] = NULL;
146 } 153 }
147 delete fPluralRules;
148 if (other.fNumberFormat) {
149 fNumberFormat = (NumberFormat*)other.fNumberFormat->clone();
150 } else {
151 fNumberFormat = NULL;
152 }
153 fLocale = other.fLocale;
154 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR; 154 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
155 i < TimeUnit::UTIMEUNIT_FIELD_COUNT; 155 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
156 i = (TimeUnit::UTimeUnitFields)(i+1)) { 156 i = (TimeUnit::UTimeUnitFields)(i+1)) {
157 UErrorCode status = U_ZERO_ERROR; 157 UErrorCode status = U_ZERO_ERROR;
158 fTimeUnitToCountToPatterns[i] = initHash(status); 158 fTimeUnitToCountToPatterns[i] = initHash(status);
159 if (U_SUCCESS(status)) { 159 if (U_SUCCESS(status)) {
160 copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatt erns[i], status); 160 copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatt erns[i], status);
161 } else { 161 } else {
162 delete fTimeUnitToCountToPatterns[i]; 162 delete fTimeUnitToCountToPatterns[i];
163 fTimeUnitToCountToPatterns[i] = NULL; 163 fTimeUnitToCountToPatterns[i] = NULL;
164 } 164 }
165 } 165 }
166 if (other.fPluralRules) {
167 fPluralRules = (PluralRules*)other.fPluralRules->clone();
168 } else {
169 fPluralRules = NULL;
170 }
171 fStyle = other.fStyle; 166 fStyle = other.fStyle;
172 return *this; 167 return *this;
173 } 168 }
174 169
175
176 UBool
177 TimeUnitFormat::operator==(const Format& other) const {
178 if (typeid(*this) == typeid(other)) {
179 TimeUnitFormat* fmt = (TimeUnitFormat*)&other;
180 UBool ret = ( ((fNumberFormat && fmt->fNumberFormat && *fNumberFormat = = *fmt->fNumberFormat)
181 || fNumberFormat == fmt->fNumberFormat )
182 && fLocale == fmt->fLocale
183 && ((fPluralRules && fmt->fPluralRules && *fPluralRules == *fmt->fPluralRules)
184 || fPluralRules == fmt->fPluralRules)
185 && fStyle == fmt->fStyle);
186 if (ret) {
187 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
188 i < TimeUnit::UTIMEUNIT_FIELD_COUNT && ret;
189 i = (TimeUnit::UTimeUnitFields)(i+1)) {
190 ret = fTimeUnitToCountToPatterns[i]->equals(*(fmt->fTimeUnitToCo untToPatterns[i]));
191 }
192 }
193 return ret;
194 }
195 return false;
196 }
197
198
199 UnicodeString&
200 TimeUnitFormat::format(const Formattable& obj, UnicodeString& toAppendTo,
201 FieldPosition& pos, UErrorCode& status) const {
202 if (U_FAILURE(status)) {
203 return toAppendTo;
204 }
205 if (obj.getType() == Formattable::kObject) {
206 const UObject* formatObj = obj.getObject();
207 const TimeUnitAmount* amount = dynamic_cast<const TimeUnitAmount*>(forma tObj);
208 if (amount != NULL){
209 Hashtable* countToPattern = fTimeUnitToCountToPatterns[amount->getTi meUnitField()];
210 double number;
211 const Formattable& amtNumber = amount->getNumber();
212 if (amtNumber.getType() == Formattable::kDouble) {
213 number = amtNumber.getDouble();
214 } else if (amtNumber.getType() == Formattable::kLong) {
215 number = amtNumber.getLong();
216 } else {
217 status = U_ILLEGAL_ARGUMENT_ERROR;
218 return toAppendTo;
219 }
220 UnicodeString count = fPluralRules->select(number);
221 #ifdef TMUTFMT_DEBUG
222 char result[1000];
223 count.extract(0, count.length(), result, "UTF-8");
224 std::cout << "number: " << number << "; format plural count: " << re sult << "\n";
225 #endif
226 MessageFormat* pattern = ((MessageFormat**)countToPattern->get(count ))[fStyle];
227 Formattable formattable[1];
228 formattable[0].setDouble(number);
229 return pattern->format(formattable, 1, toAppendTo, pos, status);
230 }
231 }
232 status = U_ILLEGAL_ARGUMENT_ERROR;
233 return toAppendTo;
234 }
235
236
237 void 170 void
238 TimeUnitFormat::parseObject(const UnicodeString& source, 171 TimeUnitFormat::parseObject(const UnicodeString& source,
239 Formattable& result, 172 Formattable& result,
240 ParsePosition& pos) const { 173 ParsePosition& pos) const {
241 double resultNumber = -1; 174 Formattable resultNumber(0.0);
242 UBool withNumberFormat = false; 175 UBool withNumberFormat = false;
243 TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT; 176 TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT;
244 int32_t oldPos = pos.getIndex(); 177 int32_t oldPos = pos.getIndex();
245 int32_t newPos = -1; 178 int32_t newPos = -1;
246 int32_t longestParseDistance = 0; 179 int32_t longestParseDistance = 0;
247 UnicodeString* countOfLongestMatch = NULL; 180 UnicodeString* countOfLongestMatch = NULL;
248 #ifdef TMUTFMT_DEBUG 181 #ifdef TMUTFMT_DEBUG
249 char res[1000]; 182 char res[1000];
250 source.extract(0, source.length(), res, "UTF-8"); 183 source.extract(0, source.length(), res, "UTF-8");
251 std::cout << "parse source: " << res << "\n"; 184 std::cout << "parse source: " << res << "\n";
(...skipping 23 matching lines...) Expand all
275 pos.setIndex(oldPos); 208 pos.setIndex(oldPos);
276 // see if we can parse 209 // see if we can parse
277 Formattable parsed; 210 Formattable parsed;
278 pattern->parseObject(source, parsed, pos); 211 pattern->parseObject(source, parsed, pos);
279 if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) { 212 if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) {
280 continue; 213 continue;
281 } 214 }
282 #ifdef TMUTFMT_DEBUG 215 #ifdef TMUTFMT_DEBUG
283 std::cout << "parsed.getType: " << parsed.getType() << "\n"; 216 std::cout << "parsed.getType: " << parsed.getType() << "\n";
284 #endif 217 #endif
285 double tmpNumber = 0; 218 Formattable tmpNumber(0.0);
286 if (pattern->getArgTypeCount() != 0) { 219 if (pattern->getArgTypeCount() != 0) {
287 // pattern with Number as beginning, such as "{0} d".
288 // check to make sure that the timeUnit is consistent
289 Formattable& temp = parsed[0]; 220 Formattable& temp = parsed[0];
290 if (temp.getType() == Formattable::kDouble) { 221 if (temp.getType() == Formattable::kString) {
291 tmpNumber = temp.getDouble(); 222 UnicodeString tmpString;
292 } else if (temp.getType() == Formattable::kLong) { 223 UErrorCode pStatus = U_ZERO_ERROR;
293 tmpNumber = temp.getLong(); 224 getNumberFormat().parse(temp.getString(tmpString), tmpNu mber, pStatus);
225 if (U_FAILURE(pStatus)) {
226 continue;
227 }
228 } else if (temp.isNumeric()) {
229 tmpNumber = temp;
294 } else { 230 } else {
295 continue; 231 continue;
296 } 232 }
297 UnicodeString select = fPluralRules->select(tmpNumber);
298 #ifdef TMUTFMT_DEBUG
299 select.extract(0, select.length(), res, "UTF-8");
300 std::cout << "parse plural select count: " << res << "\n";
301 #endif
302 if (*count != select) {
303 continue;
304 }
305 } 233 }
306 int32_t parseDistance = pos.getIndex() - oldPos; 234 int32_t parseDistance = pos.getIndex() - oldPos;
307 if (parseDistance > longestParseDistance) { 235 if (parseDistance > longestParseDistance) {
308 if (pattern->getArgTypeCount() != 0) { 236 if (pattern->getArgTypeCount() != 0) {
309 resultNumber = tmpNumber; 237 resultNumber = tmpNumber;
310 withNumberFormat = true; 238 withNumberFormat = true;
311 } else { 239 } else {
312 withNumberFormat = false; 240 withNumberFormat = false;
313 } 241 }
314 resultTimeUnit = i; 242 resultTimeUnit = i;
315 newPos = pos.getIndex(); 243 newPos = pos.getIndex();
316 longestParseDistance = parseDistance; 244 longestParseDistance = parseDistance;
317 countOfLongestMatch = count; 245 countOfLongestMatch = count;
318 } 246 }
319 } 247 }
320 } 248 }
321 } 249 }
322 /* After find the longest match, parse the number. 250 /* After find the longest match, parse the number.
323 * Result number could be null for the pattern without number pattern. 251 * Result number could be null for the pattern without number pattern.
324 * such as unit pattern in Arabic. 252 * such as unit pattern in Arabic.
325 * When result number is null, use plural rule to set the number. 253 * When result number is null, use plural rule to set the number.
326 */ 254 */
327 if (withNumberFormat == false && longestParseDistance != 0) { 255 if (withNumberFormat == false && longestParseDistance != 0) {
328 // set the number using plurrual count 256 // set the number using plurrual count
329 if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ZERO, 4)) { 257 if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ZERO, 4)) {
330 resultNumber = 0; 258 resultNumber = Formattable(0.0);
331 } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ONE, 3)) { 259 } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ONE, 3)) {
332 resultNumber = 1; 260 resultNumber = Formattable(1.0);
333 } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_TWO, 3)) { 261 } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_TWO, 3)) {
334 resultNumber = 2; 262 resultNumber = Formattable(2.0);
335 } else { 263 } else {
336 // should not happen. 264 // should not happen.
337 // TODO: how to handle? 265 // TODO: how to handle?
338 resultNumber = 3; 266 resultNumber = Formattable(3.0);
339 } 267 }
340 } 268 }
341 if (longestParseDistance == 0) { 269 if (longestParseDistance == 0) {
342 pos.setIndex(oldPos); 270 pos.setIndex(oldPos);
343 pos.setErrorIndex(0); 271 pos.setErrorIndex(0);
344 } else { 272 } else {
345 UErrorCode status = U_ZERO_ERROR; 273 UErrorCode status = U_ZERO_ERROR;
346 TimeUnitAmount* tmutamt = new TimeUnitAmount(resultNumber, resultTimeUni t, status); 274 TimeUnitAmount* tmutamt = new TimeUnitAmount(resultNumber, resultTimeUni t, status);
347 if (U_SUCCESS(status)) { 275 if (U_SUCCESS(status)) {
348 result.adoptObject(tmutamt); 276 result.adoptObject(tmutamt);
349 pos.setIndex(newPos); 277 pos.setIndex(newPos);
350 pos.setErrorIndex(-1); 278 pos.setErrorIndex(-1);
351 } else { 279 } else {
352 pos.setIndex(oldPos); 280 pos.setIndex(oldPos);
353 pos.setErrorIndex(0); 281 pos.setErrorIndex(0);
354 } 282 }
355 } 283 }
356 } 284 }
357 285
358 void 286 void
359 TimeUnitFormat::create(const Locale& locale, UTimeUnitFormatStyle style, UErrorC ode& status) { 287 TimeUnitFormat::create(UTimeUnitFormatStyle style, UErrorCode& status) {
288 // fTimeUnitToCountToPatterns[] must have its elements initialized to NULL f irst
289 // before checking for failure status.
290 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
291 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
292 i = (TimeUnit::UTimeUnitFields)(i+1)) {
293 fTimeUnitToCountToPatterns[i] = NULL;
294 }
295
360 if (U_FAILURE(status)) { 296 if (U_FAILURE(status)) {
361 return; 297 return;
362 } 298 }
363 if (style < UTMUTFMT_FULL_STYLE || style >= UTMUTFMT_FORMAT_STYLE_COUNT) { 299 if (style < UTMUTFMT_FULL_STYLE || style >= UTMUTFMT_FORMAT_STYLE_COUNT) {
364 status = U_ILLEGAL_ARGUMENT_ERROR; 300 status = U_ILLEGAL_ARGUMENT_ERROR;
365 return; 301 return;
366 } 302 }
367 fStyle = style; 303 fStyle = style;
368 fLocale = locale; 304
369 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
370 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
371 i = (TimeUnit::UTimeUnitFields)(i+1)) {
372 fTimeUnitToCountToPatterns[i] = NULL;
373 }
374 //TODO: format() and parseObj() are const member functions, 305 //TODO: format() and parseObj() are const member functions,
375 //so, can not do lazy initialization in C++. 306 //so, can not do lazy initialization in C++.
376 //setup has to be done in constructors. 307 //setup has to be done in constructors.
377 //and here, the behavior is not consistent with Java. 308 //and here, the behavior is not consistent with Java.
378 //In Java, create an empty instance does not setup locale as 309 //In Java, create an empty instance does not setup locale as
379 //default locale. If it followed by setNumberFormat(), 310 //default locale. If it followed by setNumberFormat(),
380 //in format(), the locale will set up as the locale in fNumberFormat. 311 //in format(), the locale will set up as the locale in fNumberFormat.
381 //But in C++, this sets the locale as the default locale. 312 //But in C++, this sets the locale as the default locale.
382 setup(status); 313 setup(status);
383 } 314 }
384 315
385 void 316 void
386 TimeUnitFormat::setup(UErrorCode& err) { 317 TimeUnitFormat::setup(UErrorCode& err) {
387 initDataMembers(err); 318 initDataMembers(err);
388 319
389 UVector pluralCounts(0, uhash_compareUnicodeString, 6, err); 320 UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
390 StringEnumeration* keywords = fPluralRules->getKeywords(err); 321 StringEnumeration* keywords = getPluralRules().getKeywords(err);
391 if (U_FAILURE(err)) { 322 if (U_FAILURE(err)) {
392 return; 323 return;
393 } 324 }
394 UnicodeString* pluralCount; 325 UnicodeString* pluralCount;
395 while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != N ULL) { 326 while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != N ULL) {
396 pluralCounts.addElement(pluralCount, err); 327 pluralCounts.addElement(pluralCount, err);
397 } 328 }
398 readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err); 329 readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err);
399 checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err); 330 checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
400 readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, pluralCoun ts, err); 331 readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, pluralCoun ts, err);
401 checkConsistency(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err); 332 checkConsistency(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err);
402 delete keywords; 333 delete keywords;
403 } 334 }
404 335
405 336
406 void 337 void
407 TimeUnitFormat::initDataMembers(UErrorCode& err){ 338 TimeUnitFormat::initDataMembers(UErrorCode& err){
408 if (U_FAILURE(err)) { 339 if (U_FAILURE(err)) {
409 return; 340 return;
410 } 341 }
411 if (fNumberFormat == NULL) {
412 fNumberFormat = NumberFormat::createInstance(fLocale, err);
413 }
414 delete fPluralRules;
415 fPluralRules = PluralRules::forLocale(fLocale, err);
416 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR; 342 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
417 i < TimeUnit::UTIMEUNIT_FIELD_COUNT; 343 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
418 i = (TimeUnit::UTimeUnitFields)(i+1)) { 344 i = (TimeUnit::UTimeUnitFields)(i+1)) {
419 deleteHash(fTimeUnitToCountToPatterns[i]); 345 deleteHash(fTimeUnitToCountToPatterns[i]);
420 fTimeUnitToCountToPatterns[i] = NULL; 346 fTimeUnitToCountToPatterns[i] = NULL;
421 } 347 }
422 } 348 }
423 349
424 void 350 void
425 TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke y, 351 TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke y,
426 const UVector& pluralCounts, UErrorCode& e rr) { 352 const UVector& pluralCounts, UErrorCode& e rr) {
427 if (U_FAILURE(err)) { 353 if (U_FAILURE(err)) {
428 return; 354 return;
429 } 355 }
430 // fill timeUnitToCountToPatterns from resource file 356 // fill timeUnitToCountToPatterns from resource file
431 // err is used to indicate wrong status except missing resource. 357 // err is used to indicate wrong status except missing resource.
432 // status is an error code used in resource lookup. 358 // status is an error code used in resource lookup.
433 // status does not affect "err". 359 // status does not affect "err".
434 UErrorCode status = U_ZERO_ERROR; 360 UErrorCode status = U_ZERO_ERROR;
435 UResourceBundle *rb, *unitsRes; 361 UResourceBundle *rb, *unitsRes;
436 rb = ures_open(NULL, fLocale.getName(), &status); 362 rb = ures_open(U_ICUDATA_UNIT, getLocaleID(status), &status);
437 unitsRes = ures_getByKey(rb, key, NULL, &status); 363 unitsRes = ures_getByKey(rb, key, NULL, &status);
438 unitsRes = ures_getByKey(unitsRes, "duration", unitsRes, &status); 364 unitsRes = ures_getByKey(unitsRes, "duration", unitsRes, &status);
439 if (U_FAILURE(status)) { 365 if (U_FAILURE(status)) {
440 ures_close(unitsRes); 366 ures_close(unitsRes);
441 ures_close(rb); 367 ures_close(rb);
442 return; 368 return;
443 } 369 }
444 int32_t size = ures_getSize(unitsRes); 370 int32_t size = ures_getSize(unitsRes);
445 for ( int32_t index = 0; index < size; ++index) { 371 for ( int32_t index = 0; index < size; ++index) {
446 // resource of one time unit 372 // resource of one time unit
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 // resource of count to pattern 422 // resource of count to pattern
497 UnicodeString pattern = 423 UnicodeString pattern =
498 ures_getNextUnicodeString(countsToPatternRB, &pluralCount, & status); 424 ures_getNextUnicodeString(countsToPatternRB, &pluralCount, & status);
499 if (U_FAILURE(status)) { 425 if (U_FAILURE(status)) {
500 continue; 426 continue;
501 } 427 }
502 UnicodeString pluralCountUniStr(pluralCount, -1, US_INV); 428 UnicodeString pluralCountUniStr(pluralCount, -1, US_INV);
503 if (!pluralCounts.contains(&pluralCountUniStr)) { 429 if (!pluralCounts.contains(&pluralCountUniStr)) {
504 continue; 430 continue;
505 } 431 }
506 MessageFormat* messageFormat = new MessageFormat(pattern, fLocal e, err); 432 MessageFormat* messageFormat = new MessageFormat(pattern, getLoc ale(err), err);
507 if ( U_SUCCESS(err) ) { 433 if ( U_SUCCESS(err) ) {
508 if (fNumberFormat != NULL) {
509 messageFormat->setFormat(0, *fNumberFormat);
510 }
511 MessageFormat** formatters = (MessageFormat**)countToPatterns- >get(pluralCountUniStr); 434 MessageFormat** formatters = (MessageFormat**)countToPatterns- >get(pluralCountUniStr);
512 if (formatters == NULL) { 435 if (formatters == NULL) {
513 formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_ST YLE_COUNT*sizeof(MessageFormat*)); 436 formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_ST YLE_COUNT*sizeof(MessageFormat*));
514 formatters[UTMUTFMT_FULL_STYLE] = NULL; 437 formatters[UTMUTFMT_FULL_STYLE] = NULL;
515 formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; 438 formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
516 countToPatterns->put(pluralCountUniStr, formatters, err); 439 countToPatterns->put(pluralCountUniStr, formatters, err);
517 if (U_FAILURE(err)) { 440 if (U_FAILURE(err)) {
518 uprv_free(formatters); 441 uprv_free(formatters);
519 } 442 }
520 } 443 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 // if the pattern is not found in root either, 484 // if the pattern is not found in root either,
562 // fallback to plural count "other", 485 // fallback to plural count "other",
563 // look for the pattern of "other" in the locale tree: 486 // look for the pattern of "other" in the locale tree:
564 // "de_DE" to "de" to "root". 487 // "de_DE" to "de" to "root".
565 // If not found, fall back to value of 488 // If not found, fall back to value of
566 // static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h". 489 // static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h".
567 // 490 //
568 // Following is consistency check to create pattern for each 491 // Following is consistency check to create pattern for each
569 // plural rule in each time unit using above fall-back rule. 492 // plural rule in each time unit using above fall-back rule.
570 // 493 //
571 StringEnumeration* keywords = fPluralRules->getKeywords(err); 494 StringEnumeration* keywords = getPluralRules().getKeywords(err);
572 if (U_SUCCESS(err)) { 495 if (U_SUCCESS(err)) {
573 const UnicodeString* pluralCount; 496 const UnicodeString* pluralCount;
574 while ((pluralCount = keywords->snext(err)) != NULL) { 497 while ((pluralCount = keywords->snext(err)) != NULL) {
575 if ( U_SUCCESS(err) ) { 498 if ( U_SUCCESS(err) ) {
576 for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) { 499 for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) {
577 // for each time unit, 500 // for each time unit,
578 // get all the patterns for each plural rule in this locale. 501 // get all the patterns for each plural rule in this locale.
579 Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i]; 502 Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
580 if ( countToPatterns == NULL ) { 503 if ( countToPatterns == NULL ) {
581 countToPatterns = initHash(err); 504 countToPatterns = initHash(err);
582 if (U_FAILURE(err)) { 505 if (U_FAILURE(err)) {
583 delete countToPatterns; 506 delete countToPatterns;
584 return; 507 return;
585 } 508 }
586 fTimeUnitToCountToPatterns[i] = countToPatterns; 509 fTimeUnitToCountToPatterns[i] = countToPatterns;
587 } 510 }
588 MessageFormat** formatters = (MessageFormat**)countToPattern s->get(*pluralCount); 511 MessageFormat** formatters = (MessageFormat**)countToPattern s->get(*pluralCount);
589 if( formatters == NULL || formatters[style] == NULL ) { 512 if( formatters == NULL || formatters[style] == NULL ) {
590 // look through parents 513 // look through parents
591 const char* localeName = fLocale.getName(); 514 const char* localeName = getLocaleID(err);
592 CharString pluralCountChars; 515 CharString pluralCountChars;
593 pluralCountChars.appendInvariantChars(*pluralCount, err) ; 516 pluralCountChars.appendInvariantChars(*pluralCount, err) ;
594 searchInLocaleChain(style, key, localeName, 517 searchInLocaleChain(style, key, localeName,
595 (TimeUnit::UTimeUnitFields)i, 518 (TimeUnit::UTimeUnitFields)i,
596 *pluralCount, pluralCountChars.data( ), 519 *pluralCount, pluralCountChars.data( ),
597 countToPatterns, err); 520 countToPatterns, err);
598 } 521 }
599 } 522 }
600 } 523 }
601 } 524 }
(...skipping 23 matching lines...) Expand all
625 } 548 }
626 UErrorCode status = U_ZERO_ERROR; 549 UErrorCode status = U_ZERO_ERROR;
627 char parentLocale[ULOC_FULLNAME_CAPACITY]; 550 char parentLocale[ULOC_FULLNAME_CAPACITY];
628 uprv_strcpy(parentLocale, localeName); 551 uprv_strcpy(parentLocale, localeName);
629 int32_t locNameLen; 552 int32_t locNameLen;
630 U_ASSERT(countToPatterns != NULL); 553 U_ASSERT(countToPatterns != NULL);
631 while ((locNameLen = uloc_getParent(parentLocale, parentLocale, 554 while ((locNameLen = uloc_getParent(parentLocale, parentLocale,
632 ULOC_FULLNAME_CAPACITY, &status)) >= 0){ 555 ULOC_FULLNAME_CAPACITY, &status)) >= 0){
633 // look for pattern for srcPluralCount in locale tree 556 // look for pattern for srcPluralCount in locale tree
634 UResourceBundle *rb, *unitsRes, *countsToPatternRB; 557 UResourceBundle *rb, *unitsRes, *countsToPatternRB;
635 rb = ures_open(NULL, parentLocale, &status); 558 rb = ures_open(U_ICUDATA_UNIT, parentLocale, &status);
636 unitsRes = ures_getByKey(rb, key, NULL, &status); 559 unitsRes = ures_getByKey(rb, key, NULL, &status);
637 const char* timeUnitName = getTimeUnitName(srcTimeUnitField, status); 560 const char* timeUnitName = getTimeUnitName(srcTimeUnitField, status);
638 countsToPatternRB = ures_getByKey(unitsRes, timeUnitName, NULL, &status) ; 561 countsToPatternRB = ures_getByKey(unitsRes, timeUnitName, NULL, &status) ;
639 const UChar* pattern; 562 const UChar* pattern;
640 int32_t ptLength; 563 int32_t ptLength;
641 pattern = ures_getStringByKeyWithFallback(countsToPatternRB, searchPlura lCount, &ptLength, &status); 564 pattern = ures_getStringByKeyWithFallback(countsToPatternRB, searchPlura lCount, &ptLength, &status);
642 if (U_SUCCESS(status)) { 565 if (U_SUCCESS(status)) {
643 //found 566 //found
644 MessageFormat* messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, ptLength), fLocale, err); 567 MessageFormat* messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, ptLength), getLocale(err), err);
645 if (U_SUCCESS(err)) { 568 if (U_SUCCESS(err)) {
646 if (fNumberFormat != NULL) {
647 messageFormat->setFormat(0, *fNumberFormat);
648 }
649 MessageFormat** formatters = (MessageFormat**)countToPatterns->g et(srcPluralCount); 569 MessageFormat** formatters = (MessageFormat**)countToPatterns->g et(srcPluralCount);
650 if (formatters == NULL) { 570 if (formatters == NULL) {
651 formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_ST YLE_COUNT*sizeof(MessageFormat*)); 571 formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_ST YLE_COUNT*sizeof(MessageFormat*));
652 formatters[UTMUTFMT_FULL_STYLE] = NULL; 572 formatters[UTMUTFMT_FULL_STYLE] = NULL;
653 formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; 573 formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
654 countToPatterns->put(srcPluralCount, formatters, err); 574 countToPatterns->put(srcPluralCount, formatters, err);
655 if (U_FAILURE(err)) { 575 if (U_FAILURE(err)) {
656 uprv_free(formatters); 576 uprv_free(formatters);
657 delete messageFormat; 577 delete messageFormat;
658 } 578 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_WEEK ) { 632 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_WEEK ) {
713 pattern = DEFAULT_PATTERN_FOR_WEEK; 633 pattern = DEFAULT_PATTERN_FOR_WEEK;
714 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_DAY ) { 634 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_DAY ) {
715 pattern = DEFAULT_PATTERN_FOR_DAY; 635 pattern = DEFAULT_PATTERN_FOR_DAY;
716 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MONTH ) { 636 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MONTH ) {
717 pattern = DEFAULT_PATTERN_FOR_MONTH; 637 pattern = DEFAULT_PATTERN_FOR_MONTH;
718 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_YEAR ) { 638 } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_YEAR ) {
719 pattern = DEFAULT_PATTERN_FOR_YEAR; 639 pattern = DEFAULT_PATTERN_FOR_YEAR;
720 } 640 }
721 if (pattern != NULL) { 641 if (pattern != NULL) {
722 messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, -1), fLocale, err); 642 messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, -1), getLocale(err), err);
723 } 643 }
724 if (U_SUCCESS(err)) { 644 if (U_SUCCESS(err)) {
725 if (fNumberFormat != NULL && messageFormat != NULL) {
726 messageFormat->setFormat(0, *fNumberFormat);
727 }
728 MessageFormat** formatters = (MessageFormat**)countToPatterns->get(s rcPluralCount); 645 MessageFormat** formatters = (MessageFormat**)countToPatterns->get(s rcPluralCount);
729 if (formatters == NULL) { 646 if (formatters == NULL) {
730 formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_ COUNT*sizeof(MessageFormat*)); 647 formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_ COUNT*sizeof(MessageFormat*));
731 formatters[UTMUTFMT_FULL_STYLE] = NULL; 648 formatters[UTMUTFMT_FULL_STYLE] = NULL;
732 formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; 649 formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
733 countToPatterns->put(srcPluralCount, formatters, err); 650 countToPatterns->put(srcPluralCount, formatters, err);
734 if (U_FAILURE(err)) { 651 if (U_FAILURE(err)) {
735 uprv_free(formatters); 652 uprv_free(formatters);
736 delete messageFormat; 653 delete messageFormat;
737 } 654 }
738 } 655 }
739 if (U_SUCCESS(err)) { 656 if (U_SUCCESS(err)) {
740 //delete formatters[style]; 657 //delete formatters[style];
741 formatters[style] = messageFormat; 658 formatters[style] = messageFormat;
742 } 659 }
743 } else { 660 } else {
744 delete messageFormat; 661 delete messageFormat;
745 } 662 }
746 } else { 663 } else {
747 // fall back to rule "other", and search in parents 664 // fall back to rule "other", and search in parents
748 searchInLocaleChain(style, key, localeName, srcTimeUnitField, srcPluralC ount, 665 searchInLocaleChain(style, key, localeName, srcTimeUnitField, srcPluralC ount,
749 gPluralCountOther, countToPatterns, err); 666 gPluralCountOther, countToPatterns, err);
750 } 667 }
751 } 668 }
752 669
753 void 670 void
754 TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) { 671 TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) {
755 if (U_SUCCESS(status) && fLocale != locale) { 672 if (setMeasureFormatLocale(locale, status)) {
756 fLocale = locale;
757 setup(status); 673 setup(status);
758 } 674 }
759 } 675 }
760 676
761 677
762 void 678 void
763 TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){ 679 TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
764 if (U_FAILURE(status) || (fNumberFormat && format == *fNumberFormat)) { 680 if (U_FAILURE(status)) {
765 return; 681 return;
766 } 682 }
767 delete fNumberFormat; 683 adoptNumberFormat((NumberFormat *)format.clone(), status);
768 fNumberFormat = (NumberFormat*)format.clone();
769 // reset the number formatter in the fTimeUnitToCountToPatterns map
770 for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
771 i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
772 i = (TimeUnit::UTimeUnitFields)(i+1)) {
773 int32_t pos = -1;
774 const UHashElement* elem = NULL;
775 while ((elem = fTimeUnitToCountToPatterns[i]->nextElement(pos)) != NULL) {
776 const UHashTok keyTok = elem->value;
777 MessageFormat** pattern = (MessageFormat**)keyTok.pointer;
778
779 pattern[UTMUTFMT_FULL_STYLE]->setFormat(0, format);
780 pattern[UTMUTFMT_ABBREVIATED_STYLE]->setFormat(0, format);
781 }
782 }
783 } 684 }
784 685
785 686
786 void 687 void
787 TimeUnitFormat::deleteHash(Hashtable* htable) { 688 TimeUnitFormat::deleteHash(Hashtable* htable) {
788 int32_t pos = -1; 689 int32_t pos = -1;
789 const UHashElement* element = NULL; 690 const UHashElement* element = NULL;
790 if ( htable ) { 691 if ( htable ) {
791 while ( (element = htable->nextElement(pos)) != NULL ) { 692 while ( (element = htable->nextElement(pos)) != NULL ) {
792 const UHashTok valueTok = element->value; 693 const UHashTok valueTok = element->value;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 return gTimeUnitSecond; 792 return gTimeUnitSecond;
892 default: 793 default:
893 status = U_ILLEGAL_ARGUMENT_ERROR; 794 status = U_ILLEGAL_ARGUMENT_ERROR;
894 return NULL; 795 return NULL;
895 } 796 }
896 } 797 }
897 798
898 U_NAMESPACE_END 799 U_NAMESPACE_END
899 800
900 #endif 801 #endif
OLDNEW
« no previous file with comments | « source/i18n/tmunit.cpp ('k') | source/i18n/translit.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698