tor-browser

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

number_mapper.h (8452B)


      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 #ifndef __NUMBER_MAPPER_H__
      8 #define __NUMBER_MAPPER_H__
      9 
     10 #include "number_types.h"
     11 #include "unicode/currpinf.h"
     12 #include "standardplural.h"
     13 #include "number_patternstring.h"
     14 #include "number_currencysymbols.h"
     15 #include "numparse_impl.h"
     16 
     17 #ifndef __wasi__
     18 #include <atomic>
     19 #endif
     20 
     21 U_NAMESPACE_BEGIN
     22 namespace number::impl {
     23 
     24 class AutoAffixPatternProvider;
     25 class CurrencyPluralInfoAffixProvider;
     26 
     27 
     28 class PropertiesAffixPatternProvider : public AffixPatternProvider, public UMemory {
     29  public:
     30    bool isBogus() const {
     31        return fBogus;
     32    }
     33 
     34    void setToBogus() {
     35        fBogus = true;
     36    }
     37 
     38    void setTo(const DecimalFormatProperties& properties, UErrorCode& status);
     39 
     40    // AffixPatternProvider Methods:
     41 
     42    char16_t charAt(int32_t flags, int32_t i) const override;
     43 
     44    int32_t length(int32_t flags) const override;
     45 
     46    UnicodeString getString(int32_t flags) const override;
     47 
     48    bool hasCurrencySign() const override;
     49 
     50    bool positiveHasPlusSign() const override;
     51 
     52    bool hasNegativeSubpattern() const override;
     53 
     54    bool negativeHasMinusSign() const override;
     55 
     56    bool containsSymbolType(AffixPatternType, UErrorCode&) const override;
     57 
     58    bool hasBody() const override;
     59 
     60    bool currencyAsDecimal() const override;
     61 
     62  private:
     63    UnicodeString posPrefix;
     64    UnicodeString posSuffix;
     65    UnicodeString negPrefix;
     66    UnicodeString negSuffix;
     67    bool isCurrencyPattern;
     68    bool fCurrencyAsDecimal;
     69 
     70    PropertiesAffixPatternProvider() = default; // puts instance in valid but undefined state
     71 
     72    const UnicodeString& getStringInternal(int32_t flags) const;
     73 
     74    bool fBogus{true};
     75 
     76    friend class AutoAffixPatternProvider;
     77    friend class CurrencyPluralInfoAffixProvider;
     78 };
     79 
     80 
     81 class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMemory {
     82  public:
     83    bool isBogus() const {
     84        return fBogus;
     85    }
     86 
     87    void setToBogus() {
     88        fBogus = true;
     89    }
     90 
     91    void setTo(const CurrencyPluralInfo& cpi, const DecimalFormatProperties& properties,
     92               UErrorCode& status);
     93 
     94    // AffixPatternProvider Methods:
     95 
     96    char16_t charAt(int32_t flags, int32_t i) const override;
     97 
     98    int32_t length(int32_t flags) const override;
     99 
    100    UnicodeString getString(int32_t flags) const override;
    101 
    102    bool hasCurrencySign() const override;
    103 
    104    bool positiveHasPlusSign() const override;
    105 
    106    bool hasNegativeSubpattern() const override;
    107 
    108    bool negativeHasMinusSign() const override;
    109 
    110    bool containsSymbolType(AffixPatternType, UErrorCode&) const override;
    111 
    112    bool hasBody() const override;
    113 
    114    bool currencyAsDecimal() const override;
    115 
    116  private:
    117    PropertiesAffixPatternProvider affixesByPlural[StandardPlural::COUNT];
    118 
    119    CurrencyPluralInfoAffixProvider() = default;
    120 
    121    bool fBogus{true};
    122 
    123    friend class AutoAffixPatternProvider;
    124 };
    125 
    126 
    127 class AutoAffixPatternProvider {
    128  public:
    129    inline AutoAffixPatternProvider() = default;
    130 
    131    inline AutoAffixPatternProvider(const DecimalFormatProperties& properties, UErrorCode& status) {
    132        setTo(properties, status);
    133    }
    134 
    135    inline void setTo(const DecimalFormatProperties& properties, UErrorCode& status) {
    136        if (properties.currencyPluralInfo.fPtr.isNull()) {
    137            propertiesAPP.setTo(properties, status);
    138            currencyPluralInfoAPP.setToBogus();
    139        } else {
    140            propertiesAPP.setToBogus();
    141            currencyPluralInfoAPP.setTo(*properties.currencyPluralInfo.fPtr, properties, status);
    142        }
    143    }
    144 
    145    inline void setTo(const AffixPatternProvider* provider, UErrorCode& status) {
    146        if (const auto* ptr = dynamic_cast<const PropertiesAffixPatternProvider*>(provider)) {
    147            propertiesAPP = *ptr;
    148        } else if (const auto* ptr = dynamic_cast<const CurrencyPluralInfoAffixProvider*>(provider)) {
    149            currencyPluralInfoAPP = *ptr;
    150        } else {
    151            status = U_INTERNAL_PROGRAM_ERROR;
    152        }
    153    }
    154 
    155    inline const AffixPatternProvider& get() const {
    156      if (!currencyPluralInfoAPP.isBogus()) {
    157        return currencyPluralInfoAPP;
    158      } else {
    159        return propertiesAPP;
    160      }
    161    }
    162 
    163  private:
    164    PropertiesAffixPatternProvider propertiesAPP;
    165    CurrencyPluralInfoAffixProvider currencyPluralInfoAPP;
    166 };
    167 
    168 
    169 /**
    170 * A struct for ownership of a few objects needed for formatting.
    171 */
    172 struct DecimalFormatWarehouse : public UMemory {
    173    AutoAffixPatternProvider affixProvider;
    174    LocalPointer<PluralRules> rules;
    175 };
    176 
    177 
    178 /**
    179 * Internal fields for DecimalFormat.
    180 * TODO: Make some of these fields by value instead of by LocalPointer?
    181 */
    182 struct DecimalFormatFields : public UMemory {
    183 
    184    DecimalFormatFields() {}
    185 
    186    DecimalFormatFields(const DecimalFormatProperties& propsToCopy)
    187        : properties(propsToCopy) {}
    188 
    189    /** The property bag corresponding to user-specified settings and settings from the pattern string. */
    190    DecimalFormatProperties properties;
    191 
    192    /** The symbols for the current locale. */
    193    LocalPointer<const DecimalFormatSymbols> symbols;
    194 
    195    /**
    196    * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link
    197    * #format} method uses the formatter directly without needing to synchronize.
    198    */
    199    LocalizedNumberFormatter formatter;
    200 
    201    /** The lazy-computed parser for .parse() */
    202 #ifndef __wasi__
    203    std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {};
    204 #else
    205    ::icu::numparse::impl::NumberParserImpl* atomicParser = nullptr;
    206 #endif
    207 
    208    /** The lazy-computed parser for .parseCurrency() */
    209 #ifndef __wasi__
    210    std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {};
    211 #else
    212    ::icu::numparse::impl::NumberParserImpl* atomicCurrencyParser = {};
    213 #endif
    214 
    215    /** Small object ownership warehouse for the formatter and parser */
    216    DecimalFormatWarehouse warehouse;
    217 
    218    /** The effective properties as exported from the formatter object. Used by some getters. */
    219    DecimalFormatProperties exportedProperties;
    220 
    221    // Data for fastpath
    222    bool canUseFastFormat = false;
    223    struct FastFormatData {
    224        char16_t cpZero;
    225        char16_t cpGroupingSeparator;
    226        char16_t cpMinusSign;
    227        int8_t minInt;
    228        int8_t maxInt;
    229    } fastData;
    230 };
    231 
    232 
    233 /**
    234 * Utilities for converting between a DecimalFormatProperties and a MacroProps.
    235 */
    236 class NumberPropertyMapper {
    237  public:
    238    /** Convenience method to create a NumberFormatter directly from Properties. */
    239    static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
    240                                             const DecimalFormatSymbols& symbols,
    241                                             DecimalFormatWarehouse& warehouse, UErrorCode& status);
    242 
    243    /** Convenience method to create a NumberFormatter directly from Properties. */
    244    static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
    245                                             const DecimalFormatSymbols& symbols,
    246                                             DecimalFormatWarehouse& warehouse,
    247                                             DecimalFormatProperties& exportedProperties,
    248                                             UErrorCode& status);
    249 
    250    /**
    251     * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties}
    252     * object. In other words, maps Properties to MacroProps. This function is used by the
    253     * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline.
    254     *
    255     * @param properties
    256     *            The property bag to be mapped.
    257     * @param symbols
    258     *            The symbols associated with the property bag.
    259     * @param exportedProperties
    260     *            A property bag in which to store validated properties. Used by some DecimalFormat
    261     *            getters.
    262     * @return A new MacroProps containing all of the information in the Properties.
    263     */
    264    static MacroProps oldToNew(const DecimalFormatProperties& properties,
    265                               const DecimalFormatSymbols& symbols, DecimalFormatWarehouse& warehouse,
    266                               DecimalFormatProperties* exportedProperties, UErrorCode& status);
    267 };
    268 
    269 } // namespace number::impl
    270 U_NAMESPACE_END
    271 
    272 #endif //__NUMBER_MAPPER_H__
    273 #endif /* #if !UCONFIG_NO_FORMATTING */