source: icXML/icXML-devel/src/xercesc/util/regx/BMPattern.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: 6.2 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: BMPattern.cpp 678879 2008-07-22 20:05:05Z amassari $
20 */
21
22// ---------------------------------------------------------------------------
23//  Includes
24// ---------------------------------------------------------------------------
25#include <xercesc/util/regx/BMPattern.hpp>
26#include <icxercesc/util/XMLString.hpp>
27#include <xercesc/util/Janitor.hpp>
28#include <xercesc/framework/MemoryManager.hpp>
29#include <xercesc/util/OutOfMemoryException.hpp>
30
31XERCES_CPP_NAMESPACE_BEGIN
32
33// ---------------------------------------------------------------------------
34//  BMPattern: Constructors
35// ---------------------------------------------------------------------------
36
37typedef JanitorMemFunCall<BMPattern>    CleanupType;
38
39BMPattern::BMPattern( const XMLCh*         const pattern
40                    ,       bool                 ignoreCase
41                    ,       MemoryManager* const manager) :
42
43    fIgnoreCase(ignoreCase)
44    , fShiftTableLen(256)
45    , fShiftTable(0)
46    , fPattern(0)
47    , fUppercasePattern(0)
48    , fMemoryManager(manager)
49{
50    CleanupType cleanup(this, &BMPattern::cleanUp);
51
52    try {
53        fPattern = XMLString::replicate(pattern, fMemoryManager);
54        initialize();
55    }
56    catch(const OutOfMemoryException&)
57    {
58        cleanup.release();
59
60        throw;
61    }
62
63    cleanup.release();
64}
65
66BMPattern::BMPattern( const XMLCh*         const pattern
67                    ,       int                  tableSize
68                    ,       bool                 ignoreCase
69                    ,       MemoryManager* const manager) :
70
71    fIgnoreCase(ignoreCase)
72    , fShiftTableLen(tableSize)
73    , fShiftTable(0)
74    , fPattern(0)
75    , fUppercasePattern(0)
76    , fMemoryManager(manager)
77{
78    CleanupType cleanup(this, &BMPattern::cleanUp);
79
80    try {
81        fPattern = XMLString::replicate(pattern, fMemoryManager);
82        initialize();
83    }
84    catch(const OutOfMemoryException&)
85    {
86        cleanup.release();
87
88        throw;
89    }
90
91    cleanup.release();
92}
93
94BMPattern::~BMPattern() {
95
96    cleanUp();
97}
98
99// ---------------------------------------------------------------------------
100//  BMPattern: matches methods
101// ---------------------------------------------------------------------------
102int BMPattern::matches(const XMLCh* const content, XMLSize_t start, XMLSize_t limit) const {
103
104    const XMLSize_t patternLen = XMLString::stringLen(fPattern);
105    // Uppercase Content
106    XMLCh* ucContent = 0;
107
108    if (patternLen == 0)
109        return (int)start;
110
111    if (fIgnoreCase) {
112       
113        ucContent = XMLString::replicate(content, fMemoryManager);
114        XMLString::upperCase(ucContent);
115    }
116
117    ArrayJanitor<XMLCh> janUCContent(ucContent, fMemoryManager);
118
119    XMLSize_t index = start + patternLen;
120
121    while (index <= limit) {
122
123        XMLSize_t patternIndex = patternLen;
124        XMLSize_t nIndex = index + 1;
125        XMLCh ch = 0;
126
127        while (patternIndex > 0) {
128
129            ch = content[--index];
130
131            if (ch != fPattern[--patternIndex]) {
132
133                // No match, so we will break. But first we have
134                // to check the ignore case flag. If it is set, then
135                // we try to match with the case ignored
136                if (!fIgnoreCase ||
137                    (fUppercasePattern[patternIndex] != ucContent[index]))
138                    break;
139            }
140
141            if (patternIndex == 0)
142                return (int)index;
143        }
144
145        index += fShiftTable[ch % fShiftTableLen] + 1;
146
147        if (index < nIndex)
148            index = nIndex;
149    }
150
151    return -1;
152}
153
154// ---------------------------------------------------------------------------
155//  BMPattern: private helpers methods
156// ---------------------------------------------------------------------------
157void BMPattern::initialize() {
158
159    const XMLSize_t patternLen = XMLString::stringLen(fPattern);
160    XMLCh* lowercasePattern = 0;
161
162    fShiftTable = (XMLSize_t*) fMemoryManager->allocate(fShiftTableLen*sizeof(XMLSize_t)); //new XMLSize_t[fShiftTableLen];
163
164    if (fIgnoreCase) {
165
166        fUppercasePattern = XMLString::replicate(fPattern, fMemoryManager);
167        lowercasePattern = XMLString::replicate(fPattern, fMemoryManager);
168        XMLString::upperCase(fUppercasePattern);
169        XMLString::lowerCase(lowercasePattern);
170    }
171
172    ArrayJanitor<XMLCh> janLowercase(lowercasePattern, fMemoryManager);
173
174    for (unsigned int i=0; i< fShiftTableLen; i++)
175        fShiftTable[i] = patternLen;
176
177    for (unsigned int k=0; k< patternLen; k++) {
178
179        XMLCh      ch = fPattern[k];
180        XMLSize_t diff = patternLen - k - 1;
181        int          index = ch % fShiftTableLen;
182
183        if (diff < fShiftTable[index])
184            fShiftTable[index] = diff;
185
186        if (fIgnoreCase) {
187
188            for (int j=0; j< 2; j++) {
189
190                ch = (j == 0) ? fUppercasePattern[k] : lowercasePattern[k];
191                index = ch % fShiftTableLen;
192
193                if (diff < fShiftTable[index])
194                    fShiftTable[index] = diff;
195            }
196        }
197    }
198}
199
200// ---------------------------------------------------------------------------
201//  BMPattern: Cleanup
202// ---------------------------------------------------------------------------
203void BMPattern::cleanUp() {
204
205    fMemoryManager->deallocate(fPattern);//delete [] fPattern;
206    fMemoryManager->deallocate(fUppercasePattern);//delete [] fUppercasePattern;
207    fMemoryManager->deallocate(fShiftTable);
208}
209
210XERCES_CPP_NAMESPACE_END
211
212/**
213  *    End of file BMPattern.cpp
214  */
Note: See TracBrowser for help on using the repository browser.