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 19U_NAMESPACE_BEGIN 20 21UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier) 22 23Quantifier::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 32Quantifier::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 41Quantifier::~Quantifier() { 42 delete matcher; 43} 44 45/** 46 * Implement UnicodeFunctor 47 */ 48UnicodeFunctor* 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 */ 56UnicodeMatcher* 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 63UMatchDegree 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 */ 98UnicodeString& 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 */ 125UBool Quantifier::matchesIndexValue(uint8_t v) const { 126 return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v); 127} 128 129/** 130 * Implement UnicodeMatcher 131 */ 132void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const { 133 if (maxCount > 0) { 134 matcher->toMatcher()->addMatchSetTo(toUnionTo); 135 } 136} 137 138/** 139 * Implement UnicodeFunctor 140 */ 141void Quantifier::setData(const TransliterationRuleData* d) { 142 matcher->setData(d); 143} 144 145U_NAMESPACE_END 146 147#endif /* #if !UCONFIG_NO_TRANSLITERATION */ 148 149//eof 150