tor-browser

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

numrange_capi.cpp (6326B)


      1 // © 2018 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 
      4 #include "unicode/utypes.h"
      5 
      6 #if !UCONFIG_NO_FORMATTING
      7 
      8 // Allow implicit conversion from char16_t* to UnicodeString for this file:
      9 // Helpful in toString methods and elsewhere.
     10 #define UNISTR_FROM_STRING_EXPLICIT
     11 
     12 #include "fphdlimp.h"
     13 #include "number_utypes.h"
     14 #include "numparse_types.h"
     15 #include "formattedval_impl.h"
     16 #include "numrange_impl.h"
     17 #include "number_decnum.h"
     18 #include "unicode/numberrangeformatter.h"
     19 #include "unicode/unumberrangeformatter.h"
     20 
     21 using namespace icu;
     22 using namespace icu::number;
     23 using namespace icu::number::impl;
     24 
     25 
     26 U_NAMESPACE_BEGIN
     27 namespace number::impl {
     28 
     29 /**
     30 * Implementation class for UNumberRangeFormatter. Wraps a LocalizedRangeNumberFormatter.
     31 */
     32 struct UNumberRangeFormatterData : public UMemory,
     33        // Magic number as ASCII == "NRF" (NumberRangeFormatter)
     34        public IcuCApiHelper<UNumberRangeFormatter, UNumberRangeFormatterData, 0x4E524600> {
     35    LocalizedNumberRangeFormatter fFormatter;
     36 };
     37 
     38 struct UFormattedNumberRangeImpl;
     39 
     40 // Magic number as ASCII == "FDN" (FormatteDNumber)
     41 typedef IcuCApiHelper<UFormattedNumberRange, UFormattedNumberRangeImpl, 0x46444E00> UFormattedNumberRangeApiHelper;
     42 
     43 struct UFormattedNumberRangeImpl : public UFormattedValueImpl, public UFormattedNumberRangeApiHelper {
     44    UFormattedNumberRangeImpl();
     45    ~UFormattedNumberRangeImpl();
     46 
     47    FormattedNumberRange fImpl;
     48    UFormattedNumberRangeData fData;
     49 };
     50 
     51 UFormattedNumberRangeImpl::UFormattedNumberRangeImpl()
     52        : fImpl(&fData) {
     53    fFormattedValue = &fImpl;
     54 }
     55 
     56 UFormattedNumberRangeImpl::~UFormattedNumberRangeImpl() {
     57    // Disown the data from fImpl so it doesn't get deleted twice
     58    fImpl.fData = nullptr;
     59 }
     60 
     61 } // namespace number::impl
     62 U_NAMESPACE_END
     63 
     64 
     65 UPRV_FORMATTED_VALUE_CAPI_NO_IMPLTYPE_AUTO_IMPL(
     66    UFormattedNumberRange,
     67    UFormattedNumberRangeImpl,
     68    UFormattedNumberRangeApiHelper,
     69    unumrf)
     70 
     71 
     72 const UFormattedNumberRangeData* number::impl::validateUFormattedNumberRange(
     73        const UFormattedNumberRange* uresult, UErrorCode& status) {
     74    const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, status);
     75    if (U_FAILURE(status)) {
     76        return nullptr;
     77    }
     78    return &result->fData;
     79 }
     80 
     81 
     82 U_CAPI UNumberRangeFormatter* U_EXPORT2
     83 unumrf_openForSkeletonWithCollapseAndIdentityFallback(
     84        const char16_t* skeleton,
     85        int32_t skeletonLen,
     86        UNumberRangeCollapse collapse,
     87        UNumberRangeIdentityFallback identityFallback,
     88        const char* locale,
     89        UParseError* perror,
     90        UErrorCode* ec) {
     91    auto* impl = new UNumberRangeFormatterData();
     92    if (impl == nullptr) {
     93        *ec = U_MEMORY_ALLOCATION_ERROR;
     94        return nullptr;
     95    }
     96    // Readonly-alias constructor (first argument is whether we are NUL-terminated)
     97    UnicodeString skeletonString(skeletonLen == -1, skeleton, skeletonLen);
     98    UParseError tempParseError;
     99    impl->fFormatter = NumberRangeFormatter::withLocale(locale)
    100        .numberFormatterBoth(NumberFormatter::forSkeleton(skeletonString, (perror == nullptr) ? tempParseError : *perror, *ec))
    101        .collapse(collapse)
    102        .identityFallback(identityFallback);
    103    return impl->exportForC();
    104 }
    105 
    106 U_CAPI void U_EXPORT2
    107 unumrf_formatDoubleRange(
    108        const UNumberRangeFormatter* uformatter,
    109        double first,
    110        double second,
    111        UFormattedNumberRange* uresult,
    112        UErrorCode* ec) {
    113    const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec);
    114    auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    115    if (U_FAILURE(*ec)) { return; }
    116 
    117    result->fData.resetString();
    118    result->fData.quantity1.clear();
    119    result->fData.quantity2.clear();
    120    result->fData.quantity1.setToDouble(first);
    121    result->fData.quantity2.setToDouble(second);
    122    formatter->fFormatter.formatImpl(result->fData, first == second, *ec);
    123 }
    124 
    125 U_CAPI void U_EXPORT2
    126 unumrf_formatDecimalRange(
    127        const UNumberRangeFormatter* uformatter,
    128        const char* first, int32_t firstLen,
    129        const char* second, int32_t secondLen,
    130        UFormattedNumberRange* uresult,
    131        UErrorCode* ec) {
    132    const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec);
    133    auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    134    if (U_FAILURE(*ec)) { return; }
    135 
    136    result->fData.resetString();
    137    result->fData.quantity1.clear();
    138    result->fData.quantity2.clear();
    139    result->fData.quantity1.setToDecNumber({first, firstLen}, *ec);
    140    result->fData.quantity2.setToDecNumber({second, secondLen}, *ec);
    141    formatter->fFormatter.formatImpl(result->fData, first == second, *ec);
    142 }
    143 
    144 U_CAPI UNumberRangeIdentityResult U_EXPORT2
    145 unumrf_resultGetIdentityResult(
    146        const UFormattedNumberRange* uresult,
    147        UErrorCode* ec) {
    148    const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    149    if (U_FAILURE(*ec)) {
    150        return UNUM_IDENTITY_RESULT_COUNT;
    151    }
    152    return result->fData.identityResult;
    153 }
    154 
    155 U_CAPI int32_t U_EXPORT2
    156 unumrf_resultGetFirstDecimalNumber(
    157        const UFormattedNumberRange* uresult,
    158        char* dest,
    159        int32_t destCapacity,
    160        UErrorCode* ec) {
    161    const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    162    if (U_FAILURE(*ec)) {
    163        return 0;
    164    }
    165    DecNum decnum;
    166    return result->fData.quantity1.toDecNum(decnum, *ec)
    167        .toCharString(*ec)
    168        .extract(dest, destCapacity, *ec);
    169 }
    170 
    171 U_CAPI int32_t U_EXPORT2
    172 unumrf_resultGetSecondDecimalNumber(
    173        const UFormattedNumberRange* uresult,
    174        char* dest,
    175        int32_t destCapacity,
    176        UErrorCode* ec) {
    177    const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    178    if (U_FAILURE(*ec)) {
    179        return 0;
    180    }
    181    DecNum decnum;
    182    return result->fData.quantity2
    183        .toDecNum(decnum, *ec)
    184        .toCharString(*ec)
    185        .extract(dest, destCapacity, *ec);
    186 }
    187 
    188 U_CAPI void U_EXPORT2
    189 unumrf_close(UNumberRangeFormatter* f) {
    190    UErrorCode localStatus = U_ZERO_ERROR;
    191    const UNumberRangeFormatterData* impl = UNumberRangeFormatterData::validate(f, localStatus);
    192    delete impl;
    193 }
    194 
    195 
    196 #endif /* #if !UCONFIG_NO_FORMATTING */