source: icXML/icXML-devel/src/icxercesc/util/regx/RangeTokenMap.cpp @ 2720

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

Initial check-in of icXML 0.8 source files

File size: 9.0 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: RangeTokenMap.cpp 678879 2008-07-22 20:05:05Z amassari $
20 */
21
22// ---------------------------------------------------------------------------
23//  Includes
24// ---------------------------------------------------------------------------
25#include <xercesc/util/regx/RangeTokenMap.hpp>
26#include <xercesc/util/regx/RangeToken.hpp>
27#include <xercesc/util/regx/RegxDefs.hpp>
28#include <xercesc/util/regx/TokenFactory.hpp>
29#include <xercesc/util/regx/XMLRangeFactory.hpp>
30#include <xercesc/util/regx/ASCIIRangeFactory.hpp>
31#include <xercesc/util/regx/UnicodeRangeFactory.hpp>
32#include <xercesc/util/regx/BlockRangeFactory.hpp>
33#include <xercesc/util/PlatformUtils.hpp>
34#include <xercesc/util/XMLExceptMsgs.hpp>
35#include <xercesc/util/StringPool.hpp>
36#include <xercesc/util/XMLInitializer.hpp>
37#include <xercesc/util/OutOfMemoryException.hpp>
38
39XERCES_CPP_NAMESPACE_BEGIN
40
41RangeTokenMap* RangeTokenMap::fInstance = 0;
42
43void XMLInitializer::initializeRangeTokenMap()
44{
45    RangeTokenMap::fInstance = new RangeTokenMap(
46      XMLPlatformUtils::fgMemoryManager);
47
48    if (RangeTokenMap::fInstance)
49      RangeTokenMap::fInstance->buildTokenRanges();
50}
51
52void XMLInitializer::terminateRangeTokenMap()
53{
54    delete RangeTokenMap::fInstance;
55    RangeTokenMap::fInstance = 0;
56}
57
58
59// ---------------------------------------------------------------------------
60//  RangeTokenElemMap: Constructors and Destructor
61// ---------------------------------------------------------------------------
62RangeTokenElemMap::RangeTokenElemMap(unsigned int categoryId) :
63    fCategoryId(categoryId)
64    , fRange(0)
65    , fNRange(0)
66{
67
68}
69
70RangeTokenElemMap::~RangeTokenElemMap()
71{
72
73}
74
75// ---------------------------------------------------------------------------
76//  RangeTokenMap: Constructors and Destructor
77// ---------------------------------------------------------------------------
78
79typedef JanitorMemFunCall<RangeTokenMap>    CleanupType;
80
81RangeTokenMap::RangeTokenMap(MemoryManager* manager) :
82    fTokenRegistry(0)
83    , fRangeMap(0)
84    , fCategories(0)
85    , fTokenFactory(0)
86    , fMutex(manager)
87{
88    CleanupType cleanup(this, &RangeTokenMap::cleanUp);
89
90    try {
91        fTokenRegistry = new (manager) RefHashTableOf<RangeTokenElemMap>(109, manager);
92        fRangeMap = new (manager) RefHashTableOf<RangeFactory>(29, manager);
93        fCategories = new (manager) XMLStringPool(manager);
94        fTokenFactory = new (manager) TokenFactory(manager);
95        initializeRegistry();
96    }
97    catch(const OutOfMemoryException&)
98    {
99        cleanup.release();
100
101        throw;
102    }
103
104    cleanup.release();
105}
106
107RangeTokenMap::~RangeTokenMap() {
108
109    cleanUp();
110}
111
112// ---------------------------------------------------------------------------
113//  RangeTokenMap: Getter methods
114// ---------------------------------------------------------------------------
115RangeToken* RangeTokenMap::getRange(const XMLCh* const keyword,
116                                    const bool complement) {
117
118    if (!fTokenRegistry->containsKey(keyword))
119        return 0;
120
121    RangeTokenElemMap* elemMap = fTokenRegistry->get(keyword);
122    RangeToken* rangeTok = elemMap->getRangeToken(complement);
123
124    if (!rangeTok)
125    {
126        XMLMutexLock lockInit(&fMutex);
127
128        // make sure that it was not created while we were locked
129        rangeTok = elemMap->getRangeToken(complement);
130
131        if (!rangeTok)
132        {
133            unsigned int categId = elemMap->getCategoryId();
134            const XMLCh* categName = fCategories->getValueForId(categId);
135            RangeFactory* rangeFactory = fRangeMap->get(categName);
136
137            if (rangeFactory)
138            {
139                rangeFactory->buildRanges(this);
140                rangeTok = elemMap->getRangeToken(complement);
141
142                // see if we are complementing an existing range
143                if (!rangeTok && complement)
144                {
145                    rangeTok = elemMap->getRangeToken();
146                    if (rangeTok)
147                    {
148                        rangeTok = RangeToken::complementRanges(rangeTok, fTokenFactory, fTokenRegistry->getMemoryManager());
149                        elemMap->setRangeToken(rangeTok , complement);
150                    }
151                }
152            }
153        }
154    }
155
156    return rangeTok;
157}
158
159
160// ---------------------------------------------------------------------------
161//  RangeTokenMap: Putter methods
162// ---------------------------------------------------------------------------
163void RangeTokenMap::addCategory(const XMLCh* const categoryName) {
164
165    fCategories->addOrFind(categoryName);
166}
167
168void RangeTokenMap::addRangeMap(const XMLCh* const categoryName,
169                                RangeFactory* const rangeFactory) {
170
171    fRangeMap->put((void*)categoryName, rangeFactory);
172}
173
174void RangeTokenMap::addKeywordMap(const XMLCh* const keyword,
175                                 const XMLCh* const categoryName) {
176
177    unsigned int categId = fCategories->getId(categoryName);
178
179    if (categId == 0) {
180        ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Regex_InvalidCategoryName, categoryName, fTokenRegistry->getMemoryManager());
181    }
182
183    if (fTokenRegistry->containsKey(keyword)) {
184
185        RangeTokenElemMap* elemMap = fTokenRegistry->get(keyword);
186
187        if (elemMap->getCategoryId() != categId)
188            elemMap->setCategoryId(categId);
189
190        return;
191    }
192
193    fTokenRegistry->put((void*) keyword, new RangeTokenElemMap(categId));
194}
195
196// ---------------------------------------------------------------------------
197//  RangeTokenMap: Setter methods
198// ---------------------------------------------------------------------------
199void RangeTokenMap::setRangeToken(const XMLCh* const keyword,
200                                  RangeToken* const tok,const bool complement) {
201
202    if (fTokenRegistry->containsKey(keyword)) {
203        fTokenRegistry->get(keyword)->setRangeToken(tok, complement);
204    }
205    else {
206        ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Regex_KeywordNotFound, keyword, fTokenRegistry->getMemoryManager());
207    }
208}
209
210
211// ---------------------------------------------------------------------------
212//  RangeTokenMap: Initialization methods
213// ---------------------------------------------------------------------------
214void RangeTokenMap::initializeRegistry() {
215
216    // Add categories
217    fCategories->addOrFind(fgXMLCategory);
218    fCategories->addOrFind(fgASCIICategory);
219    fCategories->addOrFind(fgUnicodeCategory);
220    fCategories->addOrFind(fgBlockCategory);
221
222    // Add xml range factory
223    RangeFactory* rangeFact = new XMLRangeFactory();
224    fRangeMap->put((void*)fgXMLCategory, rangeFact);
225    rangeFact->initializeKeywordMap(this);
226
227    // Add ascii range factory
228    rangeFact = new ASCIIRangeFactory();
229    fRangeMap->put((void*)fgASCIICategory, rangeFact);
230    rangeFact->initializeKeywordMap(this);
231
232    // Add unicode range factory
233    rangeFact = new UnicodeRangeFactory();
234    fRangeMap->put((void*)fgUnicodeCategory, rangeFact);
235    rangeFact->initializeKeywordMap(this);
236
237    // Add block range factory
238    rangeFact = new BlockRangeFactory();
239    fRangeMap->put((void*)fgBlockCategory, rangeFact);
240    rangeFact->initializeKeywordMap(this);
241}
242
243void RangeTokenMap::buildTokenRanges()
244{
245    // Build ranges */
246    RangeFactory* rangeFactory = fRangeMap->get(fgXMLCategory);
247    rangeFactory->buildRanges(this);
248
249    rangeFactory = fRangeMap->get(fgASCIICategory);
250    rangeFactory->buildRanges(this);
251
252    rangeFactory = fRangeMap->get(fgUnicodeCategory);
253    rangeFactory->buildRanges(this);
254
255    rangeFactory = fRangeMap->get(fgBlockCategory);
256    rangeFactory->buildRanges(this);
257}
258
259// ---------------------------------------------------------------------------
260//  RangeTokenMap: Instance methods
261// ---------------------------------------------------------------------------
262RangeTokenMap* RangeTokenMap::instance()
263{
264    return fInstance;
265}
266
267// ---------------------------------------------------------------------------
268//  RangeTokenMap: helper methods
269// ---------------------------------------------------------------------------
270void RangeTokenMap::cleanUp()
271{
272    delete fTokenRegistry;
273    fTokenRegistry = 0;
274
275    delete fRangeMap;
276    fRangeMap = 0;
277
278    delete fCategories;
279    fCategories = 0;
280
281    delete fTokenFactory;
282    fTokenFactory = 0;
283}
284
285XERCES_CPP_NAMESPACE_END
286
287/**
288  * End of file RangeTokenMap.cpp
289  */
Note: See TracBrowser for help on using the repository browser.