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

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

Changes to icxercesc files

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