elemstack.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 951 行 · 第 1/3 页

CPP
951
字号
        QName** newRow = (QName**) fMemoryManager->allocate        (            newCapacity * sizeof(QName*)        );//new QName*[newCapacity];        //        //  Copy over the old contents. We don't have to initialize the new        //  part because The current child count is used to know how much of        //  it is valid.        //        //  Only both doing this if there is any current content, since        //  this code also does the initial faulting in of the array when        //  both the current capacity and child count are zero.        //        if (curRow->fChildCount)        {             unsigned int index = 0;             for (; index < curRow->fChildCount; index++)                 newRow[index] = curRow->fChildren[index];        }        // Clean up the old children and store the new info        fMemoryManager->deallocate(curRow->fChildren);//delete [] curRow->fChildren;        curRow->fChildren = newRow;        curRow->fChildCapacity = newCapacity;    }    // Add this id to the end of the row's child id array and bump the count    curRow->fChildren[curRow->fChildCount++] = child;    // Return the level of the index we just filled (before the bump)    return curRow->fChildCount - 1;}const ElemStack::StackElem* ElemStack::topElement() const{    if (!fStackTop)        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);    return fStack[fStackTop - 1];}// ---------------------------------------------------------------------------//  ElemStack: Prefix map methods// ---------------------------------------------------------------------------void ElemStack::addPrefix(  const   XMLCh* const    prefixToAdd                            , const unsigned int    uriId){    if (!fStackTop)        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);    // Get a convenience pointer to the stack top row    StackElem* curRow = fStack[fStackTop - 1];    // Map the prefix to its unique id    const unsigned int prefId = fPrefixPool.addOrFind(prefixToAdd);    //    //  Add a new element to the prefix map for this element. If its full,    //  then expand it out.    //    if (curRow->fMapCount == curRow->fMapCapacity)        expandMap(curRow);    //    //  And now add a new element for this prefix. Watch for the special case    //  of xmlns=="", and force it to ""=[globalid]    //    curRow->fMap[curRow->fMapCount].fPrefId = prefId;    if ((prefId == fGlobalPoolId) && (uriId == fEmptyNamespaceId))        curRow->fMap[curRow->fMapCount].fURIId = fEmptyNamespaceId;    else        curRow->fMap[curRow->fMapCount].fURIId = uriId;    // Bump the map count now    curRow->fMapCount++;}unsigned int ElemStack::mapPrefixToURI( const   XMLCh* const    prefixToMap                                        , const MapModes        mode                                        ,       bool&           unknown) const{    // Assume we find it    unknown = false;    //    //  Map the prefix to its unique id, from the prefix string pool. If its    //  not a valid prefix, then its a failure.    //    unsigned int prefixId = fPrefixPool.getId(prefixToMap);    if (!prefixId)    {        unknown = true;        return fUnknownNamespaceId;    }    //    //  If the prefix is empty, and we are in attribute mode, then we assign    //  it to the empty namespace because the default namespace does not    //  apply to attributes.    //    if (!*prefixToMap && (mode == Mode_Attribute))        return fEmptyNamespaceId;    //    //  Check for the special prefixes 'xml' and 'xmlns' since they cannot    //  be overridden.    //    if (prefixId == fXMLPoolId)        return fXMLNamespaceId;    else if (prefixId == fXMLNSPoolId)        return fXMLNSNamespaceId;    //    //  Start at the stack top and work backwards until we come to some    //  element that mapped this prefix.    //    int startAt = (int)(fStackTop - 1);    for (int index = startAt; index >= 0; index--)    {        // Get a convenience pointer to the current element        StackElem* curRow = fStack[index];        // If no prefixes mapped at this level, then go the next one        if (!curRow->fMapCount)            continue;        // Search the map at this level for the passed prefix        for (unsigned int mapIndex = 0; mapIndex < curRow->fMapCount; mapIndex++)        {            if (curRow->fMap[mapIndex].fPrefId == prefixId)                return curRow->fMap[mapIndex].fURIId;        }    }    //    //  If the prefix is an empty string, then we will return the special    //  global namespace id. This can be overridden, but no one has or we    //  would have not gotten here.    //    if (!*prefixToMap)        return fEmptyNamespaceId;    // Oh well, don't have a clue so return the unknown id    unknown = true;    return fUnknownNamespaceId;}ValueVectorOf<PrefMapElem*>* ElemStack::getNamespaceMap() const{    fNamespaceMap->removeAllElements();    //  Start at the stack top and work backwards until we come to some    //  element that mapped this prefix.    int startAt = (int)(fStackTop - 1);    for (int index = startAt; index >= 0; index--)    {        // Get a convenience pointer to the current element        StackElem* curRow = fStack[index];        // If no prefixes mapped at this level, then go the next one        if (!curRow->fMapCount)            continue;        // Search the map at this level for the passed prefix        for (unsigned int mapIndex = 0; mapIndex < curRow->fMapCount; mapIndex++)        {            fNamespaceMap->addElement(&(curRow->fMap[mapIndex]));        }    }    return fNamespaceMap;}// ---------------------------------------------------------------------------//  ElemStack: Miscellaneous methods// ---------------------------------------------------------------------------void ElemStack::reset(  const   unsigned int    emptyId                        , const unsigned int    unknownId                        , const unsigned int    xmlId                        , const unsigned int    xmlNSId){    // Reset the stack top to clear the stack    fStackTop = 0;    // if first time, put in the standard prefixes    if (fXMLPoolId == 0) {        fGlobalPoolId = fPrefixPool.addOrFind(XMLUni::fgZeroLenString);        fXMLPoolId = fPrefixPool.addOrFind(XMLUni::fgXMLString);        fXMLNSPoolId = fPrefixPool.addOrFind(XMLUni::fgXMLNSString);    }    // And store the new special URI ids    fEmptyNamespaceId = emptyId;    fUnknownNamespaceId = unknownId;    fXMLNamespaceId = xmlId;    fXMLNSNamespaceId = xmlNSId;}// ---------------------------------------------------------------------------//  ElemStack: Private helpers// ---------------------------------------------------------------------------void ElemStack::expandMap(StackElem* const toExpand){    // For convenience get the old map size    const unsigned int oldCap = toExpand->fMapCapacity;    //    //  Expand the capacity by 25%, or initialize it to 16 if its currently    //  empty. Then allocate a new temp buffer.    //    const unsigned int newCapacity = oldCap ?                                     (unsigned int)(oldCap * 1.25) : 16;    PrefMapElem* newMap = (PrefMapElem*) fMemoryManager->allocate    (        newCapacity * sizeof(PrefMapElem)    );//new PrefMapElem[newCapacity];    //    //  Copy over the old stuff. We DON'T have to zero out the new stuff    //  since this is a by value map and the current map index controls what    //  is relevant.    //    memcpy(newMap, toExpand->fMap, oldCap * sizeof(PrefMapElem));    // Delete the old map and store the new stuff    fMemoryManager->deallocate(toExpand->fMap);//delete [] toExpand->fMap;    toExpand->fMap = newMap;    toExpand->fMapCapacity = newCapacity;}void ElemStack::expandStack(){    // Expand the capacity by 25% and allocate a new buffer    const unsigned int newCapacity = (unsigned int)(fStackCapacity * 1.25);    StackElem** newStack = (StackElem**) fMemoryManager->allocate    (        newCapacity * sizeof(StackElem*)    );//new StackElem*[newCapacity];    // Copy over the old stuff    memcpy(newStack, fStack, fStackCapacity * sizeof(StackElem*));    //    //  And zero out the new stuff. Though we use a stack top, we reuse old    //  stack contents so we need to know if elements have been initially    //  allocated or not as we push new stuff onto the stack.    //    memset    (        &newStack[fStackCapacity]        , 0        , (newCapacity - fStackCapacity) * sizeof(StackElem*)    );    // Delete the old array and update our members    fMemoryManager->deallocate(fStack);//delete [] fStack;    fStack = newStack;    fStackCapacity = newCapacity;}// ---------------------------------------------------------------------------//  WFElemStack: Constructors and Destructor// ---------------------------------------------------------------------------WFElemStack::WFElemStack(MemoryManager* const manager) :    fEmptyNamespaceId(0)    , fGlobalPoolId(0)    , fStackCapacity(32)    , fStackTop(0)    , fUnknownNamespaceId(0)    , fXMLNamespaceId(0)    , fXMLPoolId(0)    , fXMLNSNamespaceId(0)    , fXMLNSPoolId(0)    , fMapCapacity(0)    , fMap(0)    , fStack(0)    , fPrefixPool(109, manager)    , fMemoryManager(manager){    // Do an initial allocation of the stack and zero it out    fStack = (StackElem**) fMemoryManager->allocate    (        fStackCapacity * sizeof(StackElem*)    );//new StackElem*[fStackCapacity];    memset(fStack, 0, fStackCapacity * sizeof(StackElem*));}WFElemStack::~WFElemStack(){    //    //  Start working from the bottom of the stack and clear it out as we    //  go up. Once we hit an uninitialized one, we can break out.    //    for (unsigned int stackInd = 0; stackInd < fStackCapacity; stackInd++)    {        // If this entry has been set, then lets clean it up        if (!fStack[stackInd])            break;        fMemoryManager->deallocate(fStack[stackInd]->fThisElement);//delete [] fStack[stackInd]->fThisElement;        delete fStack[stackInd];    }    if (fMap)        fMemoryManager->deallocate(fMap);//delete [] fMap;    // Delete the stack array itself now    fMemoryManager->deallocate(fStack);//delete [] fStack;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?