Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / icu / source / i18n / quant.cpp
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