GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: RangeTokenMap.cpp 678879 2008-07-22 20:05:05Z amassari $ 00020 */ 00021 00022 // --------------------------------------------------------------------------- 00023 // Includes 00024 // --------------------------------------------------------------------------- 00025 #include <xercesc/util/regx/RangeTokenMap.hpp> 00026 #include <xercesc/util/regx/RangeToken.hpp> 00027 #include <xercesc/util/regx/RegxDefs.hpp> 00028 #include <xercesc/util/regx/TokenFactory.hpp> 00029 #include <xercesc/util/regx/XMLRangeFactory.hpp> 00030 #include <xercesc/util/regx/ASCIIRangeFactory.hpp> 00031 #include <xercesc/util/regx/UnicodeRangeFactory.hpp> 00032 #include <xercesc/util/regx/BlockRangeFactory.hpp> 00033 #include <xercesc/util/PlatformUtils.hpp> 00034 #include <xercesc/util/XMLExceptMsgs.hpp> 00035 #include <xercesc/util/StringPool.hpp> 00036 #include <xercesc/util/XMLInitializer.hpp> 00037 #include <xercesc/util/OutOfMemoryException.hpp> 00038 00039 XERCES_CPP_NAMESPACE_BEGIN 00040 00041 RangeTokenMap* RangeTokenMap::fInstance = 0; 00042 00043 void XMLInitializer::initializeRangeTokenMap() 00044 { 00045 RangeTokenMap::fInstance = new RangeTokenMap( 00046 XMLPlatformUtils::fgMemoryManager); 00047 00048 if (RangeTokenMap::fInstance) 00049 RangeTokenMap::fInstance->buildTokenRanges(); 00050 } 00051 00052 void XMLInitializer::terminateRangeTokenMap() 00053 { 00054 delete RangeTokenMap::fInstance; 00055 RangeTokenMap::fInstance = 0; 00056 } 00057 00058 00059 // --------------------------------------------------------------------------- 00060 // RangeTokenElemMap: Constructors and Destructor 00061 // --------------------------------------------------------------------------- 00062 RangeTokenElemMap::RangeTokenElemMap(unsigned int categoryId) : 00063 fCategoryId(categoryId) 00064 , fRange(0) 00065 , fNRange(0) 00066 { 00067 00068 } 00069 00070 RangeTokenElemMap::~RangeTokenElemMap() 00071 { 00072 00073 } 00074 00075 // --------------------------------------------------------------------------- 00076 // RangeTokenMap: Constructors and Destructor 00077 // --------------------------------------------------------------------------- 00078 00079 typedef JanitorMemFunCall<RangeTokenMap> CleanupType; 00080 00081 RangeTokenMap::RangeTokenMap(MemoryManager* manager) : 00082 fTokenRegistry(0) 00083 , fRangeMap(0) 00084 , fCategories(0) 00085 , fTokenFactory(0) 00086 , fMutex(manager) 00087 { 00088 CleanupType cleanup(this, &RangeTokenMap::cleanUp); 00089 00090 try { 00091 fTokenRegistry = new (manager) RefHashTableOf<RangeTokenElemMap>(109, manager); 00092 fRangeMap = new (manager) RefHashTableOf<RangeFactory>(29, manager); 00093 fCategories = new (manager) XMLStringPool(109, manager); 00094 fTokenFactory = new (manager) TokenFactory(manager); 00095 initializeRegistry(); 00096 } 00097 catch(const OutOfMemoryException&) 00098 { 00099 cleanup.release(); 00100 00101 throw; 00102 } 00103 00104 cleanup.release(); 00105 } 00106 00107 RangeTokenMap::~RangeTokenMap() { 00108 00109 cleanUp(); 00110 } 00111 00112 // --------------------------------------------------------------------------- 00113 // RangeTokenMap: Getter methods 00114 // --------------------------------------------------------------------------- 00115 RangeToken* RangeTokenMap::getRange(const XMLCh* const keyword, 00116 const bool complement) { 00117 00118 if (!fTokenRegistry->containsKey(keyword)) 00119 return 0; 00120 00121 RangeTokenElemMap* elemMap = fTokenRegistry->get(keyword); 00122 RangeToken* rangeTok = elemMap->getRangeToken(complement); 00123 00124 if (!rangeTok) 00125 { 00126 XMLMutexLock lockInit(&fMutex); 00127 00128 // make sure that it was not created while we were locked 00129 rangeTok = elemMap->getRangeToken(complement); 00130 00131 if (!rangeTok) 00132 { 00133 unsigned int categId = elemMap->getCategoryId(); 00134 const XMLCh* categName = fCategories->getValueForId(categId); 00135 RangeFactory* rangeFactory = fRangeMap->get(categName); 00136 00137 if (rangeFactory) 00138 { 00139 rangeFactory->buildRanges(this); 00140 rangeTok = elemMap->getRangeToken(complement); 00141 00142 // see if we are complementing an existing range 00143 if (!rangeTok && complement) 00144 { 00145 rangeTok = elemMap->getRangeToken(); 00146 if (rangeTok) 00147 { 00148 rangeTok = RangeToken::complementRanges(rangeTok, fTokenFactory, fTokenRegistry->getMemoryManager()); 00149 elemMap->setRangeToken(rangeTok , complement); 00150 } 00151 } 00152 } 00153 } 00154 } 00155 00156 return rangeTok; 00157 } 00158 00159 00160 // --------------------------------------------------------------------------- 00161 // RangeTokenMap: Putter methods 00162 // --------------------------------------------------------------------------- 00163 void RangeTokenMap::addCategory(const XMLCh* const categoryName) { 00164 00165 fCategories->addOrFind(categoryName); 00166 } 00167 00168 void RangeTokenMap::addRangeMap(const XMLCh* const categoryName, 00169 RangeFactory* const rangeFactory) { 00170 00171 fRangeMap->put((void*)categoryName, rangeFactory); 00172 } 00173 00174 void RangeTokenMap::addKeywordMap(const XMLCh* const keyword, 00175 const XMLCh* const categoryName) { 00176 00177 unsigned int categId = fCategories->getId(categoryName); 00178 00179 if (categId == 0) { 00180 ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Regex_InvalidCategoryName, categoryName, fTokenRegistry->getMemoryManager()); 00181 } 00182 00183 if (fTokenRegistry->containsKey(keyword)) { 00184 00185 RangeTokenElemMap* elemMap = fTokenRegistry->get(keyword); 00186 00187 if (elemMap->getCategoryId() != categId) 00188 elemMap->setCategoryId(categId); 00189 00190 return; 00191 } 00192 00193 fTokenRegistry->put((void*) keyword, new RangeTokenElemMap(categId)); 00194 } 00195 00196 // --------------------------------------------------------------------------- 00197 // RangeTokenMap: Setter methods 00198 // --------------------------------------------------------------------------- 00199 void RangeTokenMap::setRangeToken(const XMLCh* const keyword, 00200 RangeToken* const tok,const bool complement) { 00201 00202 if (fTokenRegistry->containsKey(keyword)) { 00203 fTokenRegistry->get(keyword)->setRangeToken(tok, complement); 00204 } 00205 else { 00206 ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Regex_KeywordNotFound, keyword, fTokenRegistry->getMemoryManager()); 00207 } 00208 } 00209 00210 00211 // --------------------------------------------------------------------------- 00212 // RangeTokenMap: Initialization methods 00213 // --------------------------------------------------------------------------- 00214 void RangeTokenMap::initializeRegistry() { 00215 00216 // Add categories 00217 fCategories->addOrFind(fgXMLCategory); 00218 fCategories->addOrFind(fgASCIICategory); 00219 fCategories->addOrFind(fgUnicodeCategory); 00220 fCategories->addOrFind(fgBlockCategory); 00221 00222 // Add xml range factory 00223 RangeFactory* rangeFact = new XMLRangeFactory(); 00224 fRangeMap->put((void*)fgXMLCategory, rangeFact); 00225 rangeFact->initializeKeywordMap(this); 00226 00227 // Add ascii range factory 00228 rangeFact = new ASCIIRangeFactory(); 00229 fRangeMap->put((void*)fgASCIICategory, rangeFact); 00230 rangeFact->initializeKeywordMap(this); 00231 00232 // Add unicode range factory 00233 rangeFact = new UnicodeRangeFactory(); 00234 fRangeMap->put((void*)fgUnicodeCategory, rangeFact); 00235 rangeFact->initializeKeywordMap(this); 00236 00237 // Add block range factory 00238 rangeFact = new BlockRangeFactory(); 00239 fRangeMap->put((void*)fgBlockCategory, rangeFact); 00240 rangeFact->initializeKeywordMap(this); 00241 } 00242 00243 void RangeTokenMap::buildTokenRanges() 00244 { 00245 // Build ranges */ 00246 RangeFactory* rangeFactory = fRangeMap->get(fgXMLCategory); 00247 rangeFactory->buildRanges(this); 00248 00249 rangeFactory = fRangeMap->get(fgASCIICategory); 00250 rangeFactory->buildRanges(this); 00251 00252 rangeFactory = fRangeMap->get(fgUnicodeCategory); 00253 rangeFactory->buildRanges(this); 00254 00255 rangeFactory = fRangeMap->get(fgBlockCategory); 00256 rangeFactory->buildRanges(this); 00257 } 00258 00259 // --------------------------------------------------------------------------- 00260 // RangeTokenMap: Instance methods 00261 // --------------------------------------------------------------------------- 00262 RangeTokenMap* RangeTokenMap::instance() 00263 { 00264 return fInstance; 00265 } 00266 00267 // --------------------------------------------------------------------------- 00268 // RangeTokenMap: helper methods 00269 // --------------------------------------------------------------------------- 00270 void RangeTokenMap::cleanUp() 00271 { 00272 delete fTokenRegistry; 00273 fTokenRegistry = 0; 00274 00275 delete fRangeMap; 00276 fRangeMap = 0; 00277 00278 delete fCategories; 00279 fCategories = 0; 00280 00281 delete fTokenFactory; 00282 fTokenFactory = 0; 00283 } 00284 00285 XERCES_CPP_NAMESPACE_END 00286