|
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 |