]> granicus.if.org Git - icu/commitdiff
ICU-11986 const ResourceValue references, sink.leave(), some more specific types...
authorMarkus Scherer <markus.icu@gmail.com>
Thu, 19 Nov 2015 22:33:25 +0000 (22:33 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Thu, 19 Nov 2015 22:33:25 +0000 (22:33 +0000)
X-SVN-Rev: 38094

icu4c/source/common/resource.cpp
icu4c/source/common/resource.h
icu4c/source/common/uresdata.cpp
icu4c/source/i18n/measfmt.cpp
icu4c/source/i18n/quantityformatter.cpp
icu4c/source/i18n/unicode/measfmt.h

index 2a61dbac65b4af25176e90e7a11b3894ebcd4420..7a4c4181bf834c60b9e26f32449b4bb6fb51af0e 100644 (file)
@@ -23,7 +23,7 @@ ResourceValue::~ResourceValue() {}
 ResourceArraySink::~ResourceArraySink() {}
 
 void ResourceArraySink::put(
-        int32_t /*index*/, ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {}
+        int32_t /*index*/, const ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {}
 
 ResourceArraySink *ResourceArraySink::getOrCreateArraySink(
         int32_t /*index*/, int32_t /*size*/, UErrorCode & /*errorCode*/) {
@@ -35,11 +35,13 @@ ResourceTableSink *ResourceArraySink::getOrCreateTableSink(
     return NULL;
 }
 
+void ResourceArraySink::leave(UErrorCode & /*errorCode*/) {}
+
 
 ResourceTableSink::~ResourceTableSink() {}
 
 void ResourceTableSink::put(
-        const char * /*key*/, ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {}
+        const char * /*key*/, const ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {}
 
 void ResourceTableSink::putNoFallback(const char * /*key*/, UErrorCode & /*errorCode*/) {}
 
@@ -53,4 +55,6 @@ ResourceTableSink *ResourceTableSink::getOrCreateTableSink(
     return NULL;
 }
 
+void ResourceTableSink::leave(UErrorCode & /*errorCode*/) {}
+
 U_NAMESPACE_END
index 58e03df6ff287fdd2faa30898a30de07171838b5..042e298b798242bb5ae05339337fb4636f0dd3c3 100644 (file)
@@ -126,7 +126,7 @@ public:
      * @param index of the resource array item
      * @param value resource value
      */
-    virtual void put(int32_t index, ResourceValue &value, UErrorCode &errorCode);
+    virtual void put(int32_t index, const ResourceValue &value, UErrorCode &errorCode);
 
     /**
      * Returns a nested resource array at the array index as another sink.
@@ -158,6 +158,13 @@ public:
     virtual ResourceTableSink *getOrCreateTableSink(
             int32_t index, int32_t initialSize, UErrorCode &errorCode);
 
+    /**
+     * "Leaves" the array.
+     * Indicates that all of the resources and sub-resources of the current array
+     * have been enumerated.
+     */
+    virtual void leave(UErrorCode &errorCode);
+
 private:
     ResourceArraySink(const ResourceArraySink &);  // no copy constructor
     ResourceArraySink &operator=(const ResourceArraySink &);  // no assignment operator
@@ -181,7 +188,7 @@ public:
      * @param key resource key string
      * @param value resource value
      */
-    virtual void put(const char *key, ResourceValue &value, UErrorCode &errorCode);
+    virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode);
 
     /**
      * Adds a no-fallback/no-inheritance marker for this key.
@@ -224,6 +231,13 @@ public:
     virtual ResourceTableSink *getOrCreateTableSink(
             const char *key, int32_t initialSize, UErrorCode &errorCode);
 
+    /**
+     * "Leaves" the table.
+     * Indicates that all of the resources and sub-resources of the current table
+     * have been enumerated.
+     */
+    virtual void leave(UErrorCode &errorCode);
+
 private:
     ResourceTableSink(const ResourceTableSink &);  // no copy constructor
     ResourceTableSink &operator=(const ResourceTableSink &);  // no assignment operator
index 91edd7c1afc6620e00bb5829efde97e4badd7b01..fbfb56de6b52045f586f1228ac7891f015a1dcd2 100644 (file)
@@ -775,6 +775,7 @@ ures_getAllTableItems(const ResourceData *pResData, Resource table,
         }
         if(U_FAILURE(errorCode)) { return; }
     }
+    sink.leave(errorCode);
 }
 
 U_CAPI Resource U_EXPORT2
@@ -862,6 +863,7 @@ ures_getAllArrayItems(const ResourceData *pResData, Resource array,
         }
         if(U_FAILURE(errorCode)) { return; }
     }
