]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/quant.cpp
ICU-6.2.14.tar.gz
[apple/icu.git] / icuSources / i18n / quant.cpp
CommitLineData
b75a7d8f 1/*
374ca955 2* Copyright (C) 2001-2003, International Business Machines Corporation and others. All Rights Reserved.
b75a7d8f
A
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
17U_NAMESPACE_BEGIN
18
374ca955 19UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier)
b75a7d8f
A
20
21Quantifier::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
30Quantifier::Quantifier(const Quantifier& o) :
31 UnicodeFunctor(o),
374ca955 32 UnicodeMatcher(o),
b75a7d8f
A
33 matcher(o.matcher->clone()),
34 minCount(o.minCount),
35 maxCount(o.maxCount)
36{
37}
38
39Quantifier::~Quantifier() {
40 delete matcher;
41}
42
43/**
44 * Implement UnicodeFunctor
45 */
46UnicodeFunctor* 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 */
54UnicodeMatcher* Quantifier::toMatcher() const {
55 return (UnicodeMatcher*) this;
56}
57
58UMatchDegree 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 */
93UnicodeString& 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 */
120UBool Quantifier::matchesIndexValue(uint8_t v) const {
121 return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
122}
123
124/**
125 * Implement UnicodeMatcher
126 */
127void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
128 if (maxCount > 0) {
374ca955 129 matcher->toMatcher()->addMatchSetTo(toUnionTo);
b75a7d8f
A
130 }
131}
132
133/**
134 * Implement UnicodeFunctor
135 */
136void Quantifier::setData(const TransliterationRuleData* d) {
137 matcher->setData(d);
138}
139
140U_NAMESPACE_END
141
142#endif /* #if !UCONFIG_NO_TRANSLITERATION */
143
144//eof