source: icXML/icXML-devel/src/xercesc/util/regx/Token.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 6 years ago

Original Xerces files with import mods for icxercesc

File size: 9.8 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: Token.cpp 678879 2008-07-22 20:05:05Z amassari $
20 */
21
22// ---------------------------------------------------------------------------
23//  Includes
24// ---------------------------------------------------------------------------
25#include <xercesc/util/regx/RangeToken.hpp>
26#include <icxercesc/util/regx/RegularExpression.hpp>
27#include <xercesc/util/regx/RegxUtil.hpp>
28
29XERCES_CPP_NAMESPACE_BEGIN
30
31// ---------------------------------------------------------------------------
32//  Static member data initialization
33// ---------------------------------------------------------------------------
34const XMLInt32         Token::UTF16_MAX = 0x10FFFF;
35
36// ---------------------------------------------------------------------------
37//  Token: Constructors and Destructors
38// ---------------------------------------------------------------------------
39Token::Token(const Token::tokType tkType
40             , MemoryManager* const manager) 
41             : fTokenType(tkType) 
42             , fMemoryManager(manager)
43{
44
45}
46
47
48Token::~Token() {
49
50}
51
52// ---------------------------------------------------------------------------
53//  Token: Getter mthods
54// ---------------------------------------------------------------------------
55XMLSize_t Token::getMinLength() const {
56
57    switch (fTokenType) {
58
59    case T_CONCAT:
60        {
61            XMLSize_t sum = 0;
62            XMLSize_t childSize = size();
63
64            for (XMLSize_t i=0; i<childSize; i++) {
65                sum += getChild(i)->getMinLength();
66            }
67            return sum;
68        }
69    case T_UNION:
70        {
71            XMLSize_t childSize = size();
72
73            if (childSize == 0) {
74                return 0;
75            }
76            XMLSize_t ret = getChild(0)->getMinLength();
77
78            for (XMLSize_t i=1; i < childSize; i++) {
79
80                XMLSize_t min = getChild(i)->getMinLength();
81                if (min < ret)
82                    ret = min;
83            }
84            return ret;
85        }
86    case T_CLOSURE:
87    case T_NONGREEDYCLOSURE:
88        if (getMin() >= 0)
89            return getMin() * getChild(0)->getMinLength();
90
91        return 0;
92    case T_EMPTY:
93    case T_ANCHOR:
94        return 0;
95    case T_DOT:
96    case T_CHAR:
97    case T_RANGE:
98    case T_NRANGE:
99        return 1;
100    case T_PAREN:
101        return getChild(0)->getMinLength();
102    case T_BACKREFERENCE:
103        return 0; // *****  - REVISIT
104    case T_STRING:
105        return XMLString::stringLen(getString());
106//    default:
107//        throw;
108    }
109
110    // We should not get here, but we have it to make some compilers happy
111    return (XMLSize_t)-1;
112}
113
114
115int Token::getMaxLength() const {
116
117    switch (fTokenType) {
118
119    case T_CONCAT:
120        {
121            int sum = 0;
122            XMLSize_t childSize = size();
123
124            for (XMLSize_t i=0; i<childSize; i++) {
125
126                int val = getChild(i)->getMaxLength();
127
128                if (val < 0){
129                    return -1;
130                }
131                sum += val;
132            }
133            return sum;
134        }
135    case T_UNION:
136        {
137            XMLSize_t childSize = size();
138
139            if (childSize == 0)
140                return 0;
141
142            int ret = getChild(0)->getMaxLength();
143
144            for (XMLSize_t i = 1; ret > 0 && i < childSize; i++) {
145
146                int max = getChild(i)->getMaxLength();
147
148                if (max < 0) {
149
150                    ret = -1;
151                    break;
152                }
153
154                if (max > ret)
155                    ret = max;
156            }
157            return ret;
158        }
159    case T_CLOSURE:
160    case T_NONGREEDYCLOSURE:
161        if (getMax() >= 0) {
162            return getMax() * getChild(0)->getMaxLength();
163        }
164        return -1;
165    case T_EMPTY:
166    case T_ANCHOR:
167        return 0;
168    case T_CHAR:
169        return 1;
170    case T_DOT:
171    case T_RANGE:
172    case T_NRANGE:
173        return 2;
174    case T_PAREN:
175        return getChild(0)->getMaxLength();
176    case T_BACKREFERENCE:
177        return -1; // REVISIT
178    case T_STRING:
179        return (int)XMLString::stringLen(getString());
180//    default:
181//        throw; //ThrowXML(RuntimeException, ...)
182    } // end switch
183
184    return -1;
185}
186
187// ---------------------------------------------------------------------------
188//  Token: Helper mthods
189// ---------------------------------------------------------------------------
190Token::firstCharacterOptions Token::analyzeFirstCharacter(RangeToken* const rangeTok,
191                                                          const int options,
192                                                          TokenFactory* const tokFactory)
193{
194    switch(fTokenType) {
195    case T_CONCAT:
196        {
197            firstCharacterOptions ret = FC_CONTINUE;
198            for (XMLSize_t i=0; i<size(); i++) {
199
200                Token* tok = getChild(i);
201                if (tok
202                    && (ret=tok->analyzeFirstCharacter(rangeTok,
203                                    options, tokFactory))!= FC_CONTINUE)
204                    break;
205            }
206            return ret;
207        }
208    case T_UNION:
209        {
210            XMLSize_t childSize = size();
211            if (childSize == 0)
212                return FC_CONTINUE;
213
214            firstCharacterOptions ret = FC_CONTINUE;
215            bool hasEmpty = false;
216
217            for (XMLSize_t i=0; i < childSize; i++) {
218
219                ret = getChild(i)->analyzeFirstCharacter(rangeTok, options, tokFactory);
220
221                if (ret == FC_ANY)
222                    break;
223                else
224                    hasEmpty = true;
225            }
226            return hasEmpty ? FC_CONTINUE : ret;
227        }
228    case T_CLOSURE:
229    case T_NONGREEDYCLOSURE:
230        {
231            Token* tok = getChild(0);
232            if (tok)
233                tok->analyzeFirstCharacter(rangeTok, options, tokFactory);
234            return FC_CONTINUE;
235        }
236    case T_DOT:
237    return FC_ANY;
238    case T_EMPTY:
239    case T_ANCHOR:
240        return FC_CONTINUE;
241    case T_CHAR:
242        {
243            XMLInt32 ch = getChar();
244            rangeTok->addRange(ch, ch);
245            if (ch < 0x1000 && isSet(options,RegularExpression::IGNORE_CASE)) {
246                //REVISIT
247            }
248        }
249        return FC_TERMINAL;
250    case T_RANGE:
251        {
252            if (isSet(options, RegularExpression::IGNORE_CASE)) {
253                rangeTok->mergeRanges(((RangeToken*)
254                                         this)->getCaseInsensitiveToken(tokFactory));
255            }
256            else {
257                rangeTok->mergeRanges(this);
258            }
259            return FC_TERMINAL;
260        }
261    case T_NRANGE:
262        {
263            if (isSet(options, RegularExpression::IGNORE_CASE)) {
264
265                RangeToken* caseITok = (((RangeToken*)
266                                           this)->getCaseInsensitiveToken(tokFactory));
267                rangeTok->mergeRanges(RangeToken::complementRanges(caseITok, tokFactory, fMemoryManager));
268            }
269            else {
270                rangeTok->mergeRanges(
271                    RangeToken::complementRanges((RangeToken*) this, tokFactory, fMemoryManager));
272            }
273        }
274    case T_PAREN:
275        {
276            Token* tok = getChild(0);
277            if (tok)
278                return tok->analyzeFirstCharacter(rangeTok,options, tokFactory);
279        }
280    case T_BACKREFERENCE:
281        rangeTok->addRange(0, UTF16_MAX);
282        return FC_ANY;
283    case T_STRING:
284        {
285            const XMLCh* str = getString();
286            XMLInt32 ch = str[0];
287
288            if (RegxUtil::isHighSurrogate((XMLCh) ch)) {
289            }
290
291            rangeTok->addRange(ch, ch);
292            if (ch<0x10000 && isSet(options,RegularExpression::IGNORE_CASE)) {
293                //REVISIT
294            }
295        }
296        return FC_TERMINAL;
297//    default:
298//        throw;
299    }
300
301    return FC_CONTINUE;
302}
303
304
305Token* Token::findFixedString(int options, int& outOptions) {
306
307    switch(fTokenType) {
308
309    case T_CHAR:
310        return 0;
311    case T_STRING:
312        outOptions = options;
313        return this;
314    case T_UNION:
315    case T_CLOSURE:
316    case T_NONGREEDYCLOSURE:
317    case T_EMPTY:
318    case T_ANCHOR:
319    case T_RANGE:
320    case T_NRANGE:
321    case T_DOT:
322    case T_BACKREFERENCE:
323        return 0;
324    case T_PAREN:
325        return getChild(0)->findFixedString(options, outOptions);
326    case T_CONCAT:
327        {
328            Token* prevTok = 0;
329            int prevOptions = 0;
330
331            for (XMLSize_t i=0; i<size(); i++) {
332
333                Token* tok = getChild(i)->findFixedString(options, outOptions);
334
335                if (prevTok == 0 || prevTok->isShorterThan(tok)) {
336
337                    prevTok = tok;
338                    prevOptions = outOptions;
339                }
340            }
341
342            outOptions = prevOptions;
343            return prevTok;
344        }
345    } // end switch
346
347    return 0;
348}
349
350
351bool Token::isShorterThan(Token* const tok) {
352
353    if (tok == 0)
354        return false;
355
356    if (getTokenType() != T_STRING && tok->getTokenType() != T_STRING)
357        return false; //Should we throw an exception?
358
359    XMLSize_t length = XMLString::stringLen(getString());
360    XMLSize_t tokLength = XMLString::stringLen(tok->getString());
361
362    return length < tokLength;
363}
364
365XERCES_CPP_NAMESPACE_END
366
367/**
368  *    End of file Token.cpp
369  */
Note: See TracBrowser for help on using the repository browser.