+    sink.leave(errorCode);
 }
 
 U_CFUNC Resource
index 623c272b7c2031ff0fbcb4c24faa38875b8d97c3..5d7faa3fef6c1cdfe392a456e48d486708b09f88 100644 (file)
@@ -77,6 +77,13 @@ private:
     NumericDateFormatters &operator=(const NumericDateFormatters &other);
 };
 
+static UMeasureFormatWidth getRegularWidth(UMeasureFormatWidth width) {
+    if (width >= WIDTH_INDEX_COUNT) {
+        return UMEASFMT_WIDTH_NARROW;
+    }
+    return width;
+}
+
 /**
  * Instances contain all MeasureFormat specific data for a particular locale.
  * This data is cached. It is never copied, but is shared via shared pointers.
@@ -111,8 +118,8 @@ public:
         delete currencyFormats[widthIndex];
         currencyFormats[widthIndex] = nfToAdopt;
     }
-    const NumberFormat *getCurrencyFormat(int32_t widthIndex) const {
-        return currencyFormats[widthIndex];
+    const NumberFormat *getCurrencyFormat(UMeasureFormatWidth width) const {
+        return currencyFormats[getRegularWidth(width)];
     }
     void adoptIntegerFormat(NumberFormat *nfToAdopt) {
         delete integerFormat;
@@ -128,7 +135,7 @@ public:
     const NumericDateFormatters *getNumericDateFormatters() const {
         return numericDateFormatters;
     }
-    void setPerUnitFormatterIfAbsent(int32_t unitIndex, int32_t width, ResourceValue &value,
+    void setPerUnitFormatterIfAbsent(int32_t unitIndex, int32_t width, const ResourceValue &value,
                                      UErrorCode &errorCode) {
         if (perUnitFormatters[unitIndex][width] == NULL) {
             perUnitFormatters[unitIndex][width] =
@@ -177,13 +184,6 @@ MeasureFormatCacheData::~MeasureFormatCacheData() {
     delete numericDateFormatters;
 }
 
-static int32_t widthToIndex(UMeasureFormatWidth width) {
-    if (width >= WIDTH_INDEX_COUNT) {
-        return WIDTH_INDEX_COUNT - 1;
-    }
-    return width;
-}
-
 static UBool isCurrency(const MeasureUnit &unit) {
     return (uprv_strcmp(unit.getType(), "currency") == 0);
 }
@@ -229,7 +229,7 @@ struct UnitDataSink : public ResourceTableSink {
     struct UnitPatternSink : public ResourceTableSink {
         UnitPatternSink(UnitDataSink &sink) : outer(sink) {}
         ~UnitPatternSink();
-        virtual void put(const char *key, ResourceValue &value, UErrorCode &errorCode) {
+        virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) {
             if (U_FAILURE(errorCode)) { return; }
             if (uprv_strcmp(key, "dnam") == 0) {
                 // Skip the unit display name for now.
@@ -278,7 +278,7 @@ struct UnitDataSink : public ResourceTableSink {
     struct UnitCompoundSink : public ResourceTableSink {
         UnitCompoundSink(UnitDataSink &sink) : outer(sink) {}
         ~UnitCompoundSink();
-        virtual void put(const char *key, ResourceValue &value, UErrorCode &errorCode) {
+        virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) {
             if (U_SUCCESS(errorCode) && uprv_strcmp(key, "per") == 0) {
                 outer.cacheData.perFormatters[outer.width].
                         compile(value.getUnicodeString(errorCode), errorCode);
@@ -318,7 +318,7 @@ struct UnitDataSink : public ResourceTableSink {
               cacheData(outputData),
               width(UMEASFMT_WIDTH_COUNT), type(NULL), unitIndex(0), hasPatterns(FALSE) {}
     ~UnitDataSink();
-    virtual void put(const char *key, ResourceValue &value, UErrorCode &errorCode) {
+    virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) {
         // Handle aliases like
         // units:alias{"/LOCALE/unitsShort"}
         // which should only occur in the root bundle.
@@ -834,7 +834,7 @@ void MeasureFormat::initMeasureFormat(
     delete listFormatter;
     listFormatter = ListFormatter::createInstance(
             locale,
-            listStyles[widthToIndex(width)],
+            listStyles[getRegularWidth(width)],
             status);
 }
 
@@ -891,14 +891,13 @@ UnicodeString &MeasureFormat::formatMeasure(
     if (isCurrency(amtUnit)) {
         UChar isoCode[4];
         u_charsToUChars(amtUnit.getSubtype(), isoCode, 4);
-        return cache->getCurrencyFormat(widthToIndex(width))->format(
+        return cache->getCurrencyFormat(width)->format(
                 new CurrencyAmount(amtNumber, isoCode, status),
                 appendTo,
                 pos,
                 status);
     }
-    const QuantityFormatter *quantityFormatter = getQuantityFormatter(
-            amtUnit.getIndex(), widthToIndex(width), status);
+    const QuantityFormatter *quantityFormatter = getQuantityFormatter(amtUnit, width, status);
     if (U_FAILURE(status)) {
         return appendTo;
     }
@@ -1041,18 +1040,18 @@ UnicodeString &MeasureFormat::formatNumeric(
 }
 
 const QuantityFormatter *MeasureFormat::getQuantityFormatter(
-        int32_t index,
-        int32_t widthIndex,
+        const MeasureUnit &unit,
+        UMeasureFormatWidth width,
         UErrorCode &status) const {
     if (U_FAILURE(status)) {
         return NULL;
     }
-    const QuantityFormatter *formatters =
-            cache->formatters[index];
-    if (formatters[widthIndex].isValid()) {
-        return &formatters[widthIndex];
+    width = getRegularWidth(width);
+    const QuantityFormatter *formatters = cache->formatters[unit.getIndex()];
+    if (formatters[width].isValid()) {
+        return &formatters[width];
     }
-    int32_t fallbackWidth = cache->widthFallback[widthIndex];
+    int32_t fallbackWidth = cache->widthFallback[width];
     if (fallbackWidth != UMEASFMT_WIDTH_COUNT && formatters[fallbackWidth].isValid()) {
         return &formatters[fallbackWidth];
     }
@@ -1061,14 +1060,15 @@ const QuantityFormatter *MeasureFormat::getQuantityFormatter(
 }
 
 const SimplePatternFormatter *MeasureFormat::getPerUnitFormatter(
-        int32_t index,
-        int32_t widthIndex) const {
+        const MeasureUnit &unit,
+        UMeasureFormatWidth width) const {
+    width = getRegularWidth(width);
     const SimplePatternFormatter * const * perUnitFormatters =
-            cache->getPerUnitFormattersByIndex(index);
-    if (perUnitFormatters[widthIndex] != NULL) {
-        return perUnitFormatters[widthIndex];
+            cache->getPerUnitFormattersByIndex(unit.getIndex());
+    if (perUnitFormatters[width] != NULL) {
+        return perUnitFormatters[width];
     }
-    int32_t fallbackWidth = cache->widthFallback[widthIndex];
+    int32_t fallbackWidth = cache->widthFallback[width];
     if (fallbackWidth != UMEASFMT_WIDTH_COUNT && perUnitFormatters[fallbackWidth] != NULL) {
         return perUnitFormatters[fallbackWidth];
     }
@@ -1076,16 +1076,17 @@ const SimplePatternFormatter *MeasureFormat::getPerUnitFormatter(
 }
 
 const SimplePatternFormatter *MeasureFormat::getPerFormatter(
-        int32_t widthIndex,
+        UMeasureFormatWidth width,
         UErrorCode &status) const {
     if (U_FAILURE(status)) {
         return NULL;
     }
+    width = getRegularWidth(width);
     const SimplePatternFormatter * perFormatters = cache->perFormatters;
-    if (perFormatters[widthIndex].getPlaceholderCount() == 2) {
-        return &perFormatters[widthIndex];
+    if (perFormatters[width].getPlaceholderCount() == 2) {
+        return &perFormatters[width];
     }
-    int32_t fallbackWidth = cache->widthFallback[widthIndex];
+    int32_t fallbackWidth = cache->widthFallback[width];
     if (fallbackWidth != UMEASFMT_WIDTH_COUNT &&
             perFormatters[fallbackWidth].getPlaceholderCount() == 2) {
         return &perFormatters[fallbackWidth];
@@ -1110,8 +1111,7 @@ int32_t MeasureFormat::withPerUnitAndAppend(
     if (U_FAILURE(status)) {
         return offset;
     }
-    const SimplePatternFormatter *perUnitFormatter = getPerUnitFormatter(
-            perUnit.getIndex(), widthToIndex(width));
+    const SimplePatternFormatter *perUnitFormatter = getPerUnitFormatter(perUnit, width);
     if (perUnitFormatter != NULL) {
         const UnicodeString *params[] = {&formatted};
         perUnitFormatter->formatAndAppend(
@@ -1123,10 +1123,8 @@ int32_t MeasureFormat::withPerUnitAndAppend(
                 status);
         return offset;
     }
-    const SimplePatternFormatter *perFormatter = getPerFormatter(
-            widthToIndex(width), status);
-    const QuantityFormatter *qf = getQuantityFormatter(
-            perUnit.getIndex(), widthToIndex(width), status);
+    const SimplePatternFormatter *perFormatter = getPerFormatter(width, status);
+    const QuantityFormatter *qf = getQuantityFormatter(perUnit, width, status);
     if (U_FAILURE(status)) {
         return offset;
     }
index ed80b38b500d1465db2ec2388bbba08ad9ee1fb6..22d19a95550ba7bd47973f25a55c0d3153988571 100644 (file)
 
 U_NAMESPACE_BEGIN
 
-// other must always be first.
-static const char * const gPluralForms[] = {
-        "other", "zero", "one", "two", "few", "many"};
-
+/**
+ * Plural forms in index order: "other", "zero", "one", "two", "few", "many"
+ * "other" must be first.
+ */
 static int32_t getPluralIndex(const char *pluralForm) {
-    int32_t len = UPRV_LENGTHOF(gPluralForms);
-    for (int32_t i = 0; i < len; ++i) {
-        if (uprv_strcmp(pluralForm, gPluralForms[i]) == 0) {
-            return i;
+    switch (*pluralForm++) {
+    case 'f':
+        if (uprv_strcmp(pluralForm, "ew") == 0) {
+            return 4;
+        }
+    case 'm':
+        if (uprv_strcmp(pluralForm, "any") == 0) {
+            return 5;
+        }
+    case 'o':
+        if (uprv_strcmp(pluralForm, "ther") == 0) {
+            return 0;
+        } else if (uprv_strcmp(pluralForm, "ne") == 0) {
+            return 2;
+        }
+        break;
+    case 't':
+        if (uprv_strcmp(pluralForm, "wo") == 0) {
+            return 3;
+        }
+    case 'z':
+        if (uprv_strcmp(pluralForm, "ero") == 0) {
+            return 1;
         }
+    default:
+        break;
     }
     return -1;
 }
index 61a1e86d9c431e7c18a48ccb976e37c16ed82c1b..b680a7dc7132237f857f7bc8d8a05216945f7a9a 100644 (file)
@@ -328,16 +328,16 @@ class U_I18N_API MeasureFormat : public Format {
     ListFormatter *listFormatter;
 
     const QuantityFormatter *getQuantityFormatter(
-            int32_t index,
-            int32_t widthIndex,
+            const MeasureUnit &unit,
+            UMeasureFormatWidth width,
             UErrorCode &status) const;
 
     const SimplePatternFormatter *getPerUnitFormatter(
-            int32_t index,
-            int32_t widthIndex) const;
+            const MeasureUnit &unit,
+            UMeasureFormatWidth width) const;
 
     const SimplePatternFormatter *getPerFormatter(
-            int32_t widthIndex,
+            UMeasureFormatWidth width,
             UErrorCode &status) const;
 
     int32_t withPerUnitAndAppend(