OLD | NEW |
1 /* | 1 /* |
2 ********************************************************************** | 2 ********************************************************************** |
3 * Copyright (c) 2004-2014, International Business Machines | 3 * Copyright (c) 2004-2015, International Business Machines |
4 * Corporation and others. All Rights Reserved. | 4 * Corporation and others. All Rights Reserved. |
5 ********************************************************************** | 5 ********************************************************************** |
6 * Author: Alan Liu | 6 * Author: Alan Liu |
7 * Created: April 20, 2004 | 7 * Created: April 20, 2004 |
8 * Since: ICU 3.0 | 8 * Since: ICU 3.0 |
9 ********************************************************************** | 9 ********************************************************************** |
10 */ | 10 */ |
11 #include "utypeinfo.h" // for 'typeid' to work | 11 #include "utypeinfo.h" // for 'typeid' to work |
12 #include "unicode/utypes.h" | 12 #include "unicode/utypes.h" |
13 | 13 |
(...skipping 16 matching lines...) Expand all Loading... |
30 #include "unicode/listformatter.h" | 30 #include "unicode/listformatter.h" |
31 #include "charstr.h" | 31 #include "charstr.h" |
32 #include "unicode/putil.h" | 32 #include "unicode/putil.h" |
33 #include "unicode/smpdtfmt.h" | 33 #include "unicode/smpdtfmt.h" |
34 #include "uassert.h" | 34 #include "uassert.h" |
35 | 35 |
36 #include "sharednumberformat.h" | 36 #include "sharednumberformat.h" |
37 #include "sharedpluralrules.h" | 37 #include "sharedpluralrules.h" |
38 #include "unifiedcache.h" | 38 #include "unifiedcache.h" |
39 | 39 |
40 #define MEAS_UNIT_COUNT 121 | 40 #define MEAS_UNIT_COUNT 129 |
41 #define WIDTH_INDEX_COUNT (UMEASFMT_WIDTH_NARROW + 1) | 41 #define WIDTH_INDEX_COUNT (UMEASFMT_WIDTH_NARROW + 1) |
42 | 42 |
43 U_NAMESPACE_BEGIN | 43 U_NAMESPACE_BEGIN |
44 | 44 |
45 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureFormat) | 45 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureFormat) |
46 | 46 |
47 // Used to format durations like 5:47 or 21:35:42. | 47 // Used to format durations like 5:47 or 21:35:42. |
48 class NumericDateFormatters : public UMemory { | 48 class NumericDateFormatters : public UMemory { |
49 public: | 49 public: |
50 // Formats like H:mm | 50 // Formats like H:mm |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 delete result; | 339 delete result; |
340 return NULL; | 340 return NULL; |
341 } | 341 } |
342 return result; | 342 return result; |
343 } | 343 } |
344 | 344 |
345 template<> U_I18N_API | 345 template<> U_I18N_API |
346 const MeasureFormatCacheData *LocaleCacheKey<MeasureFormatCacheData>::createObje
ct( | 346 const MeasureFormatCacheData *LocaleCacheKey<MeasureFormatCacheData>::createObje
ct( |
347 const void * /*unused*/, UErrorCode &status) const { | 347 const void * /*unused*/, UErrorCode &status) const { |
348 const char *localeId = fLoc.getName(); | 348 const char *localeId = fLoc.getName(); |
349 LocalUResourceBundlePointer topLevel(ures_open(NULL, localeId, &status)); | |
350 LocalUResourceBundlePointer unitsBundle(ures_open(U_ICUDATA_UNIT, localeId,
&status)); | 349 LocalUResourceBundlePointer unitsBundle(ures_open(U_ICUDATA_UNIT, localeId,
&status)); |
351 static UNumberFormatStyle currencyStyles[] = { | 350 static UNumberFormatStyle currencyStyles[] = { |
352 UNUM_CURRENCY_PLURAL, UNUM_CURRENCY_ISO, UNUM_CURRENCY}; | 351 UNUM_CURRENCY_PLURAL, UNUM_CURRENCY_ISO, UNUM_CURRENCY}; |
| 352 LocalPointer<MeasureFormatCacheData> result(new MeasureFormatCacheData(), st
atus); |
353 if (U_FAILURE(status)) { | 353 if (U_FAILURE(status)) { |
354 return NULL; | 354 return NULL; |
355 } | 355 } |
356 LocalPointer<MeasureFormatCacheData> result(new MeasureFormatCacheData()); | |
357 if (result.isNull()) { | |
358 status = U_MEMORY_ALLOCATION_ERROR; | |
359 return NULL; | |
360 } | |
361 if (!loadMeasureUnitData( | 356 if (!loadMeasureUnitData( |
362 unitsBundle.getAlias(), | 357 unitsBundle.getAlias(), |
363 *result, | 358 *result, |
364 status)) { | 359 status)) { |
365 return NULL; | 360 return NULL; |
366 } | 361 } |
367 result->adoptNumericDateFormatters(loadNumericDateFormatters( | 362 result->adoptNumericDateFormatters(loadNumericDateFormatters( |
368 topLevel.getAlias(), status)); | 363 unitsBundle.getAlias(), status)); |
369 if (U_FAILURE(status)) { | 364 if (U_FAILURE(status)) { |
370 return NULL; | 365 return NULL; |
371 } | 366 } |
372 | 367 |
373 for (int32_t i = 0; i < WIDTH_INDEX_COUNT; ++i) { | 368 for (int32_t i = 0; i < WIDTH_INDEX_COUNT; ++i) { |
374 result->adoptCurrencyFormat(i, NumberFormat::createInstance( | 369 result->adoptCurrencyFormat(i, NumberFormat::createInstance( |
375 localeId, currencyStyles[i], status)); | 370 localeId, currencyStyles[i], status)); |
376 if (U_FAILURE(status)) { | 371 if (U_FAILURE(status)) { |
377 return NULL; | 372 return NULL; |
378 } | 373 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 width = other.width; | 500 width = other.width; |
506 delete listFormatter; | 501 delete listFormatter; |
507 listFormatter = new ListFormatter(*other.listFormatter); | 502 listFormatter = new ListFormatter(*other.listFormatter); |
508 return *this; | 503 return *this; |
509 } | 504 } |
510 | 505 |
511 MeasureFormat::MeasureFormat() : | 506 MeasureFormat::MeasureFormat() : |
512 cache(NULL), | 507 cache(NULL), |
513 numberFormat(NULL), | 508 numberFormat(NULL), |
514 pluralRules(NULL), | 509 pluralRules(NULL), |
515 width(UMEASFMT_WIDTH_WIDE), | 510 width(UMEASFMT_WIDTH_SHORT), |
516 listFormatter(NULL) { | 511 listFormatter(NULL) { |
517 } | 512 } |
518 | 513 |
519 MeasureFormat::~MeasureFormat() { | 514 MeasureFormat::~MeasureFormat() { |
520 if (cache != NULL) { | 515 if (cache != NULL) { |
521 cache->removeRef(); | 516 cache->removeRef(); |
522 } | 517 } |
523 if (numberFormat != NULL) { | 518 if (numberFormat != NULL) { |
524 numberFormat->removeRef(); | 519 numberFormat->removeRef(); |
525 } | 520 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 return appendTo; | 582 return appendTo; |
588 } | 583 } |
589 | 584 |
590 void MeasureFormat::parseObject( | 585 void MeasureFormat::parseObject( |
591 const UnicodeString & /*source*/, | 586 const UnicodeString & /*source*/, |
592 Formattable & /*result*/, | 587 Formattable & /*result*/, |
593 ParsePosition& /*pos*/) const { | 588 ParsePosition& /*pos*/) const { |
594 return; | 589 return; |
595 } | 590 } |
596 | 591 |
597 UnicodeString &MeasureFormat::formatMeasuresPer( | 592 UnicodeString &MeasureFormat::formatMeasurePerUnit( |
598 const Measure *measures, | 593 const Measure &measure, |
599 int32_t measureCount, | |
600 const MeasureUnit &perUnit, | 594 const MeasureUnit &perUnit, |
601 UnicodeString &appendTo, | 595 UnicodeString &appendTo, |
602 FieldPosition &pos, | 596 FieldPosition &pos, |
603 UErrorCode &status) const { | 597 UErrorCode &status) const { |
| 598 if (U_FAILURE(status)) { |
| 599 return appendTo; |
| 600 } |
| 601 MeasureUnit *resolvedUnit = |
| 602 MeasureUnit::resolveUnitPerUnit(measure.getUnit(), perUnit); |
| 603 if (resolvedUnit != NULL) { |
| 604 Measure newMeasure(measure.getNumber(), resolvedUnit, status); |
| 605 return formatMeasure( |
| 606 newMeasure, **numberFormat, appendTo, pos, status); |
| 607 } |
604 FieldPosition fpos(pos.getField()); | 608 FieldPosition fpos(pos.getField()); |
605 UnicodeString measuresString; | 609 UnicodeString result; |
606 int32_t offset = withPerUnit( | 610 int32_t offset = withPerUnitAndAppend( |
607 formatMeasures( | 611 formatMeasure( |
608 measures, measureCount, measuresString, fpos, status), | 612 measure, **numberFormat, result, fpos, status), |
609 perUnit, | 613 perUnit, |
610 appendTo, | 614 appendTo, |
611 status); | 615 status); |
612 if (U_FAILURE(status)) { | 616 if (U_FAILURE(status)) { |
613 return appendTo; | 617 return appendTo; |
614 } | 618 } |
615 if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) { | 619 if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) { |
616 pos.setBeginIndex(fpos.getBeginIndex() + offset); | 620 pos.setBeginIndex(fpos.getBeginIndex() + offset); |
617 pos.setEndIndex(fpos.getEndIndex() + offset); | 621 pos.setEndIndex(fpos.getEndIndex() + offset); |
618 } | 622 } |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 return NULL; | 928 return NULL; |
925 } | 929 } |
926 const QuantityFormatter *formatters = | 930 const QuantityFormatter *formatters = |
927 cache->formatters[index]; | 931 cache->formatters[index]; |
928 if (formatters[widthIndex].isValid()) { | 932 if (formatters[widthIndex].isValid()) { |
929 return &formatters[widthIndex]; | 933 return &formatters[widthIndex]; |
930 } | 934 } |
931 if (formatters[UMEASFMT_WIDTH_SHORT].isValid()) { | 935 if (formatters[UMEASFMT_WIDTH_SHORT].isValid()) { |
932 return &formatters[UMEASFMT_WIDTH_SHORT]; | 936 return &formatters[UMEASFMT_WIDTH_SHORT]; |
933 } | 937 } |
934 if (formatters[UMEASFMT_WIDTH_WIDE].isValid()) { | |
935 return &formatters[UMEASFMT_WIDTH_WIDE]; | |
936 } | |
937 status = U_MISSING_RESOURCE_ERROR; | 938 status = U_MISSING_RESOURCE_ERROR; |
938 return NULL; | 939 return NULL; |
939 } | 940 } |
940 | 941 |
941 const SimplePatternFormatter *MeasureFormat::getPerUnitFormatter( | 942 const SimplePatternFormatter *MeasureFormat::getPerUnitFormatter( |
942 int32_t index, | 943 int32_t index, |
943 int32_t widthIndex) const { | 944 int32_t widthIndex) const { |
944 const SimplePatternFormatter * const * perUnitFormatters = | 945 const SimplePatternFormatter * const * perUnitFormatters = |
945 cache->getPerUnitFormattersByIndex(index); | 946 cache->getPerUnitFormattersByIndex(index); |
946 if (perUnitFormatters[widthIndex] != NULL) { | 947 if (perUnitFormatters[widthIndex] != NULL) { |
947 return perUnitFormatters[widthIndex]; | 948 return perUnitFormatters[widthIndex]; |
948 } | 949 } |
949 if (perUnitFormatters[UMEASFMT_WIDTH_SHORT] != NULL) { | 950 if (perUnitFormatters[UMEASFMT_WIDTH_SHORT] != NULL) { |
950 return perUnitFormatters[UMEASFMT_WIDTH_SHORT]; | 951 return perUnitFormatters[UMEASFMT_WIDTH_SHORT]; |
951 } | 952 } |
952 if (perUnitFormatters[UMEASFMT_WIDTH_WIDE] != NULL) { | |
953 return perUnitFormatters[UMEASFMT_WIDTH_WIDE]; | |
954 } | |
955 return NULL; | 953 return NULL; |
956 } | 954 } |
957 | 955 |
958 const SimplePatternFormatter *MeasureFormat::getPerFormatter( | 956 const SimplePatternFormatter *MeasureFormat::getPerFormatter( |
959 int32_t widthIndex, | 957 int32_t widthIndex, |
960 UErrorCode &status) const { | 958 UErrorCode &status) const { |
961 if (U_FAILURE(status)) { | 959 if (U_FAILURE(status)) { |
962 return NULL; | 960 return NULL; |
963 } | 961 } |
964 const SimplePatternFormatter * perFormatters = cache->perFormatters; | 962 const SimplePatternFormatter * perFormatters = cache->perFormatters; |
965 | 963 |
966 if (perFormatters[widthIndex].getPlaceholderCount() == 2) { | 964 if (perFormatters[widthIndex].getPlaceholderCount() == 2) { |
967 return &perFormatters[widthIndex]; | 965 return &perFormatters[widthIndex]; |
968 } | 966 } |
969 if (perFormatters[UMEASFMT_WIDTH_SHORT].getPlaceholderCount() == 2) { | 967 if (perFormatters[UMEASFMT_WIDTH_SHORT].getPlaceholderCount() == 2) { |
970 return &perFormatters[UMEASFMT_WIDTH_SHORT]; | 968 return &perFormatters[UMEASFMT_WIDTH_SHORT]; |
971 } | 969 } |
972 if (perFormatters[UMEASFMT_WIDTH_WIDE].getPlaceholderCount() == 2) { | |
973 return &perFormatters[UMEASFMT_WIDTH_WIDE]; | |
974 } | |
975 status = U_MISSING_RESOURCE_ERROR; | 970 status = U_MISSING_RESOURCE_ERROR; |
976 return NULL; | 971 return NULL; |
977 } | 972 } |
978 | 973 |
979 static void getPerUnitString( | 974 static void getPerUnitString( |
980 const QuantityFormatter &formatter, | 975 const QuantityFormatter &formatter, |
981 UnicodeString &result) { | 976 UnicodeString &result) { |
982 result = formatter.getByVariant("one")->getPatternWithNoPlaceholders(); | 977 result = formatter.getByVariant("one")->getPatternWithNoPlaceholders(); |
983 result.trim(); | 978 result.trim(); |
984 } | 979 } |
985 | 980 |
986 int32_t MeasureFormat::withPerUnit( | 981 int32_t MeasureFormat::withPerUnitAndAppend( |
987 const UnicodeString &formatted, | 982 const UnicodeString &formatted, |
988 const MeasureUnit &perUnit, | 983 const MeasureUnit &perUnit, |
989 UnicodeString &appendTo, | 984 UnicodeString &appendTo, |
990 UErrorCode &status) const { | 985 UErrorCode &status) const { |
991 int32_t offset = -1; | 986 int32_t offset = -1; |
992 if (U_FAILURE(status)) { | 987 if (U_FAILURE(status)) { |
993 return offset; | 988 return offset; |
994 } | 989 } |
995 const SimplePatternFormatter *perUnitFormatter = getPerUnitFormatter( | 990 const SimplePatternFormatter *perUnitFormatter = getPerUnitFormatter( |
996 perUnit.getIndex(), widthToIndex(width)); | 991 perUnit.getIndex(), widthToIndex(width)); |
997 if (perUnitFormatter != NULL) { | 992 if (perUnitFormatter != NULL) { |
998 const UnicodeString *params[] = {&formatted}; | 993 const UnicodeString *params[] = {&formatted}; |
999 perUnitFormatter->format( | 994 perUnitFormatter->formatAndAppend( |
1000 params, | 995 params, |
1001 UPRV_LENGTHOF(params), | 996 UPRV_LENGTHOF(params), |
1002 appendTo, | 997 appendTo, |
1003 &offset, | 998 &offset, |
1004 1, | 999 1, |
1005 status); | 1000 status); |
1006 return offset; | 1001 return offset; |
1007 } | 1002 } |
1008 const SimplePatternFormatter *perFormatter = getPerFormatter( | 1003 const SimplePatternFormatter *perFormatter = getPerFormatter( |
1009 widthToIndex(width), status); | 1004 widthToIndex(width), status); |
1010 const QuantityFormatter *qf = getQuantityFormatter( | 1005 const QuantityFormatter *qf = getQuantityFormatter( |
1011 perUnit.getIndex(), widthToIndex(width), status); | 1006 perUnit.getIndex(), widthToIndex(width), status); |
1012 if (U_FAILURE(status)) { | 1007 if (U_FAILURE(status)) { |
1013 return offset; | 1008 return offset; |
1014 } | 1009 } |
1015 UnicodeString perUnitString; | 1010 UnicodeString perUnitString; |
1016 getPerUnitString(*qf, perUnitString); | 1011 getPerUnitString(*qf, perUnitString); |
1017 const UnicodeString *params[] = {&formatted, &perUnitString}; | 1012 const UnicodeString *params[] = {&formatted, &perUnitString}; |
1018 perFormatter->format( | 1013 perFormatter->formatAndAppend( |
1019 params, | 1014 params, |
1020 UPRV_LENGTHOF(params), | 1015 UPRV_LENGTHOF(params), |
1021 appendTo, | 1016 appendTo, |
1022 &offset, | 1017 &offset, |
1023 1, | 1018 1, |
1024 status); | 1019 status); |
1025 return offset; | 1020 return offset; |
1026 } | 1021 } |
1027 | 1022 |
1028 UnicodeString &MeasureFormat::formatMeasuresSlowTrack( | 1023 UnicodeString &MeasureFormat::formatMeasuresSlowTrack( |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 MeasureFormat* U_EXPORT2 MeasureFormat::createCurrencyFormat(UErrorCode& ec) { | 1087 MeasureFormat* U_EXPORT2 MeasureFormat::createCurrencyFormat(UErrorCode& ec) { |
1093 if (U_FAILURE(ec)) { | 1088 if (U_FAILURE(ec)) { |
1094 return NULL; | 1089 return NULL; |
1095 } | 1090 } |
1096 return MeasureFormat::createCurrencyFormat(Locale::getDefault(), ec); | 1091 return MeasureFormat::createCurrencyFormat(Locale::getDefault(), ec); |
1097 } | 1092 } |
1098 | 1093 |
1099 U_NAMESPACE_END | 1094 U_NAMESPACE_END |
1100 | 1095 |
1101 #endif /* #if !UCONFIG_NO_FORMATTING */ | 1096 #endif /* #if !UCONFIG_NO_FORMATTING */ |
OLD | NEW |