tor-browser

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

numparse_symbols.cpp (6249B)


      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 "numparse_types.h"
     13 #include "numparse_symbols.h"
     14 #include "numparse_utils.h"
     15 #include "string_segment.h"
     16 
     17 using namespace icu;
     18 using namespace icu::numparse;
     19 using namespace icu::numparse::impl;
     20 
     21 
     22 SymbolMatcher::SymbolMatcher(const UnicodeString& symbolString, unisets::Key key) {
     23    fUniSet = unisets::get(key);
     24    if (fUniSet->contains(symbolString)) {
     25        fString.setToBogus();
     26    } else {
     27        fString = symbolString;
     28    }
     29 }
     30 
     31 const UnicodeSet* SymbolMatcher::getSet() const {
     32    return fUniSet;
     33 }
     34 
     35 bool SymbolMatcher::match(StringSegment& segment, ParsedNumber& result, UErrorCode&) const {
     36    // Smoke test first; this matcher might be disabled.
     37    if (isDisabled(result)) {
     38        return false;
     39    }
     40 
     41    // Test the string first in order to consume trailing chars greedily.
     42    int overlap = 0;
     43    if (!fString.isEmpty()) {
     44        overlap = segment.getCommonPrefixLength(fString);
     45        if (overlap == fString.length()) {
     46            segment.adjustOffset(fString.length());
     47            accept(segment, result);
     48            return false;
     49        }
     50    }
     51 
     52    int cp = segment.getCodePoint();
     53    if (cp != -1 && fUniSet->contains(cp)) {
     54        segment.adjustOffset(U16_LENGTH(cp));
     55        accept(segment, result);
     56        return false;
     57    }
     58 
     59    return overlap == segment.length();
     60 }
     61 
     62 bool SymbolMatcher::smokeTest(const StringSegment& segment) const {
     63    return segment.startsWith(*fUniSet) || segment.startsWith(fString);
     64 }
     65 
     66 UnicodeString SymbolMatcher::toString() const {
     67    // TODO: Customize output for each symbol
     68    return u"<Symbol>";
     69 }
     70 
     71 
     72 IgnorablesMatcher::IgnorablesMatcher(parse_flags_t parseFlags) :
     73        SymbolMatcher(
     74            {},
     75            (0 != (parseFlags & PARSE_FLAG_STRICT_IGNORABLES)) ?
     76                unisets::STRICT_IGNORABLES :
     77                unisets::DEFAULT_IGNORABLES) {
     78 }
     79 
     80 bool IgnorablesMatcher::isFlexible() const {
     81    return true;
     82 }
     83 
     84 UnicodeString IgnorablesMatcher::toString() const {
     85    return u"<Ignorables>";
     86 }
     87 
     88 bool IgnorablesMatcher::isDisabled(const ParsedNumber&) const {
     89    return false;
     90 }
     91 
     92 void IgnorablesMatcher::accept(StringSegment&, ParsedNumber&) const {
     93    // No-op
     94 }
     95 
     96 
     97 InfinityMatcher::InfinityMatcher(const DecimalFormatSymbols& dfs)
     98        : SymbolMatcher(dfs.getConstSymbol(DecimalFormatSymbols::kInfinitySymbol), unisets::INFINITY_SIGN) {
     99 }
    100 
    101 bool InfinityMatcher::isDisabled(const ParsedNumber& result) const {
    102    return 0 != (result.flags & FLAG_INFINITY);
    103 }
    104 
    105 void InfinityMatcher::accept(StringSegment& segment, ParsedNumber& result) const {
    106    result.flags |= FLAG_INFINITY;
    107    result.setCharsConsumed(segment);
    108 }
    109 
    110 
    111 MinusSignMatcher::MinusSignMatcher(const DecimalFormatSymbols& dfs, bool allowTrailing)
    112        : SymbolMatcher(dfs.getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol), unisets::MINUS_SIGN),
    113          fAllowTrailing(allowTrailing) {
    114 }
    115 
    116 bool MinusSignMatcher::isDisabled(const ParsedNumber& result) const {
    117    return !fAllowTrailing && result.seenNumber();
    118 }
    119 
    120 void MinusSignMatcher::accept(StringSegment& segment, ParsedNumber& result) const {
    121    result.flags |= FLAG_NEGATIVE;
    122    result.setCharsConsumed(segment);
    123 }
    124 
    125 
    126 NanMatcher::NanMatcher(const DecimalFormatSymbols& dfs)
    127        : SymbolMatcher(dfs.getConstSymbol(DecimalFormatSymbols::kNaNSymbol), unisets::EMPTY) {
    128 }
    129 
    130 bool NanMatcher::isDisabled(const ParsedNumber& result) const {
    131    return result.seenNumber();
    132 }
    133 
    134 void NanMatcher::accept(StringSegment& segment, ParsedNumber& result) const {
    135    result.flags |= FLAG_NAN;
    136    result.setCharsConsumed(segment);
    137 }
    138 
    139 
    140 PaddingMatcher::PaddingMatcher(const UnicodeString& padString)
    141        : SymbolMatcher(padString, unisets::EMPTY) {}
    142 
    143 bool PaddingMatcher::isFlexible() const {
    144    return true;
    145 }
    146 
    147 bool PaddingMatcher::isDisabled(const ParsedNumber&) const {
    148    return false;
    149 }
    150 
    151 void PaddingMatcher::accept(StringSegment&, ParsedNumber&) const {
    152    // No-op
    153 }
    154 
    155 
    156 PercentMatcher::PercentMatcher(const DecimalFormatSymbols& dfs)
    157        : SymbolMatcher(dfs.getConstSymbol(DecimalFormatSymbols::kPercentSymbol), unisets::PERCENT_SIGN) {
    158 }
    159 
    160 bool PercentMatcher::isDisabled(const ParsedNumber& result) const {
    161    return 0 != (result.flags & FLAG_PERCENT);
    162 }
    163 
    164 void PercentMatcher::accept(StringSegment& segment, ParsedNumber& result) const {
    165    result.flags |= FLAG_PERCENT;
    166    result.setCharsConsumed(segment);
    167 }
    168 
    169 
    170 PermilleMatcher::PermilleMatcher(const DecimalFormatSymbols& dfs)
    171        : SymbolMatcher(dfs.getConstSymbol(DecimalFormatSymbols::kPerMillSymbol), unisets::PERMILLE_SIGN) {
    172 }
    173 
    174 bool PermilleMatcher::isDisabled(const ParsedNumber& result) const {
    175    return 0 != (result.flags & FLAG_PERMILLE);
    176 }
    177 
    178 void PermilleMatcher::accept(StringSegment& segment, ParsedNumber& result) const {
    179    result.flags |= FLAG_PERMILLE;
    180    result.setCharsConsumed(segment);
    181 }
    182 
    183 
    184 PlusSignMatcher::PlusSignMatcher(const DecimalFormatSymbols& dfs, bool allowTrailing)
    185        : SymbolMatcher(dfs.getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol), unisets::PLUS_SIGN),
    186          fAllowTrailing(allowTrailing) {
    187 }
    188 
    189 bool PlusSignMatcher::isDisabled(const ParsedNumber& result) const {
    190    return !fAllowTrailing && result.seenNumber();
    191 }
    192 
    193 void PlusSignMatcher::accept(StringSegment& segment, ParsedNumber& result) const {
    194    result.setCharsConsumed(segment);
    195 }
    196 
    197 
    198 ApproximatelySignMatcher::ApproximatelySignMatcher(
    199        const DecimalFormatSymbols& dfs, bool allowTrailing) :
    200            SymbolMatcher(
    201                dfs.getConstSymbol(DecimalFormatSymbols::kApproximatelySignSymbol),
    202                unisets::APPROXIMATELY_SIGN),
    203            fAllowTrailing(allowTrailing) {
    204 }
    205 
    206 bool ApproximatelySignMatcher::isDisabled(const ParsedNumber& result) const {
    207    return !fAllowTrailing && result.seenNumber();
    208 }
    209 
    210 void ApproximatelySignMatcher::accept(StringSegment& segment, ParsedNumber& result) const {
    211    result.setCharsConsumed(segment);
    212 }
    213 
    214 
    215 #endif /* #if !UCONFIG_NO_FORMATTING */