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