/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * $Id: ElemStack.cpp 568078 2007-08-21 11:43:25Z amassari $
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <string.h>
#include <xercesc/util/EmptyStackException.hpp>
#include <xercesc/util/NoSuchElementException.hpp>
#include <xercesc/framework/XMLElementDecl.hpp>
#include <xercesc/internal/ElemStack.hpp>
#include <xercesc/validators/common/Grammar.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  ElemStack: Constructors and Destructor
// ---------------------------------------------------------------------------
ElemStack::ElemStack(MemoryManager* const manager) :

    fEmptyNamespaceId(0)
    , fGlobalPoolId(0)
    , fPrefixPool(109, manager)
    , fStack(0)
    , fStackCapacity(32)
    , fStackTop(0)
    , fUnknownNamespaceId(0)
    , fXMLNamespaceId(0)
    , fXMLPoolId(0)
    , fXMLNSNamespaceId(0)
    , fXMLNSPoolId(0)
    , fNamespaceMap(0)
    , 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*));

    fNamespaceMap = new (fMemoryManager) ValueVectorOf<PrefMapElem*>(16, fMemoryManager);
}

ElemStack::~ElemStack()
{
    //
    //  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]->fChildren);//delete [] fStack[stackInd]->fChildren;
        fMemoryManager->deallocate(fStack[stackInd]->fMap);//delete [] fStack[stackInd]->fMap;
        fMemoryManager->deallocate(fStack[stackInd]->fSchemaElemName);
        delete fStack[stackInd];
    }

    // Delete the stack array itself now
    fMemoryManager->deallocate(fStack);//delete [] fStack;
    delete fNamespaceMap;
}


// ---------------------------------------------------------------------------
//  ElemStack: Stack access
// ---------------------------------------------------------------------------
unsigned int ElemStack::addLevel()
{
    // See if we need to expand the stack
    if (fStackTop == fStackCapacity)
        expandStack();

    // If this element has not been initialized yet, then initialize it
    if (!fStack[fStackTop])
    {
        fStack[fStackTop] = new (fMemoryManager) StackElem;
        fStack[fStackTop]->fChildCapacity = 0;
        fStack[fStackTop]->fChildren = 0;
        fStack[fStackTop]->fMapCapacity = 0;
        fStack[fStackTop]->fMap = 0;
        fStack[fStackTop]->fSchemaElemName = 0;
        fStack[fStackTop]->fSchemaElemNameMaxLen = 0;
    }

    // Set up the new top row
    fStack[fStackTop]->fThisElement = 0;
    fStack[fStackTop]->fReaderNum = 0xFFFFFFFF;
    fStack[fStackTop]->fChildCount = 0;
    fStack[fStackTop]->fMapCount = 0;
    fStack[fStackTop]->fValidationFlag = false;
    fStack[fStackTop]->fCommentOrPISeen = false;
    fStack[fStackTop]->fReferenceEscaped = false;
    fStack[fStackTop]->fCurrentURI = fUnknownNamespaceId;
    fStack[fStackTop]->fCurrentScope = Grammar::TOP_LEVEL_SCOPE;
    fStack[fStackTop]->fCurrentGrammar = 0;

    // Bump the top of stack
    fStackTop++;

    return fStackTop-1;
}


unsigned int
ElemStack::addLevel(XMLElementDecl* const toSet, const unsigned int readerNum)
{
    // See if we need to expand the stack
    if (fStackTop == fStackCapacity)
        expandStack();

    // If this element has not been initialized yet, then initialize it
    if (!fStack[fStackTop])
    {
        fStack[fStackTop] = new (fMemoryManager) StackElem;
        fStack[fStackTop]->fChildCapacity = 0;
        fStack[fStackTop]->fChildren = 0;
        fStack[fStackTop]->fMapCapacity = 0;
        fStack[fStackTop]->fMap = 0;
        fStack[fStackTop]->fSchemaElemName = 0;
        fStack[fStackTop]->fSchemaElemNameMaxLen = 0;
    }

    // Set up the new top row
    fStack[fStackTop]->fThisElement = toSet;
    fStack[fStackTop]->fReaderNum = readerNum;
    fStack[fStackTop]->fChildCount = 0;
    fStack[fStackTop]->fMapCount = 0;
    fStack[fStackTop]->fValidationFlag = false;
    fStack[fStackTop]->fCommentOrPISeen = false;
    fStack[fStackTop]->fReferenceEscaped = false;
    fStack[fStackTop]->fCurrentURI = fUnknownNamespaceId;
    fStack[fStackTop]->fCurrentScope = Grammar::TOP_LEVEL_SCOPE;
    fStack[fStackTop]->fCurrentGrammar = 0;

    // Bump the top of stack
    fStackTop++;

    return fStackTop-1;
}



