Home | History | Annotate | Download | only in i18n
      1 /*
      2 **********************************************************************
      3 *   Copyright (C) 2001-2012, 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   Quantifier  *nonconst_this = const_cast<Quantifier *>(this);
     58   UnicodeMatcher *nonconst_base = static_cast<UnicodeMatcher *>(nonconst_this);
     59 
     60   return nonconst_base;
     61 }
     62 
     63 UMatchDegree Quantifier::matches(const Replaceable& text,
     64                                  int32_t& offset,
     65                                  int32_t limit,
     66                                  UBool incremental) {
     67     int32_t start = offset;
     68     uint32_t count = 0;
     69     while (count < maxCount) {
     70         int32_t pos = offset;
     71         UMatchDegree m = matcher->toMatcher()->matches(text, offset, limit, incremental);
     72         if (m == U_MATCH) {
     73             ++count;
     74             if (pos == offset) {
     75                 // If offset has not moved we have a zero-width match.
     76                 // Don't keep matching it infinitely.
     77                 break;
     78             }
     79         } else if (incremental && m == U_PARTIAL_MATCH) {
     80             return U_PARTIAL_MATCH;
     81         } else {
     82             break;
     83         }
     84     }
     85     if (incremental && offset == limit) {
     86         return U_PARTIAL_MATCH;
     87     }
     88     if (count >= minCount) {
     89         return U_MATCH;
     90     }
     91     offset = start;
     92     return U_MISMATCH;
     93 }
     94 
     95 /**
     96  * Implement UnicodeMatcher
     97  */
     98 UnicodeString& Quantifier::toPattern(UnicodeString& result,
     99                                      UBool escapeUnprintable) const {
    100 	result.truncate(0);
    101     matcher->toMatcher()->toPattern(result, escapeUnprintable);
    102     if (minCount == 0) {
    103         if (maxCount == 1) {
    104             return result.append((UChar)63); /*?*/
    105         } else if (maxCount == MAX) {
    106             return result.append((UChar)42); /***/
    107         }
    108         // else fall through
    109     } else if (minCount == 1 && maxCount == MAX) {
    110         return result.append((UChar)43); /*+*/
    111     }
    112     result.append((UChar)123); /*{*/
    113     ICU_Utility::appendNumber(result, minCount);
    114     result.append((UChar)44); /*,*/
    115     if (maxCount != MAX) {
    116         ICU_Utility::appendNumber(result, maxCount);
    117     }
    118     result.append((UChar)125); /*}*/
    119     return result;
    120 }
    121 
    122 /**
    123  * Implement UnicodeMatcher
    124  */
    125 UBool Quantifier::matchesIndexValue(uint8_t v) const {
    126     return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
    127 }
    128 
    129 /**
    130  * Implement UnicodeMatcher
    131  */
    132 void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
    133     if (maxCount > 0) {
    134         matcher->toMatcher()->addMatchSetTo(toUnionTo);
    135     }
    136 }
    137 
    138 /**
    139  * Implement UnicodeFunctor
    140  */
    141 void Quantifier::setData(const TransliterationRuleData* d) {
    142 		matcher->setData(d);
    143 }
    144 
    145 U_NAMESPACE_END
    146 
    147 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
    148 
    149 //eof
    150