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