const ElemStack::StackElem* ElemStack::popTop()
{
    // Watch for an underflow error
    if (!fStackTop)
        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_StackUnderflow, fMemoryManager);

    fStackTop--;
    return fStack[fStackTop];
}


void
ElemStack::setElement(XMLElementDecl* const toSet, const unsigned int readerNum)
{
    if (!fStackTop)
        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);

    fStack[fStackTop - 1]->fThisElement = toSet;
    fStack[fStackTop - 1]->fReaderNum = readerNum;
}


// ---------------------------------------------------------------------------
//  ElemStack: Stack top access
// ---------------------------------------------------------------------------
unsigned int ElemStack::addChild(QName* const child, const bool toParent)
{
    if (!fStackTop)
        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);

    //
    //  If they want to add to the parent, then we have to have at least two
    //  elements on the stack.
    //
    if (toParent && (fStackTop < 2))
        ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::ElemStack_NoParentPushed, fMemoryManager);

    // Get a convenience pointer to the stack top row
    StackElem* curRow = toParent
                        ? fStack[fStackTop - 2] : fStack[fStackTop - 1];

    // See if we need to expand this row's child array
    if (curRow->fChildCount == curRow->fChildCapacity)
    {
        // Increase the capacity by a quarter and allocate a new row
        const unsigned int newCapacity = curRow->fChildCapacity ?
                                         (unsigned int)(curRow->fChildCapacity * 1.25) :
                                         32;
        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;
}


// ---------------------------------------------------------------------------
//  WFElemStack: Stack access
// ---------------------------------------------------------------------------
unsigned int WFElemStack::addLevel()
{
    // See if we need to expand the stack
    if (fStackTop == fStackCapacity)
        expandStack();

    
    // If this element has not been initialized yet, then initialize it
    if (!fStack[fStackTop])
    {
        fStack[fStackTop] = new (fMemoryManager) StackElem;
        fStack[fStackTop]->fThisElement = 0;
        fStack[fStackTop]->fElemMaxLength = 0;
    }

    // Set up the new top row
    fStack[fStackTop]->fReaderNum = 0xFFFFFFFF;
    fStack[fStackTop]->fCurrentURI = fUnknownNamespaceId;
    fStack[fStackTop]->fTopPrefix = -1;

    if (fStackTop != 0)
        fStack[fStackTop]->fTopPrefix = fStack[fStackTop - 1]->fTopPrefix;

    // Bump the top of stack
    fStackTop++;

    return fStackTop-1;
}


unsigned int
WFElemStack::addLevel(const XMLCh* const toSet,
                      const unsigned int toSetLen,
                      const unsigned int readerNum)
{
    // See if we need to expand the stack
    if (fStackTop == fStackCapacity)
        expandStack();

    // If this element has not been initialized yet, then initialize it
    if (!fStack[fStackTop])
    {
        fStack[fStackTop] = new (fMemoryManager) StackElem;
        fStack[fStackTop]->fThisElement = 0;
        fStack[fStackTop]->fElemMaxLength = 0;
    }

    // Set up the new top row
    fStack[fStackTop]->fCurrentURI = fUnknownNamespaceId;
    fStack[fStackTop]->fTopPrefix = -1;

    // And store the new stuff
    if (toSetLen > fStack[fStackTop]->fElemMaxLength) {

        fMemoryManager->deallocate(fStack[fStackTop]->fThisElement);//delete [] fStack[fStackTop]->fThisElement;
        fStack[fStackTop]->fElemMaxLength = toSetLen;
        fStack[fStackTop]->fThisElement = (XMLCh*) fMemoryManager->allocate
        (
            (toSetLen + 1) * sizeof(XMLCh)
        );//new XMLCh[toSetLen + 1];
    }

    XMLString::moveChars(fStack[fStackTop]->fThisElement, toSet, toSetLen + 1);
    fStack[fStackTop]->fReaderNum = readerNum;

    if (fStackTop != 0)
        fStack[fStackTop]->fTopPrefix = fStack[fStackTop - 1]->fTopPrefix;

    // Bump the top of stack
    fStackTop++;

    return fStackTop-1;
}



