Home | History | Annotate | Download | only in i18n
      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 UnicodeFunctor* 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((UChar)63); /*?*/
    107         } else if (maxCount == MAX) {
    108             return result.append((UChar)42); /***/
    109         }
    110         // else fall through
    111     } else if (minCount == 1 && maxCount == MAX) {
    112         return result.append((UChar)43); /*+*/
    113     }
    114     result.append((UChar)123); /*{*/
    115     ICU_Utility::appendNumber(result, minCount);
    116     result.append((UChar)44); /*,*/
    117     if (maxCount != MAX) {
    118         ICU_Utility::appendNumber(result, maxCount);
    119     }
    120     result.append((UChar)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
    152