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
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier)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
Quantifier(const Quantifier & o)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
~Quantifier()41 Quantifier::~Quantifier() {
42 delete matcher;
43 }
44
45 /**
46 * Implement UnicodeFunctor
47 */
clone() const48 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 */
toMatcher() const56 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
matches(const Replaceable & text,int32_t & offset,int32_t limit,UBool incremental)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 */
toPattern(UnicodeString & result,UBool escapeUnprintable) const98 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 */
matchesIndexValue(uint8_t v) const125 UBool Quantifier::matchesIndexValue(uint8_t v) const {
126 return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
127 }
128
129 /**
130 * Implement UnicodeMatcher
131 */
addMatchSetTo(UnicodeSet & toUnionTo) const132 void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
133 if (maxCount > 0) {
134 matcher->toMatcher()->addMatchSetTo(toUnionTo);
135 }
136 }
137
138 /**
139 * Implement UnicodeFunctor
140 */
setData(const TransliterationRuleData * d)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