]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/upluralrules.cpp
ICU-64232.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / upluralrules.cpp
index 24e74e3ee223f532a83a91b7a55ad2ccc2a8caf0..5119257fd804f7d9aa92755ad05a0faa3b9a5d01 100644 (file)
 #include "unicode/unistr.h"
 #include "unicode/unum.h"
 #include "unicode/numfmt.h"
+#include "unicode/unumberformatter.h"
+#include "number_decimalquantity.h"
+#include "number_utypes.h"
 
 U_NAMESPACE_USE
 
+namespace {
+
+/**
+ * Given a number and a format, returns the keyword of the first applicable
+ * rule for the PluralRules object.
+ * @param rules The plural rules.
+ * @param obj The numeric object for which the rule should be determined.
+ * @param fmt The NumberFormat specifying how the number will be formatted
+ *        (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
+ * @param status  Input/output parameter. If at entry this indicates a
+ *                failure status, the method returns immediately; otherwise
+ *                this is set to indicate the outcome of the call.
+ * @return The keyword of the selected rule. Undefined in the case of an error.
+ */
+UnicodeString select(const PluralRules &rules, const Formattable& obj, const NumberFormat& fmt, UErrorCode& status) {
+    if (U_SUCCESS(status)) {
+        const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
+        if (decFmt != NULL) {
+            number::impl::DecimalQuantity dq;
+            decFmt->formatToDecimalQuantity(obj, dq, status);
+            if (U_SUCCESS(status)) {
+                return rules.select(dq);
+            }
+        } else {
+            double number = obj.getDouble(status);
+            if (U_SUCCESS(status)) {
+                return rules.select(number);
+            }
+        }
+    }
+    return UnicodeString();
+}
+
+}  // namespace
 
 U_CAPI UPluralRules* U_EXPORT2
 uplrules_open(const char *locale, UErrorCode *status)
@@ -56,6 +93,28 @@ uplrules_select(const UPluralRules *uplrules,
     return result.extract(keyword, capacity, *status);
 }
 
+U_CAPI int32_t U_EXPORT2
+uplrules_selectFormatted(const UPluralRules *uplrules,
+                const UFormattedNumber* number,
+                UChar *keyword, int32_t capacity,
+                UErrorCode *status)
+{
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+    if (keyword == NULL ? capacity != 0 : capacity < 0) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    const number::impl::DecimalQuantity* dq =
+        number::impl::validateUFormattedNumberToDecimalQuantity(number, *status);
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+    UnicodeString result = ((PluralRules*)uplrules)->select(*dq);
+    return result.extract(keyword, capacity, *status);
+}
+
 U_CAPI int32_t U_EXPORT2
 uplrules_selectWithFormat(const UPluralRules *uplrules,
                           double number,
@@ -73,7 +132,7 @@ uplrules_selectWithFormat(const UPluralRules *uplrules,
         return 0;
     }
     Formattable obj(number);
-    UnicodeString result = plrules->select(obj, *nf, *status);
+    UnicodeString result = select(*plrules, obj, *nf, *status);
     return result.extract(keyword, capacity, *status);
 }