| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |