• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **********************************************************************
3 *   Copyright (C) 2001-2008, 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     return (UnicodeMatcher*) this;
58 }
59 
matches(const Replaceable & text,int32_t & offset,int32_t limit,UBool incremental)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  */
toPattern(UnicodeString & result,UBool escapeUnprintable) const95 UnicodeString& Quantifier::toPattern(UnicodeString& result,
96                                      UBool escapeUnprintable) const {
97 	result.truncate(0);
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  */
matchesIndexValue(uint8_t v) const122 UBool Quantifier::matchesIndexValue(uint8_t v) const {
123     return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
124 }
125 
126 /**
127  * Implement UnicodeMatcher
128  */
addMatchSetTo(UnicodeSet & toUnionTo) const129 void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
130     if (maxCount > 0) {
131         matcher->toMatcher()->addMatchSetTo(toUnionTo);
132     }
133 }
134 
135 /**
136  * Implement UnicodeFunctor
137  */
setData(const TransliterationRuleData * d)138 void Quantifier::setData(const TransliterationRuleData* d) {
139 		matcher->setData(d);
140 }
141 
142 U_NAMESPACE_END
143 
144 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
145 
146 //eof
147