const WFElemStack::StackElem* WFElemStack::popTop()
{
    // Watch for an underflow error
    if (!fStackTop)
        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_StackUnderflow, fMemoryManager);

    fStackTop--;
    return fStack[fStackTop];
}


void
WFElemStack::setElement(const XMLCh* const toSet,
                      const unsigned int toSetLen,
                      const unsigned int readerNum)
{
    if (!fStackTop)
        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);

    if (toSetLen > fStack[fStackTop - 1]->fElemMaxLength) {

        fMemoryManager->deallocate(fStack[fStackTop - 1]->fThisElement);//delete [] fStack[fStackTop - 1]->fThisElement;
        fStack[fStackTop - 1]->fElemMaxLength = toSetLen;
        fStack[fStackTop - 1]->fThisElement = (XMLCh*) fMemoryManager->allocate
        (
            (toSetLen + 1) * sizeof(XMLCh)
        );//new XMLCh[toSetLen + 1];
    }

    XMLString::moveChars(fStack[fStackTop - 1]->fThisElement, toSet, toSetLen + 1);
    fStack[fStackTop - 1]->fReaderNum = readerNum;
}


// ---------------------------------------------------------------------------
//  WFElemStack: Stack top access
// ---------------------------------------------------------------------------
const WFElemStack::StackElem* WFElemStack::topElement() const
{
    if (!fStackTop)
        ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);

    return fStack[fStackTop - 1];
}


// ---------------------------------------------------------------------------
//  WFElemStack: Prefix map methods
// ---------------------------------------------------------------------------
void WFElemStack::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 ((unsigned int)curRow->fTopPrefix + 1 == fMapCapacity)
        expandMap();

    //
    //  And now add a new element for this prefix. Watch for the special case
    //  of xmlns=="", and force it to ""=[globalid]
    //
    fMap[curRow->fTopPrefix + 1].fPrefId = prefId;
    if ((prefId == fGlobalPoolId) && (uriId == fEmptyNamespaceId))
        fMap[curRow->fTopPrefix + 1].fURIId = fEmptyNamespaceId;
    else
        fMap[curRow->fTopPrefix + 1].fURIId = uriId;

    // Bump the map count now
    curRow->fTopPrefix++;
}


unsigned int WFElemStack::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.
    //
    //  Get a convenience pointer to the stack top row
    StackElem* curRow = fStack[fStackTop - 1];
    for (int mapIndex = curRow->fTopPrefix; mapIndex >=0; mapIndex--)
    {
        if (fMap[mapIndex].fPrefId == prefixId)
            return 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;
}


// ---------------------------------------------------------------------------
//  WFElemStack: Miscellaneous methods
// ---------------------------------------------------------------------------
void WFElemStack::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;
}


// ---------------------------------------------------------------------------
//  WFElemStack: Private helpers
// ---------------------------------------------------------------------------
void WFElemStack::expandMap()
{
    //
    //  Expand the capacity by 25%, or initialize it to 16 if its currently
    //  empty. Then allocate a new temp buffer.
    //
    const unsigned int newCapacity = fMapCapacity ?
                                     (unsigned int)(fMapCapacity * 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.
    //
    if (fMapCapacity) {

        memcpy(newMap, fMap, fMapCapacity * sizeof(PrefMapElem));
        fMemoryManager->deallocate(fMap);//delete [] fMap;
    }

    fMap = newMap;
    fMapCapacity = newCapacity;
}

void WFElemStack::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;
}


XERCES_CPP_NAMESPACE_END
