tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

upluralrules.cpp (5997B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *****************************************************************************************
      5 * Copyright (C) 2010-2012, International Business Machines
      6 * Corporation and others. All Rights Reserved.
      7 *****************************************************************************************
      8 */
      9 
     10 #include "unicode/utypes.h"
     11 
     12 #if !UCONFIG_NO_FORMATTING
     13 
     14 #include "unicode/upluralrules.h"
     15 #include "unicode/plurrule.h"
     16 #include "unicode/locid.h"
     17 #include "unicode/unistr.h"
     18 #include "unicode/unum.h"
     19 #include "unicode/numfmt.h"
     20 #include "unicode/unumberformatter.h"
     21 #include "number_decimalquantity.h"
     22 #include "number_utypes.h"
     23 #include "numrange_impl.h"
     24 
     25 U_NAMESPACE_USE
     26 
     27 namespace {
     28 
     29 /**
     30 * Given a number and a format, returns the keyword of the first applicable
     31 * rule for the PluralRules object.
     32 * @param rules The plural rules.
     33 * @param obj The numeric object for which the rule should be determined.
     34 * @param fmt The NumberFormat specifying how the number will be formatted
     35 *        (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
     36 * @param status  Input/output parameter. If at entry this indicates a
     37 *                failure status, the method returns immediately; otherwise
     38 *                this is set to indicate the outcome of the call.
     39 * @return The keyword of the selected rule. Undefined in the case of an error.
     40 */
     41 UnicodeString select(const PluralRules &rules, const Formattable& obj, const NumberFormat& fmt, UErrorCode& status) {
     42    if (U_SUCCESS(status)) {
     43        const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
     44        if (decFmt != nullptr) {
     45            number::impl::DecimalQuantity dq;
     46            decFmt->formatToDecimalQuantity(obj, dq, status);
     47            if (U_SUCCESS(status)) {
     48                return rules.select(dq);
     49            }
     50        } else {
     51            double number = obj.getDouble(status);
     52            if (U_SUCCESS(status)) {
     53                return rules.select(number);
     54            }
     55        }
     56    }
     57    return {};
     58 }
     59 
     60 }  // namespace
     61 
     62 U_CAPI UPluralRules* U_EXPORT2
     63 uplrules_open(const char *locale, UErrorCode *status)
     64 {
     65    return uplrules_openForType(locale, UPLURAL_TYPE_CARDINAL, status);
     66 }
     67 
     68 U_CAPI UPluralRules* U_EXPORT2
     69 uplrules_openForType(const char *locale, UPluralType type, UErrorCode *status)
     70 {
     71    return (UPluralRules*)PluralRules::forLocale(Locale(locale), type, *status);
     72 }
     73 
     74 U_CAPI void U_EXPORT2
     75 uplrules_close(UPluralRules *uplrules)
     76 {
     77    delete (PluralRules*)uplrules;
     78 }
     79 
     80 U_CAPI int32_t U_EXPORT2
     81 uplrules_select(const UPluralRules *uplrules,
     82                double number,
     83                char16_t *keyword, int32_t capacity,
     84                UErrorCode *status)
     85 {
     86    if (U_FAILURE(*status)) {
     87        return 0;
     88    }
     89    if (keyword == nullptr ? capacity != 0 : capacity < 0) {
     90        *status = U_ILLEGAL_ARGUMENT_ERROR;
     91        return 0;
     92    }
     93    UnicodeString result = ((PluralRules*)uplrules)->select(number);
     94    return result.extract(keyword, capacity, *status);
     95 }
     96 
     97 U_CAPI int32_t U_EXPORT2
     98 uplrules_selectFormatted(const UPluralRules *uplrules,
     99                const UFormattedNumber* number,
    100                char16_t *keyword, int32_t capacity,
    101                UErrorCode *status)
    102 {
    103    if (U_FAILURE(*status)) {
    104        return 0;
    105    }
    106    if (keyword == nullptr ? capacity != 0 : capacity < 0) {
    107        *status = U_ILLEGAL_ARGUMENT_ERROR;
    108        return 0;
    109    }
    110    const number::impl::DecimalQuantity* dq =
    111        number::impl::validateUFormattedNumberToDecimalQuantity(number, *status);
    112    if (U_FAILURE(*status)) {
    113        return 0;
    114    }
    115    UnicodeString result = ((PluralRules*)uplrules)->select(*dq);
    116    return result.extract(keyword, capacity, *status);
    117 }
    118 
    119 U_CAPI int32_t U_EXPORT2
    120 uplrules_selectForRange(const UPluralRules *uplrules,
    121                const UFormattedNumberRange* urange,
    122                char16_t *keyword, int32_t capacity,
    123                UErrorCode *status)
    124 {
    125    if (U_FAILURE(*status)) {
    126        return 0;
    127    }
    128    if (keyword == nullptr ? capacity != 0 : capacity < 0) {
    129        *status = U_ILLEGAL_ARGUMENT_ERROR;
    130        return 0;
    131    }
    132    const number::impl::UFormattedNumberRangeData* impl =
    133        number::impl::validateUFormattedNumberRange(urange, *status);
    134    UnicodeString result = ((PluralRules*)uplrules)->select(impl, *status);
    135    return result.extract(keyword, capacity, *status);
    136 }
    137 
    138 U_CAPI int32_t U_EXPORT2
    139 uplrules_selectWithFormat(const UPluralRules *uplrules,
    140                          double number,
    141                          const UNumberFormat *fmt,
    142                          char16_t *keyword, int32_t capacity,
    143                          UErrorCode *status)
    144 {
    145    if (U_FAILURE(*status)) {
    146        return 0;
    147    }
    148    const PluralRules* plrules = reinterpret_cast<const PluralRules*>(uplrules);
    149    const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
    150    if (plrules == nullptr || nf == nullptr || ((keyword == nullptr)? capacity != 0 : capacity < 0)) {
    151        *status = U_ILLEGAL_ARGUMENT_ERROR;
    152        return 0;
    153    }
    154    Formattable obj(number);
    155    UnicodeString result = select(*plrules, obj, *nf, *status);
    156    return result.extract(keyword, capacity, *status);
    157 }
    158 
    159 U_CAPI UEnumeration* U_EXPORT2
    160 uplrules_getKeywords(const UPluralRules *uplrules,
    161                     UErrorCode *status)
    162 {
    163    if (U_FAILURE(*status)) {
    164        return nullptr;
    165    }
    166    const PluralRules* plrules = reinterpret_cast<const PluralRules*>(uplrules);
    167    if (plrules == nullptr) {
    168        *status = U_ILLEGAL_ARGUMENT_ERROR;
    169        return nullptr;
    170    }
    171    StringEnumeration *senum = plrules->getKeywords(*status);
    172    if (U_FAILURE(*status)) {
    173        return nullptr;
    174    }
    175    if (senum == nullptr) {
    176        *status = U_MEMORY_ALLOCATION_ERROR;
    177        return nullptr;
    178    }
    179    return uenum_openFromStringEnumeration(senum, status);
    180 }
    181 
    182 #endif /* #if !UCONFIG_NO_FORMATTING */