tor-browser

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

quant.cpp (4152B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 **********************************************************************
      5 *   Copyright (C) 2001-2012, International Business Machines
      6 *   Corporation and others.  All Rights Reserved.
      7 **********************************************************************
      8 *   Date        Name        Description
      9 *   07/26/01    aliu        Creation.
     10 **********************************************************************
     11 */
     12 
     13 #include "unicode/utypes.h"
     14 
     15 #if !UCONFIG_NO_TRANSLITERATION
     16 
     17 #include "quant.h"
     18 #include "unicode/unistr.h"
     19 #include "util.h"
     20 
     21 U_NAMESPACE_BEGIN
     22 
     23 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier)
     24 
     25 Quantifier::Quantifier(UnicodeFunctor *adoptedMatcher,
     26                       uint32_t _minCount, uint32_t _maxCount) {
     27    // assert(adopted != 0);
     28    // assert(minCount <= maxCount);
     29    matcher = adoptedMatcher;
     30    this->minCount = _minCount;
     31    this->maxCount = _maxCount;
     32 }
     33 
     34 Quantifier::Quantifier(const Quantifier& o) :
     35    UnicodeFunctor(o),
     36    UnicodeMatcher(o),
     37    matcher(o.matcher->clone()),
     38    minCount(o.minCount),
     39    maxCount(o.maxCount)
     40 {
     41 }
     42 
     43 Quantifier::~Quantifier() {
     44    delete matcher;
     45 }
     46 
     47 /**
     48 * Implement UnicodeFunctor
     49 */
     50 Quantifier* Quantifier::clone() const {
     51    return new Quantifier(*this);
     52 }
     53 
     54 /**
     55 * UnicodeFunctor API.  Cast 'this' to a UnicodeMatcher* pointer
     56 * and return the pointer.
     57 */
     58 UnicodeMatcher* Quantifier::toMatcher() const {
     59  Quantifier  *nonconst_this = const_cast<Quantifier *>(this);
     60  UnicodeMatcher *nonconst_base = static_cast<UnicodeMatcher *>(nonconst_this);
     61  
     62  return nonconst_base;
     63 }
     64 
     65 UMatchDegree Quantifier::matches(const Replaceable& text,
     66                                 int32_t& offset,
     67                                 int32_t limit,
     68                                 UBool incremental) {
     69    int32_t start = offset;
     70    uint32_t count = 0;
     71    while (count < maxCount) {
     72        int32_t pos = offset;
     73        UMatchDegree m = matcher->toMatcher()->matches(text, offset, limit, incremental);
     74        if (m == U_MATCH) {
     75            ++count;
     76            if (pos == offset) {
     77                // If offset has not moved we have a zero-width match.
     78                // Don't keep matching it infinitely.
     79                break;
     80            }
     81        } else if (incremental && m == U_PARTIAL_MATCH) {
     82            return U_PARTIAL_MATCH;
     83        } else {
     84            break;
     85        }
     86    }
     87    if (incremental && offset == limit) {
     88        return U_PARTIAL_MATCH;
     89    }
     90    if (count >= minCount) {
     91        return U_MATCH;
     92    }
     93    offset = start;
     94    return U_MISMATCH;
     95 }
     96 
     97 /**
     98 * Implement UnicodeMatcher
     99 */
    100 UnicodeString& Quantifier::toPattern(UnicodeString& result,
    101                                     UBool escapeUnprintable) const {
    102 result.truncate(0);
    103    matcher->toMatcher()->toPattern(result, escapeUnprintable);
    104    if (minCount == 0) {
    105        if (maxCount == 1) {
    106            return result.append(static_cast<char16_t>(63)); /*?*/
    107        } else if (maxCount == MAX) {
    108            return result.append(static_cast<char16_t>(42)); /***/
    109        }
    110        // else fall through
    111    } else if (minCount == 1 && maxCount == MAX) {
    112        return result.append(static_cast<char16_t>(43)); /*+*/
    113    }
    114    result.append(static_cast<char16_t>(123)); /*{*/
    115    ICU_Utility::appendNumber(result, minCount);
    116    result.append(static_cast<char16_t>(44)); /*,*/
    117    if (maxCount != MAX) {
    118        ICU_Utility::appendNumber(result, maxCount);
    119    }
    120    result.append(static_cast<char16_t>(125)); /*}*/
    121    return result;
    122 }
    123 
    124 /**
    125 * Implement UnicodeMatcher
    126 */
    127 UBool Quantifier::matchesIndexValue(uint8_t v) const {
    128    return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
    129 }
    130 
    131 /**
    132 * Implement UnicodeMatcher
    133 */
    134 void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
    135    if (maxCount > 0) {
    136        matcher->toMatcher()->addMatchSetTo(toUnionTo);
    137    }
    138 }
    139 
    140 /**
    141 * Implement UnicodeFunctor
    142 */
    143 void Quantifier::setData(const TransliterationRuleData* d) {
    144 	matcher->setData(d);
    145 }
    146 
    147 U_NAMESPACE_END
    148 
    149 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
    150 
    151 //eof