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 + -
显示快捷键?