1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/quant.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,149 @@ 1.4 +/* 1.5 +********************************************************************** 1.6 +* Copyright (C) 2001-2012, International Business Machines 1.7 +* Corporation and others. All Rights Reserved. 1.8 +********************************************************************** 1.9 +* Date Name Description 1.10 +* 07/26/01 aliu Creation. 1.11 +********************************************************************** 1.12 +*/ 1.13 + 1.14 +#include "unicode/utypes.h" 1.15 + 1.16 +#if !UCONFIG_NO_TRANSLITERATION 1.17 + 1.18 +#include "quant.h" 1.19 +#include "unicode/unistr.h" 1.20 +#include "util.h" 1.21 + 1.22 +U_NAMESPACE_BEGIN 1.23 + 1.24 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier) 1.25 + 1.26 +Quantifier::Quantifier(UnicodeFunctor *adoptedMatcher, 1.27 + uint32_t _minCount, uint32_t _maxCount) { 1.28 + // assert(adopted != 0); 1.29 + // assert(minCount <= maxCount); 1.30 + matcher = adoptedMatcher; 1.31 + this->minCount = _minCount; 1.32 + this->maxCount = _maxCount; 1.33 +} 1.34 + 1.35 +Quantifier::Quantifier(const Quantifier& o) : 1.36 + UnicodeFunctor(o), 1.37 + UnicodeMatcher(o), 1.38 + matcher(o.matcher->clone()), 1.39 + minCount(o.minCount), 1.40 + maxCount(o.maxCount) 1.41 +{ 1.42 +} 1.43 + 1.44 +Quantifier::~Quantifier() { 1.45 + delete matcher; 1.46 +} 1.47 + 1.48 +/** 1.49 + * Implement UnicodeFunctor 1.50 + */ 1.51 +UnicodeFunctor* Quantifier::clone() const { 1.52 + return new Quantifier(*this); 1.53 +} 1.54 + 1.55 +/** 1.56 + * UnicodeFunctor API. Cast 'this' to a UnicodeMatcher* pointer 1.57 + * and return the pointer. 1.58 + */ 1.59 +UnicodeMatcher* Quantifier::toMatcher() const { 1.60 + Quantifier *nonconst_this = const_cast<Quantifier *>(this); 1.61 + UnicodeMatcher *nonconst_base = static_cast<UnicodeMatcher *>(nonconst_this); 1.62 + 1.63 + return nonconst_base; 1.64 +} 1.65 + 1.66 +UMatchDegree Quantifier::matches(const Replaceable& text, 1.67 + int32_t& offset, 1.68 + int32_t limit, 1.69 + UBool incremental) { 1.70 + int32_t start = offset; 1.71 + uint32_t count = 0; 1.72 + while (count < maxCount) { 1.73 + int32_t pos = offset; 1.74 + UMatchDegree m = matcher->toMatcher()->matches(text, offset, limit, incremental); 1.75 + if (m == U_MATCH) { 1.76 + ++count; 1.77 + if (pos == offset) { 1.78 + // If offset has not moved we have a zero-width match. 1.79 + // Don't keep matching it infinitely. 1.80 + break; 1.81 + } 1.82 + } else if (incremental && m == U_PARTIAL_MATCH) { 1.83 + return U_PARTIAL_MATCH; 1.84 + } else { 1.85 + break; 1.86 + } 1.87 + } 1.88 + if (incremental && offset == limit) { 1.89 + return U_PARTIAL_MATCH; 1.90 + } 1.91 + if (count >= minCount) { 1.92 + return U_MATCH; 1.93 + } 1.94 + offset = start; 1.95 + return U_MISMATCH; 1.96 +} 1.97 + 1.98 +/** 1.99 + * Implement UnicodeMatcher 1.100 + */ 1.101 +UnicodeString& Quantifier::toPattern(UnicodeString& result, 1.102 + UBool escapeUnprintable) const { 1.103 + result.truncate(0); 1.104 + matcher->toMatcher()->toPattern(result, escapeUnprintable); 1.105 + if (minCount == 0) { 1.106 + if (maxCount == 1) { 1.107 + return result.append((UChar)63); /*?*/ 1.108 + } else if (maxCount == MAX) { 1.109 + return result.append((UChar)42); /***/ 1.110 + } 1.111 + // else fall through 1.112 + } else if (minCount == 1 && maxCount == MAX) { 1.113 + return result.append((UChar)43); /*+*/ 1.114 + } 1.115 + result.append((UChar)123); /*{*/ 1.116 + ICU_Utility::appendNumber(result, minCount); 1.117 + result.append((UChar)44); /*,*/ 1.118 + if (maxCount != MAX) { 1.119 + ICU_Utility::appendNumber(result, maxCount); 1.120 + } 1.121 + result.append((UChar)125); /*}*/ 1.122 + return result; 1.123 +} 1.124 + 1.125 +/** 1.126 + * Implement UnicodeMatcher 1.127 + */ 1.128 +UBool Quantifier::matchesIndexValue(uint8_t v) const { 1.129 + return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v); 1.130 +} 1.131 + 1.132 +/** 1.133 + * Implement UnicodeMatcher 1.134 + */ 1.135 +void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const { 1.136 + if (maxCount > 0) { 1.137 + matcher->toMatcher()->addMatchSetTo(toUnionTo); 1.138 + } 1.139 +} 1.140 + 1.141 +/** 1.142 + * Implement UnicodeFunctor 1.143 + */ 1.144 +void Quantifier::setData(const TransliterationRuleData* d) { 1.145 + matcher->setData(d); 1.146 +} 1.147 + 1.148 +U_NAMESPACE_END 1.149 + 1.150 +#endif /* #if !UCONFIG_NO_TRANSLITERATION */ 1.151 + 1.152 +//eof