]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/quant.cpp
ICU-6.2.4.tar.gz
[apple/icu.git] / icuSources / i18n / quant.cpp
1 /*
2 * Copyright (C) 2001-2003, International Business Machines Corporation and others. All Rights Reserved.
3 **********************************************************************
4 * Date Name Description
5 * 07/26/01 aliu Creation.
6 **********************************************************************
7 */
8
9 #include "unicode/utypes.h"
10
11 #if !UCONFIG_NO_TRANSLITERATION
12
13 #include "quant.h"
14 #include "unicode/unistr.h"
15 #include "util.h"
16
17 U_NAMESPACE_BEGIN
18
19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier)
20
21 Quantifier::Quantifier(UnicodeFunctor *adoptedMatcher,
22 uint32_t _minCount, uint32_t _maxCount) {
23 // assert(adopted != 0);
24 // assert(minCount <= maxCount);
25 matcher = adoptedMatcher;
26 this->minCount = _minCount;
27 this->maxCount = _maxCount;
28 }
29
30 Quantifier::Quantifier(const Quantifier& o) :
31 UnicodeFunctor(o),
32 UnicodeMatcher(o),
33 matcher(o.matcher->clone()),
34 minCount(o.minCount),
35 maxCount(o.maxCount)
36 {
37 }
38
39 Quantifier::~Quantifier() {
40 delete matcher;
41 }
42
43 /**
44 * Implement UnicodeFunctor
45 */
46 UnicodeFunctor* Quantifier::clone() const {
47 return new Quantifier(*this);
48 }
49
50 /**
51 * UnicodeFunctor API. Cast 'this' to a UnicodeMatcher* pointer
52 * and return the pointer.
53 */
54 UnicodeMatcher* Quantifier::toMatcher() const {
55 return (UnicodeMatcher*) this;
56 }
57
58 UMatchDegree Quantifier::matches(const Replaceable& text,
59 int32_t& offset,
60 int32_t limit,
61 UBool incremental) {
62 int32_t start = offset;
63 uint32_t count = 0;
64 while (count < maxCount) {
65 int32_t pos = offset;
66 UMatchDegree m = matcher->toMatcher()->matches(text, offset, limit, incremental);
67 if (m == U_MATCH) {
68 ++count;
69 if (pos == offset) {
70 // If offset has not moved we have a zero-width match.
71 // Don't keep matching it infinitely.
72 break;
73 }
74 } else if (incremental && m == U_PARTIAL_MATCH) {
75 return U_PARTIAL_MATCH;
76 } else {
77 break;
78 }
79 }
80 if (incremental && offset == limit) {
81 return U_PARTIAL_MATCH;
82 }
83 if (count >= minCount) {
84 return U_MATCH;
85 }
86 offset = start;
87 return U_MISMATCH;
88 }
89
90 /**
91 * Implement UnicodeMatcher
92 */
93 UnicodeString& Quantifier::toPattern(UnicodeString& result,
94 UBool escapeUnprintable) const {
95 result.truncate(0);
96 matcher->toMatcher()->toPattern(result, escapeUnprintable);
97 if (minCount == 0) {
98 if (maxCount == 1) {
99 return result.append((UChar)63); /*?*/
100 } else if (maxCount == MAX) {
101 return result.append((UChar)42); /***/
102 }
103 // else fall through
104 } else if (minCount == 1 && maxCount == MAX) {
105 return result.append((UChar)43); /*+*/
106 }
107 result.append((UChar)123); /*{*/
108 ICU_Utility::appendNumber(result, minCount);
109 result.append((UChar)44); /*,*/
110 if (maxCount != MAX) {
111 ICU_Utility::appendNumber(result, maxCount);
112 }
113 result.append((UChar)125); /*}*/
114 return result;
115 }
116
117 /**
118 * Implement UnicodeMatcher
119 */
120 UBool Quantifier::matchesIndexValue(uint8_t v) const {
121 return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
122 }
123
124 /**
125 * Implement UnicodeMatcher
126 */
127 void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
128 if (maxCount > 0) {
129 matcher->toMatcher()->addMatchSetTo(toUnionTo);
130 }
131 }
132
133 /**
134 * Implement UnicodeFunctor
135 */
136 void Quantifier::setData(const TransliterationRuleData* d) {
137 matcher->setData(d);
138 }
139
140 U_NAMESPACE_END
141
142 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
143
144 //eof