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