rangetoken.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 674 行 · 第 1/2 页
CPP
674 行
/* * Copyright 2001-2002,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Log: RangeToken.cpp,v $ * Revision 1.10 2004/09/08 13:56:47 peiyongz * Apache License Version 2.0 * * Revision 1.9 2003/12/17 00:18:37 cargilld * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data. * * Revision 1.8 2003/05/16 21:37:00 knoaman * Memory manager implementation: Modify constructors to pass in the memory manager. * * Revision 1.7 2003/05/15 21:46:47 knoaman * Add missing include. * * Revision 1.6 2002/11/04 15:17:00 tng * C++ Namespace Support. * * Revision 1.5 2002/10/15 18:15:02 knoaman * [Bug 13490]: - new[]/delete mismatch in RangeToken.cpp * * Revision 1.4 2002/05/27 11:46:53 tng * Fix compilation error. The definition should match declaration. * * Revision 1.3 2002/05/24 16:42:20 knoaman * Performance fixes: eliminate mulitple calls to addRange and sort. * * Revision 1.2 2002/03/18 19:29:53 knoaman * Change constant names to eliminate possible conflict with user defined ones. * * Revision 1.1.1.1 2002/02/01 22:22:30 peiyongz * sane_include * * Revision 1.4 2001/05/29 19:39:33 knoaman * Typo fix * * Revision 1.3 2001/05/11 13:26:45 tng * Copyright update. * * Revision 1.2 2001/05/03 18:17:37 knoaman * Some design changes: * o Changed the TokenFactory from a single static instance, to a * normal class. Each RegularExpression object will have its own * instance of TokenFactory, and that instance will be passed to * other classes that need to use a TokenFactory to create Token * objects (with the exception of RangeTokenMap). * o Added a new class RangeTokenMap to map a the different ranges * in a given category to a specific RangeFactory object. In the old * design RangeFactory had dual functionality (act as a Map, and as * a factory for creating RangeToken(s)). The RangeTokenMap will * have its own copy of the TokenFactory. There will be only one * instance of the RangeTokenMap class, and that instance will be * lazily deleted when XPlatformUtils::Terminate is called. * * Revision 1.1 2001/03/02 19:26:46 knoaman * Schema: Regular expression handling part II * */// ---------------------------------------------------------------------------// Includes// ---------------------------------------------------------------------------#include <xercesc/util/regx/RangeToken.hpp>#include <xercesc/util/regx/TokenFactory.hpp>#include <xercesc/util/IllegalArgumentException.hpp>XERCES_CPP_NAMESPACE_BEGIN// ---------------------------------------------------------------------------// Static member data initialization// ---------------------------------------------------------------------------const int RangeToken::MAPSIZE = 256;const unsigned int RangeToken::INITIALSIZE = 16;// ---------------------------------------------------------------------------// RangeToken: Constructors and Destructors// ---------------------------------------------------------------------------RangeToken::RangeToken(const unsigned short tokType, MemoryManager* const manager) : Token(tokType, manager) , fSorted(false) , fCompacted(false) , fNonMapIndex(0) , fElemCount(0) , fMaxCount(INITIALSIZE) , fMap(0) , fRanges(0) , fCaseIToken(0) , fMemoryManager(manager){}RangeToken::~RangeToken() { fMemoryManager->deallocate(fMap);//delete [] fMap; fMemoryManager->deallocate(fRanges);//delete[] fRanges;}// ---------------------------------------------------------------------------// RangeToken: Getter methods// ---------------------------------------------------------------------------RangeToken* RangeToken::getCaseInsensitiveToken(TokenFactory* const tokFactory) { // REVIST // We will not build a token with case insenstive ranges // For now we will return a copy of ourselves. if (fCaseIToken == 0 && tokFactory) { bool isNRange = (getTokenType() == T_NRANGE) ? true : false; RangeToken* lwrToken = tokFactory->createRange(isNRange); lwrToken->mergeRanges(this); fCaseIToken = lwrToken; } return fCaseIToken;}// ---------------------------------------------------------------------------// RangeToken: Setter methods// ---------------------------------------------------------------------------void RangeToken::setRangeValues(XMLInt32* const rangeValues, const unsigned int count){ if (fRanges) { if (fMap) { fMemoryManager->deallocate(fMap);//delete [] fMap; fMap = 0; } fElemCount = 0; fMemoryManager->deallocate(fRanges);//delete [] fRanges; fRanges = 0; } fElemCount = fMaxCount = count; fRanges = rangeValues;}// ---------------------------------------------------------------------------// RangeToken: Range manipulation methods// ---------------------------------------------------------------------------void RangeToken::addRange(const XMLInt32 start, const XMLInt32 end) { XMLInt32 val1, val2; fCaseIToken = 0; if (start <= end) { val1 = start; val2 = end; } else { val1 = end; val2 = start; } if (fRanges == 0) { fRanges = (XMLInt32*) fMemoryManager->allocate ( fMaxCount * sizeof(XMLInt32) );//new XMLInt32[fMaxCount]; fRanges[0] = val1; fRanges[1] = val2; fElemCount = 2; fSorted = true; } else { if (fRanges[fElemCount-1] + 1 == val1) { fRanges[fElemCount-1] = val2; return; } if (fElemCount + 2 >= fMaxCount) { expand(2); } if (fRanges[fElemCount-1] >= val1) fSorted = false; fRanges[fElemCount++] = val1; fRanges[fElemCount++] = val2; if (!fSorted) { sortRanges(); } }}void RangeToken::sortRanges() { if (fSorted || fRanges == 0) return; for (int i = fElemCount - 4; i >= 0; i -= 2) { for (int j = 0; j <= i; j +=2) { if (fRanges[j] > fRanges[j + 2] || (fRanges[j]==fRanges[j+2] && fRanges[j+1] > fRanges[j+3])) { XMLInt32 tmpVal = fRanges[j+2]; fRanges[j+2] = fRanges[j]; fRanges[j] = tmpVal; tmpVal = fRanges[j+3]; fRanges[j+3] = fRanges[j+1]; fRanges[j+1] = tmpVal; } } } fSorted = true;}void RangeToken::compactRanges() { if (fCompacted || fRanges == 0 || fElemCount <= 2) return; unsigned int base = 0; unsigned int target = 0; while (target < fElemCount) { if (base != target) { fRanges[base] = fRanges[target++]; fRanges[base+1] = fRanges[target++]; } else target += 2; XMLInt32 baseEnd = fRanges[base + 1]; while (target < fElemCount) { XMLInt32 startRange = fRanges[target]; if (baseEnd + 1 < startRange) break; XMLInt32 endRange = fRanges[target + 1]; if (baseEnd + 1 == startRange || baseEnd < endRange) { baseEnd = endRange; fRanges[base+1] = baseEnd; target += 2; } else if (baseEnd >= endRange) { target += 2; } else { ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Regex_CompactRangesError, fMemoryManager); } } // inner while base += 2; } fElemCount = base; fCompacted = true;}void RangeToken::mergeRanges(const Token *const tok) { if (tok->getTokenType() != this->getTokenType()) ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Regex_MergeRangesTypeMismatch, fMemoryManager); RangeToken* rangeTok = (RangeToken *) tok; if (rangeTok->fRanges == 0) return; fCaseIToken = 0; sortRanges(); rangeTok->sortRanges(); if (fRanges == 0) { fMaxCount = rangeTok->fMaxCount; fRanges = (XMLInt32*) fMemoryManager->allocate ( fMaxCount * sizeof(XMLInt32) );//new XMLInt32[fMaxCount]; for (unsigned int index = 0; index < rangeTok->fElemCount; index++) { fRanges[index] = rangeTok->fRanges[index]; } fElemCount = rangeTok->fElemCount; return; } unsigned int newMaxCount = (fElemCount + rangeTok->fElemCount >= fMaxCount) ? fMaxCount + rangeTok->fMaxCount : fMaxCount; XMLInt32* result = (XMLInt32*) fMemoryManager->allocate ( newMaxCount * sizeof(XMLInt32) );//new XMLInt32[newMaxCount]; for (unsigned int i=0, j=0, k=0; i < fElemCount || j < rangeTok->fElemCount;) { if (i >= fElemCount) { for (int count = 0; count < 2; count++) { result[k++] = rangeTok->fRanges[j++]; } } else if (j >= rangeTok->fElemCount) { for (int count = 0; count < 2; count++) { result[k++] = fRanges[i++]; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?