[GME-commit] GMESRC/GME/Include/xercesc/dom/impl DOMAttrImpl.cpp, NONE, 1.1 DOMAttrImpl.hpp, NONE, 1.1 DOMAttrMapImpl.cpp, NONE, 1.1 DOMAttrMapImpl.hpp, NONE, 1.1 DOMAttrNSImpl.cpp, NONE, 1.1 DOMAttrNSImpl.hpp, NONE, 1.1 DOMCDATASectionImpl.cpp, NONE, 1.1 DOMCDATASectionImpl.hpp, NONE, 1.1 DOMCasts.hpp, NONE, 1.1 DOMCharacterDataImpl.cpp, NONE, 1.1 DOMCharacterDataImpl.hpp, NONE, 1.1 DOMChildNode.cpp, NONE, 1.1 DOMChildNode.hpp, NONE, 1.1 DOMCommentImpl.cpp, NONE, 1.1 DOMCommentImpl.hpp, NONE, 1.1 DOMConfigurationImpl.cpp, NONE, 1.1 DOMConfigurationImpl.hpp, NONE, 1.1 DOMDeepNodeListImpl.cpp, NONE, 1.1 DOMDeepNodeListImpl.hpp, NONE, 1.1 DOMDeepNodeListPool.c, NONE, 1.1 DOMDeepNodeListPool.hpp, NONE, 1.1 DOMDocumentFragmentImpl.cpp, NONE, 1.1 DOMDocumentFragmentImpl.hpp, NONE, 1.1 DOMDocumentImpl.cpp, NONE, 1.1 DOMDocumentImpl.hpp, NONE, 1.1 DOMDocumentTypeImpl.cpp, NONE, 1.1 DOMDocumentTypeImpl.hpp, NONE, 1.1 DOMElementImpl.cpp, NONE, 1.1 DOMElementImpl.hpp, NONE, 1.1 DOMElementNSImpl.cpp, NONE, 1.1 DOMElementNSImpl.hpp, NONE, 1.1 DOMEntity Impl.cpp, NONE, 1.1 DOMEntityImpl.hpp, NONE, 1.1 DOMEntityReferenceImpl.cpp, NONE, 1.1 DOMEntityReferenceImpl.hpp, NONE, 1.1 DOMErrorImpl.cpp, NONE, 1.1 DOMErrorImpl.hpp, NONE, 1.1 DOMImplementationImpl.cpp, NONE, 1.1 DOMImplementationImpl.hpp, NONE, 1.1 DOMImplementationRegistry.cpp, NONE, 1.1 DOMLocatorImpl.cpp, NONE, 1.1 DOMLocatorImpl.hpp, NONE, 1.1 DOMNamedNodeMapImpl.cpp, NONE, 1.1 DOMNamedNodeMapImpl.hpp, NONE, 1.1 DOMNodeIDMap.cpp, NONE, 1.1 DOMNodeIDMap.hpp, NONE, 1.1 DOMNodeImpl.cpp, NONE, 1.1 DOMNodeImpl.hpp, NONE, 1.1 DOMNodeIteratorImpl.cpp, NONE, 1.1 DOMNodeIteratorImpl.hpp, NONE, 1.1 DOMNodeListImpl.cpp, NONE, 1.1 DOMNodeListImpl.hpp, NONE, 1.1 DOMNodeVector.cpp, NONE, 1.1 DOMNodeVector.hpp, NONE, 1.1 DOMNormalizer.cpp, NONE, 1.1 DOMNormalizer.hpp, NONE, 1.1 DOMNotationImpl.cpp, NONE, 1.1 DOMNotationImpl.hpp, NONE, 1.1 DOMParentNode.cpp, NONE, 1.1 DOMParentNode.hpp, NONE, 1.1 DOMProcessingInstructionImpl.cpp, NONE, 1.1 DOMProcessingInstructionImpl.hpp, NONE, 1.1 DOMRangeImpl.cpp, NONE, 1.1 DOMRangeImpl.hpp, NONE, 1.1 DOMStri ngPool.cpp, NONE, 1.1 DOMStringPool.hpp, NONE, 1.1 DOMTextImpl.cpp, NONE, 1.1 DOMTextImpl.hpp, NONE, 1.1 DOMTreeWalkerImpl.cpp, NONE, 1.1 DOMTreeWalkerImpl.hpp, NONE, 1.1 DOMTypeInfoImpl.cpp, NONE, 1.1 DOMTypeInfoImpl.hpp, NONE, 1.1 DOMWriterImpl.cpp, NONE, 1.1 DOMWriterImpl.hpp, NONE, 1.1 Makefile.in, NONE, 1.1 XSDElementNSImpl.cpp, NONE, 1.1 XSDElementNSImpl.hpp, NONE, 1.1

Log messages of CVS commits gme-commit at list.isis.vanderbilt.edu
Tue Feb 19 14:16:50 CST 2008


Update of /project/gme-repository/GMESRC/GME/Include/xercesc/dom/impl
In directory escher:/tmp/cvs-serv26529/dom/impl

Added Files:
	DOMAttrImpl.cpp DOMAttrImpl.hpp DOMAttrMapImpl.cpp 
	DOMAttrMapImpl.hpp DOMAttrNSImpl.cpp DOMAttrNSImpl.hpp 
	DOMCDATASectionImpl.cpp DOMCDATASectionImpl.hpp DOMCasts.hpp 
	DOMCharacterDataImpl.cpp DOMCharacterDataImpl.hpp 
	DOMChildNode.cpp DOMChildNode.hpp DOMCommentImpl.cpp 
	DOMCommentImpl.hpp DOMConfigurationImpl.cpp 
	DOMConfigurationImpl.hpp DOMDeepNodeListImpl.cpp 
	DOMDeepNodeListImpl.hpp DOMDeepNodeListPool.c 
	DOMDeepNodeListPool.hpp DOMDocumentFragmentImpl.cpp 
	DOMDocumentFragmentImpl.hpp DOMDocumentImpl.cpp 
	DOMDocumentImpl.hpp DOMDocumentTypeImpl.cpp 
	DOMDocumentTypeImpl.hpp DOMElementImpl.cpp DOMElementImpl.hpp 
	DOMElementNSImpl.cpp DOMElementNSImpl.hpp DOMEntityImpl.cpp 
	DOMEntityImpl.hpp DOMEntityReferenceImpl.cpp 
	DOMEntityReferenceImpl.hpp DOMErrorImpl.cpp DOMErrorImpl.hpp 
	DOMImplementationImpl.cpp DOMImplementationImpl.hpp 
	DOMImplementationRegistry.cpp DOMLocatorImpl.cpp 
	DOMLocatorImpl.hpp DOMNamedNodeMapImpl.cpp 
	DOMNamedNodeMapImpl.hpp DOMNodeIDMap.cpp DOMNodeIDMap.hpp 
	DOMNodeImpl.cpp DOMNodeImpl.hpp DOMNodeIteratorImpl.cpp 
	DOMNodeIteratorImpl.hpp DOMNodeListImpl.cpp 
	DOMNodeListImpl.hpp DOMNodeVector.cpp DOMNodeVector.hpp 
	DOMNormalizer.cpp DOMNormalizer.hpp DOMNotationImpl.cpp 
	DOMNotationImpl.hpp DOMParentNode.cpp DOMParentNode.hpp 
	DOMProcessingInstructionImpl.cpp 
	DOMProcessingInstructionImpl.hpp DOMRangeImpl.cpp 
	DOMRangeImpl.hpp DOMStringPool.cpp DOMStringPool.hpp 
	DOMTextImpl.cpp DOMTextImpl.hpp DOMTreeWalkerImpl.cpp 
	DOMTreeWalkerImpl.hpp DOMTypeInfoImpl.cpp DOMTypeInfoImpl.hpp 
	DOMWriterImpl.cpp DOMWriterImpl.hpp Makefile.in 
	XSDElementNSImpl.cpp XSDElementNSImpl.hpp 
Log Message:
Xerces2.7 includes checkin.


CVS User: Zoltan Molnar, ISIS (zolmol)

--- NEW FILE: DOMParentNode.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMParentNode.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>

#include "DOMDocumentImpl.hpp"
#include "DOMNodeListImpl.hpp"
#include "DOMRangeImpl.hpp"
#include "DOMNodeIteratorImpl.hpp"
#include "DOMParentNode.hpp"
#include "DOMCasts.hpp"

XERCES_CPP_NAMESPACE_BEGIN

DOMParentNode::DOMParentNode(DOMDocument *ownerDoc)
    : fOwnerDocument(ownerDoc), fFirstChild(0), fChildNodeList(castToNode(this))
{    
}

// This only makes a shallow copy, cloneChildren must also be called for a
// deep clone
DOMParentNode::DOMParentNode(const DOMParentNode &other)  :
    fChildNodeList(castToNode(this))
{
    this->fOwnerDocument = other.fOwnerDocument;

    // Need to break the association w/ original kids
    this->fFirstChild = 0;
}

void DOMParentNode::changed()
{
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    doc->changed();
}


int DOMParentNode::changes() const
{
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    return doc->changes();
}


DOMNode * DOMParentNode::appendChild(DOMNode *newChild)
{
    return insertBefore(newChild, 0);
}


void DOMParentNode::cloneChildren(const DOMNode *other) {
  //    for (DOMNode *mykid = other.getFirstChild();
    for (DOMNode *mykid = other->getFirstChild();
         mykid != 0;
         mykid = mykid->getNextSibling())
    {
        appendChild(mykid->cloneNode(true));
    }
}

DOMDocument * DOMParentNode::getOwnerDocument() const {
    return fOwnerDocument;
}

// unlike getOwnerDocument this is not overriden by DocumentImpl to return 0
DOMDocument * DOMParentNode::getDocument() const {
    return fOwnerDocument;
}

void DOMParentNode::setOwnerDocument(DOMDocument* doc) {
    fOwnerDocument = doc;
}

DOMNodeList *DOMParentNode::getChildNodes() const {
    const DOMNodeList *ret = &fChildNodeList;
    return (DOMNodeList *)ret;   // cast off const.
}


DOMNode * DOMParentNode::getFirstChild() const {
    return fFirstChild;
}


DOMNode * DOMParentNode::getLastChild() const
{
    return lastChild();
}

DOMNode * DOMParentNode::lastChild() const
{
    // last child is stored as the previous sibling of first child
    if (fFirstChild == 0) {
        return 0;
    }

    DOMChildNode *firstChild = castToChildImpl(fFirstChild);
    DOMNode *ret = firstChild->previousSibling;
    return ret;
}


//
//  revisit.  Is this function used anywhere?  I don't see it.
//
void DOMParentNode::lastChild(DOMNode *node) {
    // store lastChild as previous sibling of first child
    if (fFirstChild != 0) {
        DOMChildNode *firstChild = castToChildImpl(fFirstChild);
        firstChild->previousSibling = node;
    }
}


bool DOMParentNode::hasChildNodes() const
{
    return fFirstChild!=0;
}



DOMNode *DOMParentNode::insertBefore(DOMNode *newChild, DOMNode *refChild) {
    //not really in the specs, but better than nothing
    if(newChild==NULL)
        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);

    DOMNodeImpl *thisNodeImpl = castToNodeImpl(this);
    if (thisNodeImpl->isReadOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMParentNodeMemoryManager);

    if (newChild->getOwnerDocument() != fOwnerDocument)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMParentNodeMemoryManager);

    // Prevent cycles in the tree
    //only need to do this if the node has children
    if(newChild->hasChildNodes()) {
        bool treeSafe=true;
        for(DOMNode *a=castToNode(this)->getParentNode();
            treeSafe && a!=0;
            a=a->getParentNode())
            treeSafe=(newChild!=a);
        if(!treeSafe)
            throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);
    }

    // refChild must in fact be a child of this node (or 0)
    if (refChild!=0 && refChild->getParentNode() != castToNode(this))
        throw DOMException(DOMException::NOT_FOUND_ERR,0, GetDOMParentNodeMemoryManager);

    // if the new node has to be placed before itself, we don't have to do anything 
    // (even worse, we would crash if we continue, as we assume they are two distinct nodes)
    if (refChild!=0 && newChild->isSameNode(refChild))
        return newChild;

    if (newChild->getNodeType() == DOMNode::DOCUMENT_FRAGMENT_NODE)
    {
        // SLOW BUT SAFE: We could insert the whole subtree without
        // juggling so many next/previous pointers. (Wipe out the
        // parent's child-list, patch the parent pointers, set the
        // ends of the list.) But we know some subclasses have special-
        // case behavior they add to insertBefore(), so we don't risk it.
        // This approch also takes fewer bytecodes.

        // NOTE: If one of the children is not a legal child of this
        // node, throw HIERARCHY_REQUEST_ERR before _any_ of the children
        // have been transferred. (Alternative behaviors would be to
        // reparent up to the first failure point or reparent all those
        // which are acceptable to the target node, neither of which is
        // as robust. PR-DOM-0818 isn't entirely clear on which it
        // recommends?????

        // No need to check kids for right-document; if they weren't,
        // they wouldn't be kids of that DocFrag.
        for(DOMNode *kid=newChild->getFirstChild(); // Prescan
              kid!=0;
              kid=kid->getNextSibling())
        {
            if (!DOMDocumentImpl::isKidOK(castToNode(this), kid))
              throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);
        }
        while(newChild->hasChildNodes())     // Move
            insertBefore(newChild->getFirstChild(),refChild);
    }

    else if (!DOMDocumentImpl::isKidOK(castToNode(this), newChild))
        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);

    else
    {
        DOMNode *oldparent=newChild->getParentNode();
        if(oldparent!=0)
            oldparent->removeChild(newChild);

        // Attach up
        castToNodeImpl(newChild)->fOwnerNode = castToNode(this);
        castToNodeImpl(newChild)->isOwned(true);

        // Attach before and after
        // Note: fFirstChild.previousSibling == lastChild!!
        if (fFirstChild == 0) {
            // this our first and only child
            fFirstChild = newChild;
            castToNodeImpl(newChild)->isFirstChild(true);
            // castToChildImpl(newChild)->previousSibling = newChild;
            DOMChildNode *newChild_ci = castToChildImpl(newChild);
            newChild_ci->previousSibling = newChild;
        } else {
            if (refChild == 0) {
                // this is an append
                DOMNode *lastChild = castToChildImpl(fFirstChild)->previousSibling;
                castToChildImpl(lastChild)->nextSibling = newChild;
                castToChildImpl(newChild)->previousSibling = lastChild;
                castToChildImpl(fFirstChild)->previousSibling = newChild;
            } else {
                // this is an insert
                if (refChild == fFirstChild) {
                    // at the head of the list
                    castToNodeImpl(fFirstChild)->isFirstChild(false);
                    castToChildImpl(newChild)->nextSibling = fFirstChild;
                    castToChildImpl(newChild)->previousSibling = castToChildImpl(fFirstChild)->previousSibling;
                    castToChildImpl(fFirstChild)->previousSibling = newChild;
                    fFirstChild = newChild;
                    castToNodeImpl(newChild)->isFirstChild(true);
                } else {
                    // somewhere in the middle
                    DOMNode *prev = castToChildImpl(refChild)->previousSibling;
                    castToChildImpl(newChild)->nextSibling = refChild;
                    castToChildImpl(prev)->nextSibling = newChild;
                    castToChildImpl(refChild)->previousSibling = newChild;
                    castToChildImpl(newChild)->previousSibling = prev;
                }
            }
        }
    }

    changed();

    if (this->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if ( ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateRangeForInsertedNode(newChild);
                }
            }
        }
    }

    return newChild;
}



DOMNode *DOMParentNode::removeChild(DOMNode *oldChild)
{
    if (castToNodeImpl(this)->isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMParentNodeMemoryManager);

    if (oldChild == 0 || oldChild->getParentNode() != castToNode(this))
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMParentNodeMemoryManager);

    if (this->getOwnerDocument() !=  0  ) {
        //notify iterators
        NodeIterators* nodeIterators = ((DOMDocumentImpl *)this->getOwnerDocument())->getNodeIterators();
        if (nodeIterators != 0) {
            XMLSize_t sz = nodeIterators->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    if (nodeIterators->elementAt(i) != 0)
                        nodeIterators->elementAt(i)->removeNode(oldChild);
                }
            }
        }

        //fix other ranges for change before deleting the node
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    if (ranges->elementAt(i) != 0)
                        ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);
                }
            }
        }
    }


    // Patch linked list around oldChild
    // Note: lastChild == fFirstChild->previousSibling
    if (oldChild == fFirstChild) {
        // removing first child
        castToNodeImpl(oldChild)->isFirstChild(false);
        fFirstChild = castToChildImpl(oldChild)->nextSibling;
        if (fFirstChild != 0) {
            castToNodeImpl(fFirstChild)->isFirstChild(true);
            castToChildImpl(fFirstChild)->previousSibling = castToChildImpl(oldChild)->previousSibling;
        }
    } else {
        DOMNode *prev = castToChildImpl(oldChild)->previousSibling;
        DOMNode *next = castToChildImpl(oldChild)->nextSibling;
        castToChildImpl(prev)->nextSibling = next;
        if (next == 0) {
            // removing last child
            castToChildImpl(fFirstChild)->previousSibling = prev;
        } else {
            // removing some other child in the middle
            castToChildImpl(next)->previousSibling = prev;
        }
    }

    // Remove oldChild's references to tree
    castToNodeImpl(oldChild)->fOwnerNode = fOwnerDocument;
    castToNodeImpl(oldChild)->isOwned(false);
    castToChildImpl(oldChild)->nextSibling = 0;
    castToChildImpl(oldChild)->previousSibling = 0;

    changed();

    return oldChild;
}


DOMNode *DOMParentNode::replaceChild(DOMNode *newChild, DOMNode *oldChild)
{
    insertBefore(newChild, oldChild);
    // changed() already done.
    return removeChild(oldChild);
}



//Introduced in DOM Level 2

void DOMParentNode::normalize()
{
    DOMNode *kid, *next;
    for (kid = fFirstChild; kid != 0; kid = next)
    {
        next = castToChildImpl(kid)->nextSibling;

        // If kid and next are both Text nodes (but _not_ CDATASection,
        // which is a subclass of Text), they can be merged.
        if (next != 0 &&
            kid->getNodeType() == DOMNode::TEXT_NODE   &&
            next->getNodeType() == DOMNode::TEXT_NODE )
        {
            ((DOMTextImpl *) kid)->appendData(((DOMTextImpl *) next)->getData());
            // revisit:
            //   should I release the removed node?
            //   not released in case user still referencing it externally
            removeChild(next);
            next = kid; // Don't advance; there might be another.
        }

        // Otherwise it might be an Element, which is handled recursively
        else
            if (kid->getNodeType() == DOMNode::ELEMENT_NODE)
                kid->normalize();
    }

    // changed() will have occurred when the removeChild() was done,
    // so does not have to be reissued.
}

//Introduced in DOM Level 3

bool DOMParentNode::isEqualNode(const DOMNode* arg) const
{
    if (arg && castToNodeImpl(this)->isSameNode(arg))
        return true;

    if (arg && castToNodeImpl(this)->isEqualNode(arg))
    {
        DOMNode *kid, *argKid;
        for (kid = fFirstChild, argKid = arg->getFirstChild();
             kid != 0 && argKid != 0;
             kid = kid->getNextSibling(), argKid = argKid->getNextSibling())
        {
            if (!kid->isEqualNode(argKid))
                return false;
        }
        return (kid || argKid) ? false : true;
    }
    return false;
}


//Non-standard extension
void DOMParentNode::release()
{
    DOMNode *kid, *next;
    for (kid = fFirstChild; kid != 0; kid = next)
    {
        next = castToChildImpl(kid)->nextSibling;

        // set is Owned false before releasing its child
        castToNodeImpl(kid)->isToBeReleased(true);
        kid->release();
    }
}


XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMAttrImpl.hpp ---
#ifndef DOMAttrImpl_HEADER_GUARD_
#define DOMAttrImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMAttrImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#include <xercesc/util/XercesDefs.hpp>
#include "DOMParentNode.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/framework/XMLBuffer.hpp>
#include "DOMNodeIDMap.hpp"

XERCES_CPP_NAMESPACE_BEGIN

class DOMElementImpl;
class DOMTypeInfoImpl;

class CDOM_EXPORT DOMAttrImpl: public DOMAttr {

public:
    DOMNodeImpl        fNode;
    DOMParentNode      fParent;
    const XMLCh       *fName;

private:
    const DOMTypeInfoImpl *fSchemaType;

public:
    DOMAttrImpl(DOMDocument *ownerDocument, const XMLCh *aName);
    DOMAttrImpl(const DOMAttrImpl &other, bool deep=false);
    virtual ~DOMAttrImpl();

     // Add all functions that are pure virtual in DOMNODE
    DOMNODE_FUNCTIONS;

    virtual const XMLCh *       getName() const;
    virtual bool getSpecified() const;
    virtual const XMLCh * getValue() const;
    virtual void setSpecified(bool arg);
    virtual void setValue(const XMLCh * value);
    virtual bool isId() const;

    //Introduced in DOM Level 2
    DOMElement *getOwnerElement() const;
    void setOwnerElement(DOMElement *ownerElem);    //internal use only

    // helper function for DOM Level 3 renameNode
    virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);

    virtual const DOMTypeInfo* getTypeInfo() const;

    //helper function for DOM Level 3 TypeInfo
    virtual void setTypeInfo(const DOMTypeInfoImpl* typeInfo);

   // helper method that sets this attr to an idnode and places it into the document map
   virtual void addAttrToIDNodeMap();

   // helper to remove this attr from from the id map if it is in there
   virtual void removeAttrFromIDNodeMap();

private:
    void getTextValue(DOMNode* node, XMLBuffer& buf) const;

    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    DOMAttrImpl& operator=(const DOMAttrImpl&);
};

inline void DOMAttrImpl::removeAttrFromIDNodeMap()
{
    if (fNode.isIdAttr()) {
        ((DOMDocumentImpl *)getOwnerDocument())->getNodeIDMap()->remove(this);
        fNode.isIdAttr(false);
    }
}

inline void DOMAttrImpl::addAttrToIDNodeMap()
{
    if (fNode.isIdAttr()) 
        return;

    fNode.isIdAttr(true);

    // REVIST For now, we don't worry about what happens if the new
    // name conflicts as per setValue
    DOMDocumentImpl *doc = (DOMDocumentImpl *)(fParent.fOwnerDocument);

    if (doc->fNodeIDMap == 0)
        doc->fNodeIDMap = new (doc) DOMNodeIDMap(500, doc);

    doc->getNodeIDMap()->add(this);
}

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMDeepNodeListImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMDeepNodeListImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMDeepNodeListImpl.hpp"
#include "DOMElementImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
#include "DOMNodeImpl.hpp"
#include <xercesc/util/XMLUniDefs.hpp>
#include <limits.h>

XERCES_CPP_NAMESPACE_BEGIN


static const XMLCh kAstr[] = {chAsterisk, chNull};

DOMDeepNodeListImpl::DOMDeepNodeListImpl(const DOMNode *rootNode,
                                       const XMLCh *tagName)
    : fRootNode(rootNode)
    , fChanges(0)
    , fCurrentNode(0)
    , fCurrentIndexPlus1(0)
    , fNamespaceURI(0)
    , fMatchAllURI(false)
    , fMatchURIandTagname(false)
{
    fTagName = ((DOMDocumentImpl *)(castToNodeImpl(rootNode)->getOwnerDocument()))->getPooledString(tagName);
    fMatchAll = XMLString::equals(fTagName, kAstr);
}


//DOM Level 2
DOMDeepNodeListImpl::DOMDeepNodeListImpl(const DOMNode *rootNode,
                                       const XMLCh *namespaceURI,
                                       const XMLCh *localName)
    : fRootNode(rootNode)
    , fChanges(0)
    , fCurrentNode(0)
    , fCurrentIndexPlus1(0)
    , fMatchAllURI(false)
    , fMatchURIandTagname(true)
{
    fTagName = ((DOMDocumentImpl *)(castToNodeImpl(rootNode)->getOwnerDocument()))->getPooledString(localName);
    fMatchAll = XMLString::equals(fTagName, kAstr);
    fMatchAllURI = XMLString::equals(namespaceURI, kAstr);
    fNamespaceURI = ((DOMDocumentImpl *)(castToNodeImpl(rootNode)->getOwnerDocument()))->getPooledString(namespaceURI);
}


DOMDeepNodeListImpl::~DOMDeepNodeListImpl()
{
}

XMLSize_t DOMDeepNodeListImpl::getLength() const
{
    // Reset cache to beginning of list
    item(0);

    // Preload all matching elements. (Stops when we run out of subtree!)
    item(INT_MAX);
    return fCurrentIndexPlus1;
}


DOMNode *DOMDeepNodeListImpl::item(XMLSize_t index) const
{
    return ((DOMDeepNodeListImpl*)this)->cacheItem(index);
}

// Start from the first child and count forward, 0-based. index>length-1
// should return 0.
//
// Attempts to do only work actually requested, cache work already
// done, and to flush that cache when the tree has changed.
//
// LIMITATION: ????? Unable to tell relevant tree-changes from
// irrelevant ones.  Doing so in a really useful manner would seem
// to involve a tree-walk in its own right, or maintaining our data
// in a parallel tree.
DOMNode *DOMDeepNodeListImpl::cacheItem(XMLSize_t index)
{
    XMLSize_t currentIndexPlus1 = fCurrentIndexPlus1;
    DOMNode *currentNode = fCurrentNode;

    if (castToParentImpl(fRootNode)->changes() != fChanges)
    {
        // Tree changed. Do it all from scratch!
        currentIndexPlus1 = 0;
        currentNode = (DOMNode *)fRootNode;
        fChanges = castToParentImpl(fRootNode)->changes();
    }
    else if (currentIndexPlus1 > index+1)
    {
        // Interested in something before cached node.  Do it all from scratch!
        currentIndexPlus1 = 0;
        currentNode = (DOMNode *)fRootNode;
    }
    else if (index+1 == currentIndexPlus1)
    {
        // What luck!  User is interested in cached node.
        return currentNode;
    }

    DOMNode *nextNode = 0;

// revisit - ???? How efficient is this loop? ????

    // Start at the place in the tree at which we're
    // currently pointing and count off nodes until we
    // reach the node of interest or the end of the tree.
    while (currentIndexPlus1 < index+1 && currentNode != 0)
    {
        nextNode = nextMatchingElementAfter(currentNode);
        if (nextNode == 0)
            break;
        currentNode = nextNode;
        currentIndexPlus1++;
    }

    fCurrentNode = currentNode;
    fCurrentIndexPlus1 = currentIndexPlus1;

    // If we found a node at the requested index, make that the current node
    if (nextNode != 0)
    {
        return currentNode;
    }

    // If we didn't find a node at the requested index, return 0
    return 0;
}



/* Iterative tree-walker. When you have a Parent link, there's often no
need to resort to recursion. NOTE THAT only Element nodes are matched
since we're specifically supporting getElementsByTagName().
*/
DOMNode *DOMDeepNodeListImpl::nextMatchingElementAfter(DOMNode *current)
{
    DOMNode *next;
    while (current != 0)
    {
        // Look down to first child.
        if (current->hasChildNodes())
        {
            current = current->getFirstChild();
        }
        // Look right to sibling (but not from root!)
        else
        {
            if (current != fRootNode && 0 != (next = current->getNextSibling()))
            {
                current = next;
            }
            // Look up and right (but not past root!)
            else
            {
                next = 0;
                for (;
                     current != fRootNode; // Stop on return to starting point
                     current = current->getParentNode())
                {
                    next = current->getNextSibling();
                    if (next != 0)
                        break;
                }
                current = next;
            }
        }

        // Have we found an Element with the right tagName?
        // ("*" matches anything.)
        if (current != 0 && current != fRootNode &&
            current->getNodeType() == DOMNode::ELEMENT_NODE) {
            DOMElement *currElement = (DOMElement *)current;

            if (!fMatchURIandTagname) {        //DOM Level 1
                if (fMatchAll ||
                    XMLString::equals(currElement->getTagName(), fTagName))
                    return current;
            } else {        //DOM Level 2
                if (!fMatchAllURI &&
                    !XMLString::equals(current->getNamespaceURI(), fNamespaceURI))
                    continue;

                if (fMatchAll ||
                    XMLString::equals(current->getLocalName(), fTagName))
                    return current;
            }
        }

        // Otherwise continue walking the tree
    }
    // Fell out of tree-walk; no more instances found
    return 0;
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMLocatorImpl.hpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: DOMLocatorImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */


#ifndef DOMLOCATORIMPL_HPP
#define DOMLOCATORIMPL_HPP

#include <xercesc/dom/DOMLocator.hpp>

XERCES_CPP_NAMESPACE_BEGIN



/**
  * Introduced in DOM Level 3
  *
  * Implementation of a DOMLocator interface.
  *
  * @see DOMLocator#DOMLocator
  */

class CDOM_EXPORT DOMLocatorImpl : public DOMLocator
{
public:
    /** @name Constructors and Destructor */
    //@{

    /** Constructor */
    DOMLocatorImpl();

    DOMLocatorImpl
    (
        const XMLSSize_t lineNum
        , const XMLSSize_t columnNum
        , DOMNode* const errorNode
        , const XMLCh* const uri
        , const XMLSSize_t offset = -1
    );

    /** Desctructor */
    virtual ~DOMLocatorImpl();

    //@}

    /** @name Get function */
    //@{

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the line number where the error occured. The value is -1 if there is
    * no line number available.
    *
    * @see #setLineNumber
    */
    virtual XMLSSize_t getLineNumber() const;

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the column number where the error occured. The value is -1 if there
    * is no column number available.
    *
    * @see #setColumnNumber
    */
    virtual XMLSSize_t getColumnNumber() const;

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the byte or character offset into the input source, if we're parsing
    * a file or a byte stream then this will be the byte offset into that
    * stream, but if a character media is parsed then the offset will be the
    * character offset. The value is -1 if there is no offset available.
    *
    * @see #setOffset
    */
    virtual XMLSSize_t getOffset() const;

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the DOM Node where the error occured, or <code>null</code> if there
    * is no node available.
    *
    * @see #setErrorNode
    */
    virtual DOMNode* getErrorNode() const;

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the URI where the error occured, or <code>null</code> if there is no
    * URI available.
    *
    * @see #setURI
    */
    virtual const XMLCh* getURI() const;

    //@}


   /** @name Set function */
    //@{

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the line number of the error
    *
    * @param lineNumber the line number to set
    *
    * @see #getLinNumner
    */
    virtual void setLineNumber(const XMLSSize_t lineNumber);

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the column number of the error
    *
    * @param columnNumber the column number to set.
    *
    * @see #getColumnNumner
    */
    virtual void setColumnNumber(const XMLSSize_t columnNumber);

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the byte/character offset.
    *
    * @param offset the byte/characte offset to set.
    *
    * @see #getOffset
    */
    virtual void setOffset(const XMLSSize_t offset);

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the DOM Node where the error occured
    *
    * @param errorNode the DOM Node to set
    *
    * @see #getErrorNode
    */
    virtual void setErrorNode(DOMNode* const errorNode);

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the URI where the error occured
    *
    * @param uri the URI to set.
    *
    * @see #getURI
    */
    virtual void setURI(const XMLCh* const uri);

    //@}


private :
    /* Unimplemented constructors and operators */

    /* Copy constructor */
    DOMLocatorImpl(const DOMLocatorImpl&);

    /* Assignment operator */
    DOMLocatorImpl& operator=(const DOMLocatorImpl&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fLineNum
    //  fColumnNum
    //      Track line/column number of where the error occured
    //
    //  fOffset
    //      Track character/byte offset in the input source where the error
    //      occured
    //
    //  fErrorNode
    //      Current error node where the error occured
    //
    //  fURI
    //      The uri where the error occured
    // -----------------------------------------------------------------------
    XMLSSize_t   fLineNum;
    XMLSSize_t   fColumnNum;
    XMLSSize_t   fOffset;
    DOMNode*     fErrorNode;
    const XMLCh* fURI;
};


// ---------------------------------------------------------------------------
//  DOMLocatorImpl: Getter methods
// ---------------------------------------------------------------------------
inline XMLSSize_t DOMLocatorImpl::getLineNumber() const
{
    return fLineNum;
}

inline XMLSSize_t DOMLocatorImpl::getColumnNumber() const
{
    return fColumnNum;
}

inline XMLSSize_t DOMLocatorImpl::getOffset() const
{
    return fOffset;
}

inline DOMNode* DOMLocatorImpl::getErrorNode() const
{
    return fErrorNode;
}

inline const XMLCh* DOMLocatorImpl::getURI() const
{
    return fURI;
}


// ---------------------------------------------------------------------------
//  DOMLocatorImpl: Setter methods
// ---------------------------------------------------------------------------
inline void DOMLocatorImpl::setLineNumber(const XMLSSize_t lineNumber)
{
    fLineNum = lineNumber;
}

inline void DOMLocatorImpl::setColumnNumber(const XMLSSize_t columnNumber)
{
    fColumnNum = columnNumber;
}

inline void DOMLocatorImpl::setOffset(const XMLSSize_t offset)
{
    fOffset = offset;
}

inline void DOMLocatorImpl::setErrorNode(DOMNode* const errorNode)
{
    fErrorNode = errorNode;
}

inline void DOMLocatorImpl::setURI(const XMLCh* const uri)
{
    fURI = uri;
}

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMNodeIteratorImpl.hpp ---
#ifndef DOMNodeIteratorImpl_HEADER_GUARD_
#define DOMNodeIteratorImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMNodeIteratorImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

//////////////////////////////////////////////////////////////////////
// DOMNodeIteratorImpl.hpp: interface for the DOMNodeIteratorImpl class.
//
//////////////////////////////////////////////////////////////////////

#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMNodeIterator.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class CDOM_EXPORT DOMNodeIteratorImpl : public DOMNodeIterator {
    private:
        //
        // Data
        //
        // The root.
        DOMNode* fRoot;

        // The Document used to create this iterator
        DOMDocument* fDocument;

        // The whatToShow mask.
        unsigned long fWhatToShow;

        // The NodeFilter reference.
        DOMNodeFilter* fNodeFilter;


        // The expandEntity reference flag.
        bool  fExpandEntityReferences;
        bool fDetached;


        //
        // Iterator state - current node and direction.
        //
        // Note: The current node and direction are sufficient to implement
        // the desired behaviour of the current pointer being _between_
        // two nodes. The fCurrentNode is actually the last node returned,
        // and the
        // direction is whether the pointer is in front or behind this node.
        // (usually akin to whether the node was returned via nextNode())
        // (eg fForward = true) or previousNode() (eg fForward = false).
        // The last Node returned.
        DOMNode* fCurrentNode;

        // The direction of the iterator on the fCurrentNode.
        //  <code>
        //  nextNode()  ==      fForward = true;<br>
        //  previousNode() ==   fForward = false;<br>
        //  </code>
        bool fForward;

    public:
        virtual ~DOMNodeIteratorImpl ();
        DOMNodeIteratorImpl (
            DOMDocument* fDocument,
            DOMNode* root,
            unsigned long whatToShow,
            DOMNodeFilter* nodeFilter,
            bool expandEntityRef);

        DOMNodeIteratorImpl ( const DOMNodeIteratorImpl& toCopy);
        DOMNodeIteratorImpl& operator= (const DOMNodeIteratorImpl& other);

        virtual DOMNode* getRoot ();                	
        virtual unsigned long getWhatToShow ();
        virtual DOMNodeFilter* getFilter ();
        // Get the expandEntity reference flag.
        virtual bool getExpandEntityReferences();

        virtual DOMNode* nextNode ();
        virtual DOMNode* previousNode ();
        virtual void detach ();

        virtual void release();
        void removeNode (DOMNode* node);

    private:
        DOMNode* matchNodeOrParent (DOMNode* node);
        DOMNode* nextNode (DOMNode* node, bool visitChildren);
        DOMNode* previousNode (DOMNode* node);
        bool acceptNode (DOMNode* node);

};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMTextImpl.hpp ---
#ifndef DOMTextImpl_HEADER_GUARD_
#define DOMTextImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMTextImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//



#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMText.hpp>

#include "DOMChildNode.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMCharacterDataImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMTextImpl: public DOMText {
public:
    DOMNodeImpl             fNode;
    DOMChildNode            fChild;
    DOMCharacterDataImpl    fCharacterData;

public:
    DOMTextImpl(DOMDocument* ownerDoc, const XMLCh* data);
    DOMTextImpl(const DOMTextImpl& other, bool deep=false);

    virtual                ~DOMTextImpl();
    virtual DOMText*        splitText(XMLSize_t offset);
    // DOM Level 3
    virtual bool            getIsWhitespaceInElementContent() const;
    virtual const XMLCh*    getWholeText();
    virtual DOMText*        replaceWholeText(const XMLCh* content);

    // non-standard extension
    virtual bool            isIgnorableWhitespace() const;

    // Declare the functions coming from DOMNode.
    DOMNODE_FUNCTIONS;


    // All of the functions coming from DOMCharacterData
    virtual const XMLCh*    getData() const;
    virtual XMLSize_t       getLength() const;
    virtual const XMLCh*    substringData(XMLSize_t offset,
                                          XMLSize_t count) const;
    virtual void            appendData(const XMLCh *arg);
    virtual void            insertData(XMLSize_t offset, const  XMLCh *arg);
    virtual void            deleteData(XMLSize_t offset,
                                       XMLSize_t count);
    virtual void            replaceData(XMLSize_t offset,
                                        XMLSize_t count,
                                        const XMLCh *arg);
    virtual void            setData(const XMLCh *data);

protected:
    virtual void            setIgnorableWhitespace(bool ignorable);
    friend class            AbstractDOMParser;

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMTextImpl & operator = (const DOMTextImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMCharacterDataImpl.hpp ---
#ifndef DOMCharacterDataImpl_HEADER_GUARD_
#define DOMCharacterDataImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMCharacterDataImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/XMLString.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class DOMNode;
class DOMDocument;
class DOMDocumentImpl;
class DOMBuffer;

// Instances of DOMCharacterDataImpl appear as members of node types
//   that implement the DOMCharacterData interfaces.
//   Operations in those classes are delegated to this class.
//
class CDOM_EXPORT DOMCharacterDataImpl
{
public:
    DOMBuffer* fDataBuf;
    // for the buffer bid
    DOMDocumentImpl* fDoc;

public:
                   DOMCharacterDataImpl(DOMDocument *doc, const XMLCh *dat);
                   DOMCharacterDataImpl(const DOMCharacterDataImpl &other);
                   ~DOMCharacterDataImpl();
    const          XMLCh * getNodeValue() const;
    void           setNodeValue(const XMLCh * value);
    void           appendData(const DOMNode *node, const  XMLCh *data);
    void           deleteData(const DOMNode *node, XMLSize_t offset, XMLSize_t count);
    const XMLCh*   getData() const;
    XMLSize_t      getLength() const;
    void           insertData(const DOMNode *node, XMLSize_t offset, const XMLCh * data);
    void           replaceData(const DOMNode *node, XMLSize_t offset, XMLSize_t count, const XMLCh * data);
    void           setData(const DOMNode *node, const XMLCh * arg);
    void           setNodeValue(const DOMNode *node, const XMLCh *value);


    const XMLCh*   substringData(const DOMNode *node, XMLSize_t offset, XMLSize_t count) const;
    void           releaseBuffer();

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMCharacterDataImpl & operator = (const DOMCharacterDataImpl &);   
};

#define GetDOMCharacterDataImplMemoryManager GET_DIRECT_MM(fDoc)

XERCES_CPP_NAMESPACE_END


#endif

--- NEW FILE: Makefile.in ---
#
# 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.
#
#
#
# $Id: Makefile.in,v 1.1 2008/02/19 20:16:27 zolmol Exp $
#

PLATFORM = @platform@
CC  = @cc@
CXX = @cxx@
CXXVER = @cxxver@
GCC = @GCC@
GXX = @GXX@
CXXFLAGS = @cxxflags@
CFLAGS = @cflags@
PREFIX = @prefix@
PREFIX_INCLUDE = @prefix_include@
LDFLAGS = @ldflags@
LIBS = @libs@
OSVER = @osver@
USELIBWWW = @uselibwww@
MESSAGELOADER = @messageloader@
TRANSCODER = @transcoder@
THREADS = @threads@

MODULE = dom
SUBMODULE = impl

include ../../Makefile.incl

DOM_IMPL_CPP_PUBHEADERS =

DOM_IMPL_CPP_PRIVHEADERS =  \
	DOMAttrImpl.hpp \
	DOMAttrMapImpl.hpp \
	DOMAttrNSImpl.hpp \
	DOMCasts.hpp \
	DOMCDATASectionImpl.hpp \
	DOMCharacterDataImpl.hpp \
	DOMChildNode.hpp \
	DOMCommentImpl.hpp \
        DOMConfigurationImpl.hpp \
	DOMDeepNodeListImpl.hpp \
	DOMDeepNodeListPool.hpp \
	DOMDocumentFragmentImpl.hpp \
	DOMDocumentImpl.hpp \
	DOMDocumentTypeImpl.hpp \
	DOMImplementationImpl.hpp \
	DOMElementImpl.hpp \
	DOMElementNSImpl.hpp \
	DOMEntityImpl.hpp \
	DOMEntityReferenceImpl.hpp \
	DOMErrorImpl.hpp \
	DOMLocatorImpl.hpp \
	DOMNamedNodeMapImpl.hpp \
	DOMNodeIDMap.hpp \
	DOMNodeImpl.hpp \
	DOMNodeIteratorImpl.hpp \
	DOMNodeListImpl.hpp \
	DOMNodeVector.hpp \
	DOMNormalizer.hpp \
	DOMNotationImpl.hpp \
	DOMParentNode.hpp \
	DOMProcessingInstructionImpl.hpp \
	DOMRangeImpl.hpp \
	DOMStringPool.hpp \
	DOMTextImpl.hpp \
	DOMTreeWalkerImpl.hpp \
	DOMTypeInfoImpl.hpp \
	DOMWriterImpl.hpp \
	XSDElementNSImpl.hpp

DOM_IMPL_C_FILES = \
	DOMDeepNodeListPool.c


DOM_IMPL_CPP_OBJECTS = \
	DOMAttrImpl.$(TO) \
	DOMAttrMapImpl.$(TO) \
	DOMAttrNSImpl.$(TO) \
	DOMCDATASectionImpl.$(TO) \
	DOMCharacterDataImpl.$(TO) \
	DOMChildNode.$(TO) \
	DOMCommentImpl.$(TO) \
        DOMConfigurationImpl.$(TO) \
	DOMDeepNodeListImpl.$(TO) \
	DOMDocumentFragmentImpl.$(TO) \
	DOMDocumentImpl.$(TO) \
	DOMDocumentTypeImpl.$(TO) \
	DOMImplementationImpl.$(TO) \
	DOMImplementationRegistry.$(TO) \
	DOMElementImpl.$(TO) \
	DOMElementNSImpl.$(TO) \
	DOMEntityImpl.$(TO) \
	DOMEntityReferenceImpl.$(TO) \
	DOMErrorImpl.$(TO) \
	DOMLocatorImpl.$(TO) \
	DOMNamedNodeMapImpl.$(TO) \
	DOMNodeIDMap.$(TO) \
	DOMNodeImpl.$(TO) \
	DOMNodeIteratorImpl.$(TO) \
	DOMNodeListImpl.$(TO) \
	DOMNodeVector.$(TO) \
	DOMNormalizer.$(TO) \
	DOMNotationImpl.$(TO) \
	DOMParentNode.$(TO) \
	DOMProcessingInstructionImpl.$(TO) \
	DOMRangeImpl.$(TO) \
	DOMStringPool.$(TO) \
	DOMTextImpl.$(TO) \
	DOMTreeWalkerImpl.$(TO) \
	DOMTypeInfoImpl.$(TO) \
	DOMWriterImpl.$(TO) \
	XSDElementNSImpl.$(TO)


all::	includes $(DOM_IMPL_CPP_OBJECTS)

includes::	pubheaders $(DOM_IMPL_C_FILES)

pubheaders::
	$Qmkdir -p $(XML_INC_DIR)/$(MODULE)/$(SUBMODULE)
	@echo "  (CP)  $(XML_INC_DIR)/$(MODULE)/$(SUBMODULE)"
	$Q$(CP) $(DOM_IMPL_CPP_PUBHEADERS) $(DOM_IMPL_C_FILES) $(XML_INC_DIR)/$(MODULE)/$(SUBMODULE)

# this may generate unnecessary dependencies, but it makes life easier
depend:: includes
	@echo "  (DEP)"
	$Q$(MAKE_DEPEND) $(XML_INCL)  *.cpp > $(DEPFILE)

clean::
	@echo "Making clean in $(MODULE)/$(SUBMODULE) ..."
	$Q$(RM2) $(addprefix $(XML_OBJ_DIR)/,$(DOM_IMPL_CPP_OBJECTS))

distclean::	clean
	$Q$(RM) Makefile $(DEPFILE)
	@echo "Removing all $(MODULE)/$(SUBMODULE) header files ..."
ifneq ($(strip $(DOM_IMPL_CPP_PUBHEADERS)),)
	$Q$(RM2) $(addprefix $(XML_INC_DIR)/$(MODULE)/$(SUBMODULE)/,$(DOM_IMPL_CPP_PUBHEADERS))
endif

install::
	$Qmkdir -p $(DESTDIR)$(PREFIX_INCLUDE)/$(MODULE)/$(SUBMODULE)
	@echo "  (CP)"
	$Q$(CP) $(DOM_IMPL_CPP_PUBHEADERS) $(DOM_IMPL_C_FILES) $(DESTDIR)$(PREFIX_INCLUDE)/$(MODULE)/$(SUBMODULE)

--- NEW FILE: DOMErrorImpl.cpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: DOMErrorImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMErrorImpl.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMLocator.hpp>

XERCES_CPP_NAMESPACE_BEGIN


// ---------------------------------------------------------------------------
//  DOMErrorImpl: Constructors and Destructor
// ---------------------------------------------------------------------------
DOMErrorImpl::DOMErrorImpl(const short severity) :
fAdoptLocation(false)
, fSeverity(severity)
, fMessage(0)
, fLocation(0)
, fType(0)
, fRelatedData(0)
{
}

DOMErrorImpl::DOMErrorImpl(const short severity,
                           const XMLCh* const message,
                           DOMLocator* const location) :
fAdoptLocation(false)
, fSeverity(severity)
, fMessage(message)
, fLocation(location)
, fType(0)
, fRelatedData(0)
{
}

DOMErrorImpl::DOMErrorImpl(const short severity,
                           const XMLCh* type,
                           const XMLCh* message,
                           void* relatedData) :
fAdoptLocation(false)
, fSeverity(severity)
, fMessage(message)
, fLocation(0)
, fType(type)
, fRelatedData(relatedData)
{

}

DOMErrorImpl::~DOMErrorImpl()
{
    if (fAdoptLocation)
        delete fLocation;
}

// ---------------------------------------------------------------------------
//  DOMErrorImpl: Setter methods
// ---------------------------------------------------------------------------
void DOMErrorImpl::setLocation(DOMLocator* const location)
{
    if (fAdoptLocation)
        delete fLocation;

    fLocation = location;
}

void DOMErrorImpl::setRelatedException(void*) const
{
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0);
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMStringPool.hpp ---
#ifndef DOMStringPool_HEADER_GUARD_
#define DOMStringPool_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMStringPool.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN


struct  DOMStringPoolEntry;
class   DOMDocumentImpl;

//
// DOMStringPool is a hash table of XMLCh* Strings.
//  Each DOM Document maintains a DOMStringPool containing a XMLCh* String
//  for each Element tag name and Attribute Name that has been added
//  to the document.  When creating additional elements or attributes,
//  if the name has been seen before, the already existing string
//  will be reused.
//
class DOMStringPool
{
public:
    DOMStringPool(int  hashTableSize, DOMDocumentImpl *doc);
    ~DOMStringPool();

    const XMLCh *getPooledString(const XMLCh *in);


private:
    DOMStringPool(const DOMStringPool &other);      // Copy constructor and assignment
    DOMStringPool& operator = (const DOMStringPool &other); //  of DOMStringPool are not supported.


    DOMDocumentImpl     *fDoc;
    DOMStringPoolEntry **fHashTable;
    int                 fHashTableSize;

};


//
// DOMBuffer is a lightweight text buffer
// The buffer is not nul terminated until some asks to see the raw buffer
// contents. This also avoids overhead during append operations.
class DOMBuffer
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    DOMBuffer(DOMDocumentImpl *doc, int capacity = 31);

    DOMBuffer(DOMDocumentImpl *doc, const XMLCh* string);

    ~DOMBuffer()
    {
    }

    // -----------------------------------------------------------------------
    //  Buffer Management
    // -----------------------------------------------------------------------
    void append
    (
        const   XMLCh* const    chars
        , const unsigned int    count = 0
    );

    const XMLCh* getRawBuffer() const
    {
        fBuffer[fIndex] = 0;
        return fBuffer;
    }

    void reset()
    {
        fIndex = 0;
        fBuffer[0] = 0;
    }

    void set
    (
        const   XMLCh* const    chars
        , const unsigned int    count = 0
    );

    void chop
    (
        const unsigned int    count
    )
    {
        fBuffer[count] = 0;
        fIndex = count;
    }


    // -----------------------------------------------------------------------
    //  Getters
    // -----------------------------------------------------------------------
    unsigned int getLen() const
    {
        return fIndex;
    }

    // -----------------------------------------------------------------------
    //  Private helpers
    // -----------------------------------------------------------------------
    void expandCapacity(const unsigned int extraNeeded);


private :
    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fBuffer
    //      The pointer to the buffer data. Its grown as needed. Its always
    //      one larger than fCapacity, to leave room for the null terminator.
    //
    //  fIndex
    //      The current index into the buffer, as characters are appended
    //      to it. If its zero, then the buffer is empty.
    //
    //  fCapacity
    //      The current capacity of the buffer. Its actually always one
    //      larger, to leave room for the null terminator.
    //
    //  fDoc
    //      For allocating memory
    // -----------------------------------------------------------------------
    XMLCh*          fBuffer;
    unsigned int    fIndex;
    unsigned int    fCapacity;
    DOMDocumentImpl* fDoc;

    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMBuffer(const DOMBuffer &);
    DOMBuffer & operator = (const DOMBuffer &);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMDocumentFragmentImpl.hpp ---
#ifndef DOMDocumentFragmentImpl_HEADER_GUARD_
#define DOMDocumentFragmentImpl_HEADER_GUARD_
/*
 * 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.
 */

/*
 * $Id: DOMDocumentFragmentImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMDocumentFragment.hpp>
#include "DOMParentNode.hpp"
#include "DOMNodeImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMDocumentFragmentImpl: public DOMDocumentFragment {
private:
    DOMNodeImpl     fNode;
    DOMParentNode   fParent;



protected:
    DOMDocumentFragmentImpl(DOMDocument *);

private:
    DOMDocumentFragmentImpl(const DOMDocumentFragmentImpl &other, bool deep);
    friend class DOMDocumentImpl;

    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMDocumentFragmentImpl & operator = (const DOMDocumentFragmentImpl &);

public:
    virtual ~DOMDocumentFragmentImpl();

    // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMNormalizer.cpp ---
/*
 * Copyright 2001-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.
 */

#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMErrorHandler.hpp>
#include <xercesc/dom/DOMError.hpp>
#include <xercesc/dom/DOMText.hpp>
#include <xercesc/framework/XMLBuffer.hpp>

#include <xercesc/util/Mutexes.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLInitializer.hpp>
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

#include "DOMConfigurationImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMElementImpl.hpp"
#include "DOMErrorImpl.hpp"
#include "DOMEntityReferenceImpl.hpp"
#include "DOMLocatorImpl.hpp"
#include "DOMNormalizer.hpp"
#include "DOMTextImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  Local static data
// ---------------------------------------------------------------------------

static bool            sRegistered = false;

static XMLMutex*       sNormalizerMutex = 0;
static XMLRegisterCleanup normalizerMutexCleanup;

static XMLMsgLoader*   gMsgLoader = 0;
static XMLRegisterCleanup cleanupMsgLoader;


// ---------------------------------------------------------------------------
//  Local, static functions
// ---------------------------------------------------------------------------

//  Cleanup for the message loader
void DOMNormalizer::reinitMsgLoader()
{
	delete gMsgLoader;
	gMsgLoader = 0;
}

//  Cleanup for the normalizer mutex
void DOMNormalizer::reinitNormalizerMutex()
{
    delete sNormalizerMutex;
    sNormalizerMutex = 0;
    sRegistered = false;
}

//
//  We need to fault in this mutex. But, since its used for synchronization
//  itself, we have to do this the low level way using a compare and swap.
//
static XMLMutex& gNormalizerMutex()
{
    if (!sNormalizerMutex)
    {
        XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex);

        // If we got here first, then register it and set the registered flag
        if (!sRegistered)
        {
            sNormalizerMutex = new XMLMutex(XMLPlatformUtils::fgMemoryManager);
            normalizerMutexCleanup.registerCleanup(DOMNormalizer::reinitNormalizerMutex);
            sRegistered = true;
        }
    }
    return *sNormalizerMutex;
}

static XMLMsgLoader& gNormalizerMsgLoader()
{
    if (!gMsgLoader)
    {
        XMLMutexLock lockInit(&gNormalizerMutex());

        // If we haven't loaded our message yet, then do that
        if (!gMsgLoader)
        {
            gMsgLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgXMLErrDomain);
            if (!gMsgLoader)
                XMLPlatformUtils::panic(PanicHandler::Panic_CantLoadMsgDomain);

            // Register this object to be cleaned up at termination
            cleanupMsgLoader.registerCleanup(DOMNormalizer::reinitMsgLoader);
        }
    }

    return *gMsgLoader;
}

void XMLInitializer::initializeDOMNormalizerMsgLoader()
{
    gMsgLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgXMLErrDomain);

    // Register this object to be cleaned up at termination
    if (gMsgLoader) {
        cleanupMsgLoader.registerCleanup(DOMNormalizer::reinitMsgLoader);
    }
}

DOMNormalizer::DOMNormalizer(MemoryManager* const manager) 
    : fDocument(0)
    , fConfiguration(0)
    , fErrorHandler(0)
    , fNSScope(0)
    , fNewNamespaceCount(1)
    , fMemoryManager(manager)
{
    fNSScope = new (fMemoryManager) InScopeNamespaces(fMemoryManager);
}

DOMNormalizer::~DOMNormalizer() {
    delete fNSScope;
}

void DOMNormalizer::normalizeDocument(DOMDocumentImpl *doc) {
 
    fDocument = doc;
    fConfiguration = (DOMConfigurationImpl*)doc->getDOMConfiguration();
    DOMConfigurationImpl *dci = (DOMConfigurationImpl*)fDocument->getDOMConfiguration();
    if(dci)
        fErrorHandler = dci->getErrorHandler();            
    else 
        fErrorHandler = 0;

    DOMNode *child = 0;
    DOMNode *next = 0;
    ((DOMNormalizer *)this)->fNewNamespaceCount = 1;

    for(child = doc->getFirstChild();child != 0; child = next) {
        next = child->getNextSibling();
        child = normalizeNode(child);
        if(child != 0) {
            next = child;
        }
    }
}

DOMNode * DOMNormalizer::normalizeNode(DOMNode *node) const {
    switch(node->getNodeType()) {
    case DOMNode::ELEMENT_NODE: {
        fNSScope->addScope(fMemoryManager);
        DOMNamedNodeMap *attrMap = node->getAttributes();

        if(fConfiguration->featureValues & DOMConfigurationImpl::FEATURE_NAMESPACES) {
            namespaceFixUp((DOMElementImpl*)node);
        }
        else {
            //this is done in namespace fixup so no need to do it if namespace is on 
            if(attrMap) {
                for(XMLSize_t i = 0; i < attrMap->getLength(); i++) {
                    attrMap->item(i)->normalize();
                }
            }
        }

        DOMNode *child = node->getFirstChild();
        DOMNode *next = 0;
        for (; child != 0; child = next) {
            next = child->getNextSibling();
            child = normalizeNode(child);
            if(child != 0) {
                next = child;
            }
        }
        fNSScope->removeScope();
        break;
    }
    case DOMNode::COMMENT_NODE: {  
        if (!(fConfiguration->featureValues & DOMConfigurationImpl::FEATURE_COMMENTS)) {
            DOMNode *prevSibling = node->getPreviousSibling();
            DOMNode *parent = node->getParentNode();
            // remove the comment node
            parent->removeChild(node);
            if (prevSibling != 0 && prevSibling->getNodeType() == DOMNode::TEXT_NODE) {
                DOMNode *nextSibling = prevSibling->getNextSibling();
                if (nextSibling != 0 && nextSibling->getNodeType() == DOMNode::TEXT_NODE) {
                    ((DOMTextImpl*)nextSibling)->insertData(0, prevSibling->getNodeValue());
                    parent->removeChild(prevSibling);
                    return nextSibling;
                }
            }
        }
        break;
    }
    case DOMNode::CDATA_SECTION_NODE: {
        if (!(fConfiguration->featureValues & DOMConfigurationImpl::FEATURE_CDATA_SECTIONS)) {
            // convert CDATA to TEXT nodes
            DOMText *text = fDocument->createTextNode(node->getNodeValue());
            DOMNode *parent = node->getParentNode();
            DOMNode *prevSibling = node->getPreviousSibling();
            node = parent->replaceChild(text, node);
            if (prevSibling != 0 && prevSibling->getNodeType() == DOMNode::TEXT_NODE) {
                text->insertData(0, prevSibling->getNodeValue());
                parent->removeChild(prevSibling);
            }
            return text; // Don't advance; 
        }
        break;
    }
    case DOMNode::TEXT_NODE: {
        DOMNode *next = node->getNextSibling();
        
        if(next != 0 && next->getNodeType() == DOMNode::TEXT_NODE) {
            ((DOMText*)node)->appendData(next->getNodeValue());
            node->getParentNode()->removeChild(next);
            return node;
        } else if (XMLString::stringLen(node->getNodeValue()) == 0) {
            node->getParentNode()->removeChild(node);
        }

    }
    }

    return 0;
}


void DOMNormalizer::namespaceFixUp(DOMElementImpl *ele) const {
    DOMAttrMapImpl *attrMap = ele->fAttributes;

    int len = attrMap->getLength();
    //get the ns info from the attrs
    for(int i = 0; i < len; i++) {
        DOMAttr *at = (DOMAttr*)attrMap->item(i);

        //normalize the attr whatever happens
        at->normalize();

        const XMLCh *uri = at->getNamespaceURI();
        const XMLCh *value = at->getNodeValue();
            
        if(XMLString::equals(XMLUni::fgXMLNSURIName, uri)) {
            if(XMLString::equals(XMLUni::fgXMLNSURIName, value)) {
                error(XMLErrs::NSDeclInvalid, ele);
            }
            else {
                const XMLCh *prefix = at->getPrefix();
                
                if(XMLString::equals(prefix, XMLUni::fgXMLNSString)) {
                    fNSScope->addOrChangeBinding(at->getLocalName(), value, fMemoryManager);
                }
                else {
                    fNSScope->addOrChangeBinding(XMLUni::fgZeroLenString, value, fMemoryManager);
                }
            }
        }
    }

    const XMLCh* prefix = ele->getPrefix();
    prefix ? prefix : prefix = XMLUni::fgZeroLenString;
    const XMLCh* uri = ele->getNamespaceURI();
    uri ? uri : uri = XMLUni::fgZeroLenString;

    if(!XMLString::equals(uri, XMLUni::fgZeroLenString)) {
        if(!fNSScope->isValidBinding(prefix, uri)) {
            addOrChangeNamespaceDecl(prefix, uri, ele);
            fNSScope->addOrChangeBinding(prefix, uri, fMemoryManager);
        }
    }
    else {
        if(ele->getLocalName() == 0) {
            error(XMLErrs::DOMLevel1Node, ele);
        }
        else if(!fNSScope->isValidBinding(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString)) {
            addOrChangeNamespaceDecl(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, ele);
            fNSScope->addOrChangeBinding(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, fMemoryManager);
        }
    }

    //fix up non ns attrs
    len = attrMap->getLength();

    // hp aCC complains this i is a redefinition of the i on line 283
    for(int j = 0; j < len; j++) {
        DOMAttr *at = (DOMAttr*)attrMap->item(j);
        const XMLCh *uri = at->getNamespaceURI();        
        const XMLCh* prefix = at->getPrefix();

        if(!XMLString::equals(XMLUni::fgXMLNSURIName, uri)) {
            if(uri != 0) {
                if(prefix == 0 || !fNSScope->isValidBinding(prefix, uri)) {
                    
                    const XMLCh* newPrefix =  fNSScope->getPrefix(uri);

                    if(newPrefix != 0) {
                        at->setPrefix(newPrefix);                                                
                    }
                    else {
                        if(prefix != 0 && !fNSScope->getUri(prefix)) {
                            fNSScope->addOrChangeBinding(prefix, uri, fMemoryManager);
                            addOrChangeNamespaceDecl(prefix, uri, ele);
                        }
                        else {
                            newPrefix = addCustomNamespaceDecl(uri, ele);
                            fNSScope->addOrChangeBinding(newPrefix, uri, fMemoryManager);
                            at->setPrefix(newPrefix);
                        }
                    }
                }
            }
            else if(at->getLocalName() == 0) {
                error(XMLErrs::DOMLevel1Node, at);
            }
        }
    }
}



const XMLCh * DOMNormalizer::integerToXMLCh(unsigned int i) const {
    XMLCh *buf = (XMLCh*) fMemoryManager->allocate(15 * sizeof(XMLCh));//new XMLCh[15];
	XMLCh *pos = buf + sizeof(buf) - sizeof(XMLCh);
	*pos = chNull;

	do {
        switch(i % 10) {
        case 0 : *--pos = chDigit_0;break;
        case 1 : *--pos = chDigit_1;break;
        case 2 : *--pos = chDigit_2;break;
        case 3 : *--pos = chDigit_3;break;
        case 4 : *--pos = chDigit_4;break;
        case 5 : *--pos = chDigit_5;break;
        case 6 : *--pos = chDigit_6;break;
        case 7 : *--pos = chDigit_7;break;
        case 8 : *--pos = chDigit_8;break;
        case 9 : *--pos = chDigit_9;break;
        default:;
        }
		i /= 10;
	} while (i);

    const XMLCh *copy = fDocument->getPooledString(pos);
    fMemoryManager->deallocate(buf);//delete[] buf;
	return copy;
}





void DOMNormalizer::addOrChangeNamespaceDecl(const XMLCh* prefix, const XMLCh* uri, DOMElementImpl* element) const {

    if (XMLString::equals(prefix, XMLUni::fgZeroLenString)) {
        element->setAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString, uri);
    } else {
        XMLBuffer buf(1023, fMemoryManager);
        buf.set(XMLUni::fgXMLNSString);
        buf.append(chColon);
        buf.append(prefix);
        element->setAttributeNS(XMLUni::fgXMLNSURIName, buf.getRawBuffer(), uri); 
    }
}

const XMLCh* DOMNormalizer::addCustomNamespaceDecl(const XMLCh* uri, DOMElementImpl *element) const {
    XMLBuffer preBuf(1023, fMemoryManager);
    preBuf.append(chLatin_N);
    preBuf.append(chLatin_S);
    preBuf.append(integerToXMLCh(fNewNamespaceCount));
    ((DOMNormalizer *)this)->fNewNamespaceCount++;

    while(fNSScope->getUri(preBuf.getRawBuffer())) {
        preBuf.reset();
        preBuf.append(chLatin_N);
        preBuf.append(chLatin_S);
        preBuf.append(integerToXMLCh(fNewNamespaceCount));
        ((DOMNormalizer *)this)->fNewNamespaceCount++;
    }
    
    XMLBuffer buf(1023, fMemoryManager);
    buf.set(XMLUni::fgXMLNSString);
    buf.append(chColon);
    buf.append(preBuf.getRawBuffer());
    element->setAttributeNS(XMLUni::fgXMLNSURIName, buf.getRawBuffer(), uri);

    return element->getAttributeNodeNS(XMLUni::fgXMLNSURIName, preBuf.getRawBuffer())->getLocalName();
}

int DOMNormalizer::InScopeNamespaces::size() {
    return fScopes->size();
}

DOMNormalizer::InScopeNamespaces::InScopeNamespaces(MemoryManager* const manager)
: lastScopeWithBindings(0)
{
    fScopes = new (manager) RefVectorOf<Scope>(10, true, manager);
}

DOMNormalizer::InScopeNamespaces::~InScopeNamespaces() {
    delete fScopes;
}

void DOMNormalizer::InScopeNamespaces::addOrChangeBinding(const XMLCh *prefix, const XMLCh *uri,
                                                          MemoryManager* const manager) {
    unsigned int s = fScopes->size();

    if(!s)
        addScope(manager);
    
    Scope *curScope = fScopes->elementAt(s - 1);
    curScope->addOrChangeBinding(prefix, uri, manager);

    lastScopeWithBindings = curScope;
}

void DOMNormalizer::InScopeNamespaces::addScope(MemoryManager* const manager) {
    Scope *s = new (manager) Scope(lastScopeWithBindings);
    fScopes->addElement(s);
}

void DOMNormalizer::InScopeNamespaces::removeScope() {
    lastScopeWithBindings = fScopes->elementAt(fScopes->size() - 1)->fBaseScopeWithBindings;
    Scope *s = fScopes->orphanElementAt(fScopes->size() - 1);
    delete s;
}

bool DOMNormalizer::InScopeNamespaces::isValidBinding(const XMLCh* prefix, const XMLCh* uri) const {
    const XMLCh* actual = fScopes->elementAt(fScopes->size() - 1)->getUri(prefix);
    if(actual == 0 || !XMLString::equals(actual, uri))
        return false;
    return true;
}

const XMLCh* DOMNormalizer::InScopeNamespaces::getPrefix(const XMLCh* uri) const {
    return fScopes->elementAt(fScopes->size() - 1)->getPrefix(uri);
}

const XMLCh* DOMNormalizer::InScopeNamespaces::getUri(const XMLCh* prefix) const {
    return fScopes->elementAt(fScopes->size() - 1)->getUri(prefix);
}



DOMNormalizer::InScopeNamespaces::Scope::Scope(Scope *baseScopeWithBindings) : fBaseScopeWithBindings(baseScopeWithBindings), fPrefixHash(0), fUriHash(0)
{
}

DOMNormalizer::InScopeNamespaces::Scope::~Scope() {
    delete fPrefixHash;
    delete fUriHash;
}

void DOMNormalizer::InScopeNamespaces::Scope::addOrChangeBinding(const XMLCh *prefix, const XMLCh *uri,
                                                                 MemoryManager* const manager) {
    //initialize and copy forward now we need to
    if(!fUriHash) {
        fPrefixHash = new (manager) RefHashTableOf<XMLCh>(10, (bool) false, manager);
        fUriHash = new (manager) RefHashTableOf<XMLCh>(10, (bool) false, manager);
        
        if(fBaseScopeWithBindings) {
            RefHashTableOfEnumerator<XMLCh> preEnumer(fBaseScopeWithBindings->fPrefixHash, false, manager);
            while(preEnumer.hasMoreElements()) {
                const XMLCh* prefix = (XMLCh*) preEnumer.nextElementKey();
                const XMLCh* uri  = fBaseScopeWithBindings->fPrefixHash->get((void*)prefix);
                
                //have to cast here because otherwise we have delete problems under windows :(
                fPrefixHash->put((void *)prefix, (XMLCh*)uri);
            }
            
            RefHashTableOfEnumerator<XMLCh> uriEnumer(fBaseScopeWithBindings->fUriHash, false, manager);
            while(uriEnumer.hasMoreElements()) {
                const XMLCh* uri = (XMLCh*) uriEnumer.nextElementKey();
                const XMLCh* prefix  = fBaseScopeWithBindings->fUriHash->get((void*)uri);

                //have to cast here because otherwise we have delete problems under windows :(
                fUriHash->put((void *)uri, (XMLCh*)prefix);
            }
        }
    }

    const XMLCh *oldUri = fPrefixHash->get(prefix);
    if(oldUri) {
        fUriHash->removeKey(oldUri);
    }

    fPrefixHash->put((void *)prefix, (XMLCh*)uri);
    fUriHash->put((void *)uri, (XMLCh*)prefix);
}

const XMLCh* DOMNormalizer::InScopeNamespaces::Scope::getUri(const XMLCh *prefix) const {
    const XMLCh* uri = 0;

    if(fPrefixHash) {
        uri = fPrefixHash->get(prefix);
    }
    else if(fBaseScopeWithBindings) {
        uri = fBaseScopeWithBindings->getUri(prefix);
    }
    
    return uri ? uri : 0;
}

const XMLCh* DOMNormalizer::InScopeNamespaces::Scope::getPrefix(const XMLCh* uri) const {
    const XMLCh* prefix = 0;

    if(fUriHash) {
        prefix = fUriHash->get(uri);
    }
    else if(fBaseScopeWithBindings) {
        prefix = fBaseScopeWithBindings->getPrefix(uri);
    }
    return prefix ? prefix : 0;
}

void DOMNormalizer::error(const XMLErrs::Codes code, const DOMNode *node) const
{
    if (fErrorHandler) {

        //  Load the message into alocal and replace any tokens found in
        //  the text.
        const unsigned int maxChars = 2047;
        XMLCh errText[maxChars + 1];

        if (!gNormalizerMsgLoader().loadMsg(code, errText, maxChars))
        {
                // <TBD> Should probably load a default message here
        }

        DOMErrorImpl domError(code, 0, errText, (void*)node);
        if (!fErrorHandler->handleError(domError))
            throw (XMLErrs::Codes) code;
    }
}



XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMDocumentImpl.cpp ---
/*
 * Copyright 2001-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.
 */

/*
 * $Id: DOMDocumentImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */
[...1333 lines suppressed...]
        return 0;

    return fRecycleBufferPtr->pop();
}


void * DOMDocumentImpl::allocate(size_t amount, NodeObjectType type)
{
    if (!fRecycleNodePtr)
        return allocate(amount);

    DOMNodePtr* ptr = fRecycleNodePtr->operator[](type);
    if (!ptr || ptr->empty())
        return allocate(amount);

    return (void*) ptr->pop();

}

XERCES_CPP_NAMESPACE_END

--- NEW FILE: DOMTextImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMTextImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */


#include <xercesc/util/XMLUniDefs.hpp>

#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>

#include "DOMDocumentImpl.hpp"
#include "DOMStringPool.hpp"
#include "DOMTextImpl.hpp"
#include "DOMCharacterDataImpl.hpp"
#include "DOMChildNode.hpp"
#include "DOMRangeImpl.hpp"


#include <assert.h>

XERCES_CPP_NAMESPACE_BEGIN

class DOMDocument;

DOMTextImpl::DOMTextImpl(DOMDocument *ownerDoc, const XMLCh *dat)
    : fNode(ownerDoc), fCharacterData(ownerDoc, dat)
{
    fNode.setIsLeafNode(true);
}

DOMTextImpl::DOMTextImpl(const DOMTextImpl &other, bool)
    : DOMText(other)
    , fNode(other.fNode)
    , fCharacterData(other.fCharacterData)
{
    fNode.setIsLeafNode(true);
}

DOMTextImpl::~DOMTextImpl()
{
}


DOMNode *DOMTextImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::TEXT_OBJECT) DOMTextImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMTextImpl::getNodeName() const {
    static const XMLCh gtext[] = {chPound, chLatin_t, chLatin_e, chLatin_x, chLatin_t, chNull};
    return gtext;
}

short DOMTextImpl::getNodeType() const {
    return DOMNode::TEXT_NODE;
}


DOMText *DOMTextImpl::splitText(XMLSize_t offset)
{
    if (fNode.isReadOnly())
    {
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    }
    XMLSize_t len = fCharacterData.fDataBuf->getLen();
    if (offset > len)
        throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMNodeMemoryManager);

    DOMText *newText =
                getOwnerDocument()->createTextNode(
                        this->substringData(offset, len - offset));

    DOMNode *parent = getParentNode();
    if (parent != 0)
        parent->insertBefore(newText, getNextSibling());

    fCharacterData.fDataBuf->chop(offset);

    if (this->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateSplitInfo( this, newText, offset);
                }
            }
        }
    }

    return newText;
}


bool DOMTextImpl::isIgnorableWhitespace() const
{
    return fNode.ignorableWhitespace();
}



void DOMTextImpl::setIgnorableWhitespace(bool ignorable)
{
    fNode.ignorableWhitespace(ignorable);
}


bool DOMTextImpl::getIsWhitespaceInElementContent() const
{
    return isIgnorableWhitespace();
}

const XMLCh* DOMTextImpl::getWholeText() {
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMNodeMemoryManager);
    return 0;
}

DOMText* DOMTextImpl::replaceWholeText(const XMLCh*){
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMNodeMemoryManager);
    return 0;
}


void DOMTextImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fCharacterData.releaseBuffer();
        doc->release(this, DOMDocumentImpl::TEXT_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

//
//  Delegation functions
//
           DOMNode*         DOMTextImpl::appendChild(DOMNode *newChild)          {return fNode.appendChild (newChild); }
           DOMNamedNodeMap* DOMTextImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMTextImpl::getChildNodes() const                   {return fNode.getChildNodes (); }
           DOMNode*         DOMTextImpl::getFirstChild() const                   {return fNode.getFirstChild (); }
           DOMNode*         DOMTextImpl::getLastChild() const                    {return fNode.getLastChild (); }
     const XMLCh*           DOMTextImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMTextImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMTextImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
     const XMLCh*           DOMTextImpl::getNodeValue() const                    {return fCharacterData.getNodeValue (); }
           DOMDocument*     DOMTextImpl::getOwnerDocument() const                {return fNode.getOwnerDocument (); }
     const XMLCh*           DOMTextImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMTextImpl::getParentNode() const                   {return fChild.getParentNode (this); }
           DOMNode*         DOMTextImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
           bool             DOMTextImpl::hasChildNodes() const                   {return fNode.hasChildNodes (); }
           DOMNode*         DOMTextImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                 {return fNode.insertBefore (newChild, refChild); }
           void             DOMTextImpl::normalize()                             {fNode.normalize (); }
           DOMNode*         DOMTextImpl::removeChild(DOMNode *oldChild)          {return fNode.removeChild (oldChild); }
           DOMNode*         DOMTextImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                 {return fNode.replaceChild (newChild, oldChild); }
           bool             DOMTextImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                 {return fNode.isSupported (feature, version); }
           void             DOMTextImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMTextImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMTextImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMTextImpl::isEqualNode(const DOMNode* arg) const   {return fNode.isEqualNode(arg); }
           void*            DOMTextImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                 {return fNode.setUserData(key, data, handler); }
           void*            DOMTextImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           const XMLCh*     DOMTextImpl::getBaseURI() const                      {return fNode.getBaseURI(); }
           short            DOMTextImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMTextImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMTextImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMTextImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMTextImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMTextImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMTextImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }



//
//   Delegation of CharacerData functions.
//


          const XMLCh*      DOMTextImpl::getData() const                         {return fCharacterData.getData();}
          XMLSize_t         DOMTextImpl::getLength() const                       {return fCharacterData.getLength();}
          const XMLCh*      DOMTextImpl::substringData(XMLSize_t offset, XMLSize_t count) const
                                                                                 {return fCharacterData.substringData(this, offset, count);}
          void              DOMTextImpl::appendData(const XMLCh *arg)            {fCharacterData.appendData(this, arg);}
          void              DOMTextImpl::insertData(XMLSize_t offset, const  XMLCh *arg)
                                                                                 {fCharacterData.insertData(this, offset, arg);}
          void              DOMTextImpl::deleteData(XMLSize_t offset, XMLSize_t count)
                                                                                 {fCharacterData.deleteData(this, offset, count);}
          void              DOMTextImpl::replaceData(XMLSize_t offset, XMLSize_t count, const XMLCh *arg)
                                                                                 {fCharacterData.replaceData(this, offset, count, arg);}
          void              DOMTextImpl::setData(const XMLCh *data)              {fCharacterData.setData(this, data);}
          void              DOMTextImpl::setNodeValue(const XMLCh  *nodeValue)   {fCharacterData.setNodeValue (this, nodeValue); }

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMRangeImpl.hpp ---
#ifndef DOMRangeImpl_HEADER_GUARD_
#define DOMRangeImpl_HEADER_GUARD_

/*
 * 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.
 */

 /*
 * $Id: DOMRangeImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMRange.hpp>
#include <xercesc/util/PlatformUtils.hpp>

XERCES_CPP_NAMESPACE_BEGIN



class       DOMNode;
class       DOMDocumentFragment;
class       DOMDocument;
class       DOMText;
class       MemoryManager;

class CDOM_EXPORT DOMRangeImpl: public DOMRange {
private:
    enum TraversalType {
        EXTRACT_CONTENTS = 1,
        CLONE_CONTENTS   = 2,
        DELETE_CONTENTS  = 3
    };

    enum TraversePoint {
        BEFORE  = -1,
        START   = 0,
        AFTER   = 1
    };

    //private data

    DOMNode*     fStartContainer;
    XMLSize_t    fStartOffset;
    DOMNode*     fEndContainer;
    XMLSize_t    fEndOffset;
    bool         fCollapsed;
    DOMDocument* fDocument;
    bool         fDetached;

    DOMNode*     fRemoveChild;
    MemoryManager* fMemoryManager;

public:
    //c'tor
    DOMRangeImpl(DOMDocument* doc, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    DOMRangeImpl(const DOMRangeImpl& other);

    //d'tor
    ~DOMRangeImpl();

    //getter functions
    virtual DOMNode* getStartContainer() const;
    virtual XMLSize_t getStartOffset() const;
    virtual DOMNode* getEndContainer() const;
    virtual XMLSize_t getEndOffset() const;
    virtual bool getCollapsed() const;
    virtual const DOMNode* getCommonAncestorContainer() const;

    //setter functions
    virtual void setStart(const DOMNode *parent, XMLSize_t offset);
    virtual void setEnd(const DOMNode *parent, XMLSize_t offset);

    virtual void setStartBefore(const DOMNode *refNode);
    virtual void setStartAfter(const DOMNode *refNode);
    virtual void setEndBefore(const DOMNode *refNode);
    virtual void setEndAfter(const DOMNode *refNode);

    //misc functions
    virtual void collapse(bool toStart);
    virtual void selectNode(const DOMNode *node);
    virtual void selectNodeContents(const DOMNode *node);

    //Functions related to comparing range Boundrary-Points
    virtual short compareBoundaryPoints(CompareHow how, const DOMRange* range) const;
    virtual void deleteContents();
    virtual DOMDocumentFragment* extractContents();
    virtual DOMDocumentFragment* cloneContents() const;
    virtual void insertNode(DOMNode* node);

    //Misc functions
    virtual void surroundContents(DOMNode *node);
    virtual DOMRange* cloneRange() const;
    virtual const XMLCh* toString() const;
    virtual void detach();
    virtual void release();

    //getter functions
    DOMDocument*         getDocument();

    // functions to inform all existing valid ranges about a change
    void updateSplitInfo(DOMNode* oldNode, DOMNode* startNode, XMLSize_t offset);
    void updateRangeForInsertedNode(DOMNode* node);
    void receiveReplacedText(DOMNode* node);
    void updateRangeForDeletedText(DOMNode* node, XMLSize_t offset, int count);
    void updateRangeForInsertedText(DOMNode* node, XMLSize_t offset, int count);
    void updateRangeForDeletedNode(DOMNode* node);

private:
    //setter functions
    void        setStartContainer(const DOMNode* node);
    void        setStartOffset(XMLSize_t offset) ;
    void        setEndContainer(const DOMNode* node);
    void        setEndOffset(XMLSize_t offset) ;

    //misc functions
    void        validateNode(const DOMNode* node) const;
    bool        isValidAncestorType(const DOMNode* node) const;
    bool        hasLegalRootContainer(const DOMNode* node) const;
    bool        isLegalContainedNode(const DOMNode* node ) const;
    void        checkIndex(const DOMNode* node, XMLSize_t offset) const;
    static bool isAncestorOf(const DOMNode* a, const DOMNode* b);

    XMLSize_t   indexOf(const DOMNode* child, const DOMNode* parent) const;

    const DOMNode*       commonAncestorOf(const DOMNode* pointA, const DOMNode* pointB) const;
    DOMNode*             nextNode(const DOMNode* node, bool visitChildren) const;
    DOMDocumentFragment* traverseContents(TraversalType type);
    void                  checkReadOnly(DOMNode* start, DOMNode* end,
                                  XMLSize_t starOffset, XMLSize_t endOffset);
    void                  recurseTreeAndCheck(DOMNode* start, DOMNode* end);
    DOMNode*             removeChild(DOMNode* parent, DOMNode* child);

    DOMDocumentFragment* traverseSameContainer( int how );
    DOMDocumentFragment* traverseCommonStartContainer( DOMNode *endAncestor, int how );
    DOMDocumentFragment* traverseCommonEndContainer( DOMNode *startAncestor, int how );
    DOMDocumentFragment* traverseCommonAncestors( DOMNode *startAncestor, DOMNode *endAncestor, int how );
    DOMNode*    traverseRightBoundary( DOMNode *root, int how );
    DOMNode*    traverseLeftBoundary( DOMNode *root, int how );
    DOMNode*    traverseNode( DOMNode *n, bool isFullySelected, bool isLeft, int how );
    DOMNode*    traverseFullySelected( DOMNode *n, int how );
    DOMNode*    traversePartiallySelected( DOMNode *n, int how );
    DOMNode*    traverseTextNode( DOMNode *n, bool isLeft, int how );
    DOMNode*    getSelectedNode( DOMNode *container, int offset );

    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMRangeImpl & operator = (const DOMRangeImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMEntityImpl.hpp ---
#ifndef DOMEntityImpl_HEADER_GUARD_
#define DOMEntityImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMEntityImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include "DOMNodeImpl.hpp"
#include "DOMParentNode.hpp"
#include <xercesc/dom/DOMEntity.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class    DOMEntityReference;

class CDOM_EXPORT DOMEntityImpl: public DOMEntity {
private:
    DOMNodeImpl      fNode;
    DOMParentNode    fParent;

    const XMLCh *   fName;
    const XMLCh *   fPublicId;
    const XMLCh *   fSystemId;
    const XMLCh *   fNotationName;
    DOMEntityReference*	fRefEntity;

    // New data introduced in DOM Level 3
    const XMLCh*          fActualEncoding;
    const XMLCh*          fEncoding;
    const XMLCh*          fVersion;
    const XMLCh*          fBaseURI;
    bool                  fEntityRefNodeCloned;
    // private helper function
    void	cloneEntityRefTree() const;

    friend class XercesDOMParser;

public:
    DOMEntityImpl(DOMDocument *doc, const XMLCh *eName);
    DOMEntityImpl(const DOMEntityImpl &other, bool deep=false);
    virtual ~DOMEntityImpl();

    // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;


    virtual const XMLCh *   getPublicId() const;
    virtual const XMLCh *   getSystemId() const;
    virtual const XMLCh *   getNotationName() const;
    virtual void            setNotationName(const XMLCh *arg);
    virtual void            setPublicId(const XMLCh *arg);
    virtual void            setSystemId(const XMLCh *arg);

    //DOM Level 2 additions. Non standard functions
    virtual void		setEntityRef(DOMEntityReference *);
    virtual DOMEntityReference*	getEntityRef() const;

    //Introduced in DOM Level 3
    virtual const XMLCh*           getActualEncoding() const;
    virtual void                   setActualEncoding(const XMLCh* actualEncoding);
    virtual const XMLCh*           getEncoding() const;
    virtual void                   setEncoding(const XMLCh* encoding);
    virtual const XMLCh*           getVersion() const;
    virtual void                   setVersion(const XMLCh* version);
    virtual void                   setBaseURI(const XMLCh *arg);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    DOMEntityImpl & operator = (const DOMEntityImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMAttrMapImpl.hpp ---
#ifndef DOMAttrMapImpl_HEADER_GUARD_
#define DOMAttrMapImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMAttrMapImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class DOMNodeVector;
class DOMNode;

class CDOM_EXPORT DOMAttrMapImpl : public DOMNamedNodeMap
{
protected:
    DOMNodeVector*    fNodes;
    DOMNode*          fOwnerNode;       // the node this map belongs to

    virtual void	cloneContent(const DOMAttrMapImpl *srcmap);

    bool            readOnly();  // revisit.  Look at owner node read-only.

private:
    bool attrDefaults;

public:
    DOMAttrMapImpl(DOMNode *ownerNod);

    // revisit.  This "copy" constructor is used for cloning an Element with Attributes,
    //                and for setting up default attributes.  It's probably not right
    //                for one or the other or both.
    DOMAttrMapImpl(DOMNode *ownerNod, const DOMAttrMapImpl *defaults);
    DOMAttrMapImpl();

    virtual ~DOMAttrMapImpl();
    virtual DOMAttrMapImpl *cloneAttrMap(DOMNode *ownerNode);
    virtual bool hasDefaults();
    virtual void hasDefaults(bool value);
    virtual int             findNamePoint(const XMLCh *name) const;
    virtual int             findNamePoint(const XMLCh *namespaceURI,
	                                       const XMLCh *localName) const;
    virtual DOMNode*        removeNamedItemAt(XMLSize_t index);
    virtual void            setReadOnly(bool readOnly, bool deep);


    virtual XMLSize_t       getLength() const;
    virtual DOMNode*        item(XMLSize_t index) const;

    virtual DOMNode*        getNamedItem(const XMLCh *name) const;
    virtual DOMNode*        setNamedItem(DOMNode *arg);
    virtual DOMNode*        removeNamedItem(const XMLCh *name);
    
    virtual DOMNode*        getNamedItemNS(const XMLCh *namespaceURI,
	                                        const XMLCh *localName) const;
    virtual DOMNode*        setNamedItemNS(DOMNode *arg);
    virtual DOMNode*        removeNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName);

    void reconcileDefaultAttributes(const DOMAttrMapImpl* defaults);
    void moveSpecifiedAttributes(DOMAttrMapImpl* srcmap);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMAttrMapImpl(const DOMAttrMapImpl &);
    DOMAttrMapImpl & operator = (const DOMAttrMapImpl &);
};

// ---------------------------------------------------------------------------
//  DOMAttrMapImpl: Getters & Setters
// ---------------------------------------------------------------------------

inline bool DOMAttrMapImpl::hasDefaults()
{
    return attrDefaults;
}

inline void DOMAttrMapImpl::hasDefaults(bool value)
{
    attrDefaults = value;
}

XERCES_CPP_NAMESPACE_END


#endif

--- NEW FILE: DOMDeepNodeListImpl.hpp ---
#ifndef DOMDeepNodeListImpl_HEADER_GUARD_
#define DOMDeepNodeListImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMDeepNodeListImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMNodeList.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class DOMNode;


class CDOM_EXPORT DOMDeepNodeListImpl: public DOMNodeList {
private:
    const DOMNode*   fRootNode;
    const XMLCh*     fTagName;
    bool             fMatchAll;
    int              fChanges;
    DOMNode*         fCurrentNode;
    XMLSize_t        fCurrentIndexPlus1;

    //DOM Level 2
    const XMLCh*     fNamespaceURI;
    bool		         fMatchAllURI;
    bool             fMatchURIandTagname; //match both namespaceURI and tagName

public:
    DOMDeepNodeListImpl(const DOMNode *rootNode, const XMLCh *tagName);
    DOMDeepNodeListImpl(const DOMNode *rootNode,	//DOM Level 2
	                    const XMLCh *namespaceURI,
                       const XMLCh *localName);
    virtual          ~DOMDeepNodeListImpl();
    virtual XMLSize_t getLength() const;
    virtual DOMNode*  item(XMLSize_t index) const;
    DOMNode*  cacheItem(XMLSize_t index);

private:
    DOMNode*          nextMatchingElementAfter(DOMNode *current);
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMDeepNodeListImpl(const DOMDeepNodeListImpl &);
    DOMDeepNodeListImpl & operator = (const DOMDeepNodeListImpl &);   
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMNodeImpl.hpp ---
#ifndef DOMNodeImpl_HEADER_GUARD_
#define DOMNodeImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMNodeImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

/**
 * A DOMNodeImpl doesn't have any children, and can therefore only be directly
 * inherited by classes of nodes that never have any, such as Text nodes. For
 * other types, such as Element, classes must inherit from ParentNode.
 * <P>
 * All nodes in a single document must originate
 * in that document. (Note that this is much tighter than "must be
 * same implementation") Nodes are all aware of their ownerDocument,
 * and attempts to mismatch will throw WRONG_DOCUMENT_ERR.
 * <P>
 * However, to save memory not all nodes always have a direct reference
 * to their ownerDocument. When a node is owned by another node it relies
 * on its owner to store its ownerDocument. Parent nodes always store it
 * though, so there is never more than one level of indirection.
 * And when a node doesn't have an owner, ownerNode refers to its
 * ownerDocument.
 **/

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMUserDataHandler.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class DOMNamedNodeMap;
class DOMNodeList;
class DOMNode;
class DOMDocument;
class DOMElement;

class CDOM_EXPORT DOMNodeImpl {
public:

    // data
    DOMNode                *fOwnerNode; // typically the parent but not always!

    unsigned short flags;

    static const unsigned short READONLY;
    static const unsigned short SYNCDATA;
    static const unsigned short SYNCCHILDREN;
    static const unsigned short OWNED;
    static const unsigned short FIRSTCHILD;
    static const unsigned short SPECIFIED;
    static const unsigned short IGNORABLEWS;
    static const unsigned short SETVALUE;
    static const unsigned short ID_ATTR;
    static const unsigned short USERDATA;
    static const unsigned short LEAFNODETYPE;
    static const unsigned short CHILDNODE;
    static const unsigned short TOBERELEASED;


public:
    DOMNodeImpl(DOMNode *ownerDocument);
    DOMNodeImpl(const DOMNodeImpl &other);
    ~DOMNodeImpl();

    DOMNode         * appendChild(DOMNode *newChild);
    DOMNamedNodeMap * getAttributes() const;
    DOMNodeList     * getChildNodes() const;
    DOMNode         * getFirstChild() const;
    DOMNode         * getLastChild() const;
    const XMLCh     * getLocalName() const;
    const XMLCh     * getNamespaceURI() const;
    DOMNode         * getNextSibling() const;
    const XMLCh     * getNodeValue() const;
    DOMDocument     * getOwnerDocument() const;
    DOMNode         * getParentNode() const;
    const XMLCh     * getPrefix() const;
    DOMNode         * getPreviousSibling() const;
    bool              hasChildNodes() const;
    DOMNode         * insertBefore(DOMNode *newChild, DOMNode *refChild);
    void              normalize();
    DOMNode         * removeChild(DOMNode *oldChild);
    DOMNode         * replaceChild(DOMNode *newChild, DOMNode *oldChild);
    void              setNodeValue(const XMLCh *value);
    void              setPrefix(const XMLCh *fPrefix);
    void              setReadOnly(bool readOnly, bool deep);
    bool              isSupported(const XMLCh *feature, const XMLCh *version) const;
    bool              hasAttributes() const;

    // Introduced in DOM Level 3
    void*             setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler);
    void*             getUserData(const XMLCh* key) const;
    bool              isSameNode(const DOMNode* other) const;
    bool              isEqualNode(const DOMNode* arg) const;
    const XMLCh*      getBaseURI() const ;
    short             compareTreePosition(const DOMNode* other) const;
    const XMLCh*      getTextContent() const ;
    const XMLCh*      getTextContent(XMLCh* pzBuffer, unsigned int& rnBufferLength) const;
    void              setTextContent(const XMLCh* textContent) ;
    const XMLCh*      lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const ;
    bool              isDefaultNamespace(const XMLCh* namespaceURI) const ;
    const XMLCh*      lookupNamespaceURI(const XMLCh* prefix) const  ;
    DOMNode*          getInterface(const XMLCh* feature) ;


    // Helper functions for DOM Level 3
    void              release();
    void              callUserDataHandlers(DOMUserDataHandler::DOMOperationType operation,
                                           const DOMNode* src,
                                           const DOMNode* dst) const;
    //reverses the bit pattern given by compareTreePosition
    short             reverseTreeOrderBitPattern(short pattern) const;


    //Utility, not part of DOM Level 2 API
    static  bool      isKidOK(DOMNode *parent, DOMNode *child);
    static const XMLCh *mapPrefix(const XMLCh *prefix,
                               const XMLCh *namespaceURI, short nType);

    static const XMLCh *getXmlnsString();
    static const XMLCh *getXmlnsURIString();
    static const XMLCh *getXmlString();
    static const XMLCh *getXmlURIString();

public: // should really be protected - ALH

      DOMNode* getElementAncestor (const DOMNode* currentNode) const;
      const XMLCh* lookupNamespacePrefix(const XMLCh* const namespaceURI, bool useDefaultx, DOMElement *el) const ;
     void setOwnerDocument(DOMDocument *doc);

    /*
     * Flags setters and getters
     */

    inline bool isReadOnly() const {
        return (flags & READONLY) != 0;
    }

    inline void isReadOnly(bool value) {
        flags = (value ? flags | READONLY : flags & ~READONLY);
    }

    inline bool needsSyncData() const {
        return (flags & SYNCDATA) != 0;
    }

    inline void needsSyncData(bool value) {
        flags = (value ? flags | SYNCDATA : flags & ~SYNCDATA);
    }

    inline bool needsSyncChildren() const {
        return (flags & SYNCCHILDREN) != 0;
    }

    inline void needsSyncChildren(bool value) {
        flags = (value ? flags | SYNCCHILDREN : flags & ~SYNCCHILDREN);
    }

    // For Attributes, true if the attr node is attached to an element.
    // For all other node types, true if the node has a parent node.
    inline bool isOwned() const {
        return (flags & OWNED) != 0;
    }

    inline void isOwned(bool value) {
        flags = (value ? flags | OWNED : flags & ~OWNED);
    }

    inline bool isFirstChild() const {
        return (flags & FIRSTCHILD) != 0;
    }

    inline void isFirstChild(bool value) {
        flags = (value ? flags | FIRSTCHILD : flags & ~FIRSTCHILD);
    }

    inline bool isSpecified() const {
        return (flags & SPECIFIED) != 0;
    }

    inline void isSpecified(bool value) {
        flags = (value ? flags | SPECIFIED : flags & ~SPECIFIED);
    }

    inline bool ignorableWhitespace() const {
        return (flags & IGNORABLEWS) != 0;
    }

    inline void ignorableWhitespace(bool value) {
        flags = (value ? flags | IGNORABLEWS : flags & ~IGNORABLEWS);
    }

    inline bool setValue() const {
        return (flags & SETVALUE) != 0;
    }

    inline void setValue(bool value) {
        flags = (value ? flags | SETVALUE : flags & ~SETVALUE);
    }

    inline bool isIdAttr() const {
        return (flags & ID_ATTR) != 0;
    }

    inline void isIdAttr(bool value) {
        flags = (value ? flags | ID_ATTR : flags & ~ID_ATTR);
    }

    inline bool hasUserData() const {
        return (flags & USERDATA) != 0;
    }

    inline void hasUserData(bool value) {
        flags = (value ? flags | USERDATA : flags & ~USERDATA);
    }

    //
    //  LeafNode is set true for node types that can not be ParentNodes (can't have children)
    //    This knowledge is used to allow casting from any unknown node type to the
    //    IDParentImpl or IDChildImpl parts of the node.
    //
    inline bool isLeafNode() const {
        return (flags & LEAFNODETYPE) != 0;
    }

    inline void setIsLeafNode(bool value) {
        flags = (value ? flags | LEAFNODETYPE : flags & ~LEAFNODETYPE);
    }


    //
    // ChildNode is set true for node types that can be children of other nodes, and
    //   therefore include a DOMChildNode data member.  Note that all of the leaf
    //   node types (above flag) are also ChildNodes, but not all ChildNodes are
    //   leaf nodes.
    inline bool isChildNode() const {
        return (flags & CHILDNODE) != 0;
    }

    inline void setIsChildNode(bool value) {
        flags = (value ? flags | CHILDNODE : flags & ~CHILDNODE);
    }

    // True if this node has to be released regardless if it has a owner or not
    // This is true if called from fParent->release()
    inline bool isToBeReleased() const {
        return (flags & TOBERELEASED) != 0;
    }

    inline void isToBeReleased(bool value) {
        flags = (value ? flags | TOBERELEASED : flags & ~TOBERELEASED);
    }

};


// This macro lists all of the pure virtual functions declared in DOMNode that must
//   be implemented by all node types.  Since there is no inheritance of implementation,
//   using this macro in the class declaration of the node types make it easier to
//   accurately get all of the functions declared.
//
#define DOMNODE_FUNCTIONS \
    virtual       DOMNode*         appendChild(DOMNode *newChild) ;\
    virtual       DOMNode*         cloneNode(bool deep) const ;\
    virtual       DOMNamedNodeMap* getAttributes() const ;\
    virtual       DOMNodeList*     getChildNodes() const ;\
    virtual       DOMNode*         getFirstChild() const ;\
    virtual       DOMNode*         getLastChild() const ;\
    virtual const XMLCh*           getLocalName() const ;\
    virtual const XMLCh*           getNamespaceURI() const ;\
    virtual       DOMNode*         getNextSibling() const ;\
    virtual const XMLCh*           getNodeName() const ;\
    virtual       short            getNodeType() const ;\
    virtual const XMLCh*           getNodeValue() const ;\
    virtual       DOMDocument*     getOwnerDocument() const ;\
    virtual const XMLCh*           getPrefix() const ;\
    virtual       DOMNode*         getParentNode() const ;\
    virtual       DOMNode*         getPreviousSibling() const ;\
    virtual       bool             hasChildNodes() const ;\
    virtual       DOMNode*         insertBefore(DOMNode *newChild, DOMNode *refChild) ;\
    virtual       void             normalize() ;\
    virtual       DOMNode*         removeChild(DOMNode *oldChild) ;\
    virtual       DOMNode*         replaceChild(DOMNode *newChild, DOMNode *oldChild) ;\
    virtual       void             setNodeValue(const XMLCh  *nodeValue) ;\
    virtual       bool             isSupported(const XMLCh *feature, const XMLCh *version) const ;\
    virtual       bool             hasAttributes() const ;\
    virtual       void             setPrefix(const XMLCh * prefix) ;\
    virtual       void*            setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler) ;\
    virtual       void*            getUserData(const XMLCh* key) const ;\
    virtual       bool             isSameNode(const DOMNode* other) const;\
    virtual       bool             isEqualNode(const DOMNode* arg) const;\
    virtual const XMLCh*           getBaseURI() const ;\
    virtual short                  compareTreePosition(const DOMNode* other) const ;\
    virtual const XMLCh*           getTextContent() const ;\
            const XMLCh*           getTextContent(XMLCh* pzBuffer, unsigned int& rnBufferLength) const;\
    virtual void                   setTextContent(const XMLCh* textContent) ;\
    virtual const XMLCh*           lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  ;\
    virtual bool                   isDefaultNamespace(const XMLCh* namespaceURI) const;\
    virtual const XMLCh*           lookupNamespaceURI(const XMLCh* prefix) const  ;\
    virtual       DOMNode*         getInterface(const XMLCh* feature) ;\
    virtual       void             release()


/*
 *  Here are dummy stubs for most of the functions introduced by DOMNode.
 *    Each subclass of DOMNode will have something like this that delegates each
 *    function to the appropriate implementation.
 *    Functions that must be supplied by every node class are omitted.
 *
           DOMNode*         xxx::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); };
           DOMNamedNodeMap* xxx::getAttributes() const                   {return fNode.getAttributes (); };
           DOMNodeList*     xxx::getChildNodes() const                   {return fParent.getChildNodes (); };
           DOMNode*         xxx::getFirstChild() const                   {return fParent.getFirstChild (); };
           DOMNode*         xxx::getLastChild() const                    {return fParent.getLastChild (); };
     const XMLCh*           xxx::getLocalName() const                    {return fNode.getLocalName (); };
     const XMLCh*           xxx::getNamespaceURI() const                 {return fNode.getNamespaceURI (); };
           DOMNode*         xxx::getNextSibling() const                  {return fChild.getNextSibling (); };
     const XMLCh*           xxx::getNodeValue() const                    {return fNode.getNodeValue (); };
           DOMDocument*     xxx::getOwnerDocument() const                {return fNode.getOwnerDocument (); };
     const XMLCh*           xxx::getPrefix() const                       {return fNode.getPrefix (); };
           DOMNode*         xxx::getParentNode() const                   {return fChild.getParentNode (this); };
           DOMNode*         xxx::getPreviousSibling() const              {return fChild.getPreviousSibling (this); };
           bool             xxx::hasChildNodes() const                   {return fParent.hasChildNodes (); };
           DOMNode*         xxx::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                         {return fParent.insertBefore (newChild, refChild); };
           void             xxx::normalize()                             {fParent.normalize(); };
           DOMNode*         xxx::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); };
           DOMNode*         xxx::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                         {return fParent.replaceChild (newChild, oldChild); };
           bool             xxx::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                         {return fNode.isSupported (feature, version); };
           void             xxx::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); };
           bool             xxx::hasAttributes() const                   {return fNode.hasAttributes(); };
           bool             xxx::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); };
           bool             xxx::isEqualNode(const DOMNode* arg) const   {return fNode.isEqualNode(arg); };
           void*            xxx::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                         {return fNode.setUserData(key, data, handler); };
           void*            xxx::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
           const XMLCh*     xxx::getBaseURI() const                      {return fNode.getBaseURI(); };
           short            xxx::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); };
           const XMLCh*     xxx::getTextContent() const                  {return fNode.getTextContent(); };
           void             xxx::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
           const XMLCh*     xxx::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); };
           bool             xxx::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); };
           const XMLCh*     xxx::lookupNamespaceURI(const XMLCh* prefix) const {return fNode.lookupNamespaceURI(prefix); };
           DOMNode*         xxx::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); };


*/



XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMTypeInfoImpl.cpp ---
/*
 * Copyright 2003,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.
 */

#include "DOMTypeInfoImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include <xercesc/framework/psvi/PSVIItem.hpp>
#include <xercesc/framework/psvi/XSTypeDefinition.hpp>

XERCES_CPP_NAMESPACE_BEGIN

/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedElement;
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdNotValidatedAttribute;
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute(XMLUni::fgInfosetURIName, XMLUni::fgCDATAString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedIDAttribute(XMLUni::fgInfosetURIName, XMLUni::fgIDString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute(XMLUni::fgInfosetURIName, XMLUni::fgIDRefString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute(XMLUni::fgInfosetURIName, XMLUni::fgIDRefsString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute(XMLUni::fgInfosetURIName, XMLUni::fgEntityString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute(XMLUni::fgInfosetURIName, XMLUni::fgEntitiesString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute(XMLUni::fgInfosetURIName, XMLUni::fgNmTokenString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute(XMLUni::fgInfosetURIName, XMLUni::fgNmTokensString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute(XMLUni::fgInfosetURIName, XMLUni::fgNotationString);
/*static*/ DOMTypeInfoImpl DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute(XMLUni::fgInfosetURIName, XMLUni::fgEnumerationString);

DOMTypeInfoImpl::DOMTypeInfoImpl(const XMLCh* namespaceUri/*=0*/, const XMLCh* name/*=0*/) 
: fBitFields(0),
  fTypeName(name), 
  fTypeNamespace(namespaceUri),
  fMemberTypeName(0),
  fMemberTypeNamespace(0),
  fDefaultValue(0),
  fNormalizedValue(0)
{
    // by setting the fBitField to 0 we are also setting:
    //  - [validity]=VALIDITY_NOTKNOWN
    //  - [validitation attempted]=VALIDATION_NONE
    //  - [schema specified]=false
}

const XMLCh* DOMTypeInfoImpl::getName() const {
    // if it's a DTD, return the data that was stored
    if(!getNumericProperty(PSVI_Schema_Specified))
        return fTypeName;
    // if [validity] is "invalid" or "notKnown", the {target namespace} and {name} properties of the declared type if available, otherwise null. 
    if(!getNumericProperty(PSVI_Validity))
        return fTypeName;
    if(fMemberTypeName)
        return fMemberTypeName;
    return fTypeName;
}

const XMLCh* DOMTypeInfoImpl::getNamespace() const {
    // if it's a DTD, return the data that was stored
    if(!getNumericProperty(PSVI_Schema_Specified))
        return fTypeNamespace;
    // if [validity] is "invalid" or "notKnown", the {target namespace} and {name} properties of the declared type if available, otherwise null. 
    if(!getNumericProperty(PSVI_Validity))
        return fTypeNamespace;
    if(fMemberTypeName)     // we check on the name, as the URI can be NULL
        return fMemberTypeNamespace;
    return fTypeNamespace;
}

const XMLCh* DOMTypeInfoImpl::getStringProperty(PSVIProperty prop) const {
    switch(prop)
    {
    case PSVI_Type_Definition_Name:             return fTypeName;
    case PSVI_Type_Definition_Namespace:        return fTypeNamespace;
    case PSVI_Member_Type_Definition_Name:      return fMemberTypeName;
    case PSVI_Member_Type_Definition_Namespace: return fMemberTypeNamespace;
    case PSVI_Schema_Default:                   return fDefaultValue;
    case PSVI_Schema_Normalized_Value:          return fNormalizedValue;
    default:                                    assert(false); /* it's not a string property */
    }
    return 0;
}

int DOMTypeInfoImpl::getNumericProperty(PSVIProperty prop) const {
    switch(prop)
    {
    case PSVI_Validity:                         return (PSVIItem::VALIDITY_STATE)(fBitFields & 0x0003);
    case PSVI_Validitation_Attempted:           return (PSVIItem::ASSESSMENT_TYPE)((fBitFields >> 2) & 0x0003);
    case PSVI_Type_Definition_Type:             return (fBitFields & (1 << 5))?XSTypeDefinition::COMPLEX_TYPE:XSTypeDefinition::SIMPLE_TYPE;
    case PSVI_Type_Definition_Anonymous:        return (fBitFields & (1 << 6))?true:false;
    case PSVI_Nil:                              return (fBitFields & (1 << 7))?true:false;
    case PSVI_Member_Type_Definition_Anonymous: return (fBitFields & (1 << 8))?true:false;
    case PSVI_Schema_Specified:                 return (fBitFields & (1 << 9))?true:false;
    default:                                    assert(false); /* it's not a numeric property */
    }
    return 0;
}

void DOMTypeInfoImpl::setStringProperty(PSVIProperty prop, const XMLCh* value) {
    switch(prop)
    {
    case PSVI_Type_Definition_Name:             fTypeName=value; break;
    case PSVI_Type_Definition_Namespace:        fTypeNamespace=value; break;
    case PSVI_Member_Type_Definition_Name:      fMemberTypeName=value; break;
    case PSVI_Member_Type_Definition_Namespace: fMemberTypeNamespace=value; break;
    case PSVI_Schema_Default:                   fDefaultValue=value; break;
    case PSVI_Schema_Normalized_Value:          fNormalizedValue=value; break;
    default:                                    assert(false); /* it's not a string property */
    }
}

void DOMTypeInfoImpl::setNumericProperty(PSVIProperty prop, int value) {
    switch(prop)
    {
    case PSVI_Validity:                         fBitFields |= (value & 0x0003); break;
    case PSVI_Validitation_Attempted:           fBitFields |= ((value & 0x0003) << 2); break;
    case PSVI_Type_Definition_Type:             fBitFields |= (value==XSTypeDefinition::COMPLEX_TYPE)?(1 << 5):0; break;
    case PSVI_Type_Definition_Anonymous:        fBitFields |= (value!=0)?(1 << 6):0; break;
    case PSVI_Nil:                              fBitFields |= (value!=0)?(1 << 7):0; break;
    case PSVI_Member_Type_Definition_Anonymous: fBitFields |= (value!=0)?(1 << 8):0; break;
    case PSVI_Schema_Specified:                 fBitFields |= (value!=0)?(1 << 9):0; break;
    default:                                    assert(false); /* it's not a numeric property */
    }
}


XERCES_CPP_NAMESPACE_END
/**
 * End of file DOMTypeInfo.cpp
 */

--- NEW FILE: DOMNodeListImpl.hpp ---
#ifndef DOMNodeListImpl_HEADER_GUARD_
#define DOMNodeListImpl_HEADER_GUARD_
/*
 * 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.
 */

/*
 * $Id: DOMNodeListImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


//  NodeList implementation class -
//     This is for NodeLists returned by GetChildNodes only, not for
//     node lists returned by GetElementsByTagName
//
//     Every node type capable of having children has (as an embedded member)
//     an instance of this class.  To hold down the size overhead on each node, a
//     cache of extended data for active node lists is maintained
//     separately.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMNodeList.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class DOMNode;

class CDOM_EXPORT DOMNodeListImpl: public DOMNodeList
{
private:
    DOMNode   *fNode;

    // Unused, and unimplemented constructors, operators, etc.
    DOMNodeListImpl();
    DOMNodeListImpl(const DOMNodeListImpl & other);
    DOMNodeListImpl & operator = (const DOMNodeListImpl & other);

public:
    DOMNodeListImpl(DOMNode *node);
    virtual             ~DOMNodeListImpl();
    virtual DOMNode *  item(XMLSize_t index) const;
    virtual XMLSize_t getLength() const;
};

XERCES_CPP_NAMESPACE_END

#endif



--- NEW FILE: DOMImplementationImpl.cpp ---
/*
 * Copyright 2001-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.
 */

/*
 * $Id: DOMImplementationImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMImplementationImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMDocumentTypeImpl.hpp"
#include "DOMWriterImpl.hpp"

#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLInitializer.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/util/XMLStringTokenizer.hpp>
#include <xercesc/util/XMLDOMMsg.hpp>
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/parsers/DOMBuilderImpl.hpp>

XERCES_CPP_NAMESPACE_BEGIN


// ------------------------------------------------------------
//
//  Static constants.  These are lazily initialized on first usage.
//                     (Static constructors can not be safely used because
//                      of order of initialization dependencies.)
// ------------------------------------------------------------
static const XMLCh  g1_0[] =     // Points to "1.0"
        {chDigit_1, chPeriod, chDigit_0, chNull};
static const XMLCh  g2_0[] =      // Points to "2.0"
        {chDigit_2, chPeriod, chDigit_0, chNull};
static const XMLCh  g3_0[] =      // Points to "3.0"
        {chDigit_3, chPeriod, chDigit_0, chNull};
static const XMLCh  gTrav[] =     // Points to "Traversal"
        {chLatin_T, chLatin_r, chLatin_a, chLatin_v, chLatin_e, chLatin_r,
            chLatin_s, chLatin_a, chLatin_l, chNull};
static const XMLCh  gCore[] =     // Points to "Core"
        {chLatin_C, chLatin_o, chLatin_r, chLatin_e, chNull};
static const XMLCh  gRange[] =     // Points to "Range"
        {chLatin_R, chLatin_a, chLatin_n, chLatin_g, chLatin_e, chNull};
static const XMLCh  gLS[] =     // Points to "LS"
        {chLatin_L, chLatin_S, chNull};


// -----------------------------------------------------------------------
//  Message Loader for DOM
// -----------------------------------------------------------------------
static XMLMsgLoader  *sMsgLoader4DOM = 0;   // Points to the singleton instance
static XMLMutex      *sMutex4DOM = 0;
static XMLRegisterCleanup mutex4DOMCleanup;
static XMLRegisterCleanup msgLoader4DOMCleanup;

static void reinitMsgLoader4DOM()
{
	delete sMsgLoader4DOM;
	sMsgLoader4DOM = 0;
}

static void reinitMutex4DOM()
{
	delete sMutex4DOM;
	sMutex4DOM = 0;
}

static XMLMutex& getMutex4DOM()
{
    if (!sMutex4DOM)
    {
        XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex);

        // If we got here first, then register it and set the registered flag
        if (!sMutex4DOM)
        {
            sMutex4DOM = new XMLMutex(XMLPlatformUtils::fgMemoryManager);
            mutex4DOMCleanup.registerCleanup(reinitMutex4DOM);
        }
    }
    return *sMutex4DOM;
}

XMLMsgLoader* DOMImplementationImpl::getMsgLoader4DOM()
{
    if (!sMsgLoader4DOM)
    {
        XMLMutexLock lock(&getMutex4DOM());

        if (!sMsgLoader4DOM)
        {
            sMsgLoader4DOM = XMLPlatformUtils::loadMsgSet(XMLUni::fgXMLDOMMsgDomain);

            if (!sMsgLoader4DOM)
                XMLPlatformUtils::panic(PanicHandler::Panic_CantLoadMsgDomain);
            else
                msgLoader4DOMCleanup.registerCleanup(reinitMsgLoader4DOM);
        }
    }

    return sMsgLoader4DOM;
}

void XMLInitializer::initializeMsgLoader4DOM()
{
    sMsgLoader4DOM = XMLPlatformUtils::loadMsgSet(XMLUni::fgXMLDOMMsgDomain);
    if (sMsgLoader4DOM) {
        msgLoader4DOMCleanup.registerCleanup(reinitMsgLoader4DOM);
    }
}

// -----------------------------------------------------------------------
//  Singleton DOMImplementationImpl
// -----------------------------------------------------------------------
static DOMImplementationImpl    *gDomimp = 0;   // Points to the singleton instance
                                            //  of DOMImplementation that is returnedreturned
                                            //  by any call to getImplementation().
static XMLRegisterCleanup implementationCleanup;

static void reinitImplementation()
{
	delete gDomimp;
	gDomimp = 0;
}

//  getImplementation()  - Always returns the same singleton instance, which
//                         is lazily created on the first call.  Note that
//                         DOM_Implementation must be thread-safe because
//                         it is common to all DOM documents, and while a single
//                         document is not thread-safe within itself, we do
//                         promise that different documents can safely be
//                         used concurrently by different threads.
//
DOMImplementationImpl *DOMImplementationImpl::getDOMImplementationImpl()
{
    if (!gDomimp)
    {
        XMLMutexLock lock(&getMutex4DOM());

        if (!gDomimp)
        {
            gDomimp = new DOMImplementationImpl;
            implementationCleanup.registerCleanup(reinitImplementation);
        }
    }

    return gDomimp;
}

void XMLInitializer::initializeDOMImplementationImpl()
{
    gDomimp = new DOMImplementationImpl;
    if (gDomimp) {
        implementationCleanup.registerCleanup(reinitImplementation);
    }
}

// ------------------------------------------------------------
// DOMImplementation Virtual interface
// ------------------------------------------------------------
bool  DOMImplementationImpl::hasFeature(const  XMLCh * feature,  const  XMLCh * version) const
{
    if (!feature)
        return false;

    bool anyVersion = (version == 0 || !*version);
    bool version1_0 = XMLString::equals(version, g1_0);
    bool version2_0 = XMLString::equals(version, g2_0);
    bool version3_0 = XMLString::equals(version, g3_0);

    // Currently, we support only XML Level 1 version 1.0
    if (XMLString::compareIStringASCII(feature, XMLUni::fgXMLString) == 0
        && (anyVersion || version1_0 || version2_0))
        return true;

    if (XMLString::compareIStringASCII(feature, gCore) == 0
        && (anyVersion || version1_0 || version2_0 || version3_0))
        return true;

    if (XMLString::compareIStringASCII(feature, gTrav) == 0
        && (anyVersion || version2_0))
        return true;

    if (XMLString::compareIStringASCII(feature, gRange) == 0
        && (anyVersion || version2_0))
        return true;

    if (XMLString::compareIStringASCII(feature, gLS) == 0
        && (anyVersion || version3_0))
        return true;

    return false;
}


//Introduced in DOM Level 2
DOMDocumentType *DOMImplementationImpl::createDocumentType(const XMLCh *qualifiedName,
	const XMLCh * publicId, const XMLCh *systemId)
{
    // assume XML 1.0 since we do not know its version yet.
    if(!XMLChar1_0::isValidName(qualifiedName, XMLString::stringLen(qualifiedName)))
        throw DOMException(DOMException::INVALID_CHARACTER_ERR, 0);

    //to do: do we need to create with user's memorymanager???
    DOMDocumentTypeImpl* docType = new DOMDocumentTypeImpl(0, qualifiedName, publicId, systemId, true);
    return docType;
}

DOMDocument *DOMImplementationImpl::createDocument(const XMLCh *namespaceURI,
	const XMLCh *qualifiedName, DOMDocumentType *doctype,
    MemoryManager* const manager)
{
    return new (manager) DOMDocumentImpl(namespaceURI, qualifiedName, doctype, manager);
}


//Introduced in DOM Level 3
DOMImplementation* DOMImplementationImpl::getInterface(const XMLCh*){
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0);

    return 0;
}

// Non-standard extension
DOMDocument *DOMImplementationImpl::createDocument(MemoryManager* const manager)
{
        return new (manager) DOMDocumentImpl(manager);
}

//
//  DOMImplementation::getImplementation.  DOMImplementation is supposed to
//                                              be a pure interface class.  This one static
//                                              function is the hook that lets things get started.
DOMImplementation *DOMImplementation::getImplementation()
{
    return (DOMImplementation*) DOMImplementationImpl::getDOMImplementationImpl();
}

bool DOMImplementation::loadDOMExceptionMsg
(
    const   DOMException::ExceptionCode  msgToLoad
    ,       XMLCh* const                 toFill
    , const unsigned int                 maxChars
)
{
    // load the text, the msgToLoad+XMLDOMMsgs::DOMEXCEPTION_ERRX+msgToLoad is the corresponding XMLDOMMsg Code
    return DOMImplementationImpl::getMsgLoader4DOM()->loadMsg(XMLDOMMsg::DOMEXCEPTION_ERRX+msgToLoad, toFill, maxChars);
}

bool DOMImplementation::loadDOMExceptionMsg
(
    const   DOMRangeException::RangeExceptionCode  msgToLoad
    ,       XMLCh* const                           toFill
    , const unsigned int                           maxChars
)
{
    // load the text, the XMLDOMMsgs::DOMRANGEEXCEPTION_ERRX+msgToLoad is the corresponding XMLDOMMsg Code
    return DOMImplementationImpl::getMsgLoader4DOM()->loadMsg(XMLDOMMsg::DOMRANGEEXCEPTION_ERRX+msgToLoad, toFill, maxChars);
}

// ------------------------------------------------------------
// DOMImplementationLS Virtual interface
// ------------------------------------------------------------
//Introduced in DOM Level 3
DOMBuilder* DOMImplementationImpl::createDOMBuilder(const short           mode,
                                                    const XMLCh* const,
                                                    MemoryManager* const  manager,
                                                    XMLGrammarPool* const gramPool)
{
    if (mode == DOMImplementationLS::MODE_ASYNCHRONOUS)
        throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, manager);

    return new (manager) DOMBuilderImpl(0, manager, gramPool);
}


DOMWriter* DOMImplementationImpl::createDOMWriter(MemoryManager* const manager)
{
    return new (manager) DOMWriterImpl(manager);
}

DOMInputSource* DOMImplementationImpl::createDOMInputSource()
{
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0);

    return 0;
}


// ------------------------------------------------------------
// DOMImplementationSource Virtual interface
// ------------------------------------------------------------
DOMImplementation* DOMImplementationImpl::getDOMImplementation(const XMLCh* features) const
{
    DOMImplementation* impl = DOMImplementation::getImplementation();

    XMLStringTokenizer tokenizer(features, XMLPlatformUtils::fgMemoryManager);
    const XMLCh* feature = 0;

    while (feature || tokenizer.hasMoreTokens()) {

        if (!feature)
            feature = tokenizer.nextToken();

        const XMLCh* version = 0;
        const XMLCh* token = tokenizer.nextToken();

        if (token && XMLString::isDigit(token[0]))
            version = token;

        if (!impl->hasFeature(feature, version))
            return 0;

        if (!version)
            feature = token;
    }
    return impl;
}


XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMNotationImpl.hpp ---
#ifndef DOMNotationImpl_HEADER_GUARD_
#define DOMNotationImpl_HEADER_GUARD_
/*
 * 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.
 */

/*
 * $Id: DOMNotationImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMNotation.hpp>

XERCES_CPP_NAMESPACE_BEGIN


#include "DOMNodeImpl.hpp"

class DOMDocument;


class CDOM_EXPORT DOMNotationImpl: public DOMNotation {
public:
    DOMNodeImpl      fNode;

    const XMLCh * fName;
    const XMLCh * fPublicId;
    const XMLCh * fSystemId;
    const XMLCh * fBaseURI;

public:
    DOMNotationImpl(DOMDocument *ownerDoc, const XMLCh *);
    DOMNotationImpl(const DOMNotationImpl &other, bool deep=false);

    virtual ~DOMNotationImpl();

     // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;

    //
    // The Public Identifier for this Notation. If no public identifier
    // was specified, this will be null.
    virtual const XMLCh * getPublicId() const;

    // The System Identifier for this Notation. If no system identifier
    // was specified, this will be null.
    virtual const XMLCh * getSystemId() const;

    // NON-DOM: The Public Identifier for this Notation. If no public
    // identifier was specified, this will be null.
    virtual void setPublicId(const XMLCh *arg);


    // NON-DOM: The System Identifier for this Notation. If no system
    // identifier was specified, this will be null.
    virtual void setSystemId(const XMLCh *arg);

    // NON-DOM: set base uri
    virtual void setBaseURI(const XMLCh *arg);

private:
    // unimplemented    
    DOMNotationImpl& operator= (const DOMNotationImpl& other);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMNodeIteratorImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMNodeIteratorImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//////////////////////////////////////////////////////////////////////
// DOMNodeIteratorImpl.cpp: implementation of the DOMNodeIteratorImpl class.
//
//////////////////////////////////////////////////////////////////////

#include "DOMNodeIteratorImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

DOMNodeIteratorImpl::DOMNodeIteratorImpl (DOMDocument* doc,
                                    DOMNode* root,
                                    unsigned long whatToShow,
                                    DOMNodeFilter* nodeFilter,
                                    bool expandEntityRef)
:   fRoot(root),
    fDocument(doc),
    fWhatToShow(whatToShow),
    fNodeFilter(nodeFilter),
    fExpandEntityReferences(expandEntityRef),
    fDetached(false),
    fCurrentNode(0),
    fForward(true)    
{
	
}


DOMNodeIteratorImpl::DOMNodeIteratorImpl ( const DOMNodeIteratorImpl& toCopy)
    : DOMNodeIterator(toCopy),
    fRoot(toCopy.fRoot),
    fDocument(toCopy.fDocument),
    fWhatToShow(toCopy.fWhatToShow),
    fNodeFilter(toCopy.fNodeFilter),
    fExpandEntityReferences(toCopy.fExpandEntityReferences),
    fDetached(toCopy.fDetached),
    fCurrentNode(toCopy.fCurrentNode),
    fForward(toCopy.fForward)
{
}


DOMNodeIteratorImpl& DOMNodeIteratorImpl::operator= (const DOMNodeIteratorImpl& other) {
    fRoot                   = other.fRoot;
    fCurrentNode            = other.fRoot;
    fWhatToShow             = other.fWhatToShow;
    fNodeFilter             = other.fNodeFilter;
    fForward                = other.fForward;
    fDetached               = other.fDetached;
    fExpandEntityReferences = other.fExpandEntityReferences;
    fDocument               = other.fDocument;
    return *this;
}

DOMNodeIteratorImpl::~DOMNodeIteratorImpl ()
{
	fDetached = false;
}


void DOMNodeIteratorImpl::detach ()
{
	fDetached = true;
   ((DOMDocumentImpl *)fDocument)->removeNodeIterator(this);
}


DOMNode* DOMNodeIteratorImpl::getRoot() {
    return fRoot;
}


// Implementation Note: Note that the iterator looks at whatToShow
// and filter values at each call, and therefore one _could_ add
// setters for these values and alter them while iterating!

/** Return the whatToShow value */

unsigned long DOMNodeIteratorImpl::getWhatToShow () {
    return fWhatToShow;
}


/** Return the filter */

DOMNodeFilter* DOMNodeIteratorImpl::getFilter () {
    return fNodeFilter;
}

/** Get the expandEntity reference flag. */
bool DOMNodeIteratorImpl::getExpandEntityReferences()
{
    return fExpandEntityReferences;
}

/** Return the next DOMNode* in the Iterator. The node is the next node in
 *  depth-first order which also passes the filter, and whatToShow.
 *  A 0 return means either that
 */

DOMNode* DOMNodeIteratorImpl::nextNode () {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    // if root is 0 there is no next node->
    if (!fRoot)
			return 0;

    DOMNode* aNextNode = fCurrentNode;
    bool accepted = false; // the next node has not been accepted.

    while (!accepted) {

        // if last direction is not forward, repeat node->
        if (!fForward && (aNextNode != 0)) {
            //System.out.println("nextNode():!fForward:"+fCurrentNode.getNodeName());
            aNextNode = fCurrentNode;
        } else {
        // else get the next node via depth-first
            aNextNode = nextNode(aNextNode, true);
        }

        fForward = true; //REVIST: should direction be set forward before 0 check?

        // nothing in the list. return 0.
        if (!aNextNode) return 0;

        // does node pass the filters and whatToShow?
        accepted = acceptNode(aNextNode);
        if (accepted) {
            // if so, then the node is the current node->
            fCurrentNode = aNextNode;
            return fCurrentNode;
        }
    }

    // no nodes, or no accepted nodes.
    return 0;
}


/** Return the previous Node in the Iterator. The node is the next node in
 *  _backwards_ depth-first order which also passes the filter, and whatToShow.
 */

DOMNode* DOMNodeIteratorImpl::previousNode () {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);
		
    // if the root is 0, or the current node is 0, return 0.
    if (!fRoot || !fCurrentNode) return 0;

    DOMNode* aPreviousNode = fCurrentNode;
    bool accepted = false;

    while (!accepted) {

        if (fForward && (aPreviousNode != 0)) {
            //repeat last node->
            aPreviousNode = fCurrentNode;
        } else {
            // get previous node in backwards depth first order.
            aPreviousNode = previousNode(aPreviousNode);
        }

        // we are going backwards
        fForward = false;

        // if the new previous node is 0, we're at head or past the root,
        // so return 0.
        if (!aPreviousNode) return 0;

        // check if node passes filters and whatToShow.
        accepted = acceptNode(aPreviousNode);
        if (accepted) {
            // if accepted, update the current node, and return it.
            fCurrentNode = aPreviousNode;
            return fCurrentNode;
        }
    }
    // there are no nodes?
    return 0;
}


/** The node is accepted if it passes the whatToShow and the filter. */
bool DOMNodeIteratorImpl::acceptNode (DOMNode* node) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    if (fNodeFilter == 0) {
        return ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0);
    } else {
        return ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0)
            && fNodeFilter->acceptNode(node) == DOMNodeFilter::FILTER_ACCEPT;
    }
}


/** Return node, if matches or any parent if matches. */
DOMNode* DOMNodeIteratorImpl::matchNodeOrParent (DOMNode* node) {

    for (DOMNode* n = fCurrentNode; n != fRoot; n = n->getParentNode()) {
        if (node == n) return n;
    }

    return 0;
}


/** The method nextNode(DOMNode, bool) returns the next node
 *  from the actual DOM tree.
 *
 *  The bool visitChildren determines whether to visit the children.
 *  The result is the nextNode.
 */

DOMNode* DOMNodeIteratorImpl::nextNode (DOMNode* node, bool visitChildren) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    if (!node) return fRoot;

    DOMNode* result = 0;
    // only check children if we visit children.
    if (visitChildren) {
        //if hasChildren, return 1st child.
        if ((fExpandEntityReferences || node->getNodeType()!=DOMNode::ENTITY_REFERENCE_NODE) && 
            node->hasChildNodes()) {
            result = node->getFirstChild();
            return result;
        }
    }

    // if hasSibling, return sibling
    if (node != fRoot) {
        result = node->getNextSibling();
        if (result != 0) return result;


        // return parent's 1st sibling.
        DOMNode* parent = node->getParentNode();
        while ((parent != 0) && parent != fRoot) {
            result = parent->getNextSibling();
            if (result != 0) {
                return result;
            } else {
                parent = parent->getParentNode();
            }

        } // while (parent != 0 && parent != fRoot) {
    }
    // end of list, return 0
    return 0;
}


/** The method previousNode(DOMNode) returns the previous node
 *  from the actual DOM tree.
 */

DOMNode* DOMNodeIteratorImpl::previousNode (DOMNode* node) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    DOMNode* result = 0;

    // if we're at the root, return 0.
    if (node == fRoot)
			return 0;

    // get sibling
    result = node->getPreviousSibling();
    if (!result) {
        //if 1st sibling, return parent
        result = node->getParentNode();
        return result;
    }

    // if sibling has children, keep getting last child of child.
    if (result->hasChildNodes()) {
        while ((fExpandEntityReferences || result->getNodeType()!=DOMNode::ENTITY_REFERENCE_NODE) && 
               result->hasChildNodes()) {
            result = result->getLastChild();
        }
    }

    return result;
}


/** Fix-up the iterator on a remove. Called by DOM or otherwise,
 *  before an actual DOM remove.
 */

void DOMNodeIteratorImpl::removeNode (DOMNode* node) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    // Implementation note: Fix-up means setting the current node properly
    // after a remove.

    if (!node) return;

    DOMNode* deleted = matchNodeOrParent(node);

    if (!deleted) return;

    if (fForward) {
        fCurrentNode = previousNode(deleted);
    } else
    // if (!fForward)
    {
        DOMNode* next = nextNode(deleted, false);
        if (next != 0) {
            // normal case: there _are_ nodes following this in the iterator.
            fCurrentNode = next;
        } else {
            // the last node in the iterator is to be removed,
            // so we set the current node to be the previous one.
            fCurrentNode = previousNode(deleted);
            fForward = true;
        }

    }

}


void DOMNodeIteratorImpl::release()
{
    detach();

    // for performance reason, do not recycle pointer
    // chance that this is allocated again and again is not usual
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMLocatorImpl.cpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: DOMLocatorImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMLocatorImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


// ---------------------------------------------------------------------------
//  DOMLocatorImpl: Constructors and Destructor
// ---------------------------------------------------------------------------
DOMLocatorImpl::DOMLocatorImpl() :
fLineNum(-1)
, fColumnNum(-1)
, fOffset(-1)
, fErrorNode(0)
, fURI(0)
{
}


DOMLocatorImpl::DOMLocatorImpl(const XMLSSize_t lineNum,
                               const XMLSSize_t columnNum,
                               DOMNode* const errorNode,
                               const XMLCh* const uri,
                               const XMLSSize_t offset) :
fLineNum(lineNum)
, fColumnNum(columnNum)
, fOffset(offset)
, fErrorNode(errorNode)
, fURI(uri)
{
}

DOMLocatorImpl::~DOMLocatorImpl()
{
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMWriterImpl.hpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: DOMWriterImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

/**
 *  DOMWriterImpl provides an API for serializing (writing) a DOM document out in
 * an XML document. The XML data is written to an output stream, the type of
 * which depends on the specific language bindings in use. During
 * serialization of XML data, namespace fixup is done when possible.
 * <p> <code>DOMWriterImpl</code> accepts any node type for serialization. For
 * nodes of type <code>Document</code> or <code>Entity</code>, well formed
 * XML will be created if possible. The serialized output for these node
 * types is either as a Document or an External Entity, respectively, and is
 * acceptable input for an XML parser. For all other types of nodes the
 * serialized form is not specified, but should be something useful to a
 * human for debugging or diagnostic purposes. Note: rigorously designing an
 * external (source) form for stand-alone node types that don't already have
 * one defined in  seems a bit much to take on here.
 * <p>Within a Document or Entity being serialized, Nodes are processed as
 * follows Documents are written including an XML declaration and a DTD
 * subset, if one exists in the DOM. Writing a document node serializes the
 * entire document.  Entity nodes, when written directly by
 * <code>writeNode</code> defined in the <code>DOMWriterImpl</code> interface,
 * output the entity expansion but no namespace fixup is done. The resulting
 * output will be valid as an external entity.  Entity References nodes are
 * serializes as an entity reference of the form
 * <code>"&amp;entityName;"</code>) in the output. Child nodes (the
 * expansion) of the entity reference are ignored.  CDATA sections
 * containing content characters that can not be represented in the
 * specified output encoding are handled according to the
 * "split-cdata-sections" feature.If the feature is <code>true</code>, CDATA
 * sections are split, and the unrepresentable characters are serialized as
 * numeric character references in ordinary content. The exact position and
 * number of splits is not specified. If the feature is <code>false</code>,
 * unrepresentable characters in a CDATA section are reported as errors. The
 * error is not recoverable - there is no mechanism for supplying
 * alternative characters and continuing with the serialization. All other
 * node types (Element, Text, etc.) are serialized to their corresponding
 * XML source form.
 * <p> Within the character data of a document (outside of markup), any
 * characters that cannot be represented directly are replaced with
 * character references. Occurrences of '&lt;' and '&amp;' are replaced by
 * the predefined entities &amp;lt; and &amp;amp. The other predefined
 * entities (&amp;gt, &amp;apos, etc.) are not used; these characters can be
 * included directly. Any character that can not be represented directly in
 * the output character encoding is serialized as a numeric character
 * reference.
 * <p> Attributes not containing quotes are serialized in quotes. Attributes
 * containing quotes but no apostrophes are serialized in apostrophes
 * (single quotes). Attributes containing both forms of quotes are
 * serialized in quotes, with quotes within the value represented by the
 * predefined entity &amp;quot;. Any character that can not be represented
 * directly in the output character encoding is serialized as a numeric
 * character reference.
 * <p> Within markup, but outside of attributes, any occurrence of a character
 * that cannot be represented in the output character encoding is reported
 * as an error. An example would be serializing the element
 * &lt;LaCa�ada/&gt; with the encoding="us-ascii".
 * <p> When requested by setting the <code>normalize-characters</code> feature
 * on <code>DOMWriterImpl</code>, all data to be serialized, both markup and
 * character data, is W3C Text normalized according to the rules defined in
 * . The W3C Text normalization process affects only the data as it is being
 * written; it does not alter the DOM's view of the document after
 * serialization has completed.
 * <p>Namespaces are fixed up during serialization, the serialization process
 * will verify that namespace declarations, namespace prefixes and the
 * namespace URIs associated with Elements and Attributes are consistent. If
 * inconsistencies are found, the serialized form of the document will be
 * altered to remove them. The algorithm used for doing the namespace fixup
 * while seralizing a document is a combination of the algorithms used for
 * lookupNamespaceURI and lookupNamespacePrefix . previous paragraph to be
 * defined closer here.
 * <p>Any changes made affect only the namespace prefixes and declarations
 * appearing in the serialized data. The DOM's view of the document is not
 * altered by the serialization operation, and does not reflect any changes
 * made to namespace declarations or prefixes in the serialized output.
 * <p> While serializing a document the serializer will write out
 * non-specified values (such as attributes whose <code>specified</code> is
 * <code>false</code>) if the <code>output-default-values</code> feature is
 * set to <code>true</code>. If the <code>output-default-values</code> flag
 * is set to <code>false</code> and the <code>use-abstract-schema</code>
 * feature is set to <code>true</code> the abstract schema will be used to
 * determine if a value is specified or not, if
 * <code>use-abstract-schema</code> is not set the <code>specified</code>
 * flag on attribute nodes is used to determine if attribute values should
 * be written out.
 * <p> Ref to Core spec (1.1.9, XML namespaces, 5th paragraph) entity ref
 * description about warning about unbound entity refs. Entity refs are
 * always serialized as &amp;foo;, also mention this in the load part of
 * this spec.
 * <p> When serializing a document the DOMWriterImpl checks to see if the document
 * element in the document is a DOM Level 1 element or a DOM Level 2 (or
 * higher) element (this check is done by looking at the localName of the
 * root element). If the root element is a DOM Level 1 element then the
 * DOMWriterImpl will issue an error if a DOM Level 2 (or higher) element is
 * found while serializing. Likewise if the document element is a DOM Level
 * 2 (or higher) element and the DOMWriterImpl sees a DOM Level 1 element an
 * error is issued. Mixing DOM Level 1 elements with DOM Level 2 (or higher)
 * is not supported.
 * <p> <code>DOMWriterImpl</code>s have a number of named features that can be
 * queried or set. The name of <code>DOMWriterImpl</code> features must be valid
 * XML names. Implementation specific features (extensions) should choose an
 * implementation dependent prefix to avoid name collisions.
 * <p>Here is a list of properties that must be recognized by all
 * implementations.
 * <dl>
 * <dt><code>"normalize-characters"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[
 * optional] (default) Perform the W3C Text Normalization of the characters
 * in document as they are written out. Only the characters being written
 * are (potentially) altered. The DOM document itself is unchanged. </dd>
 * <dt>
 * <code>false</code></dt>
 * <dd>[required] do not perform character normalization. </dd>
 * </dl></dd>
 * <dt>
 * <code>"split-cdata-sections"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[required] (default)
 * Split CDATA sections containing the CDATA section termination marker
 * ']]&gt;' or characters that can not be represented in the output
 * encoding, and output the characters using numeric character references.
 * If a CDATA section is split a warning is issued. </dd>
 * <dt><code>false</code></dt>
 * <dd>[
 * required] Signal an error if a <code>CDATASection</code> contains an
 * unrepresentable character. </dd>
 * </dl></dd>
 * <dt><code>"validation"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[
 * optional] Use the abstract schema to validate the document as it is being
 * serialized. If validation errors are found the error handler is notified
 * about the error. Setting this state will also set the feature
 * <code>use-abstract-schema</code> to <code>true</code>. </dd>
 * <dt><code>false</code></dt>
 * <dd>[
 * required] (default) Don't validate the document as it is being
 * serialized. </dd>
 * </dl></dd>
 * <dt><code>"expand-entity-references"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[
 * optional] Expand <code>EntityReference</code> nodes when serializing. </dd>
 * <dt>
 * <code>false</code></dt>
 * <dd>[required] (default) Serialize all
 * <code>EntityReference</code> nodes as XML entity references. </dd>
 * </dl></dd>
 * <dt>
 * <code>"whitespace-in-element-content"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[required] (
 * default) Output all white spaces in the document. </dd>
 * <dt><code>false</code></dt>
 * <dd>[
 * optional] Only output white space that is not within element content. The
 * implementation is expected to use the
 * <code>isWhitespaceInElementContent</code> flag on <code>Text</code> nodes
 * to determine if a text node should be written out or not. </dd>
 * </dl></dd>
 * <dt>
 * <code>"discard-default-content"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[required] (default
 * ) Use whatever information available to the implementation (i.e. XML
 * schema, DTD, the <code>specified</code> flag on <code>Attr</code> nodes,
 * and so on) to decide what attributes and content should be serialized or
 * not. Note that the <code>specified</code> flag on <code>Attr</code> nodes
 * in itself is not always reliable, it is only reliable when it is set to
 * <code>false</code> since the only case where it can be set to
 * <code>false</code> is if the attribute was created by a Level 1
 * implementation. </dd>
 * <dt><code>false</code></dt>
 * <dd>[required] Output all attributes and
 * all content. </dd>
 * </dl></dd>
 * <dt><code>"format-canonical"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[optional]
 * This formatting writes the document according to the rules specified in .
 * Setting this feature to true will set the feature "format-pretty-print"
 * to false. </dd>
 * <dt><code>false</code></dt>
 * <dd>[required] (default) Don't canonicalize the
 * output. </dd>
 * </dl></dd>
 * <dt><code>"format-pretty-print"</code></dt>
 * <dd>
 * <dl>
 * <dt><code>true</code></dt>
 * <dd>[optional]
 * Formatting the output by adding whitespace to produce a pretty-printed,
 * indented, human-readable form. The exact form of the transformations is
 * not specified by this specification. Setting this feature to true will
 * set the feature "format-canonical" to false. </dd>
 * <dt><code>false</code></dt>
 * <dd>[required]
 * (default) Don't pretty-print the result. </dd>
 * </dl></dd>
 * </dl>
 * <p>See also the <a href='http://www.w3.org/TR/2001/WD-DOM-Level-3-ASLS-20011025'>Document Object Model (DOM) Level 3 Abstract Schemas and Load
 * and Save Specification</a>.
 */

#ifndef DOMWriterImpl_HEADER_GUARD_
#define DOMWriterImpl_HEADER_GUARD_

#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMWriter.hpp>
#include <xercesc/util/XMLDOMMsg.hpp>
#include <xercesc/util/RefHashTableOf.hpp>
#include <xercesc/util/RefVectorOf.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMWriterImpl:public XMemory,
                                public DOMWriter {

public:

    /** @name Constructor and Destructor */
    //@{

    /**
     * Constructor.
     */
    DOMWriterImpl(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);

    /**
     * Destructor.
     */
    ~DOMWriterImpl();
    //@}

    /** @name Inplementation of Abstract interface */

    virtual bool               canSetFeature(const XMLCh* const featName
                                           , bool               state) const;

    virtual void               setFeature(const XMLCh* const featName
                                        , bool               state);
    virtual bool               getFeature(const XMLCh* const featName) const;

    virtual void               setEncoding(const XMLCh* const encoding);
    virtual const XMLCh*       getEncoding() const;

    virtual void               setNewLine(const XMLCh* const newLine);
    virtual const XMLCh*       getNewLine() const;

    virtual void               setErrorHandler(DOMErrorHandler *errorHandler);
    virtual DOMErrorHandler*   getErrorHandler() const;

    virtual void               setFilter(DOMWriterFilter *filter);
    virtual DOMWriterFilter*   getFilter() const;

    virtual bool               writeNode(XMLFormatTarget* const destination
                                       , const DOMNode         &nodeToWrite);
    virtual void               release();

    /**
	  *  The caller is responsible for the release of the returned string
	  */

    virtual XMLCh*             writeToString(const DOMNode &nodeToWrite);
    //@}

private:

    /** unimplemented copy ctor and assignment operator */
    DOMWriterImpl(const DOMWriterImpl&);
    DOMWriterImpl & operator = (const DOMWriterImpl&);

    /** helper **/
    void                          initSession(const DOMNode* const);
    void                          processNode(const DOMNode* const);

    void                          procCdataSection(const XMLCh*   const nodeValue
                                                 , const DOMNode* const nodeToWrite
                                                 , int level);

    void                          procUnrepCharInCdataSection(const XMLCh*   const nodeValue
                                                            , const DOMNode* const nodeToWrite
                                                            , int level);

protected:
    /**
     * Overidden by derived classes to extend the abilities of the standard writer
     * always returns false in the default implementation
     * @return true if the method deals with nodeToWrite
     */
    virtual bool                          customNodeSerialize(const DOMNode* const nodeToWrite, int level);

    DOMNodeFilter::FilterAction   checkFilter(const DOMNode* const) const;

    bool                          checkFeature(const XMLCh* const featName
                                             , bool               state
                                             , int&               featureId) const;

    bool                          reportError(const DOMNode* const    errorNode
                                            , DOMError::ErrorSeverity errorType
                                            , const XMLCh*   const    errorMsg);
    bool                          reportError(const DOMNode* const    errorNode
                                            , DOMError::ErrorSeverity errorType
                                            , XMLDOMMsg::Codes        toEmit);

    bool                          canSetFeature(const int featureId
                                              , bool      val)     const;
    void                          setFeature(const int featureId
                                           , bool      val);
    bool                          getFeature(const int featureId) const;

    void                          printNewLine();
    void                          setURCharRef();


    void printIndent(int level) const;
    //does the actual work for processNode while keeping track of the level
    void processNode(const DOMNode* const nodeToWrite, int level);

    void processBOM();

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fFeatures
    //
    //  fEncoding
    //      own it
    //
    //  fNewLine
    //      own it
    //
    //  fErrorHandler
    //      don't own it
    //
    //  fFilter
    //      don't own it
    //
    //  fDocumentVersion
    //      The XML Version of the document to be serialized.
    // 
    //  fEncodingUsed (session var)
    //      the actual encoding used in WriteNode(),
    //      it does not own any data(memory).
    //
    //  fNewLineUsed (session var)
    //      the actual "end of line" sequence used in WriteNode(),
    //      it does not own any data(memory).
    //
    //  fFormatter (session var)
    //      the formatter used in WriteNode()
    //
    //  fErrorCount
    //      the count of error encountered in the serialization,
    //      which neither the error handler, nor the serializer itself,
    //      treat as fatal. And the serializer will return true/false
    //      based on this value.
    //
    //  fCurrentLine
    //      the current line. Used to track the line number the current
    //      node begins on
    //
    // -----------------------------------------------------------------------

    int                           fFeatures;
    XMLCh                        *fEncoding;
    XMLCh                        *fNewLine;
    DOMErrorHandler              *fErrorHandler;
    DOMWriterFilter              *fFilter;
    const XMLCh                  *fDocumentVersion;

    //session vars
    const XMLCh                  *fEncodingUsed;
    const XMLCh                  *fNewLineUsed;
    XMLFormatter                 *fFormatter;
    int                           fErrorCount;
    int                           fCurrentLine;

    RefVectorOf< RefHashTableOf<XMLCh> >* fNamespaceStack;
    MemoryManager*               fMemoryManager;
};

inline void DOMWriterImpl::setFeature(const int featureId
                                    , bool      val)
{
    (val)? fFeatures |= (1<<featureId) : fFeatures &= ~(1<<featureId);
};

inline bool DOMWriterImpl::getFeature(const int featureId) const
{
    return ((fFeatures & ( 1<<featureId )) != 0) ? true : false;
};

inline void DOMWriterImpl::setURCharRef()
{
    fFormatter->setUnRepFlags(XMLFormatter::UnRep_CharRef);
}

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMCharacterDataImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMCharacterDataImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMCharacterDataImpl.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>
#include "DOMRangeImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
#include "DOMStringPool.hpp"
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMCharacterDataImpl::DOMCharacterDataImpl(DOMDocument *doc, const XMLCh *dat)
 : fDataBuf(0)
 , fDoc(0)
{
    fDoc = (DOMDocumentImpl*)doc;

    fDataBuf = fDoc->popBuffer();
    if (!fDataBuf)
        fDataBuf = new (fDoc) DOMBuffer(fDoc, dat);
    else
        fDataBuf->set(dat);

}


DOMCharacterDataImpl::DOMCharacterDataImpl(const DOMCharacterDataImpl &other)
 : fDataBuf(0)
 , fDoc(0)
{
    fDoc = (DOMDocumentImpl*)other.fDoc;

    fDataBuf = fDoc->popBuffer();
    if (!fDataBuf)
        fDataBuf = new (fDoc) DOMBuffer(fDoc, other.fDataBuf->getRawBuffer());
    else
        fDataBuf->set(other.fDataBuf->getRawBuffer());

}


DOMCharacterDataImpl::~DOMCharacterDataImpl() {
}


const XMLCh * DOMCharacterDataImpl::getNodeValue() const
{
    return fDataBuf->getRawBuffer();
}


void DOMCharacterDataImpl::setNodeValue(const DOMNode *node, const XMLCh *value)
{
    if (castToNodeImpl(node)->isReadOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);
    fDataBuf->set(value);

    if (node->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)node->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->receiveReplacedText((DOMNode*)node);
                }
            }
        }
    }
}


void DOMCharacterDataImpl::appendData(const DOMNode *node, const XMLCh *dat)
{
    if(castToNodeImpl(node)->isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);

    fDataBuf->append(dat);
}


void DOMCharacterDataImpl::deleteData(const DOMNode *node, XMLSize_t offset, XMLSize_t count)
{
    if (castToNodeImpl(node)->isReadOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);

    // Note: the C++ XMLCh * operation throws the correct DOMExceptions
    //       when parameter values are bad.
    //

    XMLSize_t len = this->fDataBuf->getLen();
    if (offset > len)
        throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMCharacterDataImplMemoryManager);



    // Cap the value of delLength to avoid trouble with overflows
    //  in the following length computations.
    if (count > len)
        count = len;

    // If the length of data to be deleted would extend off the end
    //   of the string, cut it back to stop at the end of string.
    if (offset + count >= len)
        count = len - offset;

    XMLSize_t newLen = len - count;

    XMLCh* newString;
    XMLCh temp[4000];
    if (newLen >= 3999)
        newString = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate
        (
            (newLen+1) * sizeof(XMLCh)
        );//new XMLCh[newLen+1];
    else
        newString = temp;

    XMLString::copyNString(newString, fDataBuf->getRawBuffer(), offset);
    XMLString::copyString(newString+offset, fDataBuf->getRawBuffer()+offset+count);

    fDataBuf->set(newString);

    if (newLen >= 3999)
        XMLPlatformUtils::fgMemoryManager->deallocate(newString);//delete[] newString;

    // We don't delete the old string (doesn't work), or alter
    //   the old string (may be shared)
    //   It just hangs around, possibly orphaned.

    if (node->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)node->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateRangeForDeletedText( (DOMNode*)node, offset, count);
                }
            }
        }
    }
}



const XMLCh *DOMCharacterDataImpl::getData() const
{
    return fDataBuf->getRawBuffer();
}


//
//  getCharDataLength - return the length of the character data string.
//
XMLSize_t DOMCharacterDataImpl::getLength() const
{
    return fDataBuf->getLen();
}



void DOMCharacterDataImpl::insertData(const DOMNode *node, XMLSize_t offset, const XMLCh *dat)
{
    if (castToNodeImpl(node)->isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);

    // Note: the C++ XMLCh * operation throws the correct DOMExceptions
    //       when parameter values are bad.
    //

    XMLSize_t len = fDataBuf->getLen();
    if (offset > len)
        throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMCharacterDataImplMemoryManager);

    XMLSize_t datLen = XMLString::stringLen(dat);

    XMLSize_t newLen = len + datLen;

    XMLCh* newString;
    XMLCh temp[4000];
    if (newLen >= 3999)
        newString = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate
        (
            (newLen + 1) * sizeof(XMLCh)
        );//new XMLCh[newLen+1];
    else
        newString = temp;

    XMLString::copyNString(newString, fDataBuf->getRawBuffer(), offset);
    XMLString::copyNString(newString+offset, dat, datLen);
    XMLString::copyString(newString+offset+datLen, fDataBuf->getRawBuffer()+offset);

    fDataBuf->set(newString);

    if (newLen >= 3999)
        XMLPlatformUtils::fgMemoryManager->deallocate(newString);//delete[] newString;

    if (node->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)node->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateRangeForInsertedText( (DOMNode*)node, offset, datLen);
                }
            }
        }
    }
}



void DOMCharacterDataImpl::replaceData(const DOMNode *node, XMLSize_t offset, XMLSize_t count,
                                    const XMLCh *dat)
{
    if (castToNodeImpl(node)->isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);

    deleteData(node, offset, count);
    insertData(node, offset, dat);
}




void DOMCharacterDataImpl::setData(const DOMNode *node, const XMLCh *arg)
{
    setNodeValue(node, arg);
}





const XMLCh * DOMCharacterDataImpl::substringData(const DOMNode *node, XMLSize_t offset,
                                           XMLSize_t count) const
{

    // Note: the C++ XMLCh * operation throws the correct DOMExceptions
    //       when parameter values are bad.
    //


    XMLSize_t len = fDataBuf->getLen();

    if (offset > len)
        throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMCharacterDataImplMemoryManager);


    XMLCh* newString;
    XMLCh temp[4000];
    if (len >= 3999)
        newString = (XMLCh*) ((DOMDocumentImpl *)node->getOwnerDocument())->getMemoryManager()->allocate
        (
            (len + 1) * sizeof(XMLCh)
        );//new XMLCh[len+1];
    else
        newString = temp;

    XMLString::copyNString(newString, fDataBuf->getRawBuffer()+offset, count);
    newString[count] = chNull;

    const XMLCh* retString = ((DOMDocumentImpl *)node->getOwnerDocument())->getPooledString(newString);

    if (len >= 3999)
        ((DOMDocumentImpl *)node->getOwnerDocument())->getMemoryManager()->deallocate(newString);//delete[] newString;

    return retString;

}


void DOMCharacterDataImpl::releaseBuffer() {
    fDoc->releaseBuffer(fDataBuf);
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: XSDElementNSImpl.hpp ---
#ifndef XSDElementNSImpl_HEADER_GUARD_
#define XSDElementNSImpl_HEADER_GUARD_

/*
 * Copyright 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.
 */

/*
 * $Id: XSDElementNSImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It is used by TraverseSchema to store line/column information.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#include "DOMElementNSImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN



class CDOM_EXPORT XSDElementNSImpl: public DOMElementNSImpl {
protected:
    XMLSSize_t fLineNo;     //Line number
    XMLSSize_t fColumnNo;   //Column number


public:
    XSDElementNSImpl(DOMDocument *ownerDoc, const XMLCh *name);
    XSDElementNSImpl(DOMDocument *ownerDoc, //DOM Level 2
	                 const XMLCh *namespaceURI,
                     const XMLCh *qualifiedName,
                     const XMLSSize_t lineNo,
                     const XMLSSize_t columnNo);
    XSDElementNSImpl(const XSDElementNSImpl &other, bool deep=false);

    virtual DOMNode * cloneNode(bool deep) const;

    XMLSSize_t getLineNo() const   { return fLineNo;   }
    XMLSSize_t getColumnNo() const { return fColumnNo; }

private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    XSDElementNSImpl& operator=(const XSDElementNSImpl&);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMElementImpl.cpp ---
/*
 * Copyright 2001-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.
 */

/*
 * $Id: DOMElementImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMElementImpl.hpp"

#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLUri.hpp>

#include "DOMAttrMapImpl.hpp"
#include "DOMAttrImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMParentNode.hpp"
#include "DOMCasts.hpp"
#include "DOMElementNSImpl.hpp"
#include "DOMTypeInfoImpl.hpp"

#include "DOMDocumentTypeImpl.hpp"
#include <xercesc/util/OutOfMemoryException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class DOMAttr;

DOMElementImpl::DOMElementImpl(DOMDocument *ownerDoc, const XMLCh *eName)
    : fNode(ownerDoc), fParent(ownerDoc), fAttributes(0), fDefaultAttributes(0)
{
    DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc;
    fName = docImpl->getPooledString(eName);
    setupDefaultAttributes();
    if (!fDefaultAttributes) {
        fDefaultAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
        fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
    }
    else {
        fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, fDefaultAttributes);
    }
}


DOMElementImpl::DOMElementImpl(const DOMElementImpl &other, bool deep)
    : DOMElement(other),
      fNode(other.getOwnerDocument()),
      fParent(other.getOwnerDocument()),
      fAttributes(0),
      fDefaultAttributes(0)
{
    fName = other.fName;

    if (deep)
        fParent.cloneChildren(&other);

    if (other.getAttributes())
    {
        fAttributes = ((DOMAttrMapImpl *)other.getAttributes())->cloneAttrMap(this);
    }

    if (other.getDefaultAttributes())
    {
        fDefaultAttributes = ((DOMAttrMapImpl *)other.getDefaultAttributes())->cloneAttrMap(this);
    }

    if (!fDefaultAttributes)
        setupDefaultAttributes();

    if (!fDefaultAttributes)
        fDefaultAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);

    if (!fAttributes) {
        if (!fDefaultAttributes) {
            fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
        }
        else {
            fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, fDefaultAttributes);
        }
    }

}


DOMElementImpl::~DOMElementImpl()
{
}


DOMNode *DOMElementImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::ELEMENT_OBJECT) DOMElementImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}




const XMLCh * DOMElementImpl::getNodeName() const {
    return fName;
}


short DOMElementImpl::getNodeType() const {
    return DOMNode::ELEMENT_NODE;
}


const XMLCh * DOMElementImpl::getAttribute(const XMLCh *nam) const
{
    DOMNode * attr = fAttributes->getNamedItem(nam);
    if (attr)
        return attr->getNodeValue();

    return XMLUni::fgZeroLenString;
}



DOMAttr *DOMElementImpl::getAttributeNode(const XMLCh *nam) const
{
    return  (DOMAttr *)fAttributes->getNamedItem(nam);
}


DOMNamedNodeMap *DOMElementImpl::getAttributes() const
{
    DOMElementImpl *ncThis = (DOMElementImpl *)this;   // cast off const
    return ncThis->fAttributes;
}



DOMNodeList *DOMElementImpl::getElementsByTagName(const XMLCh *tagname) const
{
    DOMDocumentImpl *docImpl = (DOMDocumentImpl *)getOwnerDocument();
    return docImpl->getDeepNodeList(this,tagname);
}


const XMLCh * DOMElementImpl::getTagName() const
{
    return fName;
}


void DOMElementImpl::removeAttribute(const XMLCh *nam)
{
    if (fNode.isReadOnly())
        throw DOMException(
             DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    XMLSSize_t i = fAttributes->findNamePoint(nam);
    if (i >= 0)
    {
        DOMNode *att = fAttributes->removeNamedItemAt(i);
        ((DOMAttrImpl *)att)->removeAttrFromIDNodeMap();
        att->release();
    }
}



DOMAttr *DOMElementImpl::removeAttributeNode(DOMAttr *oldAttr)
{
    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    DOMNode* found = 0;

    // Since there is no removeAttributeNodeNS, check if this oldAttr has NS or not
    const XMLCh* localName = oldAttr->getLocalName();
    XMLSSize_t i = 0;
    if (localName)
        i = fAttributes->findNamePoint(oldAttr->getNamespaceURI(), localName);
    else
        i = fAttributes->findNamePoint(oldAttr->getName());

    if (i >= 0) {
        // If it is in fact the right object, remove it.
        found = fAttributes->item(i);
        if (found == oldAttr) {
            fAttributes->removeNamedItemAt(i);
            ((DOMAttrImpl *)oldAttr)->removeAttrFromIDNodeMap();
        }
        else
            throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager);

    }
    else
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager);

   return (DOMAttr *)found;
}



void DOMElementImpl::setAttribute(const XMLCh *nam, const XMLCh *val)
{
    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    DOMAttr* newAttr = getAttributeNode(nam);
    if (!newAttr)
    {
        newAttr = this->fNode.getOwnerDocument()->createAttribute(nam);
        fAttributes->setNamedItem(newAttr);
    }

    newAttr->setNodeValue(val);
}

void DOMElementImpl::setIdAttribute(const XMLCh* name)
{
    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    DOMAttr *attr = getAttributeNode(name);

    if (!attr) 
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager);

    ((DOMAttrImpl *)attr)->addAttrToIDNodeMap();
}

void DOMElementImpl::setIdAttributeNS(const XMLCh* namespaceURI, const XMLCh* localName) {

    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    DOMAttr *attr = getAttributeNodeNS(namespaceURI, localName);

    if (!attr) 
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager);

    ((DOMAttrImpl *)attr)->addAttrToIDNodeMap();

}


void DOMElementImpl::setIdAttributeNode(const DOMAttr *idAttr) {

    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    DOMAttr *attr;
    const XMLCh* localName = idAttr->getLocalName();
    if (localName)
        attr = getAttributeNodeNS(idAttr->getNamespaceURI(), idAttr->getLocalName());
    else 
        attr = getAttributeNode(idAttr->getName());
    
    if(!attr) 
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNodeMemoryManager);

    ((DOMAttrImpl *)attr)->addAttrToIDNodeMap();
}


DOMAttr * DOMElementImpl::setAttributeNode(DOMAttr *newAttr)
{
    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    if (newAttr->getNodeType() != DOMNode::ATTRIBUTE_NODE)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager);
        // revisit.  Exception doesn't match test.

    // This will throw INUSE if necessary
    DOMAttr *oldAttr = (DOMAttr *) fAttributes->setNamedItem(newAttr);

    return oldAttr;
}


void DOMElementImpl::setNodeValue(const XMLCh *x)
{
    fNode.setNodeValue(x);
}



void DOMElementImpl::setReadOnly(bool readOnl, bool deep)
{
    fNode.setReadOnly(readOnl,deep);
    fAttributes->setReadOnly(readOnl,true);
}


//Introduced in DOM Level 2
const XMLCh * DOMElementImpl::getAttributeNS(const XMLCh *fNamespaceURI,
    const XMLCh *fLocalName) const
{
    DOMAttr * attr=
      (DOMAttr *)(fAttributes->getNamedItemNS(fNamespaceURI, fLocalName));
    return (attr==0) ? XMLUni::fgZeroLenString : attr->getValue();
}


void DOMElementImpl::setAttributeNS(const XMLCh *fNamespaceURI,
    const XMLCh *qualifiedName, const XMLCh *fValue)
{
    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    DOMAttr* newAttr = getAttributeNodeNS(fNamespaceURI, qualifiedName);

    if (!newAttr)
    {
        newAttr = this->fNode.getOwnerDocument()->createAttributeNS(fNamespaceURI, qualifiedName);
        fAttributes->setNamedItemNS(newAttr);
    }

    newAttr->setNodeValue(fValue);
}


void DOMElementImpl::removeAttributeNS(const XMLCh *fNamespaceURI,
    const XMLCh *fLocalName)
{
    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    XMLSSize_t i = fAttributes->findNamePoint(fNamespaceURI, fLocalName);
    if (i >= 0)
    {
        DOMNode *att = fAttributes->removeNamedItemAt(i);
        att->release();
    }
}


DOMAttr *DOMElementImpl::getAttributeNodeNS(const XMLCh *fNamespaceURI,
    const XMLCh *fLocalName) const
{
    return (DOMAttr *)fAttributes->getNamedItemNS(fNamespaceURI, fLocalName);
}


DOMAttr *DOMElementImpl::setAttributeNodeNS(DOMAttr *newAttr)
{
    if (fNode.isReadOnly())
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    if (newAttr -> getOwnerDocument() != this -> getOwnerDocument())
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager);

    // This will throw INUSE if necessary
    DOMAttr *oldAttr = (DOMAttr *) fAttributes->setNamedItemNS(newAttr);

    return oldAttr;
}


DOMNodeList *DOMElementImpl::getElementsByTagNameNS(const XMLCh *namespaceURI,
    const XMLCh *localName) const
{
    DOMDocumentImpl *docImpl = (DOMDocumentImpl *)getOwnerDocument();
    return docImpl->getDeepNodeList(this, namespaceURI, localName);
}

bool DOMElementImpl::hasAttributes() const
{
    return (fAttributes != 0 && fAttributes->getLength() != 0);
}


bool DOMElementImpl::hasAttribute(const XMLCh *name) const
{
    return (getAttributeNode(name) != 0);
}


bool DOMElementImpl::hasAttributeNS(const XMLCh *namespaceURI,
    const XMLCh *localName) const
{
    return (getAttributeNodeNS(namespaceURI, localName) != 0);
}


// util functions for default attributes
// returns the default attribute map for this node from the owner document
DOMAttrMapImpl *DOMElementImpl::getDefaultAttributes() const
{
    return fDefaultAttributes;
}

// initially set up the default attribute information based on doctype information
void DOMElementImpl::setupDefaultAttributes()
{
    DOMDocument *tmpdoc = getOwnerDocument();
    if ((fNode.fOwnerNode == 0) || (tmpdoc == 0) || (tmpdoc->getDoctype() == 0))
        return;

    DOMNode *eldef = ((DOMDocumentTypeImpl*)tmpdoc->getDoctype())->getElements()->getNamedItem(getNodeName());
    DOMAttrMapImpl* defAttrs = (eldef == 0) ? 0 : (DOMAttrMapImpl *)(eldef->getAttributes());

    if (defAttrs)
        fDefaultAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, defAttrs);
}

DOMAttr * DOMElementImpl::setDefaultAttributeNode(DOMAttr *newAttr)
{
    if (fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    if (newAttr->getNodeType() != DOMNode::ATTRIBUTE_NODE)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager);
        // revisit.  Exception doesn't match test.

    // This will throw INUSE if necessary
    DOMAttr *oldAttr = (DOMAttr *) fDefaultAttributes->setNamedItem(newAttr);
    fAttributes->hasDefaults(true);

    return oldAttr;
}


DOMAttr *DOMElementImpl::setDefaultAttributeNodeNS(DOMAttr *newAttr)
{
    if (fNode.isReadOnly())
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);

    if (newAttr -> getOwnerDocument() != this -> getOwnerDocument())
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNodeMemoryManager);

    // This will throw INUSE if necessary
    DOMAttr *oldAttr = (DOMAttr *) fDefaultAttributes->setNamedItemNS(newAttr);
    fAttributes->hasDefaults(true);

    return oldAttr;
}

void DOMElementImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMDocumentImpl::ELEMENT_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

const XMLCh* DOMElementImpl::getBaseURI() const
{
    const XMLCh* baseURI = fNode.fOwnerNode->getBaseURI();
    if (fAttributes) {
        const XMLCh xmlBaseString[] =
        {
            chLatin_x, chLatin_m, chLatin_l, chColon, chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
        };
        DOMNode* attrNode = fAttributes->getNamedItem(xmlBaseString);
        if (attrNode) {
            const XMLCh* uri =  attrNode->getNodeValue();
            if (uri && *uri) {// attribute value is always empty string
                try {
                    XMLUri temp(baseURI, ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager());
                    XMLUri temp2(&temp, uri, ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager());
                    uri = ((DOMDocumentImpl *)this->getOwnerDocument())->cloneString(temp2.getUriText());
                }
                catch(const OutOfMemoryException&)
                {
                    throw;
                }
                catch (...){
                    // REVISIT: what should happen in this case?
                    return 0;
                }
                return uri;
            }
        }
    }
    return baseURI;
}



//
//   Functions inherited from Node
//
           DOMNode*         DOMElementImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); }
           DOMNodeList*     DOMElementImpl::getChildNodes() const                   {return fParent.getChildNodes (); }
           DOMNode*         DOMElementImpl::getFirstChild() const                   {return fParent.getFirstChild (); }
           DOMNode*         DOMElementImpl::getLastChild() const                    {return fParent.getLastChild (); }
     const XMLCh*           DOMElementImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMElementImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMElementImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
     const XMLCh*           DOMElementImpl::getNodeValue() const                    {return fNode.getNodeValue (); }
           DOMDocument*     DOMElementImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; }
     const XMLCh*           DOMElementImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMElementImpl::getParentNode() const                   {return fChild.getParentNode (this); }
           DOMNode*         DOMElementImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
           bool             DOMElementImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); }
           DOMNode*         DOMElementImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                    {return fParent.insertBefore (newChild, refChild); }
           void             DOMElementImpl::normalize()                             {fParent.normalize (); }
           DOMNode*         DOMElementImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); }
           DOMNode*         DOMElementImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                    {return fParent.replaceChild (newChild, oldChild); }
           bool             DOMElementImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                    {return fNode.isSupported (feature, version); }
           void             DOMElementImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMElementImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           void*            DOMElementImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                    {return fNode.setUserData(key, data, handler); }
           void*            DOMElementImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           short            DOMElementImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMElementImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMElementImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMElementImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMElementImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMElementImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMElementImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }



bool DOMElementImpl::isEqualNode(const DOMNode* arg) const
{
    if (isSameNode(arg)) {
        return true;
    }

    if (!fNode.isEqualNode(arg)) {
        return false;
    }

    bool hasAttrs = hasAttributes();

    if (hasAttrs != arg->hasAttributes()) {
        return false;
    }

    if (hasAttrs) {
        DOMNamedNodeMap* map1 = getAttributes();
        DOMNamedNodeMap* map2 = arg->getAttributes();

        XMLSize_t len = map1->getLength();
        if (len != map2->getLength()) {
            return false;
        }
        for (XMLSize_t i = 0; i < len; i++) {
            DOMNode* n1 = map1->item(i);
            if (!n1->getLocalName()) { // DOM Level 1 Node
                DOMNode* n2 = map2->getNamedItem(n1->getNodeName());
                if (!n2 || !n1->isEqualNode(n2)) {
                    return false;
                }
            }
            else {
                DOMNode* n2 = map2->getNamedItemNS(n1->getNamespaceURI(),
                                              n1->getLocalName());
                if (!n2 || !n1->isEqualNode(n2)) {
                    return false;
                }
            }
        }
    }

    return fParent.isEqualNode(arg);
}

DOMNode* DOMElementImpl::rename(const XMLCh* namespaceURI, const XMLCh* name)
{
    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();

    if (!namespaceURI || !*namespaceURI) {
        fName = doc->getPooledString(name);
        fAttributes->reconcileDefaultAttributes(getDefaultAttributes());

        return this;
    }
    else {

        // create a new ElementNS
        DOMElementNSImpl* newElem = (DOMElementNSImpl*)doc->createElementNS(namespaceURI, name);

        // transfer the userData
        doc->transferUserData(castToNodeImpl(this), castToNodeImpl(newElem));

        // remove old node from parent if any
        DOMNode* parent = getParentNode();
        DOMNode* nextSib = getNextSibling();
        if (parent) {
            parent->removeChild(this);
        }

        // move children to new node
        DOMNode* child = getFirstChild();
        while (child) {
            removeChild(child);
            newElem->appendChild(child);
            child = getFirstChild();
        }

        // insert new node where old one was
        if (parent) {
            parent->insertBefore(newElem, nextSib);
        }

        // move specified attributes to new node
        newElem->fAttributes->moveSpecifiedAttributes(fAttributes);

        // and fire user data NODE_RENAMED event
        castToNodeImpl(newElem)->callUserDataHandlers(DOMUserDataHandler::NODE_RENAMED, this, newElem);

        return newElem;
    }
}

const DOMTypeInfo *DOMElementImpl::getTypeInfo() const
{
    return &DOMTypeInfoImpl::g_DtdValidatedElement;
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMNodeListImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMNodeListImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */


#include <xercesc/util/XercesDefs.hpp>
#include "DOMNodeListImpl.hpp"
#include "DOMCasts.hpp"

XERCES_CPP_NAMESPACE_BEGIN


// revisit
//   this implementation is too stupid - needs a cache of some kind.
//

DOMNodeListImpl::DOMNodeListImpl(DOMNode *node)
:   fNode(node)
{
}


DOMNodeListImpl:: ~DOMNodeListImpl()
{
}



XMLSize_t DOMNodeListImpl::getLength() const{
    XMLSize_t count = 0;
    if (fNode) {
        DOMNode *node = castToParentImpl(fNode)->fFirstChild;
        while(node != 0){
            ++count;
            node = castToChildImpl(node)->nextSibling;
        }
    }

    return count;
}



DOMNode *DOMNodeListImpl::item(XMLSize_t index) const{
    if (fNode) {
        DOMNode *node = castToParentImpl(fNode)->fFirstChild;
        for(XMLSize_t i=0; i<index && node!=0; ++i)
            node = castToChildImpl(node)->nextSibling;
        return node;
    }
    return 0;
}


XERCES_CPP_NAMESPACE_END



--- NEW FILE: DOMChildNode.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMChildNode.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

// This class only adds the ability to have siblings

#include <xercesc/util/XercesDefs.hpp>
#include "DOMNodeImpl.hpp"
#include "DOMChildNode.hpp"
#include "DOMCasts.hpp"

XERCES_CPP_NAMESPACE_BEGIN


DOMChildNode::DOMChildNode()
{
    this->previousSibling  = 0;
    this->nextSibling  = 0;
}

// This only makes a shallow copy, cloneChildren must also be called for a
// deep clone
DOMChildNode::DOMChildNode(const DOMChildNode &)
{
    // Need to break the association w/ original siblings and parent
    this->previousSibling = 0;
    this->nextSibling = 0;
}

DOMChildNode::~DOMChildNode() {
}


DOMNode * DOMChildNode::getNextSibling() const {
    return nextSibling;
}

//
//  Note:  for getParentNode and getPreviousSibling(), below, an
//         extra paramter "thisNode" is required.  This is because there
//         is no way to cast from a DOMChildNode pointer back to the
//         DOMNodeImpl that it is part of.  Our "this" may or may not
//         be preceded by a fParent in the object layout, and there's no
//         practical way to tell, so we just take an extra parameter instead.

DOMNode * DOMChildNode::getParentNode(const DOMNode *thisNode) const
{
    // if we have an owner, ownerNode is our parent, otherwise it's
    // our ownerDocument and we don't have a parent
    DOMNodeImpl *thisNodeImpl = castToNodeImpl(thisNode);
    return thisNodeImpl->isOwned() ? thisNodeImpl->fOwnerNode : 0;
}

DOMNode * DOMChildNode::getPreviousSibling(const DOMNode *thisNode) const {
    // if we are the firstChild, previousSibling actually refers to our
    // parent's lastChild, but we hide that
    return castToNodeImpl(thisNode)->isFirstChild() ? 0 : previousSibling;
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMRangeImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMRangeImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */
[...2075 lines suppressed...]
    }

    type = fEndContainer->getNodeType();
    if (oldNode == fEndContainer
        && (type == DOMNode::TEXT_NODE
        || type == DOMNode::CDATA_SECTION_NODE
        || type == DOMNode::COMMENT_NODE
        || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
    {
        if (fEndOffset > offset) {
            fEndContainer = startNode;
           fEndOffset = fEndOffset - offset;
        }
    }
}



XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMEntityReferenceImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMEntityReferenceImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMDocumentImpl.hpp"
#include "DOMDocumentTypeImpl.hpp"
#include "DOMEntityImpl.hpp"
#include "DOMEntityReferenceImpl.hpp"

#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMEntityReferenceImpl::DOMEntityReferenceImpl(DOMDocument *ownerDoc,
                                         const XMLCh *entityName)
    : fNode(ownerDoc), fParent(ownerDoc), fBaseURI(0)
{
    fName = ((DOMDocumentImpl *)getOwnerDocument())->getPooledString(entityName);
    // EntityReference behaves as a read-only node, since its contents
    // reflect the Entity it refers to -- but see setNodeName().
    //retrieve the corresponding entity content

    if (ownerDoc) {
        if (ownerDoc->getDoctype()) {
            if (ownerDoc->getDoctype()->getEntities()) {
                DOMEntityImpl* entity = (DOMEntityImpl*)ownerDoc->getDoctype()->getEntities()->getNamedItem(entityName);
                if (entity) {
                    fBaseURI = entity->getBaseURI();
                    DOMEntityReference* refEntity = entity->getEntityRef();
                    if (refEntity) {
                        fParent.cloneChildren(refEntity);
                    }
                }
            }
        }
    }

    fNode.setReadOnly(true, true);
}


DOMEntityReferenceImpl::DOMEntityReferenceImpl(DOMDocument *ownerDoc,
                                         const XMLCh *entityName,
                                         bool cloneChild)
    : fNode(ownerDoc), fParent(ownerDoc), fBaseURI(0)
{
    fName = ((DOMDocumentImpl *)getOwnerDocument())->getPooledString(entityName);
    // EntityReference behaves as a read-only node, since its contents
    // reflect the Entity it refers to -- but see setNodeName().
    //retrieve the corresponding entity content

    if (ownerDoc) {
        if (ownerDoc->getDoctype()) {
            if (ownerDoc->getDoctype()->getEntities()) {
                DOMEntityImpl* entity = (DOMEntityImpl*)ownerDoc->getDoctype()->getEntities()->getNamedItem(entityName);
                if (entity) {
                    fBaseURI = entity->getBaseURI();
                    if (cloneChild) {
                        DOMEntityReference* refEntity = entity->getEntityRef();
                        if (refEntity) {
                            fParent.cloneChildren(refEntity);
                        }
                    }
                }
            }
        }
    }

    fNode.setReadOnly(true, true);
}

DOMEntityReferenceImpl::DOMEntityReferenceImpl(const DOMEntityReferenceImpl &other,
                                         bool deep)
    : DOMEntityReference(other), 
      fNode(other.fNode), 
      fParent(other.fParent), 
      fChild(other.fChild), 
      fName(other.fName), 
      fBaseURI(other.fBaseURI)
{    
    if (deep)
        fParent.cloneChildren(&other);
    fNode.setReadOnly(true, true);
}



DOMEntityReferenceImpl::~DOMEntityReferenceImpl()
{
}

DOMNode *DOMEntityReferenceImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::ENTITY_REFERENCE_OBJECT) DOMEntityReferenceImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMEntityReferenceImpl::getNodeName() const
{
    return fName;
}


short DOMEntityReferenceImpl::getNodeType() const {
    return DOMNode::ENTITY_REFERENCE_NODE;
}



/**
* EntityReferences never have a nodeValue.
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR)
*/
void DOMEntityReferenceImpl::setNodeValue(const XMLCh *x)
{
    fNode.setNodeValue(x);
}


/**
* EntityRef is already, and must be, a read-only node. Attempts to change
* that will throw a NO_MODIFICATION_ALLOWED_ERR DOMException.
* <P>
* If you want to alter its contents, edit the Entity definition.
*
* @param readOnly boolean
*/
void DOMEntityReferenceImpl::setReadOnly(bool readOnl,bool deep)
{
    if(((DOMDocumentImpl *)getOwnerDocument())->getErrorChecking() && readOnl==false)
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    fNode.setReadOnly(readOnl,deep);
}


void DOMEntityReferenceImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMDocumentImpl::ENTITY_REFERENCE_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

const XMLCh* DOMEntityReferenceImpl::getBaseURI() const
{
    return fBaseURI;
}



//
//   Delegate functions from Node to the appropriate implementation.
//


           DOMNode*         DOMEntityReferenceImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); }
           DOMNamedNodeMap* DOMEntityReferenceImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMEntityReferenceImpl::getChildNodes() const                   {return fParent.getChildNodes (); }
           DOMNode*         DOMEntityReferenceImpl::getFirstChild() const                   {return fParent.getFirstChild (); }
           DOMNode*         DOMEntityReferenceImpl::getLastChild() const                    {return fParent.getLastChild (); }
     const XMLCh*           DOMEntityReferenceImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMEntityReferenceImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMEntityReferenceImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
     const XMLCh*           DOMEntityReferenceImpl::getNodeValue() const                    {return fNode.getNodeValue (); }
           DOMDocument*     DOMEntityReferenceImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; }
     const XMLCh*           DOMEntityReferenceImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMEntityReferenceImpl::getParentNode() const                   {return fChild.getParentNode (this); }
           DOMNode*         DOMEntityReferenceImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
           bool             DOMEntityReferenceImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); }
           DOMNode*         DOMEntityReferenceImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                            {return fParent.insertBefore (newChild, refChild); }
           void             DOMEntityReferenceImpl::normalize()                             {fParent.normalize (); }
           DOMNode*         DOMEntityReferenceImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); }
           DOMNode*         DOMEntityReferenceImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                            {return fParent.replaceChild (newChild, oldChild); }
           bool             DOMEntityReferenceImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                            {return fNode.isSupported (feature, version); }
           void             DOMEntityReferenceImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMEntityReferenceImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMEntityReferenceImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMEntityReferenceImpl::isEqualNode(const DOMNode* arg) const   {return fParent.isEqualNode(arg); }
           void*            DOMEntityReferenceImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                            {return fNode.setUserData(key, data, handler); }
           void*            DOMEntityReferenceImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           short            DOMEntityReferenceImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMEntityReferenceImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMEntityReferenceImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMEntityReferenceImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMEntityReferenceImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMEntityReferenceImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMEntityReferenceImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMImplementationImpl.hpp ---
#ifndef DOMImplementationImpl_HEADER_GUARD_
#define DOMImplementationImpl_HEADER_GUARD_
/*
 * 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.
 */

/*
 * $Id: DOMImplementationImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationSource.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class XMLMsgLoader;

class DOMImplementationImpl: public XMemory,
                             public DOMImplementation,
                             public DOMImplementationSource
{
private:
    DOMImplementationImpl(const DOMImplementationImpl &);
    DOMImplementationImpl & operator = (const DOMImplementationImpl &);
    friend class XMLInitializer;
protected:
    DOMImplementationImpl() {};
public:
    virtual ~DOMImplementationImpl() {};
    static DOMImplementationImpl*   getDOMImplementationImpl();
    static XMLMsgLoader* getMsgLoader4DOM();

    // ------------------------------------------------------------
    // DOMImplementation Virtual interface
    // ------------------------------------------------------------
    virtual bool                hasFeature(const  XMLCh * feature,  const  XMLCh * version) const;

    // Introduced in DOM Level 2
    virtual DOMDocumentType*    createDocumentType(const XMLCh *qualifiedName,
                                                   const XMLCh * publicId,
                                                   const XMLCh *systemId);
    virtual DOMDocument*        createDocument(const XMLCh *namespaceURI,
                                               const XMLCh *qualifiedName,
                                               DOMDocumentType *doctype,
                                               MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);

    // DOM Level 3
    virtual DOMImplementation*  getInterface(const XMLCh* feature);

    // Non-standard extension
    virtual DOMDocument*        createDocument(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);

    // ------------------------------------------------------------
    // DOMImplementationLS Virtual interface
    // ------------------------------------------------------------
    // Introduced in DOM Level 3
    // Experimental - subject to change
    virtual DOMBuilder*         createDOMBuilder(const short           mode,
                                                 const XMLCh* const    schemaType,
                                                 MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager,
                                                 XMLGrammarPool* const gramPool = 0);
    virtual DOMWriter*          createDOMWriter(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    virtual DOMInputSource*     createDOMInputSource();

    // ------------------------------------------------------------
    // DOMImplementationSource Virtual interface
    // ------------------------------------------------------------
    virtual DOMImplementation* getDOMImplementation(const XMLCh* features) const;

};


XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMNodeVector.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMNodeVector.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//	file:   DOMNodeVector.cpp
//			Implementation of class DOMNodeVector.
//			(Use of STL vector, or equivalent, would have been nice,
//			but is not available.  'DOMNode *' is the only type
//			kept in Vectors in this DOM implementation, so this is
//			a hardwired implementation for that type.
//

#include "DOMNodeVector.hpp"
#include "DOMDocumentImpl.hpp"
#include <assert.h>

XERCES_CPP_NAMESPACE_BEGIN


DOMNodeVector::DOMNodeVector(DOMDocument *doc)
{
	init(doc, 10);
}

DOMNodeVector::DOMNodeVector(DOMDocument *doc, XMLSize_t size) {
	init(doc, size);
}


void DOMNodeVector::init(DOMDocument *doc, XMLSize_t size) {
    assert(size > 0);
    //data = new (doc) DOMNode *[size];
    data = (DOMNode**) ((DOMDocumentImpl *)doc)->allocate(sizeof(DOMNode*) * size);
    assert(data != 0);
    XMLSize_t i;
    for (i=0; i<size; i++)
        data[i] = 0;
    allocatedSize = size;
    nextFreeSlot = 0;
}


DOMNodeVector::~DOMNodeVector() {
}


void DOMNodeVector::addElement(DOMNode *elem) {
	checkSpace();
	data[nextFreeSlot] = elem;
	++nextFreeSlot;
}


void DOMNodeVector::checkSpace() {
    if (nextFreeSlot == allocatedSize) {
        XMLSize_t grow = allocatedSize/2;
        if (grow < 10) grow = 10;
        XMLSize_t newAllocatedSize = allocatedSize + grow;
        DOMDocument *doc = data[0]->getOwnerDocument();

        //DOMNode **newData = new (doc) DOMNode *[newAllocatedSize];
        DOMNode **newData = (DOMNode**) ((DOMDocumentImpl *)doc)->allocate(sizeof(DOMNode*) * newAllocatedSize);

        assert(newData != 0);
        for (XMLSize_t i=0; i<allocatedSize; i++) {
            newData[i] = data[i];
        }
        // delete [] data;  // revisit.  Can't delete!  Recycle?
        allocatedSize = newAllocatedSize;
        data = newData;
    }
}


void DOMNodeVector::insertElementAt(DOMNode *elem, XMLSize_t index) {
	XMLSize_t i;

	assert(index <= nextFreeSlot);

	checkSpace();
	for (i=nextFreeSlot; i>index; --i) {
		data[i] = data[i-1];
	}
	data[index] = elem;
	++nextFreeSlot;

}


void DOMNodeVector::removeElementAt(XMLSize_t index) {
	assert(index < nextFreeSlot);
	for (XMLSize_t i=index; i<nextFreeSlot-1; ++i) {
		data[i] = data[i+1];
	}
	--nextFreeSlot;
}

void DOMNodeVector::reset() {
	nextFreeSlot = 0;
}

void DOMNodeVector::setElementAt(DOMNode *elem, XMLSize_t index) {
	assert(index < nextFreeSlot);
	data[index] = elem;
}


XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMErrorImpl.hpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: DOMErrorImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */


#ifndef DOMERRORIMPL_HPP
#define DOMERRORIMPL_HPP

#include <xercesc/dom/DOMError.hpp>
#include <xercesc/util/XMLString.hpp>
XERCES_CPP_NAMESPACE_BEGIN


/**
  * Introduced in DOM Level 3
  * Implementation of a DOMError interface.
  *
  * @see DOMError#DOMError
  */

class CDOM_EXPORT DOMErrorImpl : public DOMError
{
public:
    /** @name Constructors and Destructor */
    //@{

    /** Constructors */
    DOMErrorImpl(const short severity);

    DOMErrorImpl
    (
        const short severity
        , const XMLCh* const message
        , DOMLocator* const location
    );

    DOMErrorImpl
    (
        const short severity
        , const XMLCh* type
        , const XMLCh* message
        , void* relatedData 
    );

    /** Desctructor */
    virtual ~DOMErrorImpl();

    //@}

    /** @name Get function */
    //@{

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the severity of the error
    */
    virtual short getSeverity() const;

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the message describing the error that occured.
    */
    virtual const XMLCh* getMessage() const;

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Get the location of the error
    */
    virtual DOMLocator* getLocation() const;

    /**
     * The related platform dependent exception if any.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     * @see   setRelatedException
     * @since DOM Level 3
     */
    virtual void* getRelatedException() const;

    virtual const XMLCh* getType() const;

    virtual void* getRelatedData() const;

    //@}


   /** @name Set function */
    //@{

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the severity of the error
    *
    * @param severity the type of the error to set
    */
    virtual void setSeverity(const short severity);

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the error message
    *
    * @param message the error message to set.
    */
    virtual void setMessage(const XMLCh* const message);

   /**
    * <p><b>"Experimental - subject to change"</b></p>
    *
    * Set the location of the error
    *
    * @param location the location of the error to set.
    */
    virtual void setLocation(DOMLocator* const location);

   /**
    * @param value <code>true</code> if DOMLocator is owned and should be
    *              deleted, <code>false</code> otherwise.
    */
    void setAdoptLocation(const bool value);

    /**
     * The related platform dependent exception if any.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     * @param exc the related exception to set.
     * @see   getRelatedException
     * @since DOM Level 3
     */
    virtual void setRelatedException(void* exc) const;

    virtual void setType(const XMLCh* type);

    virtual void setRelatedData(void* relatedData);


private :
    /* Unimplemented constructors and operators */

    /* Copy constructor */
    DOMErrorImpl(const DOMErrorImpl&);

    /* Assignment operator */
    DOMErrorImpl& operator=(const DOMErrorImpl&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fAdoptLocation
    //      Indicates whether we own the DOMLocator object or not.
    //
    //  fSeverity
    //      The type of the error.
    //
    //  fMessage
    //      The error message.
    //
    //  fLocation
    //      The location info of the error.
    //
    //  fType
    //      The type of the error.
    //
    //  fRelatedData
    //      The data related to this error.
    //
    // -----------------------------------------------------------------------
    bool         fAdoptLocation;
    short        fSeverity;
    const XMLCh* fMessage;
    DOMLocator*  fLocation;
    const XMLCh* fType;
    void*        fRelatedData;
};

// ---------------------------------------------------------------------------
//  DOMErrorImpl: Getter methods
// ---------------------------------------------------------------------------
inline short DOMErrorImpl::getSeverity() const
{
    return fSeverity;
}

inline const XMLCh* DOMErrorImpl::getMessage() const
{
    return fMessage;
}

inline DOMLocator* DOMErrorImpl::getLocation() const
{
    return fLocation;
}

inline void* DOMErrorImpl::getRelatedException() const
{
    return 0;
}

inline const XMLCh* DOMErrorImpl::getType() const 
{
    return fType;
}

inline void* DOMErrorImpl::getRelatedData() const 
{
    return fRelatedData;
}

// ---------------------------------------------------------------------------
//  DOMLocatorImpl: Setter methods
// ---------------------------------------------------------------------------
inline void DOMErrorImpl::setSeverity(const short severity)
{
    fSeverity = severity;
}

inline void DOMErrorImpl::setMessage(const XMLCh* const message)
{
    fMessage = message;
}

inline void DOMErrorImpl::setAdoptLocation(const bool value)
{
    fAdoptLocation = value;
}

inline void DOMErrorImpl::setType(const XMLCh* type)
{
    fType = type;
}

inline void DOMErrorImpl::setRelatedData(void* relatedData)
{
    fRelatedData = relatedData;
}


XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMCDATASectionImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMCDATASectionImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMCDATASectionImpl.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMRangeImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
#include "DOMStringPool.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMCDATASectionImpl::DOMCDATASectionImpl(DOMDocument *ownerDoc,
                                   const XMLCh *dat)
    : fNode(ownerDoc), fParent(ownerDoc), fCharacterData(ownerDoc, dat)
{
}


DOMCDATASectionImpl::DOMCDATASectionImpl(const DOMCDATASectionImpl &other, bool /*deep*/)
    : DOMCDATASection(other),
    fNode(*castToNodeImpl(&other)),
    fParent(*castToParentImpl(&other)),
    fChild(*castToChildImpl(&other)),
    fCharacterData(other.fCharacterData)
{
    // revisit.  Something nees to make "deep" work.
}


DOMCDATASectionImpl::~DOMCDATASectionImpl()
{
}


DOMNode  *DOMCDATASectionImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (this->getOwnerDocument(), DOMDocumentImpl::CDATA_SECTION_OBJECT) DOMCDATASectionImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMCDATASectionImpl::getNodeName() const {
    static const XMLCh gcdata_section[] = {chPound, chLatin_c, chLatin_d, chLatin_a, chLatin_t, chLatin_a,
        chDash, chLatin_s, chLatin_e, chLatin_c, chLatin_t, chLatin_i, chLatin_o, chLatin_n, 0};
    return gcdata_section;
}


short DOMCDATASectionImpl::getNodeType() const {
    return DOMNode::CDATA_SECTION_NODE;
}


bool DOMCDATASectionImpl::isIgnorableWhitespace() const
{
    return fNode.ignorableWhitespace();
}


//
//  splitText.   revist - factor into a common function for use
//                             here and in DOMTextImpl
//
DOMText *DOMCDATASectionImpl::splitText(XMLSize_t offset)
{
    if (fNode.isReadOnly())
    {
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    }
    XMLSize_t len = fCharacterData.fDataBuf->getLen();
    if (offset > len)
        throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMNodeMemoryManager);

    DOMText *newText =
                getOwnerDocument()->createCDATASection(
                        this->substringData(offset, len - offset));

    DOMNode *parent = getParentNode();
    if (parent != 0)
        parent->insertBefore(newText, getNextSibling());

    fCharacterData.fDataBuf->chop(offset);

    if (this->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateSplitInfo( this, newText, offset);
                }
            }
        }
    }

    return newText;
}


bool DOMCDATASectionImpl::getIsWhitespaceInElementContent() const
{
    return isIgnorableWhitespace();
}

const XMLCh* DOMCDATASectionImpl::getWholeText() {
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMNodeMemoryManager);
    return 0;
}

DOMText* DOMCDATASectionImpl::replaceWholeText(const XMLCh*){
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMNodeMemoryManager);
    return 0;
}


void DOMCDATASectionImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();

    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        fCharacterData.releaseBuffer();
        doc->release(this, DOMDocumentImpl::CDATA_SECTION_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}


//
//  Delegation stubs for other DOM_Node inherited functions.
//
           DOMNode*         DOMCDATASectionImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); }
           DOMNamedNodeMap* DOMCDATASectionImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMCDATASectionImpl::getChildNodes() const                   {return fParent.getChildNodes (); }
           DOMNode*         DOMCDATASectionImpl::getFirstChild() const                   {return fParent.getFirstChild (); }
           DOMNode*         DOMCDATASectionImpl::getLastChild() const                    {return fParent.getLastChild (); }
     const XMLCh*           DOMCDATASectionImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMCDATASectionImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMCDATASectionImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
     const XMLCh*           DOMCDATASectionImpl::getNodeValue() const                    {return fCharacterData.getNodeValue (); }
           DOMDocument*     DOMCDATASectionImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; }
     const XMLCh*           DOMCDATASectionImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMCDATASectionImpl::getParentNode() const                   {return fChild.getParentNode (this); }
           DOMNode*         DOMCDATASectionImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
           bool             DOMCDATASectionImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); }
           DOMNode*         DOMCDATASectionImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                         {return fParent.insertBefore (newChild, refChild); }
           void             DOMCDATASectionImpl::normalize()                             {fNode.normalize (); }
           DOMNode*         DOMCDATASectionImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); }
           DOMNode*         DOMCDATASectionImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                         {return fParent.replaceChild (newChild, oldChild); }
           bool             DOMCDATASectionImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                         {return fNode.isSupported (feature, version); }
           void             DOMCDATASectionImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMCDATASectionImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMCDATASectionImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMCDATASectionImpl::isEqualNode(const DOMNode* arg) const   {return fParent.isEqualNode(arg); }
           void*            DOMCDATASectionImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                         {return fNode.setUserData(key, data, handler); }
           void*            DOMCDATASectionImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           const XMLCh*     DOMCDATASectionImpl::getBaseURI() const                      {return fNode.getBaseURI(); }
           short            DOMCDATASectionImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMCDATASectionImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMCDATASectionImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMCDATASectionImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMCDATASectionImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMCDATASectionImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMCDATASectionImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }



//
//   Delegation of CharacerData functions.
//


           const XMLCh*     DOMCDATASectionImpl::getData() const                         {return fCharacterData.getData();}
           XMLSize_t        DOMCDATASectionImpl::getLength() const                       {return fCharacterData.getLength();}
           const XMLCh*     DOMCDATASectionImpl::substringData(XMLSize_t offset, XMLSize_t count) const
                                                                                         {return fCharacterData.substringData(this, offset, count);}
           void             DOMCDATASectionImpl::appendData(const XMLCh *arg)            {fCharacterData.appendData(this, arg);}
           void             DOMCDATASectionImpl::insertData(XMLSize_t offset, const  XMLCh *arg)
                                                                                         {fCharacterData.insertData(this, offset, arg);}
           void             DOMCDATASectionImpl::deleteData(XMLSize_t offset, XMLSize_t count)
                                                                                         {fCharacterData.deleteData(this, offset, count);}
           void             DOMCDATASectionImpl::replaceData(XMLSize_t offset, XMLSize_t count, const XMLCh *arg)
                                                                                         {fCharacterData.replaceData(this, offset, count, arg);}
           void             DOMCDATASectionImpl::setData(const XMLCh *data)              {fCharacterData.setData(this, data);}
           void             DOMCDATASectionImpl::setNodeValue(const XMLCh  *nodeValue)   {fCharacterData.setNodeValue (this, nodeValue); }

XERCES_CPP_NAMESPACE_END



--- NEW FILE: DOMElementImpl.hpp ---
#ifndef DOMElementImpl_HEADER_GUARD_
#define DOMElementImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMElementImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOMElement.hpp>

#include "DOMChildNode.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMParentNode.hpp"

#include "DOMAttrMapImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN

class DOMTypeInfo;
class DOMNodeList;
class DOMAttrMapImpl;
class DOMDocument;




class CDOM_EXPORT DOMElementImpl: public DOMElement {
public:
    DOMNodeImpl       fNode;
    DOMParentNode     fParent;
    DOMChildNode      fChild;
    DOMAttrMapImpl    *fAttributes;
    DOMAttrMapImpl    *fDefaultAttributes;
    const XMLCh      *fName;

public:
    DOMElementImpl(DOMDocument *ownerDoc, const XMLCh *name);

    DOMElementImpl(const DOMElementImpl &other, bool deep=false);
    virtual ~DOMElementImpl();

    // Declare functions from DOMNode.  They all must be implemented by this class
    DOMNODE_FUNCTIONS;

    // Functions introduced on Element...
    virtual const XMLCh*      getAttribute(const XMLCh *name) const;
    virtual DOMAttr*          getAttributeNode(const XMLCh *name) const;
    virtual DOMNodeList*      getElementsByTagName(const XMLCh *tagname) const;
    virtual const XMLCh*      getTagName() const;
    virtual void              removeAttribute(const XMLCh *name);
    virtual DOMAttr*          removeAttributeNode(DOMAttr * oldAttr);
    virtual void              setAttribute(const XMLCh *name, const XMLCh *value);
    virtual DOMAttr*          setAttributeNode(DOMAttr *newAttr);
    virtual void              setReadOnly(bool readOnly, bool deep);

    //Introduced in DOM Level 2
    virtual const XMLCh*      getAttributeNS(const XMLCh *namespaceURI,
                                             const XMLCh *localName) const;
    virtual void              setAttributeNS(const XMLCh *namespaceURI,
                                             const XMLCh *qualifiedName,
                                             const XMLCh *value);
    virtual void              removeAttributeNS(const XMLCh *namespaceURI,
                                                const XMLCh *localName);
    virtual DOMAttr*          getAttributeNodeNS(const XMLCh *namespaceURI,
                                                 const XMLCh *localName) const;
    virtual DOMAttr*          setAttributeNodeNS(DOMAttr *newAttr);
    virtual DOMNodeList*      getElementsByTagNameNS(const XMLCh *namespaceURI,
                                                     const XMLCh *localName) const;
    virtual bool              hasAttribute(const XMLCh *name) const;
    virtual bool              hasAttributeNS(const XMLCh *namespaceURI,
                                             const XMLCh *localName) const;

    //Introduced in DOM level 3
    virtual void setIdAttribute(const XMLCh* name);
    virtual void setIdAttributeNS(const XMLCh* namespaceURI, const XMLCh* localName);
    virtual void setIdAttributeNode(const DOMAttr *idAttr);
    virtual const DOMTypeInfo * getTypeInfo() const;

    // for handling of default attribute
    virtual DOMAttr*          setDefaultAttributeNode(DOMAttr *newAttr);
    virtual DOMAttr*          setDefaultAttributeNodeNS(DOMAttr *newAttr);
    virtual DOMAttrMapImpl*   getDefaultAttributes() const;

    // helper function for DOM Level 3 renameNode
    virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);

protected:
    // default attribute helper functions
    virtual void setupDefaultAttributes();

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    DOMElementImpl & operator = (const DOMElementImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: XSDElementNSImpl.cpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: XSDElementNSImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/dom/DOMException.hpp>

#include "DOMDocumentImpl.hpp"
#include "XSDElementNSImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


XSDElementNSImpl::XSDElementNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) :
    DOMElementNSImpl(ownerDoc, nam)
    , fLineNo(0)
    , fColumnNo(0)
{
}

//Introduced in DOM Level 2
XSDElementNSImpl::XSDElementNSImpl(DOMDocument *ownerDoc,
                                   const XMLCh *namespaceURI,
                                   const XMLCh *qualifiedName,
                                   const XMLSSize_t lineNo,
                                   const XMLSSize_t columnNo) :
    DOMElementNSImpl(ownerDoc, namespaceURI, qualifiedName)
    , fLineNo(lineNo)
    , fColumnNo(columnNo)
{
}

XSDElementNSImpl::XSDElementNSImpl(const XSDElementNSImpl &other, bool deep) :
    DOMElementNSImpl(other, deep)
{
    this->fLineNo = other.fLineNo;
    this->fColumnNo =other.fColumnNo;
}

DOMNode * XSDElementNSImpl::cloneNode(bool deep) const {
    DOMNode* newNode = new (getOwnerDocument()) XSDElementNSImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMConfigurationImpl.hpp ---
/*
 * Copyright 2003,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.
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//



#if !defined(DOMCONFIGURATIONIMPL_HPP)
#define DOMCONFIGURATIONIMPL_HPP

//------------------------------------------------------------------------------------
//  Includes
//------------------------------------------------------------------------------------
#include <xercesc/dom/DOMConfiguration.hpp>
#include <xercesc/dom/DOMErrorHandler.hpp>
#include <xercesc/util/XMLString.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class DOMDocumentImpl;

class CDOM_EXPORT DOMConfigurationImpl : public DOMConfiguration
{
private:
    //unimplemented
    DOMConfigurationImpl(const DOMConfiguration &);
    DOMConfigurationImpl & operator = (const DOMConfiguration &);


public:

    //-----------------------------------------------------------------------------------
    //  Constructor
    //-----------------------------------------------------------------------------------
    DOMConfigurationImpl(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    ~DOMConfigurationImpl();
    
    enum DOMConfigurationFeature {
        FEATURE_CANONICAL_FORM                = 0x0001,
        FEATURE_CDATA_SECTIONS                = 0x0002,
        FEATURE_COMMENTS                      = 0x0004,
        FEATURE_DATATYPE_NORMALIZATION        = 0x0008,
        FEATURE_DISCARD_DEFAULT_CONTENT       = 0x0010, 
        FEATURE_ENTITIES                      = 0x0020,  
        FEATURE_INFOSET                       = 0x0040, 
        FEATURE_NAMESPACES                    = 0x0080, 
        FEATURE_NAMESPACE_DECLARATIONS        = 0x0100, 
        FEATURE_NORMALIZE_CHARACTERS          = 0x0200, 
        FEATURE_SPLIT_CDATA_SECTIONS          = 0x0400, 
        FEATURE_VALIDATE                      = 0x0800, 
        FEATURE_VALIDATE_IF_SCHEMA            = 0x1000, 
        FEATURE_WHITESPACE_IN_ELEMENT_CONTENT = 0x2000
    };

    unsigned short featureValues;

    // -----------------------------------------------------------------------
    //  Setter methods
    // -----------------------------------------------------------------------

    void setParameter(const XMLCh* name, const void* value);

    // -----------------------------------------------------------------------
    //  Getter methods
    // -----------------------------------------------------------------------
    
    const void* getParameter(const XMLCh* name) const;

                                        
    // -----------------------------------------------------------------------
    //  Query methods
    // -----------------------------------------------------------------------

    bool canSetParameter(const XMLCh* name, const void* value) const;


    // ---------------------------------------------------------------------------
    // Impl specific methods
    // ---------------------------------------------------------------------------
    
    /* specific get and set methods for non-boolean parameters
     * */

    DOMErrorHandler* getErrorHandler() const;

    const XMLCh* getSchemaType() const;

    const XMLCh* getSchemaLocation() const;

    void setErrorHandler(DOMErrorHandler *erHandler);

    void setSchemaType(const XMLCh* st);

    void setSchemaLocation(const XMLCh* sl);
    
    // --------------------------------------
    // static consts names 
    // --------------------------------------
    static const XMLCh fgCANONICAL_FORM[];
    static const XMLCh fgCDATA_SECTIONS[];
    static const XMLCh fgCOMMENTS[];
    static const XMLCh fgDATATYPE_NORMALIZATION[];
    static const XMLCh fgDISCARD_DEFAULT_CONTENT[];
    static const XMLCh fgENTITIES[];
    static const XMLCh fgINFOSET[];
    static const XMLCh fgNAMESPACES[];
    static const XMLCh fgNAMESPACE_DECLARATIONS[];
    static const XMLCh fgNORMALIZE_CHARACTERS[];
    static const XMLCh fgSPLIT_CDATA_SECTIONS[];
    static const XMLCh fgVALIDATE[];
    static const XMLCh fgVALIDATE_IF_SCHEMA[];
    static const XMLCh fgWHITESPACE_IN_ELEMENT_CONTENT[];

    static const XMLCh fgERROR_HANDLER[];
    static const XMLCh fgSCHEMA_TYPE[];
    static const XMLCh fgSCHEMA_LOCATION[];

    // The default values for the boolean parameters
    // from CANONICAL_FORM to WHITESPACE_IN_ELEMENT_CONTENT
    // 10010110010110 = 0x2596
    static const unsigned short fDEFAULT_VALUES;
    

private:
    // implements a simple map between the name and its enum value
    DOMConfigurationFeature getFeatureFlag(const XMLCh* name) const;

    // the error handler
    DOMErrorHandler* fErrorHandler;
    
    // the schema type
    const XMLCh* fSchemaType;
    
    // the schema location
    const XMLCh* fSchemaLocation;

    static const bool fFalse;
    static const bool fTrue;
    
    MemoryManager* fMemoryManager;
};

XERCES_CPP_NAMESPACE_END

#endif

/**
 * End of file DOMConfigurationImpl.hpp
 */

--- NEW FILE: DOMConfigurationImpl.cpp ---
/*
 * Copyright 2003,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.
 */

#include "DOMConfigurationImpl.hpp"
#include <xercesc/dom/DOMErrorHandler.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/Janitor.hpp>

XERCES_CPP_NAMESPACE_BEGIN

const bool DOMConfigurationImpl::fFalse = false;
const bool DOMConfigurationImpl::fTrue = true;

/* canonical-form */
const XMLCh DOMConfigurationImpl::fgCANONICAL_FORM[] = { chLatin_c, chLatin_a, chLatin_n, chLatin_o, chLatin_n, chLatin_i, chLatin_c, chLatin_a, chLatin_l, chDash, chLatin_f, chLatin_o, chLatin_r, chLatin_m, chNull };

/* cdata-sections */
const XMLCh DOMConfigurationImpl::fgCDATA_SECTIONS[] = { chLatin_c, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chDash, chLatin_s, chLatin_e, chLatin_c, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chLatin_s, chNull };

/* comments */
const XMLCh DOMConfigurationImpl::fgCOMMENTS[] = { chLatin_c, chLatin_o, chLatin_m, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chLatin_s, chNull };

/* datatype-normalization */
const XMLCh DOMConfigurationImpl::fgDATATYPE_NORMALIZATION[] = { chLatin_d, chLatin_a, chLatin_t, chLatin_a, chLatin_t, chLatin_y, chLatin_p, chLatin_e, chDash, chLatin_n, chLatin_o, chLatin_r, chLatin_m, chLatin_a, chLatin_l, chLatin_i, chLatin_z, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };

/* discard-default-content */
const XMLCh DOMConfigurationImpl::fgDISCARD_DEFAULT_CONTENT[] = { chLatin_d, chLatin_i, chLatin_s, chLatin_c, chLatin_a, chLatin_r, chLatin_d, chDash, chLatin_d, chLatin_e, chLatin_f, chLatin_a, chLatin_u, chLatin_l, chLatin_t, chDash, chLatin_c, chLatin_o, chLatin_n, chLatin_t, chLatin_e, chLatin_n, chLatin_t, chNull };

/* entities */
const XMLCh DOMConfigurationImpl::fgENTITIES[] = { chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_i, chLatin_e, chLatin_s, chNull };

/* infoset */
const XMLCh DOMConfigurationImpl::fgINFOSET[] = { chLatin_i, chLatin_n, chLatin_f, chLatin_o, chLatin_s, chLatin_e, chLatin_t, chNull };

/* namespaces */
const XMLCh DOMConfigurationImpl::fgNAMESPACES[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chLatin_s, chNull };

/* namespace-declarations */
const XMLCh DOMConfigurationImpl::fgNAMESPACE_DECLARATIONS[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chDash, chLatin_d, chLatin_e, chLatin_c, chLatin_l, chLatin_a, chLatin_r, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chLatin_s, chNull };

/* normalize-characters */
const XMLCh DOMConfigurationImpl::fgNORMALIZE_CHARACTERS[] = { chLatin_n, chLatin_o, chLatin_r, chLatin_m, chLatin_a, chLatin_l, chLatin_i, chLatin_z, chLatin_e, chDash, chLatin_c, chLatin_h, chLatin_a, chLatin_r, chLatin_a, chLatin_c, chLatin_t, chLatin_e, chLatin_r, chLatin_s, chNull };

/* split-cdata-sections */
const XMLCh DOMConfigurationImpl::fgSPLIT_CDATA_SECTIONS[] = { chLatin_s, chLatin_p, chLatin_l, chLatin_i, chLatin_t, chDash, chLatin_c, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chDash, chLatin_s, chLatin_e, chLatin_c, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chLatin_s, chNull };

/* validate */
const XMLCh DOMConfigurationImpl::fgVALIDATE[] = { chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d, chLatin_a, chLatin_t, chLatin_e, chNull };

/* validate-if-schema */
const XMLCh DOMConfigurationImpl::fgVALIDATE_IF_SCHEMA[] = { chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d, chLatin_a, chLatin_t, chLatin_e, chDash, chLatin_i, chLatin_f, chDash, chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chNull };

/* whitespace-in-element-content */
const XMLCh DOMConfigurationImpl::fgWHITESPACE_IN_ELEMENT_CONTENT[] = { chLatin_w, chLatin_h, chLatin_i, chLatin_t, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chDash, chLatin_i, chLatin_n, chDash, chLatin_e, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chDash, chLatin_c, chLatin_o, chLatin_n, chLatin_t, chLatin_e, chLatin_n, chLatin_t, chNull };

/* error-handler */
const XMLCh DOMConfigurationImpl::fgERROR_HANDLER[] = { chLatin_e, chLatin_r, chLatin_r, chLatin_o, chLatin_r, chDash, chLatin_h, chLatin_a, chLatin_n, chLatin_d, chLatin_l, chLatin_e, chLatin_r, chNull };

/* schema-type */
const XMLCh DOMConfigurationImpl::fgSCHEMA_TYPE[] = { chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chDash, chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };

/* schema-location */
const XMLCh DOMConfigurationImpl::fgSCHEMA_LOCATION[] = { chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chDash, chLatin_l, chLatin_o, chLatin_c, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };

const unsigned short DOMConfigurationImpl::fDEFAULT_VALUES = 0x2596;

DOMConfigurationImpl::DOMConfigurationImpl(MemoryManager* const manager): featureValues(fDEFAULT_VALUES),
                                              fErrorHandler(0), fSchemaType(0), fSchemaLocation(0)
, fMemoryManager(manager)
 {
}

DOMConfigurationImpl::~DOMConfigurationImpl() {
}
                                        
void DOMConfigurationImpl::setParameter(const XMLCh* name, const void* value) {

    XMLCh* lowerCaseName = XMLString::replicate(name, fMemoryManager);
    ArrayJanitor<XMLCh> janName(lowerCaseName, fMemoryManager);

    XMLString::lowerCaseASCII(lowerCaseName);

    if(!canSetParameter(lowerCaseName, value)) {
        throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);
    }

    DOMConfigurationFeature whichFlag;
    try {
        whichFlag = getFeatureFlag(lowerCaseName);
        if(*((bool*)value)) {
            featureValues |= whichFlag;
        } else {
            featureValues &= ~whichFlag;
        }
    } catch(DOMException&) {
        // must not be a boolean parameter
        if(XMLString::equals(lowerCaseName, fgERROR_HANDLER)) {
            fErrorHandler = (DOMErrorHandler*)value;
        } else if (XMLString::equals(lowerCaseName, fgSCHEMA_TYPE)) {
            fSchemaType = (XMLCh*)value;
        } else if (XMLString::equals(lowerCaseName, fgSCHEMA_LOCATION)) {
            fSchemaLocation = (XMLCh*)value;
        } else {  // canSetParameter above should take care of this case
            throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);
        }
    }

}

// --------------------------------------
// Getter Methods
// --------------------------------------

const void* DOMConfigurationImpl::getParameter(const XMLCh* name) const {

    XMLCh* lowerCaseName = XMLString::replicate(name, fMemoryManager);
    ArrayJanitor<XMLCh> janName(lowerCaseName, fMemoryManager);

    XMLString::lowerCaseASCII(lowerCaseName);

    DOMConfigurationFeature whichFlag;
    try {
        whichFlag = getFeatureFlag(lowerCaseName);
        if(featureValues & whichFlag) {
            return &fTrue;
        } else {
            return &fFalse;
        }
   } catch (DOMException&) {
        // must not be a boolean parameter
        if(XMLString::equals(lowerCaseName, fgERROR_HANDLER)) {
            return fErrorHandler;
        } else if (XMLString::equals(lowerCaseName, fgSCHEMA_TYPE)) {
            return fSchemaType;
        } else if (XMLString::equals(lowerCaseName, fgSCHEMA_LOCATION)) {
            return fSchemaLocation;
        } else {
            throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);
        }
    }

}

// -----------------------------------------
// Query Methods
// -----------------------------------------

bool DOMConfigurationImpl::canSetParameter(const XMLCh* name, const void* value) const {

    /**
     * canSetParameter(name, value) returns false in two conditions:
     *  1) if a [required] feature has no supporting code, then return false in 
     *     both the true and false outcomes (This is in order to be either fully 
     *     spec compliant, or not at all)
     *  2) if an [optional] feature has no supporting code, then return false
     **/ 
    
    // if value is null, return true
    if(value == 0) return true;

    XMLCh* lowerCaseName = XMLString::replicate(name, fMemoryManager);
    ArrayJanitor<XMLCh> janName(lowerCaseName, fMemoryManager);
    
    XMLString::lowerCaseASCII(lowerCaseName);
    
    DOMConfigurationFeature whichFlag;
    try {
        whichFlag = getFeatureFlag(lowerCaseName);
        bool booleanValue = *((bool*)value);
        switch (whichFlag) {
            case FEATURE_CANONICAL_FORM: 
                if(booleanValue) return false;      // optional //
                else             return true;       // required // 
            case FEATURE_CDATA_SECTIONS: 
                return true;
            case FEATURE_COMMENTS:  
                return true;
            case FEATURE_DATATYPE_NORMALIZATION:  
                if(booleanValue) return false;       // required //
                else             return true;        // required //
            case FEATURE_DISCARD_DEFAULT_CONTENT:  
                if(booleanValue) return false;       // required //
                else             return true;        // required //
            case FEATURE_ENTITIES:  
                if(booleanValue) return true;       // required //
                else             return true;       // required //
            case FEATURE_INFOSET:  
                if(booleanValue) return false;       // required //
                else             return true;       // no effect//
            case FEATURE_NAMESPACES:  
                return true;       
            case FEATURE_NAMESPACE_DECLARATIONS:  
                if(booleanValue) return true;      // optional //
                else             return false;       // required //
            case FEATURE_NORMALIZE_CHARACTERS:  
                if(booleanValue) return false;      // optional //
                else             return true;       // required //
            case FEATURE_SPLIT_CDATA_SECTIONS:  
                //we dont report an error in the false case so we cant claim we do it
                if(booleanValue) return false;       // required //
                else             return false;       // required //
            case FEATURE_VALIDATE:  
                if(booleanValue) return false;      // optional //
                else             return true;       // required //
            case FEATURE_VALIDATE_IF_SCHEMA:  
                if(booleanValue) return false;      // optional //
                else             return true;       // required //
              
            case FEATURE_WHITESPACE_IN_ELEMENT_CONTENT:  
                if(booleanValue) return true;       // required //
                else             return false;      // optional //
            default: return false; // should never be here
        }
   } catch (DOMException&) {
        // must not be a boolean parameter
        if(XMLString::equals(lowerCaseName, fgERROR_HANDLER)) {
            return true;                               // required //
        } else if (XMLString::equals(lowerCaseName, fgSCHEMA_TYPE)) {
            return false;                            // optional //
        } else if (XMLString::equals(lowerCaseName, fgSCHEMA_LOCATION)) {
            return false;                            // optional //
        } 
    }
    return false;
}

// -------------------------------------------
// Impl methods
// -------------------------------------------

DOMConfigurationImpl::DOMConfigurationFeature DOMConfigurationImpl::getFeatureFlag(const XMLCh* name) const {
    XMLCh* lowerCaseName = XMLString::replicate(name, fMemoryManager);
    ArrayJanitor<XMLCh> janName(lowerCaseName, fMemoryManager);
    
    XMLString::lowerCaseASCII(lowerCaseName);
  
    if(XMLString::equals(lowerCaseName, fgCANONICAL_FORM)) {
        return FEATURE_CANONICAL_FORM;
    } else if (XMLString::equals(lowerCaseName, fgCDATA_SECTIONS )) {
        return FEATURE_CDATA_SECTIONS;
    } else if (XMLString::equals(lowerCaseName, fgCOMMENTS)) {
        return FEATURE_COMMENTS;
    } else if (XMLString::equals(lowerCaseName, fgDATATYPE_NORMALIZATION))  {
        return FEATURE_DATATYPE_NORMALIZATION;
    } else if (XMLString::equals(lowerCaseName, fgDISCARD_DEFAULT_CONTENT)) {
        return FEATURE_DISCARD_DEFAULT_CONTENT;
    } else if (XMLString::equals(lowerCaseName, fgENTITIES)) {
        return FEATURE_ENTITIES;
    } else if (XMLString::equals(lowerCaseName, fgINFOSET))  {
        return FEATURE_INFOSET;
    } else if (XMLString::equals(lowerCaseName, fgNAMESPACES)) {
        return FEATURE_NAMESPACES;
    } else if (XMLString::equals(lowerCaseName, fgNAMESPACE_DECLARATIONS)) {
        return FEATURE_NAMESPACE_DECLARATIONS;
    } else if (XMLString::equals(lowerCaseName, fgNORMALIZE_CHARACTERS)) {
        return FEATURE_NORMALIZE_CHARACTERS;
    } else if (XMLString::equals(lowerCaseName, fgSPLIT_CDATA_SECTIONS)) {
        return FEATURE_SPLIT_CDATA_SECTIONS;
    } else if (XMLString::equals(lowerCaseName, fgVALIDATE)) {
        return FEATURE_VALIDATE;
    } else if (XMLString::equals(lowerCaseName, fgVALIDATE_IF_SCHEMA)) {
        return FEATURE_VALIDATE_IF_SCHEMA;
    } else if (XMLString::equals(lowerCaseName, fgWHITESPACE_IN_ELEMENT_CONTENT)) {
        return FEATURE_WHITESPACE_IN_ELEMENT_CONTENT;
    } else {
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);
    }
        
}

DOMErrorHandler* DOMConfigurationImpl::getErrorHandler() const {
    return fErrorHandler;
}

const XMLCh* DOMConfigurationImpl::getSchemaType() const {
    return fSchemaType;
}

const XMLCh* DOMConfigurationImpl::getSchemaLocation() const {
    return fSchemaLocation;
}

void DOMConfigurationImpl::setErrorHandler(DOMErrorHandler *erHandler) {
    fErrorHandler = erHandler;
}

void DOMConfigurationImpl::setSchemaType(const XMLCh* st) {
    fSchemaType = st;
}

void DOMConfigurationImpl::setSchemaLocation(const XMLCh* sl) {
    fSchemaLocation = sl;
}


XERCES_CPP_NAMESPACE_END


/**
 * End of file DOMConfigurationImpl.cpp
 */

--- NEW FILE: DOMDocumentImpl.hpp ---
#ifndef DOMDocumentImpl_HEADER_GUARD_
#define DOMDocumentImpl_HEADER_GUARD_

/*
 * Copyright 2001-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.
 */

/*
 * $Id: DOMDocumentImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/RefArrayOf.hpp>
#include <xercesc/util/RefStackOf.hpp>
#include <xercesc/util/RefHash2KeysTableOf.hpp>
#include <xercesc/util/StringPool.hpp>
#include <xercesc/util/KeyRefPair.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMUserDataHandler.hpp>
#include "DOMNodeImpl.hpp"
#include "DOMParentNode.hpp"
#include "DOMDeepNodeListPool.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class DOMAttrImpl;
class DOMCDATASectionImpl;
class DOMCommentImpl;
class DOMConfiguration;
class DOMDeepNodeListImpl;
class DOMDocumentFragmentImpl;
class DOMDocumentTypeImpl;
class DOMElementImpl;
class DOMEntityImpl;
class DOMEntityReferenceImpl;
class DOMNotationImpl;
class DOMProcessingInstructionImpl;
class DOMTextImpl;
class DOMNodeIteratorImpl;
class DOMNormalizer;
class DOMTreeWalkerImpl;
class DOMNodeFilter;
class DOMNodeFilterImpl;
class DOMImplementation;
class DOMNodeIDMap;
class DOMRangeImpl;
class DOMStringPool;
class DOMBuffer;
class MemoryManager;
class XPathNSResolver;
class XPathExpression;

typedef RefVectorOf<DOMRangeImpl>        Ranges;
typedef RefVectorOf<DOMNodeIteratorImpl>     NodeIterators;
typedef KeyRefPair<void, DOMUserDataHandler> DOMUserDataRecord;
typedef RefStackOf<DOMNode>               DOMNodePtr;

class CDOM_EXPORT DOMDocumentImpl: public XMemory, public DOMDocument {
public:
    // -----------------------------------------------------------------------
    //  data types
    // -----------------------------------------------------------------------
    enum NodeObjectType {
        ATTR_OBJECT                   = 0,
        ATTR_NS_OBJECT                = 1,
        CDATA_SECTION_OBJECT          = 2,
        COMMENT_OBJECT                = 3,
        DOCUMENT_FRAGMENT_OBJECT      = 4,
        DOCUMENT_TYPE_OBJECT          = 5,
        ELEMENT_OBJECT                = 6,
        ELEMENT_NS_OBJECT             = 7,
        ENTITY_OBJECT                 = 8,
        ENTITY_REFERENCE_OBJECT       = 9,
        NOTATION_OBJECT               = 10,
        PROCESSING_INSTRUCTION_OBJECT = 11,
        TEXT_OBJECT                   = 12
    };


    // -----------------------------------------------------------------------
    //  data
    // -----------------------------------------------------------------------
    DOMNodeImpl           fNode;           // Implements common node functionality.
    DOMParentNode         fParent;         // Implements common parent node functionality
    DOMNodeIDMap*         fNodeIDMap;     // for use by GetElementsById().

public:
    DOMDocumentImpl(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    DOMDocumentImpl(const XMLCh*     namespaceURI,     //DOM Level 2
                    const XMLCh*     qualifiedName,
                    DOMDocumentType* doctype,
                    MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    virtual ~DOMDocumentImpl();

    void                         setDocumentType(DOMDocumentType *doctype);

    // Add all functions that are pure virutal in DOMNODE
    DOMNODE_FUNCTIONS;

    // Add all functions that are pure virutal in DOMDocument
    virtual DOMAttr*             createAttribute(const XMLCh *name);
    virtual DOMCDATASection*     createCDATASection(const XMLCh *data);
    virtual DOMComment*          createComment(const XMLCh *data);
    virtual DOMDocumentFragment* createDocumentFragment();
    virtual DOMDocumentType*     createDocumentType(const XMLCh *name);
    virtual DOMDocumentType*     createDocumentType(const XMLCh *qName,
                                                    const XMLCh *publicId,
                                                    const XMLCh *systemId);
    virtual DOMElement*          createElement(const XMLCh * tagName);
    virtual DOMElement*          createElementNoCheck(const XMLCh *tagName);
    virtual DOMEntity*           createEntity(const XMLCh * name);
    virtual DOMEntityReference*  createEntityReference(const XMLCh * name);
    virtual DOMNotation*         createNotation(const XMLCh * name);
    virtual DOMProcessingInstruction* createProcessingInstruction(const XMLCh * target, const XMLCh * data);
    virtual DOMText*             createTextNode(const XMLCh * data);
    virtual DOMDocumentType*     getDoctype() const;
    virtual DOMElement*          getDocumentElement() const;
    virtual DOMNodeList*         getElementsByTagName(const XMLCh * tagname) const;
    virtual DOMImplementation*   getImplementation() const;
    bool                         isXMLName(const XMLCh * s);
    virtual DOMNodeIterator*     createNodeIterator(DOMNode *root,
                                                    unsigned long whatToShow,
                                                    DOMNodeFilter* filter,
                                                    bool entityReferenceExpansion);
    virtual DOMTreeWalker*       createTreeWalker(DOMNode *root,
                                                  unsigned long whatToShow,
                                                  DOMNodeFilter* filter,
                                                  bool entityReferenceExpansion);


    virtual DOMRange*            createRange();
    virtual Ranges*              getRanges() const;  //non-standard api
    virtual NodeIterators*       getNodeIterators() const;  //non-standard api
    virtual void                 removeRange(DOMRangeImpl* range); //non-standard api
    virtual void                 removeNodeIterator(DOMNodeIteratorImpl* nodeIterator); //non-standard api

    virtual const DOMXPathExpression*    createExpression(const XMLCh *expression, const DOMXPathNSResolver *resolver);
    virtual const DOMXPathNSResolver*    createNSResolver(DOMNode *nodeResolver);
    virtual void* evaluate(const XMLCh *expression, DOMNode *contextNode, const DOMXPathNSResolver *resolver, 
                           unsigned short type, void* result);


    // Extension to be called by the Parser
    DOMEntityReference*  createEntityReferenceByParser(const XMLCh * name);


    //
    // Functions to keep track of document mutations, so that node list chached
    //   information can be invalidated.  One global changes counter per document.
    //
    virtual void                 changed();
    virtual int                  changes() const;

    /**
     * Sets whether the DOM implementation performs error checking
     * upon operations. Turning off error checking only affects
     * the following DOM checks:
     * <ul>
     * <li>Checking strings to make sure that all characters are
     *     legal XML characters
     * <li>Hierarchy checking such as allowed children, checks for
     *     cycles, etc.
     * </ul>
     * <p>
     * Turning off error checking does <em>not</em> turn off the
     * following checks:
     * <ul>
     * <li>Read only checks
     * <li>Checks related to DOM events
     * </ul>
     */
    inline void setErrorChecking(bool check) {
        errorChecking = check;
    }

    /**
     * Returns true if the DOM implementation performs error checking.
     */
    inline bool getErrorChecking() const {
        return errorChecking;
    }

    //Introduced in DOM Level 2
    virtual DOMNode*             importNode(DOMNode *source, bool deep);
    virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
                                                 const XMLCh *qualifiedName);
    virtual DOMElement*          createElementNS(const XMLCh *namespaceURI,
                                                 const XMLCh *qualifiedName,
                                                 const XMLSSize_t lineNo,
                                                 const XMLSSize_t columnNo);
    virtual DOMAttr*             createAttributeNS(const XMLCh *namespaceURI,
                                                   const XMLCh *qualifiedName);
    virtual DOMNodeList*         getElementsByTagNameNS(const XMLCh *namespaceURI,
                                                        const XMLCh *localName) const;
    virtual DOMElement*          getElementById(const XMLCh *elementId) const;

    //Introduced in DOM Level 3
    virtual const XMLCh*         getActualEncoding() const;
    virtual void                 setActualEncoding(const XMLCh* actualEncoding);
    virtual const XMLCh*         getEncoding() const;
    virtual void                 setEncoding(const XMLCh* encoding);
    virtual bool                 getStandalone() const;
    virtual void                 setStandalone(bool standalone);
    virtual const XMLCh*         getVersion() const;
    virtual void                 setVersion(const XMLCh* version);
    virtual const XMLCh*         getDocumentURI() const;
    virtual void                 setDocumentURI(const XMLCh* documentURI);
    virtual bool                 getStrictErrorChecking() const;
    virtual void                 setStrictErrorChecking(bool strictErrorChecking);
    virtual DOMNode*             adoptNode(DOMNode* source);
    virtual void                 normalizeDocument();
    virtual DOMConfiguration*    getDOMConfiguration() const;
    virtual void                 setDOMConfiguration(DOMConfiguration *config);

    // helper functions to prevent storing userdata pointers on every node.
    void*                        setUserData(DOMNodeImpl* n,
                                            const XMLCh* key,
                                            void* data,
                                            DOMUserDataHandler* handler);
    void*                        getUserData(const DOMNodeImpl* n,
                                             const XMLCh* key) const;
    void                         callUserDataHandlers(const DOMNodeImpl* n,
                                                      DOMUserDataHandler::DOMOperationType operation,
                                                      const DOMNode* src,
                                                      const DOMNode* dst) const;
    void                         transferUserData(DOMNodeImpl* n1, DOMNodeImpl* n2);

    DOMNode*                     renameNode(DOMNode* n,
                                            const XMLCh* namespaceURI,
                                            const XMLCh* name);

    //Return the index > 0 of ':' in the given qualified name qName="prefix:localName".
    //Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".
    static  int                  indexofQualifiedName(const XMLCh * qName);
    static  bool                 isKidOK(DOMNode *parent, DOMNode *child);

    inline DOMNodeIDMap*         getNodeIDMap() {return fNodeIDMap;};


    //
    // Memory Management Functions.  All memory is allocated by and owned by
    //                               a document, and is not recovered until the
    //                               document itself is deleted.
    //
    void*                        allocate(size_t amount);
    void*                        allocate(size_t amount, NodeObjectType type);
    XMLCh*                       cloneString(const XMLCh *src);
    const XMLCh*                 getPooledString(const XMLCh *src);
    void                         deleteHeap();
    void                         release(DOMNode* object, NodeObjectType type);
    void                         releaseDocNotifyUserData(DOMNode* object);
    void                         releaseBuffer(DOMBuffer* buffer);
    DOMBuffer*                   popBuffer();
    MemoryManager*               getMemoryManager() const;

    // Factory methods for getting/creating node lists.
    // Because nothing is ever deleted, the implementation caches and recycles
    //  previously used instances of DOMDeepNodeList
    //
    DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode, const XMLCh *tagName);
    DOMNodeList*                 getDeepNodeList(const DOMNode *rootNode,    //DOM Level 2
                                                 const XMLCh *namespaceURI,
                                                 const XMLCh *localName);

private:
    //Internal helper functions
    virtual DOMNode*             importNode(DOMNode *source, bool deep, bool cloningNode);

    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMDocumentImpl(const DOMDocumentImpl &);
    DOMDocumentImpl & operator = (const DOMDocumentImpl &);

private:
    // -----------------------------------------------------------------------
    //  data
    // -----------------------------------------------------------------------
    // New data introduced in DOM Level 3
    const XMLCh*          fActualEncoding;
    const XMLCh*          fEncoding;
    bool                  fStandalone;
    const XMLCh*          fVersion;
    const XMLCh*          fDocumentURI;
    DOMConfiguration*     fDOMConfiguration;
    
    XMLStringPool         fUserDataTableKeys;
    RefHash2KeysTableOf<DOMUserDataRecord>* fUserDataTable;


    // Per-Document heap Variables.
    //   The heap consists of one or more biggish blocks which are
    //   sub-allocated for individual allocations of nodes, strings, etc.
    //   The big blocks form a linked list, allowing them to be located for deletion.
    //
    //   There is no provision for deleting suballocated blocks, other than
    //     deleting the entire heap when the document is deleted.
    //
    //   There is no header on individual sub-allocated blocks.
    //   The header on big blocks consists only of a single back pointer to
    //    the previously allocated big block (our linked list of big blocks)
    //
    //
    //   revisit - this heap should be encapsulated into its own
    //                  class, rather than hanging naked on Document.
    //
    void*                 fCurrentBlock;
    char*                 fFreePtr;
    XMLSize_t             fFreeBytesRemaining;

    // To recycle the DOMNode pointer
    RefArrayOf<DOMNodePtr>* fRecycleNodePtr;

    // To recycle DOMBuffer pointer
    RefStackOf<DOMBuffer>* fRecycleBufferPtr;

    // Pool of DOMNodeList for getElementsByTagName
    DOMDeepNodeListPool<DOMDeepNodeListImpl>* fNodeListPool;

    // Other data
    DOMDocumentType*      fDocType;
    DOMElement*           fDocElement;
    DOMStringPool*        fNamePool;
    DOMNormalizer*        fNormalizer;
    Ranges*               fRanges;
    NodeIterators*        fNodeIterators;
    MemoryManager*        fMemoryManager;   // configurable memory manager

    int                   fChanges;
    bool                  errorChecking;    // Bypass error checking.

};

inline MemoryManager* DOMDocumentImpl::getMemoryManager() const
{
    return fMemoryManager;
}

XERCES_CPP_NAMESPACE_END

// ---------------------------------------------------------------------------
//
//  Operator new.  Global overloaded version, lets any object be allocated on
//                 the heap owned by a document.
//
// ---------------------------------------------------------------------------
inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl::NodeObjectType type)
{
    // revist.  Probably should be a checked cast.
    void *p = ((XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl *)doc)->allocate(amt, type);
    return p;
}

inline void * operator new(size_t amt, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc)
{
    // revist.  Probably should be a checked cast.
    void *p = ((XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl *)doc)->allocate(amt);
    return p;
}

// ---------------------------------------------------------------------------
//  For DOM:
//  Bypass compiler warning:
//    no matching operator delete found; memory will not be freed if initialization throws an exception
// ---------------------------------------------------------------------------
#if _MSC_VER >= 1200 /* VC++ 6.0 */
inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * /*doc*/)
{
    return;
}
inline void operator delete(void* /*ptr*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * /*doc*/, XERCES_CPP_NAMESPACE_QUALIFIER DOMDocumentImpl::NodeObjectType /*type*/)
{
    return;
}
#endif

#endif

--- NEW FILE: DOMTypeInfoImpl.hpp ---
/*
 * Copyright 2003,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.
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#if !defined(DOMTYPEINFOIMPL_HPP)
#define DOMTYPEINFOIMPL_HPP

//------------------------------------------------------------------------------------
//  Includes
//------------------------------------------------------------------------------------
#include <xercesc/dom/DOMTypeInfo.hpp>
#include <xercesc/dom/DOMPSVITypeInfo.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class DOMDocumentImpl;

class CDOM_EXPORT DOMTypeInfoImpl : public DOMTypeInfo, public DOMPSVITypeInfo
{
public:

    //-----------------------------------------------------------------------------------
    //  Constructor
    //-----------------------------------------------------------------------------------
    DOMTypeInfoImpl(const XMLCh* namespaceUri=0, const XMLCh* name=0);

    static DOMTypeInfoImpl  g_DtdValidatedElement;
    static DOMTypeInfoImpl  g_DtdNotValidatedAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedCDATAAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedIDAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedIDREFAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedIDREFSAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedENTITYAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedENTITIESAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedNMTOKENAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedNMTOKENSAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedNOTATIONAttribute;
    static DOMTypeInfoImpl  g_DtdValidatedENUMERATIONAttribute;

    //@{
    // -----------------------------------------------------------------------
    //  Getter methods
    // -----------------------------------------------------------------------
    /**
     * Returns The name of a type declared for the associated <code>DOMElement</code> 
     * or <code>DOMAttr</code>, or null if undeclared.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     * @return The name of a type declared for the associated <code>DOMElement</code> 
     * or <code>DOMAttribute</code>, or null if undeclared.
     * @since DOM level 3
     */
    virtual const XMLCh* getName() const;

    /**
     * The namespace of the type declared for the associated <code>DOMElement</code> 
     * or <code>DOMAttr</code> or null if the <code>DOMElement</code> does not have 
     * declaration or if no namespace information is available.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     * @return The namespace of the type declared for the associated <code>DOMElement</code> 
     * or <code>DOMAttr</code> or null if the <code>DOMElement</code> does not have 
     * declaration or if no namespace information is available.
     * @since DOM level 3
     */
    virtual const XMLCh* getNamespace() const;

    /**
     * Returns the string value of the specified PSVI property associated to a 
     * <code>DOMElement</code> or <code>DOMAttr</code>, or null if not available.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     * @return the string value of the specified PSVI property associated to a 
     * <code>DOMElement</code> or <code>DOMAttr</code>, or null if not available.
     */
    virtual const XMLCh* getStringProperty(PSVIProperty prop) const;

    /**
     * Returns the numeric value of the specified PSVI property associated to a 
     * <code>DOMElement</code> or <code>DOMAttr</code>, or 0 if not available.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     * @return the numeric value of the specified PSVI property associated to a 
     * <code>DOMElement</code> or <code>DOMAttr</code>, or 0 if not available.
     */
    virtual int getNumericProperty(PSVIProperty prop) const;
    //@}

    //@{
    // -----------------------------------------------------------------------
    //  Setter methods
    // -----------------------------------------------------------------------

    /**
     * Set the value for a string PSVI property.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     */
    virtual void setStringProperty(PSVIProperty prop, const XMLCh* value);

    /**
     * Set the value for a numeric PSVI property.
     *
     * <p><b>"Experimental - subject to change"</b></p>
     *
     */
    virtual void setNumericProperty(PSVIProperty prop, int value);
    //@}
  
  private:
    int             fBitFields;
    const XMLCh*    fTypeName;
    const XMLCh*    fTypeNamespace;
    const XMLCh*    fMemberTypeName;
    const XMLCh*    fMemberTypeNamespace;
    const XMLCh*    fDefaultValue;
    const XMLCh*    fNormalizedValue;
    
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMTypeInfoImpl (const DOMTypeInfoImpl&);
    DOMTypeInfoImpl & operator = (const DOMTypeInfoImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif

/**
 * End of file DOMTypeInfo.hpp
 */

--- NEW FILE: DOMNamedNodeMapImpl.hpp ---
#ifndef DOMNamedNodeMapImpl_HEADER_GUARD_
#define DOMNamedNodeMapImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMNamedNodeMapImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class       DOMNodeVector;
class       DOMNode;

#define MAP_SIZE    193

class CDOM_EXPORT DOMNamedNodeMapImpl: public DOMNamedNodeMap {
protected:
    DOMNodeVector*    fBuckets[MAP_SIZE];
    DOMNode*          fOwnerNode;       // the node this map belongs to
    //bool             fReadOnly;     // revisit - flag on owner node instead?

    bool            readOnly();  // revisit.  Look at owner node read-only.

public:
    DOMNamedNodeMapImpl(DOMNode *ownerNode);

    virtual                 ~DOMNamedNodeMapImpl();
    virtual DOMNamedNodeMapImpl *cloneMap(DOMNode *ownerNode);
    virtual void            setReadOnly(bool readOnly, bool deep);

    virtual XMLSize_t       getLength() const;
    virtual DOMNode*        item(XMLSize_t index) const;
    virtual DOMNode*        getNamedItem(const XMLCh *name) const;
    virtual DOMNode*        setNamedItem(DOMNode *arg);
    virtual DOMNode*        removeNamedItem(const XMLCh *name);

    //Introduced in DOM Level 2
    virtual DOMNode*        getNamedItemNS(const XMLCh *namespaceURI,
	                                        const XMLCh *localName) const;
    virtual DOMNode*        setNamedItemNS(DOMNode *arg);
    virtual DOMNode*        removeNamedItemNS(const XMLCh *namespaceURI,
	                                           const XMLCh *localName);
private:
    // unimplemented
    DOMNamedNodeMapImpl(const DOMNamedNodeMapImpl &);
    DOMNamedNodeMapImpl & operator = (const DOMNamedNodeMapImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMEntityReferenceImpl.hpp ---
#ifndef DOMEntityReferenceImpl_HEADER_GUARD_
#define DOMEntityReferenceImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMEntityReferenceImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMEntityReference.hpp>

#include "DOMParentNode.hpp"
#include "DOMChildNode.hpp"
#include "DOMNodeImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMEntityReferenceImpl: public DOMEntityReference
{
private:
    DOMNodeImpl      fNode;
    DOMParentNode    fParent;
    DOMChildNode     fChild;

    const XMLCh    *fName;
    const XMLCh    *fBaseURI;

    friend class XercesDOMParser;

public:
    DOMEntityReferenceImpl(DOMDocument *ownerDoc, const XMLCh *entityName);
    DOMEntityReferenceImpl(DOMDocument *ownerDoc, const XMLCh *entityName, bool cloneChild);
    DOMEntityReferenceImpl(const DOMEntityReferenceImpl &other, bool deep=false);
    virtual ~DOMEntityReferenceImpl();

    // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;

    virtual void setReadOnly(bool readOnly,bool deep);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    DOMEntityReferenceImpl & operator = (const DOMEntityReferenceImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMAttrImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMAttrImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMException.hpp>

#include "DOMAttrImpl.hpp"
#include "DOMStringPool.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
#include "DOMTypeInfoImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN

DOMAttrImpl::DOMAttrImpl(DOMDocument *ownerDoc, const XMLCh *aName)
    : fNode(ownerDoc), fParent (ownerDoc), fSchemaType(0)
{
    DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc;
    fName = docImpl->getPooledString(aName);
    fNode.isSpecified(true);
}

DOMAttrImpl::DOMAttrImpl(const DOMAttrImpl &other, bool /*deep*/)
    : DOMAttr(other)
    , fNode(other.fNode)
    , fParent (other.fParent)
    , fName(other.fName)
    , fSchemaType(other.fSchemaType)
{    
    if (other.fNode.isSpecified())
        fNode.isSpecified(true);
    else
        fNode.isSpecified(false);

    if (other.fNode.isIdAttr())
    {
        fNode.isIdAttr(true);
        DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
        doc->getNodeIDMap()->add(this);
    }

    fParent.cloneChildren(&other);
}


DOMAttrImpl::~DOMAttrImpl() {
}


DOMNode * DOMAttrImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (this->getOwnerDocument(), DOMDocumentImpl::ATTR_OBJECT) DOMAttrImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMAttrImpl::getNodeName()  const{
    return fName;
}


short DOMAttrImpl::getNodeType() const {
    return DOMNode::ATTRIBUTE_NODE;
}


const XMLCh * DOMAttrImpl::getName() const {
    return fName;
}


const XMLCh * DOMAttrImpl::getNodeValue() const
{
    return getValue();
}


bool DOMAttrImpl::getSpecified() const
{
    return fNode.isSpecified();
}




const XMLCh * DOMAttrImpl::getValue() const
{
    if (fParent.fFirstChild == 0) {
        return XMLUni::fgZeroLenString; // return "";
    }

    // Simple case where attribute value is just a single text node
    DOMNode *node = castToChildImpl(fParent.fFirstChild)->nextSibling;
    if (node == 0 && fParent.fFirstChild->getNodeType() == DOMNode::TEXT_NODE) {
        return fParent.fFirstChild->getNodeValue();
    }

    //
    // Complicated case whre attribute value is a DOM tree
    //
    // According to the spec, the child nodes of the Attr node may be either
    // Text or EntityReference nodes.
    //
    // The parser will not create such thing, this is for those created by users.
    //
    // In such case, we have to visit each child to retrieve the text
    //

    XMLBuffer buf(1023, ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager());
    getTextValue(fParent.fFirstChild, buf);

    return (XMLCh*) ((DOMDocumentImpl *)this->getOwnerDocument())->getPooledString(buf.getRawBuffer());
}

void DOMAttrImpl::getTextValue(DOMNode* node, XMLBuffer& buf) const
{
    if (node->getNodeType() == DOMNode::TEXT_NODE)
        buf.append(node->getNodeValue());
    else if (node->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE)
    {
        for (node = node->getFirstChild(); node != 0; node = castToChildImpl(node)->nextSibling)
        {
            getTextValue(node, buf);
        }
    }

    return;
}


void DOMAttrImpl::setNodeValue(const XMLCh *val)
{
    setValue(val);
}



void DOMAttrImpl::setSpecified(bool arg)
{
    fNode.isSpecified(arg);
}



void DOMAttrImpl::setValue(const XMLCh *val)
{
    if (fNode.isReadOnly())
    {
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    }

    //  If this attribute was of type ID and in the map, take it out,
    //    then put it back in with the new name.  For now, we don't worry
    //    about what happens if the new name conflicts
    //
    DOMDocumentImpl *doc = (DOMDocumentImpl *)getOwnerDocument();
    if (fNode.isIdAttr())
        doc->getNodeIDMap()->remove(this);

    DOMNode *kid;
    while ((kid = fParent.fFirstChild) != 0)         // Remove existing kids
    {
        DOMNode* node = removeChild(kid);
        if (node)
            node->release();
    }

    if (val != 0)              // Create and add the new one
        appendChild(doc->createTextNode(val));
    fNode.isSpecified(true);
    fParent.changed();

    if (fNode.isIdAttr())
        doc->getNodeIDMap()->add(this);

}




//Introduced in DOM Level 2

DOMElement *DOMAttrImpl::getOwnerElement() const
{
    // if we have an owner, ownerNode is our ownerElement, otherwise it's
    // our ownerDocument and we don't have an ownerElement
    return (DOMElement *) (fNode.isOwned() ? fNode.fOwnerNode : 0);
}


//internal use by parser only
void DOMAttrImpl::setOwnerElement(DOMElement *ownerElem)
{
    fNode.fOwnerNode = ownerElem;
    // revisit.  Is this backwards?  isOwned(true)?
    fNode.isOwned(false);
}


//For DOM Level 3

void DOMAttrImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMDocumentImpl::ATTR_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}


bool DOMAttrImpl::isId() const {
    return fNode.isIdAttr();
}


DOMNode* DOMAttrImpl::rename(const XMLCh* namespaceURI, const XMLCh* name)
{
    DOMElement* el = getOwnerElement();
    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();

    if (el)
        el->removeAttributeNode(this);

    if (!namespaceURI || !*namespaceURI) {
        fName = doc->getPooledString(name);

        if (el)
            el->setAttributeNode(this);

        return this;
    }
    else {

        // create a new AttrNS
        DOMAttr* newAttr = doc->createAttributeNS(namespaceURI, name);

        // transfer the userData
        doc->transferUserData(castToNodeImpl(this), castToNodeImpl(newAttr));

        // move children to new node
        DOMNode* child = getFirstChild();
        while (child) {
            removeChild(child);
            newAttr->appendChild(child);
            child = getFirstChild();
        }

        // and fire user data NODE_RENAMED event
        castToNodeImpl(newAttr)->callUserDataHandlers(DOMUserDataHandler::NODE_RENAMED, this, newAttr);

        // reattach attr to element
        if (el)
            el->setAttributeNodeNS(newAttr);

        return newAttr;
    }
}

const DOMTypeInfo *DOMAttrImpl::getTypeInfo() const
{
    if(!fSchemaType)
        return &DOMTypeInfoImpl::g_DtdNotValidatedAttribute;

    return fSchemaType;
}


void DOMAttrImpl::setTypeInfo(const DOMTypeInfoImpl* typeInfo) 
{
    fSchemaType = typeInfo;
}


DOMNode * DOMAttrImpl::getInterface(const XMLCh* feature)
{
    if(XMLString::equals(feature, XMLUni::fgXercescInterfacePSVITypeInfo))
        return (DOMNode*)(DOMPSVITypeInfo*)fSchemaType;
    return fNode.getInterface(feature); 
}

           DOMNode*         DOMAttrImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); }
           DOMNamedNodeMap* DOMAttrImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMAttrImpl::getChildNodes() const                   {return fParent.getChildNodes (); }
           DOMNode*         DOMAttrImpl::getFirstChild() const                   {return fParent.getFirstChild (); }
           DOMNode*         DOMAttrImpl::getLastChild() const                    {return fParent.getLastChild (); }
     const XMLCh*           DOMAttrImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMAttrImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMAttrImpl::getNextSibling() const                  {return fNode.getNextSibling (); }
           DOMDocument*     DOMAttrImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; }
     const XMLCh*           DOMAttrImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMAttrImpl::getParentNode() const                   {return fNode.getParentNode (); }
           DOMNode*         DOMAttrImpl::getPreviousSibling() const              {return fNode.getPreviousSibling (); }
           bool             DOMAttrImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); }
           DOMNode*         DOMAttrImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                 {return fParent.insertBefore (newChild, refChild); }
           void             DOMAttrImpl::normalize()                             {fParent.normalize (); }
           DOMNode*         DOMAttrImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); }
           DOMNode*         DOMAttrImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                 {return fParent.replaceChild (newChild, oldChild); }
           bool             DOMAttrImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                 {return fNode.isSupported (feature, version); }
           void             DOMAttrImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMAttrImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMAttrImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMAttrImpl::isEqualNode(const DOMNode* arg) const   {return fParent.isEqualNode(arg); }
           void*            DOMAttrImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                 {return fNode.setUserData(key, data, handler); }
           void*            DOMAttrImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           const XMLCh*     DOMAttrImpl::getBaseURI() const                      {return fNode.getBaseURI(); }
           short            DOMAttrImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMAttrImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMAttrImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMAttrImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMAttrImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMAttrImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMAttrNSImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMAttrNSImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include <xercesc/util/XMLUniDefs.hpp>
#include "DOMAttrNSImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMException.hpp>

#include "assert.h"

XERCES_CPP_NAMESPACE_BEGIN

DOMAttrNSImpl::DOMAttrNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) :
DOMAttrImpl(ownerDoc, nam)
{
    this->fNamespaceURI=0;	//DOM Level 2
    this->fLocalName=0;       //DOM Level 2
    this->fPrefix=0;
}

//Introduced in DOM Level 2
DOMAttrNSImpl::DOMAttrNSImpl(DOMDocument *ownerDoc,
                           const XMLCh *namespaceURI,
                           const XMLCh *qualifiedName) :
DOMAttrImpl(ownerDoc, qualifiedName)
{
    setName(namespaceURI, qualifiedName);
}

DOMAttrNSImpl::DOMAttrNSImpl(const DOMAttrNSImpl &other, bool deep) :
DOMAttrImpl(other, deep)
{
    this->fNamespaceURI = other.fNamespaceURI;	//DOM Level 2
    this->fLocalName = other.fLocalName;          //DOM Level 2
    this->fPrefix = other.fPrefix;
}

DOMNode * DOMAttrNSImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::ATTR_NS_OBJECT) DOMAttrNSImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}

const XMLCh * DOMAttrNSImpl::getNamespaceURI() const
{
    return fNamespaceURI;
}

const XMLCh * DOMAttrNSImpl::getPrefix() const
{
    return fPrefix;
}

const XMLCh * DOMAttrNSImpl::getLocalName() const
{
    return fLocalName;
}

void DOMAttrNSImpl::setPrefix(const XMLCh *prefix)
{
    const XMLCh * xmlns = DOMNodeImpl::getXmlnsString();

    if (fNode.isReadOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull || XMLString::equals(fLocalName, xmlns))
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);

    if (prefix == 0 || prefix[0] == chNull) {
        fName = fLocalName;
        fPrefix = 0;
        return;
    }

    if (!((DOMDocumentImpl *)this->getOwnerDocument())->isXMLName(prefix))
        throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, GetDOMNodeMemoryManager);

    const XMLCh * xml = DOMNodeImpl::getXmlString();
    const XMLCh * xmlURI = DOMNodeImpl::getXmlURIString();
    const XMLCh * xmlnsURI = DOMNodeImpl::getXmlnsURIString();

    if (XMLString::equals(prefix, xml)&&
        !XMLString::equals(fNamespaceURI, xmlURI)||
        XMLString::equals(prefix, xmlns)&&
        !XMLString::equals(fNamespaceURI, xmlnsURI))
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);

    if (XMLString::indexOf(prefix, chColon) != -1) {
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
    }

    this-> fPrefix = ((DOMDocumentImpl *)this->getOwnerDocument())->getPooledString(prefix);

    int prefixLen = XMLString::stringLen(prefix);
    int newQualifiedNameLen = prefixLen+1+XMLString::stringLen(fLocalName);
    XMLCh* newName;
    XMLCh temp[4000];
    if (newQualifiedNameLen >= 3999)
        newName = (XMLCh*) ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager()->allocate
        (
            newQualifiedNameLen * sizeof(XMLCh)
        );//new XMLCh[newQualifiedNameLen];
    else
        newName = temp;

    // newName = prefix + chColon + fLocalName;
    XMLString::copyString(newName, prefix);
    newName[prefixLen] = chColon;
    XMLString::copyString(&newName[prefixLen+1], fLocalName);

    fName = ((DOMDocumentImpl *)this->getOwnerDocument())->
                                           getPooledString(newName);

    if (newQualifiedNameLen >= 3999)
        ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager()->deallocate(newName);//delete[] newName;

}

void DOMAttrNSImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMDocumentImpl::ATTR_NS_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}


DOMNode* DOMAttrNSImpl::rename(const XMLCh* namespaceURI, const XMLCh* name)
{
    DOMElement* el = getOwnerElement();
    if (el)
        el->removeAttributeNode(this);

    setName(namespaceURI, name);

    if (el)
        el->setAttributeNodeNS(this);

    return this;
}

void DOMAttrNSImpl::setName(const XMLCh* namespaceURI, const XMLCh* qualifiedName)
{
    DOMDocumentImpl* ownerDoc = (DOMDocumentImpl *) getOwnerDocument();
    const XMLCh * xmlns = DOMNodeImpl::getXmlnsString();
    const XMLCh * xmlnsURI = DOMNodeImpl::getXmlnsURIString();
    this->fName = ownerDoc->getPooledString(qualifiedName);

    int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
    if (index < 0)
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);

    bool xmlnsAlone = false;	//true if attribute name is "xmlns"
    if (index == 0) {	//qualifiedName contains no ':'
        if (XMLString::equals(this->fName, xmlns)) {
            if (!XMLString::equals(namespaceURI, xmlnsURI))
                throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
            xmlnsAlone = true;
        }
        this -> fPrefix = 0;
        this -> fLocalName = this -> fName;
    } else {	//0 < index < this->name.length()-1
        XMLCh* newName;
        XMLCh temp[4000];
        if (index >= 3999)
            newName = (XMLCh*) ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager()->allocate
            (
                (XMLString::stringLen(qualifiedName) + 1) * sizeof(XMLCh)
            );//new XMLCh[XMLString::stringLen(qualifiedName)+1];
        else
            newName = temp;

        XMLString::copyNString(newName, fName, index);
        newName[index] = chNull;
        this-> fPrefix = ownerDoc->getPooledString(newName);
        this -> fLocalName = ownerDoc->getPooledString(fName+index+1);

        if (index >= 3999)
            ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager()->deallocate(newName);//delete[] newName;

        // Before we carry on, we should check if the prefix or localName are valid XMLName
        if (!((DOMDocumentImpl *)this->getOwnerDocument())->isXMLName(fPrefix) || !((DOMDocumentImpl *)this->getOwnerDocument())->isXMLName(fLocalName))
            throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
    }

    // DOM Level 3: namespace URI is never empty string.
    const XMLCh * URI = xmlnsAlone ? xmlnsURI
        : DOMNodeImpl::mapPrefix
          (
              fPrefix,
              (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
              DOMNode::ATTRIBUTE_NODE
          );
    this -> fNamespaceURI = (URI == 0) ? 0 : ownerDoc->getPooledString(URI);
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMTreeWalkerImpl.hpp ---
#ifndef DOMTreeWalkerImpl_HEADER_GUARD_
#define DOMTreeWalkerImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMTreeWalkerImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/dom/DOMTreeWalker.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMTreeWalkerImpl : public DOMTreeWalker {
    private:
        // The whatToShow mask.
        unsigned long fWhatToShow;

        // The NodeFilter reference.
        DOMNodeFilter* fNodeFilter;

        // The current Node.
        DOMNode* fCurrentNode;

        // The root Node.
        DOMNode* fRoot;

        // The expandEntity reference flag.
        bool fExpandEntityReferences;

	public:
    // Implementation Note: No state is kept except the data above
    // (fWhatToShow, fNodeFilter, fCurrentNode, fRoot) such that
    // setters could be created for these data values and the
    // implementation will still work.

    /** Public constructor */
    DOMTreeWalkerImpl (
        DOMNode* root,
        unsigned long whatToShow,
        DOMNodeFilter* nodeFilter,
        bool expandEntityRef);
    DOMTreeWalkerImpl (const DOMTreeWalkerImpl& twi);
    DOMTreeWalkerImpl& operator= (const DOMTreeWalkerImpl& twi);

    // Return the root node.
    virtual DOMNode* getRoot ();

    // Return the whatToShow value.
    virtual unsigned long  getWhatToShow ();

    // Return the NodeFilter.
    virtual DOMNodeFilter* getFilter ();

	
    // Return the current DOMNode.
    virtual DOMNode* getCurrentNode ();

    // Return the current Node.
    virtual void setCurrentNode (DOMNode* node);

    // Return the parent Node from the current node,
    //  after applying filter, whatToshow.
    //  If result is not null, set the current Node.
    virtual DOMNode* parentNode ();

    // Return the first child Node from the current node,
    //  after applying filter, whatToshow.
    //  If result is not null, set the current Node.
    virtual DOMNode* firstChild ();

    // Return the last child Node from the current node,
    //  after applying filter, whatToshow.
    //  If result is not null, set the current Node.
    virtual DOMNode* lastChild ();

    // Return the previous sibling Node from the current node,
    //  after applying filter, whatToshow.
    //  If result is not null, set the current Node.
    virtual DOMNode* previousSibling ();

    // Return the next sibling Node from the current node,
    //  after applying filter, whatToshow.
    //  If result is not null, set the current Node.

    virtual DOMNode* nextSibling ();
    // Return the previous Node from the current node,
    //  after applying filter, whatToshow.
    //  If result is not null, set the current Node.
    virtual DOMNode* previousNode ();

    // Return the next Node from the current node,
    //  after applying filter, whatToshow.
    //  If result is not null, set the current Node.
    virtual DOMNode* nextNode ();

    // Get the expandEntity reference flag.
    virtual bool getExpandEntityReferences();

    // release the resource
    virtual void release();

protected:

    // Internal function.
    //  Return the parent Node, from the input node
    //  after applying filter, whatToshow.
    //  The current node is not consulted or set.
    DOMNode* getParentNode (DOMNode* node);

    // Internal function.
    //  Return the nextSibling Node, from the input node
    //  after applying filter, whatToshow.
    //  The current node is not consulted or set.
    DOMNode* getNextSibling (DOMNode* node);

    // Internal function.
    //  Return the previous sibling Node, from the input node
    //  after applying filter, whatToshow.
    //  The current node is not consulted or set.
    DOMNode* getPreviousSibling (DOMNode* node);

    // Internal function.
    //  Return the first child Node, from the input node
    //  after applying filter, whatToshow.
    //  The current node is not consulted or set.
    DOMNode* getFirstChild (DOMNode* node);

    // Internal function.
    //  Return the last child Node, from the input node
    //  after applying filter, whatToshow.
    //  The current node is not consulted or set.
    DOMNode* getLastChild (DOMNode* node);

    // The node is accepted if it passes the whatToShow and the filter.
    short acceptNode (DOMNode* node);

    		
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMDeepNodeListPool.hpp ---
/*
 * 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.
 */

/*
 * $Id: DOMDeepNodeListPool.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#if !defined(DOMDeepNODELISTPOOL_HPP)
#define DOMDeepNODELISTPOOL_HPP


#include <xercesc/util/HashBase.hpp>
#include <xercesc/util/IllegalArgumentException.hpp>
#include <xercesc/util/NoSuchElementException.hpp>
#include <xercesc/util/RuntimeException.hpp>
#include <xercesc/util/XMLExceptMsgs.hpp>
#include <xercesc/util/XMLEnumerator.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/HashXMLCh.hpp>
#include <xercesc/util/HashPtr.hpp>

XERCES_CPP_NAMESPACE_BEGIN


// This hash table is modified from RefHash3KeysIdPool with first key as object ptr (DOMNode),
// second and third keys are both XMLCh* string

template <class TVal> struct DOMDeepNodeListPoolTableBucketElem;


//
//  This should really be a nested class, but some of the compilers we
//  have to support cannot deal with that!
//
template <class TVal>
struct DOMDeepNodeListPoolTableBucketElem : public XMemory
{
    DOMDeepNodeListPoolTableBucketElem
    (
        void* key1
        , XMLCh* key2
        , XMLCh* key3
        , TVal* const value
        , DOMDeepNodeListPoolTableBucketElem<TVal>* next
        , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
    ) :
    fData(value)
    , fNext(next)
    , fKey1(key1)
    , fKey2(0)
    , fKey3(0)
    {
        if (key2)
            fKey2 = XMLString::replicate(key2, manager);

        if (key3)
            fKey3 = XMLString::replicate(key3, manager);
    }

    TVal*                                     fData;
    DOMDeepNodeListPoolTableBucketElem<TVal>* fNext;
    void*                                     fKey1;
    XMLCh*                                    fKey2;
    XMLCh*                                    fKey3;

    ~DOMDeepNodeListPoolTableBucketElem() {};
};


template <class TVal> class DOMDeepNodeListPool
{
public:
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    // backwards compatability - default hasher is HashXMLCh
    DOMDeepNodeListPool
    (
        const XMLSize_t modulus
      , const XMLSize_t initSize = 128
    );

    // backwards compatability - default hasher is HashXMLCh
    DOMDeepNodeListPool
    (
        const XMLSize_t modulus
      , const bool adoptElems
      , const XMLSize_t initSize = 128
    );

    // if a hash function is passed in, it will be deleted when the hashtable is deleted.
    // use a new instance of the hasher class for each hashtable, otherwise one hashtable
    // may delete the hasher of a different hashtable if both use the same hasher.
    DOMDeepNodeListPool
    (
         const XMLSize_t modulus
       , const bool adoptElems
       , HashBase* hashBase
       , const XMLSize_t initSize = 128
    );

    ~DOMDeepNodeListPool();

    // -----------------------------------------------------------------------
    //  Element management
    // -----------------------------------------------------------------------
    bool isEmpty() const;
    bool containsKey(const void* const key1, const XMLCh* const key2, const XMLCh* const key3) const;
    void removeAll();
    void cleanup();


    // -----------------------------------------------------------------------
    //  Getters
    // -----------------------------------------------------------------------
    TVal* getByKey(const void* const key1, const XMLCh* const key2, const XMLCh* const key3);
    const TVal* getByKey(const void* const key1, const XMLCh* const key2, const XMLCh* const key3) const;

    TVal* getById(const XMLSize_t elemId);
    const TVal* getById(const XMLSize_t elemId) const;

    // -----------------------------------------------------------------------
    //  Putters
    // -----------------------------------------------------------------------
	XMLSize_t put(void* key1, XMLCh* key2, XMLCh* key3, TVal* const valueToAdopt);

private:

    // -----------------------------------------------------------------------
    //  Private methods
    // -----------------------------------------------------------------------
    DOMDeepNodeListPoolTableBucketElem<TVal>* findBucketElem(const void* const key1, const XMLCh* const key2, const XMLCh* const key3, XMLSize_t& hashVal);
    const DOMDeepNodeListPoolTableBucketElem<TVal>* findBucketElem(const void* const key1, const XMLCh* const key2, const XMLCh* const key3, XMLSize_t& hashVal) const;
    void initialize(const XMLSize_t modulus);

    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMDeepNodeListPool(const DOMDeepNodeListPool<TVal> &);
    DOMDeepNodeListPool<TVal> & operator = (const DOMDeepNodeListPool<TVal> &);

    // -----------------------------------------------------------------------
    //  Data members
    //
    //  fAdoptedElems
    //      Indicates whether the values added are adopted or just referenced.
    //      If adopted, then they are deleted when they are removed from the
    //      hash table.
    //
    //  fBucketList
    //      This is the array that contains the heads of all of the list
    //      buckets, one for each possible hash value.
    //
    //  fHashModulus
    //      The modulus used for this hash table, to hash the keys. This is
    //      also the number of elements in the bucket list.
    //
    //  fHash
    //      The hasher for the key1 data type.
    //
    //  fIdPtrs
    //  fIdPtrsCount
    //      This is the array of pointers to the bucket elements in order of
    //      their assigned ids. So taking id N and referencing this array
    //      gives you the element with that id. The count field indicates
    //      the current size of this list. When fIdCounter+1 reaches this
    //      value the list must be expanded.
    //
    //  fIdCounter
    //      This is used to give out unique ids to added elements. It starts
    //      at zero (which means empty), and is bumped up for each newly added
    //      element. So the first element is 1, the next is 2, etc... This
    //      means that this value is set to the top index of the fIdPtrs array.
    // -----------------------------------------------------------------------
    bool                                       fAdoptedElems;
    DOMDeepNodeListPoolTableBucketElem<TVal>** fBucketList;
    XMLSize_t                                  fHashModulus;
    HashBase*                                  fHash;
    TVal**                                     fIdPtrs;
    XMLSize_t                                  fIdPtrsCount;
    XMLSize_t                                  fIdCounter;
    MemoryManager*                             fMemoryManager;
};

XERCES_CPP_NAMESPACE_END

#if !defined(XERCES_TMPLSINC)
#include <xercesc/dom/impl/DOMDeepNodeListPool.c>
#endif

#endif

--- NEW FILE: DOMNodeIDMap.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMNodeIDMap.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMAttrImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMNodeIDMap.hpp"

#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/RuntimeException.hpp>
#include <stdio.h>

XERCES_CPP_NAMESPACE_BEGIN


static const int gPrimes[] = {997, 9973, 99991, 999983, 0 };  // To do - add a few more.

static const float gMaxFill = 0.8f;   // The maximum fraction of the total
                                    // table entries to consume before exanding.

DOMNodeIDMap::DOMNodeIDMap(int initialSize, DOMDocument *doc)
: fNumEntries(0)
, fDoc(doc)
{
    for (fSizeIndex = 0; gPrimes[fSizeIndex] < initialSize; fSizeIndex++)
    {
        if (gPrimes[fSizeIndex] == 0)
        {
            // We need a bigger size than the largest available one.
            //   Big trouble.
            fSizeIndex--;
            ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::NodeIDMap_GrowErr, ((DOMDocumentImpl *)fDoc)->getMemoryManager());
        }
    }

    fSize = gPrimes[fSizeIndex];    
    fMaxEntries = (XMLSize_t)(float(fSize) * gMaxFill);

    //fTable = new (fDoc) DOMAttr*[fSize];
    fTable = (DOMAttr**) ((DOMDocumentImpl *)fDoc)->allocate(sizeof(DOMAttr*) * fSize);
    XMLSize_t i;
    for (i=0; i<fSize; i++)
        fTable[i] = 0;
}


DOMNodeIDMap::~DOMNodeIDMap()
{
    // don't delete - the document owns the storage.
    fTable = 0;
}



void DOMNodeIDMap::add(DOMAttr *attr)
{
	//
	//  If the table is getting too full, grow it.  We arbitrarily limit
	//   the table to 80 full, which should limit the average number of
	//   rehashes to a reasonable value.
	//
	if (fNumEntries >= fMaxEntries)
		growTable();
    fNumEntries++;

	//
	// Hash the value string from the ID attribute being added to the table
	//      0 < Initial hash value < table size.
	//      An initial hash of zero would cause the rehash to fail.
	//
	const XMLCh *id=attr->getValue();
    XMLSize_t initalHash = XMLString::hash(id, fSize-1, ((DOMDocumentImpl *)fDoc)->getMemoryManager());
	initalHash++;
	XMLSize_t currentHash = initalHash;

	//
	// Loop looking for an empty slot for this ID.
	//   Don't even bother checking to see if the ID is already there -
	//   the table is only filled by the parser from valid documents, which
	//   can not have duplicates.  Behavior of invalid docs is not defined.
	//
    while (true)
	{
		DOMAttr *tableSlot = fTable[currentHash];
		if (tableSlot == 0 ||
			tableSlot == (DOMAttr *)-1)
			break;
		currentHash += initalHash;  // rehash
        if (currentHash >= fSize)
            currentHash = currentHash % fSize;
    }

    //
    // We've found our slot.  Stick the pointer to the attr into it.
    //
    fTable[currentHash] = attr;

}


void DOMNodeIDMap::remove(DOMAttr *attr)
{
    //
	// Hash the value string from the ID attribute being added to the table
	//      0 < Initial hash value < table size.
	//      An initial hash of zero would cause the rehash to fail.
	//
	const XMLCh *id=attr->getValue();
    XMLSize_t initalHash = XMLString::hash(id, fSize-1, ((DOMDocumentImpl *)fDoc)->getMemoryManager());
	initalHash++;
	XMLSize_t currentHash = initalHash;

	//
	// Loop looking for a slot pointing to an attr with this id.
    //
    while (true)
	{
		DOMAttr *tableSlot = fTable[currentHash];
		if (tableSlot == 0)
        {
            // There is no matching entry in the table
            return;
        }

        if (tableSlot == attr)
        {
            //  Found the attribute.  Set the slot to -1 to indicate
            //   that it was once used, meaning that lookups, while never
            //   matching here, can not stop either, but must rehash again
            //   and continue searching.
            fTable[currentHash] = (DOMAttr *)-1;
            return;
        }

        currentHash += initalHash;  // rehash.
        if (currentHash >= fSize)
            currentHash = currentHash % fSize;
    }

}


DOMAttr *DOMNodeIDMap::find(const XMLCh *id)
{
    //
    //  Get the hashcode for the supplied string.
    //
	XMLSize_t initalHash = XMLString::hash(id, fSize-1, ((DOMDocumentImpl *)fDoc)->getMemoryManager());
	initalHash++;
	XMLSize_t currentHash = initalHash;

	//
	// Loop looking for a slot pointing to an attr with this id.
    //
    while (true)
	{
		DOMAttr *tableSlot = fTable[currentHash];
		if (tableSlot == 0)
        {
            // There is no matching entry in the table
            return 0;
        }


        if ((tableSlot != (DOMAttr *)-1) && XMLString::equals(tableSlot->getValue(), id))
            return tableSlot;

        currentHash += initalHash;  // rehash
        if (currentHash >= fSize)
            currentHash = currentHash % fSize;
    }
    return 0;  // Never gets here, but keeps some compilers happy.
}


//
//  Grow the table to the next larger size.
//      It has gotten too full for efficient operation.
//     (We never fill it all the way)
//
void DOMNodeIDMap::growTable()
{
    DOMAttr     **oldTable = fTable;
    XMLSize_t oldSize  = fSize;

    //
    //  Figure the new table size.
    //
#if defined(XERCES_DEBUG)
    fprintf(stderr, "growing...\n");
#endif
    fSizeIndex++;
    fSize = gPrimes[fSizeIndex];
    if (fSize == 0)
    {
        // We need to grow bigger than the largest available size.
        //   Big trouble.
        fSizeIndex--;
        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::NodeIDMap_GrowErr, ((DOMDocumentImpl *)fDoc)->getMemoryManager());
    }

    //
    //  Allocate the new table.
    //
    //fTable = new (fDoc) DOMAttr *[fSize];
    fTable = (DOMAttr**) ((DOMDocumentImpl *)fDoc)->allocate(sizeof(DOMAttr*) * fSize);
    XMLSize_t i;
    for (i=0; i<fSize; i++)
        fTable[i] = 0;

    fMaxEntries = (XMLSize_t)(float(fSize) * gMaxFill);

    //
    // Move entries over from the old table to the new one.
    //
    for (i=0; i<oldSize; i++)
    {
        if ((oldTable[i] != 0)  &&  (oldTable[i] != (DOMAttr *)-1))
            add(oldTable[i]);
    }

    // delete [] oldTable;   (The document owns the storage.  The old table will just
    //                        need to leak until until the document is discarded.)

}


XERCES_CPP_NAMESPACE_END



--- NEW FILE: DOMProcessingInstructionImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMProcessingInstructionImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMProcessingInstructionImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMStringPool.hpp"
#include "DOMRangeImpl.hpp"

#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMProcessingInstructionImpl::DOMProcessingInstructionImpl(DOMDocument *ownerDoc,
                                                     const XMLCh *targt,
                                                     const XMLCh *dat)
    : fNode(ownerDoc), fCharacterData(ownerDoc, dat), fBaseURI(0)
{
    fNode.setIsLeafNode(true);
    this->fTarget = ((DOMDocumentImpl *)ownerDoc)->cloneString(targt);
}


DOMProcessingInstructionImpl::DOMProcessingInstructionImpl(
                                        const DOMProcessingInstructionImpl &other,
                                        bool /*deep*/)
    : DOMProcessingInstruction(other), 
      fNode(other.fNode), 
      fChild(other.fChild), 
      fCharacterData(other.fCharacterData),
      fTarget(other.fTarget), 
      fBaseURI(other.fBaseURI)
{
    fNode.setIsLeafNode(true);
}


DOMProcessingInstructionImpl::~DOMProcessingInstructionImpl()
{
}


DOMNode *DOMProcessingInstructionImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::PROCESSING_INSTRUCTION_OBJECT) DOMProcessingInstructionImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMProcessingInstructionImpl::getNodeName() const
{
    return fTarget;
}


short DOMProcessingInstructionImpl::getNodeType() const {
    return DOMNode::PROCESSING_INSTRUCTION_NODE;
}


/** A PI's "target" states what processor channel the PI's data
should be directed to. It is defined differently in HTML and XML.

  In XML, a PI's "target" is the first (whitespace-delimited) token
  following the "<?" token that begins the PI.

    In HTML, target is always 0.

      Note that getNodeName is aliased to getTarget.
*/
const XMLCh * DOMProcessingInstructionImpl::getTarget() const
{
    return fTarget;
}


void DOMProcessingInstructionImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fCharacterData.releaseBuffer();
        doc->release(this, DOMDocumentImpl::PROCESSING_INSTRUCTION_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

void DOMProcessingInstructionImpl::setBaseURI(const XMLCh* baseURI) {
    this->fBaseURI = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(baseURI);
}

const XMLCh* DOMProcessingInstructionImpl::getBaseURI() const
{
    return fBaseURI? fBaseURI : fNode.fOwnerNode->getBaseURI();
}

// Non standard extension for the range to work
DOMProcessingInstruction *DOMProcessingInstructionImpl::splitText(XMLSize_t offset)
{
    if (fNode.isReadOnly())
    {
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    }
    XMLSize_t len = fCharacterData.fDataBuf->getLen();
    if (offset > len)
        throw DOMException(DOMException::INDEX_SIZE_ERR, 0,  GetDOMNodeMemoryManager);

    DOMProcessingInstruction *newText =
                getOwnerDocument()->createProcessingInstruction(fTarget,
                        this->substringData(offset, len - offset));

    DOMNode *parent = getParentNode();
    if (parent != 0)
        parent->insertBefore(newText, getNextSibling());

    fCharacterData.fDataBuf->chop(offset);

    if (this->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateSplitInfo( this, newText, offset);
                }
            }
        }
    }

    return newText;
}

//
//    Delegation stubs for inherited functions
//
           DOMNode*         DOMProcessingInstructionImpl::appendChild(DOMNode *newChild)          {return fNode.appendChild (newChild); }
           DOMNamedNodeMap* DOMProcessingInstructionImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMProcessingInstructionImpl::getChildNodes() const                   {return fNode.getChildNodes (); }
           DOMNode*         DOMProcessingInstructionImpl::getFirstChild() const                   {return fNode.getFirstChild (); }
           DOMNode*         DOMProcessingInstructionImpl::getLastChild() const                    {return fNode.getLastChild (); }
     const XMLCh*           DOMProcessingInstructionImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMProcessingInstructionImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMProcessingInstructionImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
     const XMLCh*           DOMProcessingInstructionImpl::getNodeValue() const                    {return fCharacterData.getNodeValue (); }
           DOMDocument*     DOMProcessingInstructionImpl::getOwnerDocument() const                {return fNode.getOwnerDocument (); }
     const XMLCh*           DOMProcessingInstructionImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMProcessingInstructionImpl::getParentNode() const                   {return fChild.getParentNode (this); }
           DOMNode*         DOMProcessingInstructionImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
           bool             DOMProcessingInstructionImpl::hasChildNodes() const                   {return fNode.hasChildNodes (); }
           DOMNode*         DOMProcessingInstructionImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                                  {return fNode.insertBefore (newChild, refChild); }
           void             DOMProcessingInstructionImpl::normalize()                             {fNode.normalize (); }
           DOMNode*         DOMProcessingInstructionImpl::removeChild(DOMNode *oldChild)          {return fNode.removeChild (oldChild); }
           DOMNode*         DOMProcessingInstructionImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                                  {return fNode.replaceChild (newChild, oldChild); }
           bool             DOMProcessingInstructionImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                                  {return fNode.isSupported (feature, version); }
           void             DOMProcessingInstructionImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMProcessingInstructionImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMProcessingInstructionImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMProcessingInstructionImpl::isEqualNode(const DOMNode* arg) const   {return fNode.isEqualNode(arg); }
           void*            DOMProcessingInstructionImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                                  {return fNode.setUserData(key, data, handler); }
           void*            DOMProcessingInstructionImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           short            DOMProcessingInstructionImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMProcessingInstructionImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMProcessingInstructionImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMProcessingInstructionImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMProcessingInstructionImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMProcessingInstructionImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMProcessingInstructionImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }

//
//   Delegation of CharacerData functions.
//


           const XMLCh*     DOMProcessingInstructionImpl::getData() const                         {return fCharacterData.getData();}
           void             DOMProcessingInstructionImpl::deleteData(XMLSize_t offset, XMLSize_t count)
                                                                                    {fCharacterData.deleteData(this, offset, count);}
           const XMLCh*     DOMProcessingInstructionImpl::substringData(XMLSize_t offset, XMLSize_t count) const
                                                                                    {return fCharacterData.substringData(this, offset, count);}
           void             DOMProcessingInstructionImpl::setData(const XMLCh *data)              {fCharacterData.setData(this, data);}
           void             DOMProcessingInstructionImpl::setNodeValue(const XMLCh  *nodeValue)   {fCharacterData.setNodeValue (this, nodeValue); }


XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMElementNSImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMElementNSImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include <xercesc/util/XMLUniDefs.hpp>
#include "DOMElementNSImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMTypeInfoImpl.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/XMLUri.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) :
    DOMElementImpl(ownerDoc, nam)
{
    this->fNamespaceURI=0;	  //DOM Level 2
    this->fLocalName=0;       //DOM Level 2
    this->fPrefix=0;
    this->fSchemaType = 0;
}

//Introduced in DOM Level 2
DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc,
                             const XMLCh *namespaceURI,
                             const XMLCh *qualifiedName) :
    DOMElementImpl(ownerDoc, qualifiedName)
{
    setName(namespaceURI, qualifiedName);
    this->fSchemaType = 0;
}

DOMElementNSImpl::DOMElementNSImpl(const DOMElementNSImpl &other, bool deep) :
    DOMElementImpl(other, deep)
{
    this->fNamespaceURI = other.fNamespaceURI;	        //DOM Level 2
    this->fLocalName = other.fLocalName;                //DOM Level 2
    this->fPrefix = other.fPrefix;
    this->fSchemaType = other.fSchemaType;
}

DOMNode * DOMElementNSImpl::cloneNode(bool deep) const {
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::ELEMENT_NS_OBJECT) DOMElementNSImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}

const XMLCh * DOMElementNSImpl::getNamespaceURI() const
{
    return fNamespaceURI;
}

const XMLCh * DOMElementNSImpl::getPrefix() const
{
    return fPrefix;
}


const XMLCh * DOMElementNSImpl::getLocalName() const
{
    return fLocalName;
}

const XMLCh* DOMElementNSImpl::getBaseURI() const
{
    const XMLCh* baseURI = (fNode.fOwnerNode)->getBaseURI();
    if (fAttributes) {
        const XMLCh baseString[] =
        {
            chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
        };
        DOMNode* attrNode = fAttributes->getNamedItemNS(DOMNodeImpl::getXmlURIString(), baseString);
        if (attrNode) {
            const XMLCh* uri =  attrNode->getNodeValue();
            if (uri && *uri) {// attribute value is always empty string
                // if there is a base URI for the parent node, use it to resolve relative URI
                if(baseURI)
                {
                    try {
                        XMLUri temp(baseURI, ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager());
                        XMLUri temp2(&temp, uri, ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager());
                        uri = ((DOMDocumentImpl *)this->getOwnerDocument())->cloneString(temp2.getUriText());
                    }
                    catch(const OutOfMemoryException&)
                    {
                        throw;
                    }
                    catch (...){
                        // REVISIT: what should happen in this case?
                        return 0;
                    }
                }
                return uri;
            }
        }
    }
    return baseURI;
}


void DOMElementNSImpl::setPrefix(const XMLCh *prefix)
{
    if (fNode.isReadOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull)
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);

    if (prefix == 0 || *prefix == 0) {
        fPrefix = 0;
        fName = fLocalName;
        return;
    }

    if(!((DOMDocumentImpl *)this->getOwnerDocument())->isXMLName(prefix))
        throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, GetDOMNodeMemoryManager);

    const XMLCh * xml      = DOMNodeImpl::getXmlString();
    const XMLCh * xmlURI   = DOMNodeImpl::getXmlURIString();

    if (XMLString::equals(prefix, xml) &&
        !XMLString::equals(fNamespaceURI, xmlURI))
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);


    if (XMLString::indexOf(prefix, chColon) != -1) {
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
    }

    this-> fPrefix = ((DOMDocumentImpl *)this->getOwnerDocument())->getPooledString(prefix);

    int prefixLen = XMLString::stringLen(prefix);
    int newQualifiedNameLen = prefixLen+1+XMLString::stringLen(fLocalName);

    XMLCh *newName;
    XMLCh temp[4000];
    if (newQualifiedNameLen >= 3999)
        newName = (XMLCh*) ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager()->allocate
        (
            newQualifiedNameLen * sizeof(XMLCh)
        );//new XMLCh[newQualifiedNameLen];
    else
        newName = temp;

    // newName = prefix + chColon + fLocalName;
    XMLString::copyString(newName, prefix);
    newName[prefixLen] = chColon;
    XMLString::copyString(&newName[prefixLen+1], fLocalName);

    fName = ((DOMDocumentImpl *)this->getOwnerDocument())->
                                           getPooledString(newName);

    if (newQualifiedNameLen >= 3999)
        ((DOMDocumentImpl *)this->getOwnerDocument())->getMemoryManager()->deallocate(newName);//delete[] newName;

}

void DOMElementNSImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMDocumentImpl::ELEMENT_NS_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

DOMNode* DOMElementNSImpl::rename(const XMLCh* namespaceURI, const XMLCh* name)
{
    setName(namespaceURI, name);
    fAttributes->reconcileDefaultAttributes(getDefaultAttributes());
    return this;
}

void DOMElementNSImpl::setName(const XMLCh *namespaceURI,
                               const XMLCh *qualifiedName)
{
    DOMDocumentImpl* ownerDoc = (DOMDocumentImpl *) getOwnerDocument();
    this->fName = ownerDoc->getPooledString(qualifiedName);

    int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
    if (index < 0)
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);

    if (index == 0) {	//qualifiedName contains no ':'
        this -> fPrefix = 0;
        this -> fLocalName = this -> fName;
    } else {	//0 < index < this->name.length()-1
        XMLCh* newName;
        XMLCh temp[4000];
        if (index >= 3999)
            newName = (XMLCh*) ownerDoc->getMemoryManager()->allocate
            (
                (XMLString::stringLen(qualifiedName) + 1) * sizeof(XMLCh)
            );//new XMLCh[XMLString::stringLen(qualifiedName)+1];
        else
            newName = temp;

        XMLString::copyNString(newName, fName, index);
        newName[index] = chNull;
        this-> fPrefix = ownerDoc->getPooledString(newName);
        this -> fLocalName = ownerDoc->getPooledString(fName+index+1);

        if (index >= 3999)
            ownerDoc->getMemoryManager()->deallocate(newName);//delete[] newName;

        // Before we carry on, we should check if the prefix or localName are valid XMLName
        if (!((DOMDocumentImpl *)this->getOwnerDocument())->isXMLName(fPrefix) || !((DOMDocumentImpl *)this->getOwnerDocument())->isXMLName(fLocalName))
            throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
    }

    // DOM Level 3: namespace URI is never empty string.
    const XMLCh * URI = DOMNodeImpl::mapPrefix
        (
            fPrefix,
            (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
            DOMNode::ELEMENT_NODE
        );
    this -> fNamespaceURI = (URI == 0) ? 0 : ownerDoc->getPooledString(URI);
}

const DOMTypeInfo *DOMElementNSImpl::getTypeInfo() const
{
    if(!fSchemaType) 
        return &DOMTypeInfoImpl::g_DtdValidatedElement;
    return fSchemaType;
}

void DOMElementNSImpl::setTypeInfo(const DOMTypeInfoImpl* typeInfo) 
{
    fSchemaType = typeInfo;
}

DOMNode * DOMElementNSImpl::getInterface(const XMLCh* feature)
{
    if(XMLString::equals(feature, XMLUni::fgXercescInterfacePSVITypeInfo))
        return (DOMNode*)(DOMPSVITypeInfo*)fSchemaType;
    return DOMElementImpl::getInterface(feature);
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMDocumentFragmentImpl.cpp ---
/*
 * Copyright 2001-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.
 */

/*
 * $Id: DOMDocumentFragmentImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMDocumentFragmentImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMDocumentFragmentImpl::DOMDocumentFragmentImpl(DOMDocument *masterDoc)
    : fNode(masterDoc), fParent(masterDoc)
{
}


DOMDocumentFragmentImpl::DOMDocumentFragmentImpl(const DOMDocumentFragmentImpl &other,
                                           bool deep)
    : fNode(other.fNode), fParent(other.fParent)
{
    if (deep)
        castToParentImpl(this)->cloneChildren(&other);
}


DOMDocumentFragmentImpl::~DOMDocumentFragmentImpl()
{
}



DOMNode *DOMDocumentFragmentImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (castToNodeImpl(this)->getOwnerDocument(), DOMDocumentImpl::DOCUMENT_FRAGMENT_OBJECT) DOMDocumentFragmentImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMDocumentFragmentImpl::getNodeName() const {
    static const XMLCh name[] = {chPound, chLatin_d, chLatin_o, chLatin_c, chLatin_u, chLatin_m,
        chLatin_e, chLatin_n, chLatin_t, chDash,
        chLatin_f, chLatin_r, chLatin_a, chLatin_g, chLatin_m, chLatin_e, chLatin_n, chLatin_t, 0};
    return name;
}


short DOMDocumentFragmentImpl::getNodeType() const {
    return DOMNode::DOCUMENT_FRAGMENT_NODE;
}


void DOMDocumentFragmentImpl::setNodeValue(const XMLCh *x)
{
    fNode.setNodeValue(x);
}


void DOMDocumentFragmentImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMDocumentImpl::DOCUMENT_FRAGMENT_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

//
//  Delegation stubs for inherited functions.
//
           DOMNode*         DOMDocumentFragmentImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); }
           DOMNamedNodeMap* DOMDocumentFragmentImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMDocumentFragmentImpl::getChildNodes() const                   {return fParent.getChildNodes (); }
           DOMNode*         DOMDocumentFragmentImpl::getFirstChild() const                   {return fParent.getFirstChild (); }
           DOMNode*         DOMDocumentFragmentImpl::getLastChild() const                    {return fParent.getLastChild (); }
     const XMLCh*           DOMDocumentFragmentImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMDocumentFragmentImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMDocumentFragmentImpl::getNextSibling() const                  {return fNode.getNextSibling (); }
     const XMLCh*           DOMDocumentFragmentImpl::getNodeValue() const                    {return fNode.getNodeValue (); }
           DOMDocument*     DOMDocumentFragmentImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; }
     const XMLCh*           DOMDocumentFragmentImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMDocumentFragmentImpl::getParentNode() const                   {return fNode.getParentNode (); }
           DOMNode*         DOMDocumentFragmentImpl::getPreviousSibling() const              {return fNode.getPreviousSibling (); }
           bool             DOMDocumentFragmentImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); }
           DOMNode*         DOMDocumentFragmentImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                             {return fParent.insertBefore (newChild, refChild); }
           void             DOMDocumentFragmentImpl::normalize()                             {fParent.normalize (); }
           DOMNode*         DOMDocumentFragmentImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); }
           DOMNode*         DOMDocumentFragmentImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                             {return fParent.replaceChild (newChild, oldChild); }
           bool             DOMDocumentFragmentImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                             {return fNode.isSupported (feature, version); }
           void             DOMDocumentFragmentImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMDocumentFragmentImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMDocumentFragmentImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMDocumentFragmentImpl::isEqualNode(const DOMNode* arg) const   {return fParent.isEqualNode(arg); }
           void*            DOMDocumentFragmentImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                             {return fNode.setUserData(key, data, handler); }
           void*            DOMDocumentFragmentImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           const XMLCh*     DOMDocumentFragmentImpl::getBaseURI() const                      {return fNode.getBaseURI(); }
           short            DOMDocumentFragmentImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMDocumentFragmentImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMDocumentFragmentImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMDocumentFragmentImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMDocumentFragmentImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMDocumentFragmentImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMDocumentFragmentImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }

XERCES_CPP_NAMESPACE_END



--- NEW FILE: DOMDeepNodeListPool.c ---
/*
 * 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.
 */

/**
 * $Id: DOMDeepNodeListPool.c,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */


// ---------------------------------------------------------------------------
//  Include
// ---------------------------------------------------------------------------
#include <xercesc/util/XercesDefs.hpp>
#if defined(XERCES_TMPLSINC)
#include <xercesc/dom/impl/DOMDeepNodeListPool.hpp>
#endif

#include <assert.h>

XERCES_CPP_NAMESPACE_BEGIN



// ---------------------------------------------------------------------------
//  DOMDeepNodeListPool: Constructors and Destructor
// ---------------------------------------------------------------------------
template <class TVal>
DOMDeepNodeListPool<TVal>::DOMDeepNodeListPool( const XMLSize_t modulus
                                              , const bool adoptElems
                                              , const XMLSize_t initSize) :
	 fAdoptedElems(adoptElems)
    , fBucketList(0)
    , fHashModulus(modulus)
    , fHash(0)
    , fIdPtrs(0)
    , fIdPtrsCount(initSize)
    , fIdCounter(0)
    , fMemoryManager(XMLPlatformUtils::fgMemoryManager)
{
    initialize(modulus);

    // create default hasher
#if defined (XML_GCC_VERSION) && (XML_GCC_VERSION < 29600)
    fHash = new HashPtr();
#else
    fHash = new (fMemoryManager) HashPtr();
#endif
    //
    //  Allocate the initial id pointers array. We don't have to zero them
    //  out since the fIdCounter value tells us which ones are valid. The
    //  zeroth element is never used (and represents an invalid pool id.)
    //
    if (!fIdPtrsCount)
        fIdPtrsCount = 256;

    fIdPtrs = (TVal**) fMemoryManager->allocate(fIdPtrsCount * sizeof(TVal*));//new TVal*[fIdPtrsCount];
    fIdPtrs[0] = 0;
}

template <class TVal>
DOMDeepNodeListPool<TVal>::DOMDeepNodeListPool( const XMLSize_t modulus
                                              , const bool adoptElems
                                              , HashBase* hashBase
                                              , const XMLSize_t initSize) :
	 fAdoptedElems(adoptElems)
    , fBucketList(0)
    , fHashModulus(modulus)
    , fHash(0)
    , fIdPtrs(0)
    , fIdPtrsCount(initSize)
    , fIdCounter(0)
    , fMemoryManager(XMLPlatformUtils::fgMemoryManager)
{
    initialize(modulus);
    // set hasher
    fHash = hashBase;

    //
    //  Allocate the initial id pointers array. We don't have to zero them
    //  out since the fIdCounter value tells us which ones are valid. The
    //  zeroth element is never used (and represents an invalid pool id.)
    //
    if (!fIdPtrsCount)
        fIdPtrsCount = 256;

    fIdPtrs = (TVal**) fMemoryManager->allocate(fIdPtrsCount * sizeof(TVal*));//new TVal*[fIdPtrsCount];
    fIdPtrs[0] = 0;
}

template <class TVal>
DOMDeepNodeListPool<TVal>::DOMDeepNodeListPool( const XMLSize_t modulus
                                              , const XMLSize_t initSize) :
	 fAdoptedElems(true)
    , fBucketList(0)
    , fHashModulus(modulus)
    , fHash(0)
    , fIdPtrs(0)
    , fIdPtrsCount(initSize)
    , fIdCounter(0)
    , fMemoryManager(XMLPlatformUtils::fgMemoryManager)
{
    initialize(modulus);

    // create default hasher
#if defined (XML_GCC_VERSION) && (XML_GCC_VERSION < 29600)
    fHash = new HashPtr();
#else
    fHash = new (fMemoryManager) HashPtr();
#endif    

    //
    //  Allocate the initial id pointers array. We don't have to zero them
    //  out since the fIdCounter value tells us which ones are valid. The
    //  zeroth element is never used (and represents an invalid pool id.)
    //
    if (!fIdPtrsCount)
        fIdPtrsCount = 256;

    fIdPtrs = (TVal**) fMemoryManager->allocate(fIdPtrsCount * sizeof(TVal*));//new TVal*[fIdPtrsCount];
    fIdPtrs[0] = 0;
}

template <class TVal>
void DOMDeepNodeListPool<TVal>::initialize(const XMLSize_t modulus)
{
	if (modulus == 0)
        ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::HshTbl_ZeroModulus, fMemoryManager);

    // Allocate the bucket list and zero them
    fBucketList = (DOMDeepNodeListPoolTableBucketElem<TVal>**)
        fMemoryManager->allocate
        (
            fHashModulus * sizeof(DOMDeepNodeListPoolTableBucketElem<TVal>*)
        );//new DOMDeepNodeListPoolTableBucketElem<TVal>*[fHashModulus];
    for (XMLSize_t index = 0; index < fHashModulus; index++)
        fBucketList[index] = 0;
}

template <class TVal> DOMDeepNodeListPool<TVal>::~DOMDeepNodeListPool()
{
    removeAll();

    // Then delete the bucket list & hasher & id pointers list
    fMemoryManager->deallocate(fIdPtrs);//delete [] fIdPtrs;
    fMemoryManager->deallocate(fBucketList);//delete [] fBucketList;
    delete fHash;
}


// ---------------------------------------------------------------------------
//  DOMDeepNodeListPool: Element management
// ---------------------------------------------------------------------------
template <class TVal>
bool DOMDeepNodeListPool<TVal>::isEmpty() const
{
    // Just check the bucket list for non-empty elements
    for (XMLSize_t buckInd = 0; buckInd < fHashModulus; buckInd++)
    {
        if (fBucketList[buckInd] != 0)
            return false;
    }
    return true;
}

template <class TVal>
bool DOMDeepNodeListPool<TVal>::containsKey( const void* const key1
                                           , const XMLCh* const key2
                                           , const XMLCh* const key3) const
{
    XMLSize_t hashVal;
    const DOMDeepNodeListPoolTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, key3, hashVal);
    return (findIt != 0);
}

template <class TVal>
void DOMDeepNodeListPool<TVal>::removeAll()
{
    // Clean up the buckets first
    for (XMLSize_t buckInd = 0; buckInd < fHashModulus; buckInd++)
    {
        // Get the bucket list head for this entry
        DOMDeepNodeListPoolTableBucketElem<TVal>* curElem = fBucketList[buckInd];
        DOMDeepNodeListPoolTableBucketElem<TVal>* nextElem;
        while (curElem)
        {
            // Save the next element before we hose this one
            nextElem = curElem->fNext;

            // If we adopted the data, then delete it too
            //    (Note:  the userdata hash table instance has data type of void *.
            //    This will generate compiler warnings here on some platforms, but they
            //    can be ignored since fAdoptedElements is false.
            if (fAdoptedElems)
                delete curElem->fData;

            // Then delete the current element and move forward
            fMemoryManager->deallocate(curElem->fKey2);//delete [] curElem->fKey2;
            fMemoryManager->deallocate(curElem->fKey3);//delete [] curElem->fKey3;

            delete curElem;
            curElem = nextElem;
        }

        // Clean out this entry
        fBucketList[buckInd] = 0;
    }

    // Reset the id counter
    fIdCounter = 0;
}

template <class TVal> void DOMDeepNodeListPool<TVal>::cleanup()
{
    removeAll();

    // Then delete the bucket list & hasher & id pointers list
    fMemoryManager->deallocate(fIdPtrs);//delete [] fIdPtrs;
    fMemoryManager->deallocate(fBucketList);//delete [] fBucketList;
    delete fHash;
}



// ---------------------------------------------------------------------------
//  DOMDeepNodeListPool: Getters
// ---------------------------------------------------------------------------
template <class TVal> TVal*
DOMDeepNodeListPool<TVal>::getByKey(const void* const key1, const XMLCh* const key2, const XMLCh* const key3)
{
    XMLSize_t hashVal;
    DOMDeepNodeListPoolTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, key3, hashVal);
    if (!findIt)
        return 0;
    return findIt->fData;
}

template <class TVal> const TVal*
DOMDeepNodeListPool<TVal>::getByKey(const void* const key1, const XMLCh* const key2, const XMLCh* const key3) const
{
    XMLSize_t hashVal;
    const DOMDeepNodeListPoolTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, key3, hashVal);
    if (!findIt)
        return 0;
    return findIt->fData;
}

template <class TVal> TVal*
DOMDeepNodeListPool<TVal>::getById(const XMLSize_t elemId)
{
    // If its either zero or beyond our current id, its an error
    if (!elemId || (elemId > fIdCounter))
        ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Pool_InvalidId, fMemoryManager);

    return fIdPtrs[elemId];
}

template <class TVal> const TVal*
DOMDeepNodeListPool<TVal>::getById(const XMLSize_t elemId) const
{
    // If its either zero or beyond our current id, its an error
    if (!elemId || (elemId > fIdCounter))
        ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Pool_InvalidId, fMemoryManager);

    return fIdPtrs[elemId];
}

// ---------------------------------------------------------------------------
//  DOMDeepNodeListPool: Putters
// ---------------------------------------------------------------------------
template <class TVal> XMLSize_t
DOMDeepNodeListPool<TVal>::put(void* key1, XMLCh* key2, XMLCh* key3, TVal* const valueToAdopt)
{
    // First see if the key exists already
    XMLSize_t hashVal;
    DOMDeepNodeListPoolTableBucketElem<TVal>* newBucket = findBucketElem(key1, key2, key3, hashVal);

    //
    //  If so,then update its value. If not, then we need to add it to
    //  the right bucket
    //
    if (newBucket)
    {
        if (fAdoptedElems)
            delete newBucket->fData;

        fMemoryManager->deallocate(newBucket->fKey2);//delete[] newBucket->fKey2;
        fMemoryManager->deallocate(newBucket->fKey3);//delete[] newBucket->fKey3;

        newBucket->fData = valueToAdopt;
        newBucket->fKey1 = key1;
        newBucket->fKey2 = XMLString::replicate(key2, fMemoryManager);
        newBucket->fKey3 = XMLString::replicate(key3, fMemoryManager);
    }
    else
    {
    // Revisit: the gcc compiler 2.95.x is generating an
    // internal compiler error message. So we use the default
    // memory manager for now.
#if defined (XML_GCC_VERSION) && (XML_GCC_VERSION < 29600)
        newBucket = new DOMDeepNodeListPoolTableBucketElem<TVal>
        (
            key1
            , key2
            , key3
            , valueToAdopt
            , fBucketList[hashVal]
            , fMemoryManager
        );
#else
        newBucket = new (fMemoryManager) DOMDeepNodeListPoolTableBucketElem<TVal>
        (
            key1
            , key2
            , key3
            , valueToAdopt
            , fBucketList[hashVal]
            , fMemoryManager
        );
#endif
        fBucketList[hashVal] = newBucket;
    }

    //
    //  Give this new one the next available id and add to the pointer list.
    //  Expand the list if that is now required.
    //
    if (fIdCounter + 1 == fIdPtrsCount)
    {
        // Create a new count 1.5 times larger and allocate a new array
        XMLSize_t newCount = (XMLSize_t)(fIdPtrsCount * 1.5);
        TVal** newArray = (TVal**) fMemoryManager->allocate
        (
            newCount * sizeof(TVal*)
        );//new TVal*[newCount];

        // Copy over the old contents to the new array
        memcpy(newArray, fIdPtrs, fIdPtrsCount * sizeof(TVal*));

        // Ok, toss the old array and store the new data
        fMemoryManager->deallocate(fIdPtrs); //delete [] fIdPtrs;
        fIdPtrs = newArray;
        fIdPtrsCount = newCount;
    }
    const XMLSize_t retId = ++fIdCounter;
    fIdPtrs[retId] = valueToAdopt;

    // Return the id that we gave to this element
    return retId;
}

// ---------------------------------------------------------------------------
//  DOMDeepNodeListPool: Private methods
// ---------------------------------------------------------------------------
template <class TVal> DOMDeepNodeListPoolTableBucketElem<TVal>* DOMDeepNodeListPool<TVal>::
findBucketElem(const void* const key1, const XMLCh* const key2, const XMLCh* const key3, XMLSize_t& hashVal)
{
    // Hash the key
    hashVal = fHash->getHashVal(key1, fHashModulus, fMemoryManager);
    assert(hashVal < fHashModulus);

    // Search that bucket for the key
    DOMDeepNodeListPoolTableBucketElem<TVal>* curElem = fBucketList[hashVal];
    while (curElem)
    {
        //key2 and key3 are XMLCh*, compareString takes null pointer vs zero len string the same
        //but we need them to be treated as different keys in this case
        if (fHash->equals(key1, curElem->fKey1) && (XMLString::equals(key2, curElem->fKey2)) && (XMLString::equals(key3, curElem->fKey3))) {
            if (!key2 || !curElem->fKey2) {
                if (key2 || curElem->fKey2) {
                    curElem = curElem->fNext;
                    continue;
                }
            }
            if (!key3 || !curElem->fKey3) {
                if (key3 || curElem->fKey3) {
                    curElem = curElem->fNext;
                    continue;
                }
            }

            return curElem;
        }

        curElem = curElem->fNext;
    }
    return 0;
}

template <class TVal> const DOMDeepNodeListPoolTableBucketElem<TVal>* DOMDeepNodeListPool<TVal>::
findBucketElem(const void* const key1, const XMLCh* const key2, const XMLCh* const key3, XMLSize_t& hashVal) const
{
    // Hash the key
    hashVal = fHash->getHashVal(key1, fHashModulus, fMemoryManager);
    assert(hashVal < fHashModulus);
    
    // Search that bucket for the key
    const DOMDeepNodeListPoolTableBucketElem<TVal>* curElem = fBucketList[hashVal];
    while (curElem)
    {
        //key2 and key3 are XMLCh*, compareString takes null pointer vs zero len string the same
        //but we need them to be treated as different keys in this case
        if (fHash->equals(key1, curElem->fKey1) && (XMLString::equals(key2, curElem->fKey2)) && (XMLString::equals(key3, curElem->fKey3))) {
            if (!key2 || !curElem->fKey2) {
                if (key2 || curElem->fKey2) {
                    curElem = curElem->fNext;
                    continue;
                }
            }
            if (!key3 || !curElem->fKey3) {
                if (key3 || curElem->fKey3) {
                    curElem = curElem->fNext;
                    continue;
                }
            }
            return curElem;
        }

        curElem = curElem->fNext;
    }
    return 0;
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMAttrNSImpl.hpp ---
#ifndef DOMAttrNSImpl_HEADER_GUARD_
#define DOMAttrNSImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMAttrNSImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include "DOMAttrImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMAttrNSImpl: public DOMAttrImpl {
protected:
    //Introduced in DOM Level 2
    const XMLCh * fNamespaceURI;     //namespace URI of this node
    const XMLCh * fLocalName;        //local part of qualified name
    const XMLCh * fPrefix;           // prefix part of qualified name
                           // revisit - can return local part
                           //    by pointing into the qualified (L1) name.

public:
    DOMAttrNSImpl(DOMDocument *ownerDoc, const XMLCh *name);
    DOMAttrNSImpl(DOMDocument *ownerDoc, //DOM Level 2
	                const XMLCh *namespaceURI, const XMLCh *qualifiedName);
    DOMAttrNSImpl(const DOMAttrNSImpl &other, bool deep=false);

    virtual DOMNode * cloneNode(bool deep) const;
    //Introduced in DOM Level 2
    virtual const XMLCh *   getNamespaceURI() const;
    virtual const XMLCh *   getPrefix() const;
    virtual const XMLCh *   getLocalName() const;
    virtual void            setPrefix(const XMLCh *prefix);
    virtual void            release();

   // helper function for DOM Level 3 renameNode
   virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);
   void setName(const XMLCh* namespaceURI, const XMLCh* name);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    DOMAttrNSImpl & operator = (const DOMAttrNSImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMWriterImpl.cpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: DOMWriterImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */
[...1636 lines suppressed...]
    {
        fFormatter->writeBOM(BOM_ucs4be, 4);
    }
    else if ((XMLString::compareIStringASCII(fEncoding, XMLUni::fgUCS4EncodingString)  == 0) ||
             (XMLString::compareIStringASCII(fEncoding, XMLUni::fgUCS4EncodingString2) == 0) ||
             (XMLString::compareIStringASCII(fEncoding, XMLUni::fgUCS4EncodingString3) == 0)  )
    {
#if defined(ENDIANMODE_LITTLE)
        fFormatter->writeBOM(BOM_ucs4le, 4);
#elif defined(ENDIANMODE_BIG)
        fFormatter->writeBOM(BOM_ucs4be, 4);
#endif
    }

    return;

}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMDocumentTypeImpl.hpp ---
#ifndef DOMDocumentTypeImpl_HEADER_GUARD_
#define DOMDocumentTypeImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMDocumentTypeImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//



#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include "DOMNodeImpl.hpp"
#include "DOMChildNode.hpp"
#include "DOMParentNode.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class DOMNamedNodeMapImpl;

class CDOM_EXPORT DOMDocumentTypeImpl: public DOMDocumentType {
private:
    DOMNodeImpl          fNode;
    DOMParentNode        fParent;
    DOMChildNode         fChild;

    const XMLCh *        fName;
    DOMNamedNodeMapImpl* fEntities;
    DOMNamedNodeMapImpl* fNotations;
    DOMNamedNodeMapImpl* fElements;
    const XMLCh *        fPublicId;
    const XMLCh *        fSystemId;
    const XMLCh *        fInternalSubset;

    bool			     fIntSubsetReading;
    bool                 fIsCreatedFromHeap;

    virtual void         setPublicId(const XMLCh * value);
    virtual void         setSystemId(const XMLCh * value);
    virtual void         setInternalSubset(const XMLCh *value);
    bool                 isIntSubsetReading() const;

    friend class AbstractDOMParser;
    friend class DOMDocumentImpl;

public:
    DOMDocumentTypeImpl(DOMDocument *, const XMLCh *, bool);
    DOMDocumentTypeImpl(DOMDocument *,
                     const XMLCh *qualifiedName,	//DOM Level 2
                     const XMLCh *publicId, const XMLCh *systemId, bool);
    DOMDocumentTypeImpl(const DOMDocumentTypeImpl &other, bool heap, bool deep=false);
    virtual ~DOMDocumentTypeImpl();

    // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;

    virtual void setOwnerDocument(DOMDocument *doc);
    virtual DOMNamedNodeMap * getEntities() const;
    virtual const XMLCh *       getName() const;
    virtual DOMNamedNodeMap * getNotations() const;
    virtual DOMNamedNodeMap * getElements() const;
    virtual void                setReadOnly(bool readOnly, bool deep);

    //Introduced in DOM Level 2

    virtual const XMLCh *     getPublicId() const;
    virtual const XMLCh *     getSystemId() const;
    virtual const XMLCh *     getInternalSubset() const;

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    DOMDocumentTypeImpl & operator = (const DOMDocumentTypeImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMStringPool.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMStringPool.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>

#include "DOMStringPool.hpp"
#include "DOMDocumentImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


//
//  DStringPoolEntry - one of these structs is allocated for each
//                      XMLCh String in the pool.  Each slot in the
//                      hash table array itself is a pointer to the head
//                      of a singly-linked list of these structs.
//
//                      Although this struct is delcared with a string length of one,
//                      the factory method allocates enough storage to hold the full
//                      string length.
//
struct DOMStringPoolEntry
{
    DOMStringPoolEntry    *fNext;
    XMLCh                 fString[1];
};


//
// createSPE - factory method for creating sting pool entry structs.
//             Allocates sufficient storage to hold the entire string
//
static DOMStringPoolEntry *createSPE(const XMLCh *str, DOMDocumentImpl *doc)
{
    //  Compute size to allocate.  Note that there's 1 char of string declared in the
    //       struct, so we don't need to add one again to account for the trailing null.
    //
    size_t sizeToAllocate = sizeof(DOMStringPoolEntry) + XMLString::stringLen(str)*sizeof(XMLCh);
    DOMStringPoolEntry *newSPE = (DOMStringPoolEntry *)doc->allocate(sizeToAllocate);
    newSPE->fNext = 0;
    XMLCh * nonConstStr = (XMLCh *)newSPE->fString;
    XMLString::copyString(nonConstStr, str);
    return newSPE;
}



DOMStringPool::DOMStringPool(int hashTableSize, DOMDocumentImpl *doc)
:   fDoc(doc)
,   fHashTableSize(hashTableSize)
{
    // needed to get access to the doc's storage allocator.

    //fHashTable = new (fDoc) DOMStringPoolEntry *[hashTableSize];
    void* p = doc->allocate(sizeof(DOMStringPoolEntry*) * hashTableSize);
    fHashTable = (DOMStringPoolEntry**) p;
    for (int i=0; i<fHashTableSize; i++)
        fHashTable[i] = 0;
}


//  Destructor.    Nothing to do, since storage all belongs to the document.
//
DOMStringPool::~DOMStringPool()
{
}


const XMLCh *DOMStringPool::getPooledString(const XMLCh *in)
{
    DOMStringPoolEntry    **pspe;
    DOMStringPoolEntry    *spe;

    int    inHash     = XMLString::hash(in, fHashTableSize, fDoc->getMemoryManager());
    pspe = &fHashTable[inHash];
    while (*pspe != 0)
    {
        if (XMLString::equals((*pspe)->fString, in))
            return (*pspe)->fString;
        pspe = &((*pspe)->fNext);
    }

    // This string hasn't been seen before.  Add it to the pool.
    *pspe = spe = createSPE(in, fDoc);
    return spe->fString;
}


// -----------------------------------------------------------------------
//  DOMBuffer: Constructors
// -----------------------------------------------------------------------
DOMBuffer::DOMBuffer(DOMDocumentImpl *doc, int capacity) :
    fBuffer(0)
    , fIndex(0)
    , fCapacity(capacity)
    , fDoc(doc)
{
    // Buffer is one larger than capacity, to allow for zero term
    fBuffer = (XMLCh*) doc->allocate((fCapacity+1)*sizeof(XMLCh));

    // Keep it null terminated
    fBuffer[0] = XMLCh(0);
}

DOMBuffer::DOMBuffer(DOMDocumentImpl *doc, const XMLCh* string) :
    fBuffer(0)
    , fIndex(0)
    , fCapacity(0)
    , fDoc(doc)
{
    unsigned int actualCount = XMLString::stringLen(string);
    fCapacity = actualCount + 15;

    // Buffer is one larger than capacity, to allow for zero term
    fBuffer = (XMLCh*) doc->allocate((fCapacity+1)*sizeof(XMLCh));

    memcpy(fBuffer, string, actualCount * sizeof(XMLCh));
    fIndex = actualCount;

    // Keep it null terminated
    fBuffer[fIndex] = 0;
}

// ---------------------------------------------------------------------------
//  DOMBuffer: Buffer management
// ---------------------------------------------------------------------------
void DOMBuffer::append(const XMLCh* const chars, const unsigned int count)
{
    unsigned int actualCount = count;
    if (!count)
        actualCount = XMLString::stringLen(chars);
    if (fIndex + actualCount >= fCapacity)
        expandCapacity(actualCount);
    memcpy(&fBuffer[fIndex], chars, actualCount * sizeof(XMLCh));
    fIndex += actualCount;

    // Keep it null terminated
    fBuffer[fIndex] = 0;
}

void DOMBuffer::set(const XMLCh* const chars, const unsigned int count)
{
    unsigned int actualCount = count;
    if (!count)
        actualCount = XMLString::stringLen(chars);
    fIndex = 0;
    if (fIndex + actualCount >= fCapacity)
        expandCapacity(actualCount);
    memcpy(fBuffer, chars, actualCount * sizeof(XMLCh));
    fIndex = actualCount;

    // Keep it null terminated
    fBuffer[fIndex] = 0;
}


// ---------------------------------------------------------------------------
//  DOMBuffer: Private helper methods
// ---------------------------------------------------------------------------
void DOMBuffer::expandCapacity(const unsigned int extraNeeded)
{
    //not enough room. Calc new capacity and allocate new buffer
    const unsigned int newCap = (unsigned int)((fIndex + extraNeeded) * 1.25);
    XMLCh* newBuf = (XMLCh*) fDoc->allocate((newCap+1)*sizeof(XMLCh));

    // Copy over the old stuff
    memcpy(newBuf, fBuffer, fCapacity * sizeof(XMLCh));

    // revisit: Leave the old buffer in document heap, yes, this is a leak, but live with it!
    // store new stuff
    fBuffer = newBuf;
    fCapacity = newCap;
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMCasts.hpp ---
#ifndef DOMCasts_HEADER_GUARD_
#define DOMCasts_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMCasts.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

//
//  Define inline casting functions to convert from
//    (DOMNode *) to DOMParentNode or DOMChildNode *.
//
//  This requires knowledge of the structure of the fields of
//   for all node types.  There are three categories -
//
//  Nodetypes that can have children and can be a child themselves.
//    e.g.  Elements
//
//       Object
//           DOMNodeImpl     fNode;
//           DOMParentNode   fParent;
//           DOMChildNode    fChild;
//             ...            // other fields, depending on node type.
//
//  Nodetypes that can not have children, e.g. TEXT
//
//       Object
//           DOMNodeImpl     fNode;
//           DOMChildNode    fChild;
//              ...            // other fields, depending on node type
//
//  Nodetypes that can not be a child of other nodes, but that can
//  have children (are a parent)  e.g. ATTR
//       Object
//           DOMNodeImpl     fNode;
//           DOMParentNode   fParent
//               ...           // other fields, depending on node type
//
//   The casting functions make these assumptions:
//      1.  The cast is possible.  Using code will not attempt to
//          cast to something that does not exist, such as the child
//          part of an ATTR
//
//      2.  The nodes belong to this implementation.
//
//    Some of the casts use the LEAFNODE flag in the common fNode part to
//    determine whether an fParent field exists, and thus the
//    position of the fChild part within the node.
//
//  These functions also cast off const.  It was either do that, or make
//  a second overloaded set that took and returned const arguements.
//

//
//	Note that using offsetof, or taking the offset of an object member at
//	a 0 address, is now undefined in C++. And gcc now warns about this behavior.
//	This is because doing do so is unreliable for some types of objects.
//		See: http://gcc.gnu.org/ml/gcc/2004-06/msg00227.html
//		   : http://gcc.gnu.org/ml/gcc-bugs/2000-03/msg00805.html
//  The casting code below works around gcc's warnings by using a dummy
//	pointer, which the compiler cannot tell is null. The defeats the warning,
//	but also masks the potential problem.
//	The gcc option -Wno-invalid-offsetof may also be used to turn off this warning.
//

#include "DOMElementImpl.hpp"
#include "DOMTextImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


static inline DOMNodeImpl *castToNodeImpl(const DOMNode *p)
{
    DOMElementImpl *pE = (DOMElementImpl *)p;
    return &(pE->fNode);
}


static inline DOMParentNode *castToParentImpl(const DOMNode *p) {
    DOMElementImpl *pE = (DOMElementImpl *)p;
    return &(pE->fParent);
}


static inline DOMChildNode *castToChildImpl(const DOMNode *p) {
    DOMElementImpl *pE = (DOMElementImpl *)p;
    if (pE->fNode.isLeafNode())  {
        DOMTextImpl *pT = (DOMTextImpl *)p;
        return &(pT->fChild);
    }
    return &(pE->fChild);
}


static inline DOMNode *castToNode(const DOMParentNode *p ) {
	DOMElementImpl* dummy = 0;
    size_t parentOffset = (char *)&(dummy->fParent) - (char *)dummy;
    char *retPtr = (char *)p - parentOffset;
    return (DOMNode *)retPtr;
}

static inline DOMNode *castToNode(const DOMNodeImpl *p) {
	DOMElementImpl* dummy = 0;
    size_t nodeImplOffset = (char *)&(dummy->fNode) - (char *)dummy;
    char *retPtr = (char *)p - nodeImplOffset;
    return (DOMNode *)retPtr;
}


static inline DOMNodeImpl *castToNodeImpl(const DOMParentNode *p)
{
	DOMElementImpl* dummy = 0;
    size_t nodeImplOffset = (char *)&(dummy->fNode) - (char *)dummy;
    size_t parentOffset = (char *)&(dummy->fParent) - (char *)dummy;
    char *retPtr = (char *)p - parentOffset + nodeImplOffset;
    return (DOMNodeImpl *)retPtr;
}

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMChildNode.hpp ---
#ifndef DOMChildNode_HEADER_GUARD_
#define DOMChildNode_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMChildNode.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

/**
 * ChildNode adds to NodeImpl the capability of being a child, this is having
 * siblings.
 **/

#include <xercesc/util/XercesDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class DOMDocument;
class DOMNode;


class CDOM_EXPORT DOMChildNode {

public:
    DOMNode                *previousSibling;
    DOMNode                *nextSibling;

    DOMChildNode();
    DOMChildNode(const DOMChildNode &other);
    ~DOMChildNode();

    DOMNode * getNextSibling() const;
    DOMNode * getParentNode(const DOMNode *thisNode) const;
    DOMNode * getPreviousSibling(const DOMNode *thisNode) const;

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMChildNode & operator = (const DOMChildNode &);   
};


XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMParentNode.hpp ---
#ifndef DOMParentNode_HEADER_GUARD_
#define DOMParentNode_HEADER_GUARD_


/*
 * 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.
 */

/*
 * $Id: DOMParentNode.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

/**
 * ParentNode provides the capability of having child
 * nodes. Not every node in the DOM can have children, so only nodes that can
 * should include this class and pay the price for it.
 * <P>
 * While we have a direct reference to the first child, the last child is
 * stored as the previous sibling of the first child. First child nodes are
 * marked as being so, and getNextSibling hides this fact.
 *
 **/

#include <xercesc/util/XercesDefs.hpp>
#include "DOMNodeListImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class DOMChildNode;
class DOMDocument;
class DOMNode;
class DOMNodeList;

class CDOM_EXPORT DOMParentNode  {
public:
    DOMDocument            *fOwnerDocument; // Document this node belongs to
    DOMNode                *fFirstChild;
    DOMNodeListImpl            fChildNodeList;      // for GetChildNodes()

public:
    DOMParentNode(DOMDocument *ownerDocument);
    DOMParentNode(const DOMParentNode &other);

    DOMDocument * getOwnerDocument() const;
    void setOwnerDocument(DOMDocument* doc);

    // Track changes to the node tree structure under this node.  An optimization
    //   for NodeLists.
    int changes() const;
    void changed();

    DOMNode*     appendChild(DOMNode *newChild);
    DOMNodeList* getChildNodes() const;
    DOMNode*     getFirstChild() const;
    DOMNode*     getLastChild() const;
    XMLSize_t    getLength() const;
    bool         hasChildNodes() const;
    DOMNode*     insertBefore(DOMNode *newChild, DOMNode *refChild);
    DOMNode*     item(XMLSize_t index) const;
    DOMNode*     removeChild(DOMNode *oldChild);
    DOMNode*     replaceChild(DOMNode *newChild, DOMNode *oldChild);

    //Introduced in DOM Level 2
    void	normalize();

    //Introduced in DOM Level 3
    bool isEqualNode(const DOMNode* arg) const;

    // NON-DOM
    // unlike getOwnerDocument this never returns null, even for Document nodes
    DOMDocument * getDocument() const;
    void          release();


public:
    void cloneChildren(const DOMNode *other);
    DOMNode * lastChild() const;
    void lastChild(DOMNode *);

private:
    // unimplemented    
    DOMParentNode& operator= (const DOMParentNode& other);
};

#define GetDOMParentNodeMemoryManager GET_DIRECT_MM(fOwnerDocument)

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMNamedNodeMapImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMNamedNodeMapImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */


#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

#include "DOMNodeVector.hpp"
#include "DOMNamedNodeMapImpl.hpp"
#include "DOMCasts.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMNodeImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN

DOMNamedNodeMapImpl::DOMNamedNodeMapImpl(DOMNode *ownerNod)
{
    fOwnerNode=ownerNod;
    memset(fBuckets,0,MAP_SIZE*sizeof(DOMNodeVector*));
}

DOMNamedNodeMapImpl::~DOMNamedNodeMapImpl()
{
}

bool DOMNamedNodeMapImpl::readOnly() 
{
    return castToNodeImpl(fOwnerNode)->isReadOnly();
}

DOMNamedNodeMapImpl *DOMNamedNodeMapImpl::cloneMap(DOMNode *ownerNod)
{
    DOMDocumentImpl *doc = (DOMDocumentImpl *)(castToNodeImpl(ownerNod)->getOwnerDocument());
    DOMNamedNodeMapImpl *newmap = new (doc) DOMNamedNodeMapImpl(ownerNod);
	
    for(int index=0;index<MAP_SIZE;index++)
        if (fBuckets[index] != 0) {
            XMLSize_t size=fBuckets[index]->size();
            newmap->fBuckets[index] = new (doc) DOMNodeVector(doc, size);
            for (XMLSize_t i = 0; i < size; ++i) {
                DOMNode *s = fBuckets[index]->elementAt(i);
                DOMNode *n = s->cloneNode(true);
			    castToNodeImpl(n)->isSpecified(castToNodeImpl(s)->isSpecified());
                castToNodeImpl(n)->fOwnerNode = ownerNod;
                castToNodeImpl(n)->isOwned(true);
                newmap->fBuckets[index]->addElement(n);
            }
        }

    return newmap;
}


XMLSize_t DOMNamedNodeMapImpl::getLength() const
{
    XMLSize_t count=0;
    for(int index=0;index<MAP_SIZE;index++)
        count+=(fBuckets[index]==0?0:fBuckets[index]->size());
    return count;
}

DOMNode * DOMNamedNodeMapImpl::item(XMLSize_t index) const
{
    XMLSize_t count=0;
    for(XMLSize_t i=0;i<MAP_SIZE;i++) {
        if(fBuckets[i]==0)
            continue;
        XMLSize_t thisBucket=fBuckets[i]->size();
        if(index>=count && index<(count+thisBucket))
            return fBuckets[i]->elementAt(index-count);
        count+=thisBucket;
    }
    return NULL;
}


DOMNode * DOMNamedNodeMapImpl::getNamedItem(const XMLCh *name) const
{
    unsigned int hash=XMLString::hash(name,MAP_SIZE);
    if(fBuckets[hash]==0)
        return 0;

    int i = 0;
    int size = fBuckets[hash]->size();
    for (i = 0; i < size; ++i) {
        DOMNode *n=fBuckets[hash]->elementAt(i);
        if(XMLString::equals(name,n->getNodeName()))
            return n;
    }

    return 0;
}


//
// removeNamedItem() - Remove the named item, and return it.
//                      The caller can release the
//                      returned item if it's not used
//                      we can't do it here because the caller would
//                      never see the returned node.
//
DOMNode * DOMNamedNodeMapImpl::removeNamedItem(const XMLCh *name)
{
    if (this->readOnly())
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    
    unsigned int hash=XMLString::hash(name,MAP_SIZE);
    if(fBuckets[hash]==0)
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    int i = 0;
    int size = fBuckets[hash]->size();
    for (i = 0; i < size; ++i) {
        DOMNode *n=fBuckets[hash]->elementAt(i);
        if(XMLString::equals(name,n->getNodeName())) {
            fBuckets[hash]->removeElementAt(i);
            castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
            castToNodeImpl(n)->isOwned(false);
            return n;
        }
    }

    throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    return 0;
}



//
// setNamedItem()  Put the item into the NamedNodeList by name.
//                  If an item with the same name already was
//                  in the list, replace it.  Return the old
//                  item, if there was one.
//                  Caller is responsible for arranging for
//                  deletion of the old item if its ref count is
//                  zero.
//
DOMNode * DOMNamedNodeMapImpl::setNamedItem(DOMNode * arg)
{
    DOMDocument *doc = fOwnerNode->getOwnerDocument();
    DOMNodeImpl *argImpl = castToNodeImpl(arg);
    if(argImpl->getOwnerDocument() != doc)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0, GetDOMNamedNodeMapMemoryManager);
    if (this->readOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    if ((arg->getNodeType() == DOMNode::ATTRIBUTE_NODE) && argImpl->isOwned() && (argImpl->fOwnerNode != fOwnerNode))
        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);

    argImpl->fOwnerNode = fOwnerNode;
    argImpl->isOwned(true);

    const XMLCh* name=arg->getNodeName();
    unsigned int hash=XMLString::hash(name,MAP_SIZE);
    if(fBuckets[hash]==0)
        fBuckets[hash] = new (doc) DOMNodeVector(doc, 3);

    int i = 0;
    int size = fBuckets[hash]->size();
    for (i = 0; i < size; ++i) {
        DOMNode *n=fBuckets[hash]->elementAt(i);
        if(XMLString::equals(name,n->getNodeName())) {
            fBuckets[hash]->setElementAt(arg,i);
            castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
            castToNodeImpl(n)->isOwned(false);
            return n;
        }
    }
    fBuckets[hash]->addElement(arg);
    return 0;
}


void DOMNamedNodeMapImpl::setReadOnly(bool readOnl, bool deep)
{
    // this->fReadOnly=readOnl;
    if(deep) {
        for (int index = 0; index < MAP_SIZE; index++) {
            if(fBuckets[index]==0)
                continue;
            int sz = fBuckets[index]->size();
            for (int i=0; i<sz; ++i)
                castToNodeImpl(fBuckets[index]->elementAt(i))->setReadOnly(readOnl, deep);
        }
    }
}


//Introduced in DOM Level 2

DOMNode *DOMNamedNodeMapImpl::getNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName) const
{
    // the map is indexed using the full name of nodes; to search given a namespace and a local name
    // we have to do a linear search
    for (int index = 0; index < MAP_SIZE; index++) {
        if(fBuckets[index]==0)
            continue;

        int i = 0;
        int size = fBuckets[index]->size();
        for (i = 0; i < size; ++i) {
            DOMNode *n=fBuckets[index]->elementAt(i);
            const XMLCh * nNamespaceURI = n->getNamespaceURI();
            const XMLCh * nLocalName = n->getLocalName();
            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
                continue;
            else {
                if (XMLString::equals(localName, nLocalName)
                    ||
                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName())))
                    return n;
            }
        }
    }
    return 0;
}


//
// setNamedItemNS()  Put the item into the NamedNodeList by name.
//                  If an item with the same name already was
//                  in the list, replace it.  Return the old
//                  item, if there was one.
//                  Caller is responsible for arranging for
//                  deletion of the old item if its ref count is
//                  zero.
//
DOMNode * DOMNamedNodeMapImpl::setNamedItemNS(DOMNode *arg)
{
    DOMDocument *doc = fOwnerNode->getOwnerDocument();
    DOMNodeImpl *argImpl = castToNodeImpl(arg);
    if (argImpl->getOwnerDocument() != doc)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0, GetDOMNamedNodeMapMemoryManager);
    if (this->readOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    if (argImpl->isOwned())
        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);

    argImpl->fOwnerNode = fOwnerNode;
    argImpl->isOwned(true);

    const XMLCh* namespaceURI=arg->getNamespaceURI();
    const XMLCh* localName=arg->getLocalName();
    // the map is indexed using the full name of nodes; to search given a namespace and a local name
    // we have to do a linear search
    for (int index = 0; index < MAP_SIZE; index++) {
        if(fBuckets[index]==0)
            continue;

        int i = 0;
        int size = fBuckets[index]->size();
        for (i = 0; i < size; ++i) {
            DOMNode *n=fBuckets[index]->elementAt(i);
            const XMLCh * nNamespaceURI = n->getNamespaceURI();
            const XMLCh * nLocalName = n->getLocalName();
            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
                continue;
            else {
                if (XMLString::equals(localName, nLocalName)
                    ||
                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName()))) {
                    fBuckets[index]->setElementAt(arg,i);
                    castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
                    castToNodeImpl(n)->isOwned(false);
                    return n;
                }
            }
        }
    }
    // if not found, add it using the full name as key
    return setNamedItem(arg);
}


// removeNamedItemNS() - Remove the named item, and return it.
//                      The caller can release the
//                      returned item if it's not used
//                      we can't do it here because the caller would
//                      never see the returned node.
DOMNode *DOMNamedNodeMapImpl::removeNamedItemNS(const XMLCh *namespaceURI,
                                                 const XMLCh *localName)
{
    if (this->readOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    // the map is indexed using the full name of nodes; to search given a namespace and a local name
    // we have to do a linear search
    for (int index = 0; index < MAP_SIZE; index++) {
        if(fBuckets[index]==0)
            continue;

        int i = 0;
        int size = fBuckets[index]->size();
        for (i = 0; i < size; ++i) {
            DOMNode *n=fBuckets[index]->elementAt(i);
            const XMLCh * nNamespaceURI = n->getNamespaceURI();
            const XMLCh * nLocalName = n->getLocalName();
            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
                continue;
            else {
                if (XMLString::equals(localName, nLocalName)
                    ||
                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName()))) {
                    fBuckets[index]->removeElementAt(i);
                    castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
                    castToNodeImpl(n)->isOwned(false);
                    return n;
                }
            }
        }
    }
    throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    return 0;
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMNotationImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMNotationImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMDocumentImpl.hpp"
#include "DOMNotationImpl.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMNotationImpl::DOMNotationImpl(DOMDocument *ownerDoc, const XMLCh *nName)
    : fNode(ownerDoc), fName(0), fPublicId(0), fSystemId(0), fBaseURI(0)
{
    fNode.setIsLeafNode(true);
    fName = ((DOMDocumentImpl *)ownerDoc)->getPooledString(nName);
}

DOMNotationImpl::DOMNotationImpl(const DOMNotationImpl &other, bool /*deep*/)
    : DOMNotation(other), 
      fNode(other.fNode), 
      fName(other.fName), 
      fPublicId(other.fPublicId),
      fSystemId(other.fSystemId), 
      fBaseURI(other.fBaseURI)
{
    fNode.setIsLeafNode(true);
}


DOMNotationImpl::~DOMNotationImpl()
{
}


DOMNode *DOMNotationImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::NOTATION_OBJECT) DOMNotationImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMNotationImpl::getNodeName() const {
    return fName;
}


short DOMNotationImpl::getNodeType() const {
    return DOMNode::NOTATION_NODE;
}



const XMLCh * DOMNotationImpl::getPublicId() const
{
    return fPublicId;
}


const XMLCh * DOMNotationImpl::getSystemId() const
{
    return fSystemId;
}


void DOMNotationImpl::setNodeValue(const XMLCh *arg)
{
    fNode.setNodeValue(arg);
}


void DOMNotationImpl::setPublicId(const XMLCh *arg)
{
    if(fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR,0, GetDOMNodeMemoryManager);

    fPublicId = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(arg);
}


void DOMNotationImpl::setSystemId(const XMLCh *arg)
{
    if(fNode.isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR,0, GetDOMNodeMemoryManager);

    fSystemId = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(arg);
}

void DOMNotationImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        doc->release(this, DOMDocumentImpl::NOTATION_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

void DOMNotationImpl::setBaseURI(const XMLCh* baseURI) {
    if (baseURI && *baseURI) {
        XMLCh* temp = (XMLCh*) ((DOMDocumentImpl *)getOwnerDocument())->allocate((XMLString::stringLen(baseURI) + 9)*sizeof(XMLCh));
        XMLString::fixURI(baseURI, temp);
        fBaseURI = temp;
    }
    else
        fBaseURI = 0;
}

const XMLCh* DOMNotationImpl::getBaseURI() const
{
    return fBaseURI;
}


           DOMNode*         DOMNotationImpl::appendChild(DOMNode *newChild)          {return fNode.appendChild (newChild); }
           DOMNamedNodeMap* DOMNotationImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMNotationImpl::getChildNodes() const                   {return fNode.getChildNodes (); }
           DOMNode*         DOMNotationImpl::getFirstChild() const                   {return fNode.getFirstChild (); }
           DOMNode*         DOMNotationImpl::getLastChild() const                    {return fNode.getLastChild (); }
     const XMLCh*           DOMNotationImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMNotationImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMNotationImpl::getNextSibling() const                  {return fNode.getNextSibling (); }
     const XMLCh*           DOMNotationImpl::getNodeValue() const                    {return fNode.getNodeValue (); }
           DOMDocument*     DOMNotationImpl::getOwnerDocument() const                {return fNode.getOwnerDocument (); }
     const XMLCh*           DOMNotationImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMNotationImpl::getParentNode() const                   {return fNode.getParentNode (); }
           DOMNode*         DOMNotationImpl::getPreviousSibling() const              {return fNode.getPreviousSibling (); }
           bool             DOMNotationImpl::hasChildNodes() const                   {return fNode.hasChildNodes (); }
           DOMNode*         DOMNotationImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                     {return fNode.insertBefore (newChild, refChild); }
           void             DOMNotationImpl::normalize()                             {fNode.normalize (); }
           DOMNode*         DOMNotationImpl::removeChild(DOMNode *oldChild)          {return fNode.removeChild (oldChild); }
           DOMNode*         DOMNotationImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                     {return fNode.replaceChild (newChild, oldChild); }
           bool             DOMNotationImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                     {return fNode.isSupported (feature, version); }
           void             DOMNotationImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMNotationImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMNotationImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMNotationImpl::isEqualNode(const DOMNode* arg) const   {return fNode.isEqualNode(arg); }
           void*            DOMNotationImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                     {return fNode.setUserData(key, data, handler); }
           void*            DOMNotationImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           short            DOMNotationImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMNotationImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMNotationImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMNotationImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMNotationImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMNotationImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMNotationImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }


XERCES_CPP_NAMESPACE_END



--- NEW FILE: DOMAttrMapImpl.cpp ---
/*
 * 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.
 */


/*
 * $Id: DOMAttrMapImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMAttrMapImpl.hpp"
#include "DOMAttrImpl.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMElementImpl.hpp"
#include "DOMCasts.hpp"
#include "DOMNodeVector.hpp"

#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/dom/DOMException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMAttrMapImpl::DOMAttrMapImpl(DOMNode *ownerNod)
{
    this->fOwnerNode=ownerNod;
    this->fNodes = 0;
	hasDefaults(false);
}

DOMAttrMapImpl::DOMAttrMapImpl(DOMNode *ownerNod, const DOMAttrMapImpl *defaults)
{
    this->fOwnerNode=ownerNod;
    this->fNodes = 0;
	hasDefaults(false);
	if (defaults != 0)
	{
		if (defaults->getLength() > 0)
		{
			hasDefaults(true);
			cloneContent(defaults);
		}
	}
}

DOMAttrMapImpl::~DOMAttrMapImpl()
{
}

void DOMAttrMapImpl::cloneContent(const DOMAttrMapImpl *srcmap)
{
    if ((srcmap != 0) && (srcmap->fNodes != 0))
    {
        if (fNodes != 0)
            fNodes->reset();
        else
        {
            XMLSize_t size = srcmap->fNodes->size();
            if(size > 0) {
                DOMDocument *doc = fOwnerNode->getOwnerDocument();
                fNodes = new (doc) DOMNodeVector(doc, size);
            }
        }

        for (XMLSize_t i = 0; i < srcmap->fNodes->size(); i++)
        {
            DOMNode *n = srcmap->fNodes->elementAt(i);
            DOMNode *clone = n->cloneNode(true);
            castToNodeImpl(clone)->isSpecified(castToNodeImpl(n)->isSpecified());
            castToNodeImpl(clone)->fOwnerNode = fOwnerNode;
            castToNodeImpl(clone)->isOwned(true);
            fNodes->addElement(clone);
        }
    }
}

DOMAttrMapImpl *DOMAttrMapImpl::cloneAttrMap(DOMNode *ownerNode_p)
{
	DOMAttrMapImpl *newmap = new (castToNodeImpl(ownerNode_p)->getOwnerDocument()) DOMAttrMapImpl(ownerNode_p);
	newmap->cloneContent(this);
	// newmap->attrDefaults = this->attrDefaults;  // revisit
	return newmap;
}

void DOMAttrMapImpl::setReadOnly(bool readOnl, bool deep)
{
    // this->fReadOnly=readOnl;
    if(deep && fNodes!=0)
    {
        int sz = fNodes->size();
        for (int i=0; i<sz; ++i) {
            castToNodeImpl(fNodes->elementAt(i))->setReadOnly(readOnl, deep);
        }
    }
}

bool DOMAttrMapImpl::readOnly() {
    return castToNodeImpl(fOwnerNode)->isReadOnly();
}

int DOMAttrMapImpl::findNamePoint(const XMLCh *name) const
{

    // Binary search
    int i=0;
    if(fNodes!=0)
    {
        int first=0,last=fNodes->size()-1;

        while(first<=last)
        {
            i=(first+last)/2;
            int test = XMLString::compareString(name, fNodes->elementAt(i)->getNodeName());
            if(test==0)
                return i; // Name found
            else if(test<0)
                last=i-1;
            else
                first=i+1;
        }
        if(first>i) i=first;
    }
    /********************
    // Linear search
    int i = 0;
    if (fNodes != 0)
    for (i = 0; i < fNodes.size(); ++i)
    {
    int test = name.compareTo(((NodeImpl *) (fNodes.elementAt(i))).getNodeName());
    if (test == 0)
    return i;
    else
    if (test < 0)
    {
    break; // Found insertpoint
    }
    }

    *******************/
    return -1 - i; // not-found has to be encoded.
}

DOMNode * DOMAttrMapImpl::getNamedItem(const XMLCh *name) const
{
    int i=findNamePoint(name);
    return (i<0) ? 0 : fNodes->elementAt(i);
}

DOMNode *DOMAttrMapImpl::setNamedItem(DOMNode *arg)
{
    if (arg->getNodeType() != DOMNode::ATTRIBUTE_NODE)
        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    DOMDocument *doc = fOwnerNode->getOwnerDocument();
    DOMNodeImpl *argImpl = castToNodeImpl(arg);
    if(argImpl->getOwnerDocument() != doc)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    if (this->readOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    if ((arg->getNodeType() == DOMNode::ATTRIBUTE_NODE) && argImpl->isOwned() && (argImpl->fOwnerNode != fOwnerNode))
        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);

    argImpl->fOwnerNode = fOwnerNode;
    argImpl->isOwned(true);
    int i=findNamePoint(arg->getNodeName());
    DOMNode * previous=0;
    if(i>=0)
    {
        previous = fNodes->elementAt(i);
        fNodes->setElementAt(arg,i);
    }
    else
    {
        i=-1-i; // Insert point (may be end of list)
        if(0==fNodes)
        {
            fNodes=new (doc) DOMNodeVector(doc);
        }
        fNodes->insertElementAt(arg,i);
    }
    if (previous != 0) {
        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();
        castToNodeImpl(previous)->isOwned(false);
    }

    return previous;
}

//Introduced in DOM Level 2

int DOMAttrMapImpl::findNamePoint(const XMLCh *namespaceURI,
	const XMLCh *localName) const
{
    if (fNodes == 0)
	return -1;
    // This is a linear search through the same fNodes Vector.
    // The Vector is sorted on the DOM Level 1 nodename.
    // The DOM Level 2 NS keys are namespaceURI and Localname,
    // so we must linear search thru it.
    // In addition, to get this to work with fNodes without any namespace
    // (namespaceURI and localNames are both 0) we then use the nodeName
    // as a secondary key.
    int i, len = fNodes -> size();
    for (i = 0; i < len; ++i) {
        DOMNode *node = fNodes -> elementAt(i);
        const XMLCh * nNamespaceURI = node->getNamespaceURI();
        const XMLCh * nLocalName = node->getLocalName();
        if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
            continue;
        else {
            if (XMLString::equals(localName, nLocalName)
                ||
                (nLocalName == 0 && XMLString::equals(localName, node->getNodeName())))
                return i;
        }
    }
    return -1;	//not found
}

DOMNode *DOMAttrMapImpl::getNamedItemNS(const XMLCh *namespaceURI,
	const XMLCh *localName) const
{
    int i = findNamePoint(namespaceURI, localName);
    return i < 0 ? 0 : fNodes -> elementAt(i);
}

DOMNode *DOMAttrMapImpl::setNamedItemNS(DOMNode* arg)
{
    if (arg->getNodeType() != DOMNode::ATTRIBUTE_NODE)
        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    DOMDocument *doc = fOwnerNode->getOwnerDocument();
    DOMNodeImpl *argImpl = castToNodeImpl(arg);
    if (argImpl->getOwnerDocument() != doc)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0, GetDOMNamedNodeMapMemoryManager);
    if (this->readOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    if (argImpl->isOwned())
        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);

    argImpl->fOwnerNode = fOwnerNode;
    argImpl->isOwned(true);
    int i=findNamePoint(arg->getNamespaceURI(), arg->getLocalName());
    DOMNode *previous=0;
    if(i>=0) {
        previous = fNodes->elementAt(i);
        fNodes->setElementAt(arg,i);
    } else {
        i=findNamePoint(arg->getNodeName()); // Insert point (may be end of list)
        if (i<0)
          i = -1 - i;
        if(0==fNodes)
            fNodes=new (doc) DOMNodeVector(doc);
        fNodes->insertElementAt(arg,i);
    }
    if (previous != 0) {
        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();
        castToNodeImpl(previous)->isOwned(false);
    }

    return previous;
}

DOMNode *DOMAttrMapImpl::removeNamedItem(const XMLCh *name)
{
    if (this->readOnly())
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    int i=findNamePoint(name);
    DOMNode *removed = 0;

    if(i<0)
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    removed = fNodes->elementAt(i);
    fNodes->removeElementAt(i);
    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();
    castToNodeImpl(removed)->isOwned(false);

    // Replace it if it had a default value
    // (DOM spec level 1 - Element Interface)
    if (hasDefaults() && (removed != 0))
    {
        DOMAttrMapImpl* defAttrs = ((DOMElementImpl*)fOwnerNode)->getDefaultAttributes();
        DOMAttr* attr = (DOMAttr*)(defAttrs->getNamedItem(name));
        if (attr != 0)
        {
            DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);
            setNamedItem(newAttr);
        }
    }

    return removed;
}

DOMNode *DOMAttrMapImpl::removeNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName)
{
    if (this->readOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
    int i = findNamePoint(namespaceURI, localName);
    if (i < 0)
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    DOMNode * removed = fNodes -> elementAt(i);
    fNodes -> removeElementAt(i);	//remove n from nodes
    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();
    castToNodeImpl(removed)->isOwned(false);

    // Replace it if it had a default value
    // (DOM spec level 2 - Element Interface)

    if (hasDefaults() && (removed != 0))
    {
        DOMAttrMapImpl* defAttrs = ((DOMElementImpl*)fOwnerNode)->getDefaultAttributes();
        DOMAttr* attr = (DOMAttr*)(defAttrs->getNamedItemNS(namespaceURI, localName));
        if (attr != 0)
        {
            DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);
            setNamedItemNS(newAttr);
        }
    }

    return removed;
}

// remove the name using index
// avoid calling findNamePoint again if the index is already known
DOMNode * DOMAttrMapImpl::removeNamedItemAt(XMLSize_t index)
{
    if (this->readOnly())
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    DOMNode *removed = item(index);
    if(!removed)
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);

    fNodes->removeElementAt(index);
    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();
    castToNodeImpl(removed)->isOwned(false);

    // Replace it if it had a default value
    // (DOM spec level 1 - Element Interface)
    if (hasDefaults() && (removed != 0))
    {
        DOMAttrMapImpl* defAttrs = ((DOMElementImpl*)fOwnerNode)->getDefaultAttributes();

        const XMLCh* localName = removed->getLocalName();
        DOMAttr* attr = 0;
        if (localName)
            attr = (DOMAttr*)(defAttrs->getNamedItemNS(removed->getNamespaceURI(), localName));
        else
            attr = (DOMAttr*)(defAttrs->getNamedItem(((DOMAttr*)removed)->getName()));

        if (attr != 0)
        {
            DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);
            setNamedItem(newAttr);
        }
    }

    return removed;
}

/**
 * Get this AttributeMap in sync with the given "defaults" map.
 * @param defaults The default attributes map to sync with.
 */
void DOMAttrMapImpl::reconcileDefaultAttributes(const DOMAttrMapImpl* defaults) {

    // remove any existing default
    XMLSize_t nsize = getLength();
    for (XMLSSize_t i = nsize - 1; i >= 0; i--) {
        DOMAttr* attr = (DOMAttr*)item(i);
        if (!attr->getSpecified()) {
            removeNamedItemAt(i);
        }
    }

    hasDefaults(false);

    // add the new defaults
    if (defaults) {
        hasDefaults(true);

        if (nsize == 0) {
            cloneContent(defaults);
        }
        else {
            XMLSize_t dsize = defaults->getLength();
            for (XMLSize_t n = 0; n < dsize; n++) {
                DOMAttr* attr = (DOMAttr*)defaults->item(n);

                DOMAttr* newAttr = (DOMAttr*)attr->cloneNode(true);
                setNamedItemNS(newAttr);
                DOMAttrImpl* newAttrImpl = (DOMAttrImpl*) newAttr;
                newAttrImpl->setSpecified(false);
            }
        }
    }
} // reconcileDefaults()


/**
 * Move specified attributes from the given map to this one
 */
void DOMAttrMapImpl::moveSpecifiedAttributes(DOMAttrMapImpl* srcmap) {
    XMLSize_t nsize = srcmap->getLength();

    for (XMLSSize_t i = nsize - 1; i >= 0; i--) {
        DOMAttr* attr = (DOMAttr*)srcmap->item(i);
        if (attr->getSpecified()) {
            srcmap->removeNamedItemAt(i);
        }

        if (attr->getLocalName())
            setNamedItemNS(attr);
        else
            setNamedItem(attr);
    }
} // moveSpecifiedAttributes(AttributeMap):void

XMLSize_t DOMAttrMapImpl::getLength() const
{
    return (fNodes != 0) ? fNodes->size() : 0;
}

DOMNode * DOMAttrMapImpl::item(XMLSize_t index) const
{
    return (fNodes != 0 && index < fNodes->size()) ?
        fNodes->elementAt(index) : 0;
}


XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMNodeVector.hpp ---
#ifndef DOMNodeVector_HEADER_GUARD_
#define DOMNodeVector_HEADER_GUARD_
/*
 * 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.
 */

/*
 * $Id: DOMNodeVector.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN


class DOMNode;
class DOMDocument;


class  DOMNodeVector {
private:
    DOMNode        **data;
    XMLSize_t      allocatedSize;
    XMLSize_t      nextFreeSlot;
    void           init(DOMDocument *doc, XMLSize_t size);
    void           checkSpace();
    
    // unimplemented
    DOMNodeVector ( const DOMNodeVector& toCopy);
    DOMNodeVector& operator= (const DOMNodeVector& other);

public:
    DOMNodeVector(DOMDocument *doc);
    DOMNodeVector(DOMDocument *doc, XMLSize_t size);
    ~DOMNodeVector();

    XMLSize_t      size();
    DOMNode*       elementAt(XMLSize_t index);
    DOMNode*       lastElement();
    void           addElement(DOMNode *);
    void           insertElementAt(DOMNode *, XMLSize_t index);
    void           setElementAt(DOMNode *val, XMLSize_t index);
    void           removeElementAt(XMLSize_t index);
    void           reset();
};

inline DOMNode *DOMNodeVector::elementAt(XMLSize_t index) {
    if (index >= nextFreeSlot)
        return 0;
	return data[index];
}

inline DOMNode *DOMNodeVector::lastElement() {
	if (nextFreeSlot == 0)
		return 0;
	return data[nextFreeSlot-1];
}

inline XMLSize_t DOMNodeVector::size() {
	return nextFreeSlot;
}

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMImplementationRegistry.cpp ---
/*
 * Copyright 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.
 */

/*
 * $Id: DOMImplementationRegistry.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLInitializer.hpp>
#include <xercesc/util/RefVectorOf.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMImplementationSource.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include "DOMImplementationImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


// -----------------------------------------------------------------------
//  Static constants.  These are lazily initialized on first usage.
//                     (Static constructors can not be safely used because
//                      of order of initialization dependencies.)
// -----------------------------------------------------------------------
// Points to the singleton instance of a registry of DOMImplementationSource
static RefVectorOf<DOMImplementationSource>* gDOMImplSrcVector = 0;

//  Global mutex that is used to synchronize access to the vector
static XMLMutex* gDOMImplSrcVectorMutex = 0;

static XMLRegisterCleanup cleanupDOMImplSrcVector;
static XMLRegisterCleanup cleanupDOMImplSrcVectorMutex;

// -----------------------------------------------------------------------
//  Function prototypes for internally used functions.
// -----------------------------------------------------------------------
RefVectorOf<DOMImplementationSource>* getDOMImplSrcVector();
XMLMutex& getDOMImplSrcVectorMutex();


// -----------------------------------------------------------------------
//  Reset the static data
// -----------------------------------------------------------------------
static void reinitDOMImplSrcVector()
{
	delete gDOMImplSrcVector;
	gDOMImplSrcVector = 0;
}

static void reinitDOMImplSrcVectorMutex()
{
    delete gDOMImplSrcVectorMutex;
    gDOMImplSrcVectorMutex = 0;
}

// -----------------------------------------------------------------------
//  Get the static data
// -----------------------------------------------------------------------
RefVectorOf<DOMImplementationSource>* getDOMImplSrcVector()
{
    // Note: we are not synchronizing on creation since that caller is doing
    //       it (i.e. caller is locking a mutex before calling us)
    if (!gDOMImplSrcVector)
    {
        gDOMImplSrcVector = new RefVectorOf<DOMImplementationSource>(3, false);
        cleanupDOMImplSrcVector.registerCleanup(reinitDOMImplSrcVector);
    }

    return gDOMImplSrcVector;
}

XMLMutex& getDOMImplSrcVectorMutex()
{
    if (!gDOMImplSrcVectorMutex)
    {
        XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex);

        if (!gDOMImplSrcVectorMutex)
        {
            gDOMImplSrcVectorMutex = new XMLMutex(XMLPlatformUtils::fgMemoryManager);
            cleanupDOMImplSrcVectorMutex.registerCleanup(reinitDOMImplSrcVectorMutex);
        }
    }

    return *gDOMImplSrcVectorMutex;
}

void XMLInitializer::initializeDOMImplementationRegistry()
{
    // mutex
    gDOMImplSrcVectorMutex = new XMLMutex(XMLPlatformUtils::fgMemoryManager);
    if (gDOMImplSrcVectorMutex) {
        cleanupDOMImplSrcVectorMutex.registerCleanup(reinitDOMImplSrcVectorMutex);
    }

    // vector
    gDOMImplSrcVector = new RefVectorOf<DOMImplementationSource>(3, false);
    if (gDOMImplSrcVector) {
        cleanupDOMImplSrcVector.registerCleanup(reinitDOMImplSrcVector);
    }
}


// -----------------------------------------------------------------------
//  DOMImplementationRegistry Functions
// -----------------------------------------------------------------------
DOMImplementation *DOMImplementationRegistry::getDOMImplementation(const XMLCh* features) {

    XMLMutexLock lock(&getDOMImplSrcVectorMutex());

    unsigned int len = getDOMImplSrcVector()->size();

    // Put our defined source there
    if (len == 0)
        getDOMImplSrcVector()->addElement((DOMImplementationSource*)DOMImplementationImpl::getDOMImplementationImpl());

    len = getDOMImplSrcVector()->size();

    for (unsigned int i = len; i > 0; i--) {
        DOMImplementationSource* source = getDOMImplSrcVector()->elementAt(i-1);
        DOMImplementation* impl = source->getDOMImplementation(features);
        if (impl)
            return impl;
    }

    return 0;
}

void DOMImplementationRegistry::addSource (DOMImplementationSource* source) {
    XMLMutexLock lock(&getDOMImplSrcVectorMutex());
    getDOMImplSrcVector()->addElement(source);
}


XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMCommentImpl.hpp ---
#ifndef DOMCommentImpl_HEADER_GUARD_
#define DOMCommentImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMCommentImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */


//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMComment.hpp>

#include "DOMNodeImpl.hpp"
#include "DOMChildNode.hpp"
#include "DOMCharacterDataImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMCommentImpl: public DOMComment {
public:
    DOMNodeImpl            fNode;
    DOMChildNode           fChild;
    DOMCharacterDataImpl   fCharacterData;

public:
    DOMCommentImpl(DOMDocument *, const XMLCh *);
    DOMCommentImpl(const DOMCommentImpl &other, bool deep);
    virtual ~DOMCommentImpl();

    // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;


    // Functions from DOMCharacterData
    virtual void          appendData(const  XMLCh *data);
    virtual void          deleteData(XMLSize_t offset, XMLSize_t count);
    virtual const XMLCh * getData() const;
    virtual XMLSize_t  getLength() const;
    virtual void          insertData(XMLSize_t offset, const XMLCh * data);
    virtual void          replaceData(XMLSize_t offset, XMLSize_t count, const XMLCh * data);
    virtual void          setData(const XMLCh * arg);
    virtual const XMLCh * substringData(XMLSize_t offset, XMLSize_t count) const;

    // Non standard extension for the range to work
    DOMComment* splitText(XMLSize_t offset);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMCommentImpl & operator = (const DOMCommentImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMEntityImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMEntityImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMEntityReference.hpp>
#include "DOMEntityImpl.hpp"
#include "DOMDocumentImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN

DOMEntityImpl::DOMEntityImpl(DOMDocument *ownerDoc, const XMLCh *eName)
   : fNode(ownerDoc),
     fParent(ownerDoc),
     fPublicId(0),
     fSystemId(0),
     fNotationName(0),
     fRefEntity(0),
     fActualEncoding(0),
     fEncoding(0),
     fVersion(0),     
     fBaseURI(0),
     fEntityRefNodeCloned(false)
{   
    fName        = ((DOMDocumentImpl *)ownerDoc)->getPooledString(eName);
    fNode.setReadOnly(true, true);
}


DOMEntityImpl::DOMEntityImpl(const DOMEntityImpl &other, bool deep)
    : DOMEntity(other),
      fNode(other.fNode),
      fParent(other.fParent),
      fName(other.fName),
      fPublicId(other.fPublicId),
      fSystemId(other.fSystemId),
      fNotationName(other.fNotationName),
      fRefEntity(other.fRefEntity),
      fActualEncoding(other.fActualEncoding),
      fEncoding(other.fEncoding),
      fVersion(other.fVersion),
      fBaseURI(other.fBaseURI),
      fEntityRefNodeCloned(false)
{    
    if (deep)
        fParent.cloneChildren(&other);   
    fNode.setReadOnly(true, true);
}


DOMEntityImpl::~DOMEntityImpl() {
}


DOMNode *DOMEntityImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::ENTITY_OBJECT) DOMEntityImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMEntityImpl::getNodeName() const {
    return fName;
}


short DOMEntityImpl::getNodeType() const {
    return DOMNode::ENTITY_NODE;
}


const XMLCh * DOMEntityImpl::getNotationName() const
{
    return fNotationName;
}


const XMLCh * DOMEntityImpl::getPublicId() const {
    return fPublicId;
}


const XMLCh * DOMEntityImpl::getSystemId() const
{
    return fSystemId;
}


const XMLCh* DOMEntityImpl::getBaseURI() const
{
    return fBaseURI;
}


void DOMEntityImpl::setNodeValue(const XMLCh *arg)
{
    fNode.setNodeValue(arg);
}


void DOMEntityImpl::setNotationName(const XMLCh *arg)
{
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    fNotationName = doc->cloneString(arg);
}


void DOMEntityImpl::setPublicId(const XMLCh *arg)
{
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    fPublicId = doc->cloneString(arg);
}


void DOMEntityImpl::setSystemId(const XMLCh *arg)
{
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    fSystemId = doc->cloneString(arg);
}


void DOMEntityImpl::setBaseURI(const XMLCh* baseURI) {
    if (baseURI && *baseURI) {
        XMLCh* temp = (XMLCh*) ((DOMDocumentImpl *)getOwnerDocument())->allocate((XMLString::stringLen(baseURI) + 9)*sizeof(XMLCh));
        XMLString::fixURI(baseURI, temp);
        fBaseURI = temp;
    }
    else
        fBaseURI = 0;
}


void   DOMEntityImpl::setEntityRef(DOMEntityReference* other)
{
    fRefEntity = other;
}


DOMEntityReference*  DOMEntityImpl::getEntityRef() const
{
    return fRefEntity;
}

void  DOMEntityImpl::cloneEntityRefTree() const
{
    if (fEntityRefNodeCloned)
        return;

    // cast off const.  This method is const because it is
    //   called from a bunch of logically const methods, like
    //   getFirstChild().
    DOMEntityImpl *ncThis = (DOMEntityImpl *)this;

    //lazily clone the entityRef tree to this entity
    if (fParent.fFirstChild != 0)
        return;

    if (!fRefEntity)
        return;

    ncThis->fEntityRefNodeCloned = true;
    ncThis->fNode.setReadOnly(false, true);
    ncThis->fParent.cloneChildren(fRefEntity);
    ncThis->fNode.setReadOnly(true, true);
}

DOMNode * DOMEntityImpl::getFirstChild() const
{
    cloneEntityRefTree();
    return fParent.fFirstChild;
}

DOMNode *   DOMEntityImpl::getLastChild() const
{
    cloneEntityRefTree();
    return fParent.getLastChild();
}

DOMNodeList* DOMEntityImpl::getChildNodes() const
{
    cloneEntityRefTree();
    return this->fParent.getChildNodes();

}

bool DOMEntityImpl::hasChildNodes() const
{
    cloneEntityRefTree();
    return fParent.fFirstChild!=0;
}


void DOMEntityImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMDocumentImpl::ENTITY_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

//
//  Functions inherited from Node
//

           DOMNode*         DOMEntityImpl::appendChild(DOMNode *newChild)          {cloneEntityRefTree(); return fParent.appendChild (newChild); }
           DOMNamedNodeMap* DOMEntityImpl::getAttributes() const                   {return fNode.getAttributes (); }
     const XMLCh*           DOMEntityImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMEntityImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMEntityImpl::getNextSibling() const                  {return fNode.getNextSibling (); }
     const XMLCh*           DOMEntityImpl::getNodeValue() const                    {return fNode.getNodeValue (); }
           DOMDocument*     DOMEntityImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; }
     const XMLCh*           DOMEntityImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMEntityImpl::getParentNode() const                   {return fNode.getParentNode (); }
           DOMNode*         DOMEntityImpl::getPreviousSibling() const              {return fNode.getPreviousSibling (); }
           DOMNode*         DOMEntityImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                   {cloneEntityRefTree(); return fParent.insertBefore (newChild, refChild); }
           void             DOMEntityImpl::normalize()                             {cloneEntityRefTree(); fParent.normalize (); }
           DOMNode*         DOMEntityImpl::removeChild(DOMNode *oldChild)          {cloneEntityRefTree(); return fParent.removeChild (oldChild); }
           DOMNode*         DOMEntityImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                   {cloneEntityRefTree(); return fParent.replaceChild (newChild, oldChild); }
           bool             DOMEntityImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                   {return fNode.isSupported (feature, version); }
           void             DOMEntityImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMEntityImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMEntityImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMEntityImpl::isEqualNode(const DOMNode* arg) const   {cloneEntityRefTree(); return fParent.isEqualNode(arg); }
           void*            DOMEntityImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                   {return fNode.setUserData(key, data, handler); }
           void*            DOMEntityImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           short            DOMEntityImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMEntityImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMEntityImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMEntityImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMEntityImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMEntityImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMEntityImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }


//Introduced in DOM Level 3
const XMLCh* DOMEntityImpl::getActualEncoding() const {
    return fActualEncoding;
}

void DOMEntityImpl::setActualEncoding(const XMLCh* actualEncoding){
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    fActualEncoding = doc->cloneString(actualEncoding);
}

const XMLCh* DOMEntityImpl::getEncoding() const {
    return fEncoding;
}

void DOMEntityImpl::setEncoding(const XMLCh* encoding){
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    fEncoding = doc->cloneString(encoding);
}

const XMLCh* DOMEntityImpl::getVersion() const {
    return fVersion;
}

void DOMEntityImpl::setVersion(const XMLCh* version){
    DOMDocumentImpl *doc = (DOMDocumentImpl *)this->getOwnerDocument();
    fVersion = doc->cloneString(version);
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMDocumentTypeImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMDocumentTypeImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMDocumentTypeImpl.hpp"
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>

#include "DOMNamedNodeMapImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  Local static data
// ---------------------------------------------------------------------------

static DOMDocument*       sDocument = 0;
static XMLRegisterCleanup documentCleanup;

static void reinitDocument()
{
    if (sDocument) {
        sDocument->release();
        sDocument = 0;
    }
}

static DOMDocument& gDocTypeDocument()
{
    if (!sDocument)
    {
        static const XMLCh gCoreStr[] = { chLatin_C, chLatin_o, chLatin_r, chLatin_e, chNull };
        DOMImplementation* impl =  DOMImplementationRegistry::getDOMImplementation(gCoreStr);
        DOMDocument* tmpDoc = impl->createDocument();                   // document type object (DTD).

        if (XMLPlatformUtils::compareAndSwap((void**)&sDocument, tmpDoc, 0))
        {
            // Someone beat us to it, so let's clean up ours
            delete tmpDoc;
        }
        else
        {
            documentCleanup.registerCleanup(reinitDocument);
        }
    }

    return *sDocument;
}


DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
                                   const XMLCh *dtName,
                                   bool heap)
    : fNode(ownerDoc),
    fParent(ownerDoc),
    fName(0),
    fEntities(0),
    fNotations(0),
    fElements(0),
    fPublicId(0),
    fSystemId(0),
    fInternalSubset(0),
    fIntSubsetReading(false),
    fIsCreatedFromHeap(heap)
{
    if (ownerDoc) {
        fName = ((DOMDocumentImpl *)ownerDoc)->getPooledString(dtName);
        fEntities = new (ownerDoc) DOMNamedNodeMapImpl(this);
        fNotations= new (ownerDoc) DOMNamedNodeMapImpl(this);
        fElements = new (ownerDoc) DOMNamedNodeMapImpl(this);
    }
    else {
        DOMDocument* doc = &gDocTypeDocument();
        fName = ((DOMDocumentImpl *)doc)->getPooledString(dtName);
        fEntities = new (doc) DOMNamedNodeMapImpl(this);
        fNotations= new (doc) DOMNamedNodeMapImpl(this);
        fElements = new (doc) DOMNamedNodeMapImpl(this);
    }
}


//Introduced in DOM Level 2
DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
                                   const XMLCh *qualifiedName,
                                   const XMLCh *pubId,
                                   const XMLCh *sysId,
                                   bool heap)
    : fNode(ownerDoc),
    fParent(ownerDoc),
    fName(0),
    fEntities(0),
    fNotations(0),
    fElements(0),
    fPublicId(0),
    fSystemId(0),
    fInternalSubset(0),    
    fIntSubsetReading(false),        
    fIsCreatedFromHeap(heap)
{
    int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
    if (index < 0)
        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
    else if (index > 0)
    {
        // we have to make sure the qualifiedName has correct prefix and localName
        // although we don't really to store them separately
        XMLCh* newName;
        XMLCh temp[4000];
        if (index >= 3999)
            newName = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate
            (
                (XMLString::stringLen(qualifiedName)+1) * sizeof(XMLCh)
            );//new XMLCh[XMLString::stringLen(qualifiedName)+1];
        else
            newName = temp;

        XMLString::copyNString(newName, qualifiedName, index);
        newName[index] = chNull;

        // Before we carry on, we should check if the prefix or localName are valid XMLName
        if (ownerDoc) {
            if (!((DOMDocumentImpl*)ownerDoc)->isXMLName(newName) || !((DOMDocumentImpl*)ownerDoc)->isXMLName(qualifiedName+index+1))
                throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
        }
        else {
            // document is not there yet, so assume XML 1.0
            if (!XMLChar1_0::isValidName(newName, index) || !XMLChar1_0::isValidName(qualifiedName+index+1, XMLString::stringLen(qualifiedName)-index-1))
                throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
        }

        if (index >= 3999)
            XMLPlatformUtils::fgMemoryManager->deallocate(newName);//delete[] newName;
    }

    if (ownerDoc) {
        DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc;
        fPublicId = docImpl->cloneString(pubId);
        fSystemId = docImpl->cloneString(sysId);
        fName = ((DOMDocumentImpl *)ownerDoc)->getPooledString(qualifiedName);
        fEntities = new (ownerDoc) DOMNamedNodeMapImpl(this);
        fNotations= new (ownerDoc) DOMNamedNodeMapImpl(this);
        fElements = new (ownerDoc) DOMNamedNodeMapImpl(this);
    }
    else {
        DOMDocument* doc = &gDocTypeDocument();
        fPublicId = ((DOMDocumentImpl*) doc)->cloneString(pubId);
        fSystemId = ((DOMDocumentImpl*) doc)->cloneString(sysId);
        fName = ((DOMDocumentImpl*) doc)->getPooledString(qualifiedName);
        fEntities = new (doc) DOMNamedNodeMapImpl(this);
        fNotations= new (doc) DOMNamedNodeMapImpl(this);
        fElements = new (doc) DOMNamedNodeMapImpl(this);
    }
}


DOMDocumentTypeImpl::DOMDocumentTypeImpl(const DOMDocumentTypeImpl &other, bool heap, bool deep)
    : fNode(other.fNode),
    fParent(other.fParent),
    fChild(other.fChild),
    fName(0),
    fEntities(0),
    fNotations(0),
    fElements(0),
    fPublicId(0),
    fSystemId(0),
    fInternalSubset(0),
    fIntSubsetReading(other.fIntSubsetReading),       
    fIsCreatedFromHeap(heap)
{
    fName = other.fName;

    //DOM Level 2
    fPublicId        = other.fPublicId;
    fSystemId        = other.fSystemId;
    fInternalSubset  = other.fInternalSubset;

    if ((DOMDocumentImpl *)this->fNode.getOwnerDocument() && deep)
        fParent.cloneChildren(&other);

    fEntities = other.fEntities->cloneMap(this);
    fNotations= other.fNotations->cloneMap(this);
    fElements = other.fElements->cloneMap(this);
}


DOMDocumentTypeImpl::~DOMDocumentTypeImpl()
{
}


DOMNode *DOMDocumentTypeImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = 0;
    if (castToNodeImpl(this)->getOwnerDocument())
        newNode = new (castToNodeImpl(this)->getOwnerDocument(), DOMDocumentImpl::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(*this, false, deep);
    else
        newNode = new (&gDocTypeDocument(), DOMDocumentImpl::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(*this, false, deep);

    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}

/**
 * NON-DOM
 * set the ownerDocument of this node and its children
 */
void DOMDocumentTypeImpl::setOwnerDocument(DOMDocument *doc) {

    if (castToNodeImpl(this)->getOwnerDocument()) {
        fNode.setOwnerDocument(doc);
        fParent.setOwnerDocument(doc);
    }
    else {
        if (doc) {
            DOMDocumentImpl *docImpl = (DOMDocumentImpl *)doc;

            fPublicId = docImpl->cloneString(fPublicId);
            fSystemId = docImpl->cloneString(fSystemId);
            fInternalSubset = docImpl->cloneString(fInternalSubset);
            fName = docImpl->getPooledString(fName);
            
            fNode.setOwnerDocument(doc);
            fParent.setOwnerDocument(doc);

            DOMNamedNodeMapImpl* entitiesTemp = fEntities->cloneMap(this);
            DOMNamedNodeMapImpl* notationsTemp = fNotations->cloneMap(this);
            DOMNamedNodeMapImpl* elementsTemp = fElements->cloneMap(this);

            fEntities = entitiesTemp;
            fNotations = notationsTemp;
            fElements = elementsTemp;
        }
    }
}

const XMLCh * DOMDocumentTypeImpl::getNodeName() const
{
    return fName;
}


short DOMDocumentTypeImpl::getNodeType()  const {
    return DOMNode::DOCUMENT_TYPE_NODE;
}


DOMNamedNodeMap *DOMDocumentTypeImpl::getEntities() const
{
    return fEntities;
}



const XMLCh * DOMDocumentTypeImpl::getName() const
{
    return fName;
}


DOMNamedNodeMap *DOMDocumentTypeImpl::getNotations() const
{
    return fNotations;
}


DOMNamedNodeMap *DOMDocumentTypeImpl::getElements() const
{
    return fElements;
}


void DOMDocumentTypeImpl::setNodeValue(const XMLCh *val)
{
    fNode.setNodeValue(val);
}


void DOMDocumentTypeImpl::setReadOnly(bool readOnl, bool deep)
{
    fNode.setReadOnly(readOnl,deep);
    if (fEntities)
        fEntities->setReadOnly(readOnl,true);
    if (fNotations)
        fNotations->setReadOnly(readOnl,true);
}


//Introduced in DOM Level 2

const XMLCh * DOMDocumentTypeImpl::getPublicId() const
{
    return fPublicId;
}


const XMLCh * DOMDocumentTypeImpl::getSystemId() const
{
    return fSystemId;
}


const XMLCh * DOMDocumentTypeImpl::getInternalSubset() const
{
    return fInternalSubset;
}

bool DOMDocumentTypeImpl::isIntSubsetReading() const
{
    return fIntSubsetReading;
}


//set functions

void DOMDocumentTypeImpl::setPublicId(const XMLCh *value)
{
    // revist.  Why shouldn't 0 be assigned like any other value?
    if (value == 0)
        return;

    if ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())
        fPublicId = ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())->cloneString(value);
    else {
        fPublicId = ((DOMDocumentImpl *)&gDocTypeDocument())->cloneString(value);
    }
}

void DOMDocumentTypeImpl::setSystemId(const XMLCh *value)
{
    if ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())
        fSystemId = ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())->cloneString(value);
    else {
        fSystemId = ((DOMDocumentImpl *)&gDocTypeDocument())->cloneString(value);
    }
}

void DOMDocumentTypeImpl::setInternalSubset(const XMLCh *value)
{
    if ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())
        fInternalSubset = ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())->cloneString(value);
    else {
        fInternalSubset = ((DOMDocumentImpl *)&gDocTypeDocument())->cloneString(value);
    }
}

void DOMDocumentTypeImpl::release()
{
    if (fNode.isOwned()) {
        if (fNode.isToBeReleased()) {
            // we are calling from documnet.release() which will notify the user data handler
            if (fIsCreatedFromHeap) {
                DOMDocumentType* docType = this;
                delete docType;
            }
        }
        else
            throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
    else {
        if (fIsCreatedFromHeap) {
            fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
            DOMDocumentType* docType = this;
            delete docType;
        }
        else {
            DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
            if (doc) {
                fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
                doc->release(this, DOMDocumentImpl::DOCUMENT_TYPE_OBJECT);
            }
            else {
                // shouldn't reach here
                throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
            }
        }
    }
}


//
// Delegation for functions inherited from Node
//

           DOMNode*         DOMDocumentTypeImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); }
           DOMNamedNodeMap* DOMDocumentTypeImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMDocumentTypeImpl::getChildNodes() const                   {return fParent.getChildNodes (); }
           DOMNode*         DOMDocumentTypeImpl::getFirstChild() const                   {return fParent.getFirstChild (); }
           DOMNode*         DOMDocumentTypeImpl::getLastChild() const                    {return fParent.getLastChild (); }
     const XMLCh*           DOMDocumentTypeImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMDocumentTypeImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMDocumentTypeImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
     const XMLCh*           DOMDocumentTypeImpl::getNodeValue() const                    {return fNode.getNodeValue (); }
           DOMDocument*     DOMDocumentTypeImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; }
     const XMLCh*           DOMDocumentTypeImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMDocumentTypeImpl::getParentNode() const                   {return fChild.getParentNode (this); }
           DOMNode*         DOMDocumentTypeImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
           bool             DOMDocumentTypeImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); }
           DOMNode*         DOMDocumentTypeImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                         {return fParent.insertBefore (newChild, refChild); }
           void             DOMDocumentTypeImpl::normalize()                             {fParent.normalize (); }
           DOMNode*         DOMDocumentTypeImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); }
           DOMNode*         DOMDocumentTypeImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                         {return fParent.replaceChild (newChild, oldChild); }
           bool             DOMDocumentTypeImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                         {return fNode.isSupported (feature, version); }
           void             DOMDocumentTypeImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMDocumentTypeImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMDocumentTypeImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           void*            DOMDocumentTypeImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                         {return fNode.setUserData(key, data, handler); }
           void*            DOMDocumentTypeImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           const XMLCh*     DOMDocumentTypeImpl::getBaseURI() const                      {return fNode.getBaseURI(); }
           short            DOMDocumentTypeImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMDocumentTypeImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMDocumentTypeImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMDocumentTypeImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMDocumentTypeImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMDocumentTypeImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }


bool DOMDocumentTypeImpl::isEqualNode(const DOMNode* arg) const
{
    if (isSameNode(arg)) {
        return true;
    }

    if (!fNode.isEqualNode(arg)) {
        return false;
    }

    DOMDocumentType* argDT = (DOMDocumentType*) arg;
    // check the string values
    if (!getPublicId()) {
        if (argDT->getPublicId()) {
            return false;
        }
    }
    else if (!XMLString::equals(getPublicId(), argDT->getPublicId())) {
        return false;
    }

    if (!getSystemId()) {
        if (argDT->getSystemId()) {
            return false;
        }
    }
    else if (!XMLString::equals(getSystemId(), argDT->getSystemId())) {
        return false;
    }

    if (!getInternalSubset()) {
        if (argDT->getInternalSubset()) {
            return false;
        }
    }
    else if (!XMLString::equals(getInternalSubset(), argDT->getInternalSubset())) {
        return false;
    }

    // check the notations
    if (getNotations()) {
        if (!argDT->getNotations())
            return false;

        DOMNamedNodeMap* map1 = getNotations();
        DOMNamedNodeMap* map2 = argDT->getNotations();

        XMLSize_t len = map1->getLength();
        if (len != map2->getLength()) {
            return false;
        }
        for (XMLSize_t i = 0; i < len; i++) {
            DOMNode* n1 = map1->item(i);
            DOMNode* n2 = map2->getNamedItem(n1->getNodeName());
            if (!n2 || !n1->isEqualNode(n2)) {
                return false;
            }
        }
    }
    else {
        if (argDT->getNotations())
            return false;
    }

    // check the entities
    if (getEntities()) {
        if (!argDT->getEntities())
            return false;

        DOMNamedNodeMap* map1 = getEntities();
        DOMNamedNodeMap* map2 = argDT->getEntities();

        XMLSize_t len = map1->getLength();
        if (len != map2->getLength()) {
            return false;
        }
        for (XMLSize_t i = 0; i < len; i++) {
            DOMNode* n1 = map1->item(i);
            DOMNode* n2 = map2->getNamedItem(n1->getNodeName());
            if (!n2 || !n1->isEqualNode(n2)) {
                return false;
            }
        }
    }
    else {
        if (argDT->getEntities())
            return false;
    }

    return fParent.isEqualNode(arg);
}

DOMNode * DOMDocumentTypeImpl::getInterface(const XMLCh* feature)
{
    if(XMLString::equals(feature, XMLUni::fgXercescInterfaceDOMDocumentTypeImpl))
        return (DOMNode*)(DOMDocumentTypeImpl*)this;
    return fNode.getInterface(feature);
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMElementNSImpl.hpp ---
#ifndef DOMElementNSImpl_HEADER_GUARD_
#define DOMElementNSImpl_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMElementNSImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#include "DOMElementImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN

class DOMTypeInfoImpl;

class CDOM_EXPORT DOMElementNSImpl: public DOMElementImpl {
protected:
    //Introduced in DOM Level 2
    const XMLCh * fNamespaceURI;     //namespace URI of this node
    const XMLCh * fLocalName;        //local part of qualified name
    const XMLCh * fPrefix;

private:
    const DOMTypeInfoImpl *fSchemaType;

public:
    DOMElementNSImpl(DOMDocument *ownerDoc, const XMLCh *name);
    DOMElementNSImpl(DOMDocument *ownerDoc, //DOM Level 2
	const XMLCh *namespaceURI, const XMLCh *qualifiedName);
    DOMElementNSImpl(const DOMElementNSImpl &other, bool deep=false);

    virtual DOMNode * cloneNode(bool deep) const;
    virtual DOMNode * getInterface(const XMLCh* feature);

    //Introduced in DOM Level 2
    virtual const XMLCh *getNamespaceURI() const;
    virtual const XMLCh *getPrefix() const;
    virtual const XMLCh *getLocalName() const;
    virtual void         setPrefix(const XMLCh *prefix);
    virtual void         release();

    //Introduced in DOM Level 3
    virtual const XMLCh *getBaseURI() const;
    virtual const DOMTypeInfo * getTypeInfo() const;

   // helper function for DOM Level 3 renameNode
   virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);
   void setName(const XMLCh* namespaceURI, const XMLCh* name);

    //helper function for DOM Level 3 TypeInfo
    virtual void setTypeInfo(const DOMTypeInfoImpl* typeInfo);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------    
    DOMElementNSImpl & operator = (const DOMElementNSImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMNormalizer.hpp ---
#ifndef DOMNormalizer_HEADER_GUARD_
#define DOMNormalizer_HEADER_GUARD_

/*
 * Copyright 2001-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.
 */


//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/RefHashTableOf.hpp>
#include <xercesc/util/RefVectorOf.hpp>
#include <xercesc/framework/XMLErrorCodes.hpp>


XERCES_CPP_NAMESPACE_BEGIN

class DOMConfigurationImpl;
class DOMErrorHandler;
class DOMDocumentImpl;
class DOMNode;
class DOMElementImpl;
class DOMAttr;
class DOMNamedNodeMap;

class DOMNormalizer : public XMemory {

    //the following are the data structures maintain the stack of namespace information 
    class InScopeNamespaces : public XMemory {
        class Scope : public XMemory {
        public:
            Scope(Scope *baseScopeWithBindings);
            ~Scope();
            void addOrChangeBinding(const XMLCh *prefix, const XMLCh *uri,
                                    MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
            const XMLCh* getUri(const XMLCh *prefix) const;
            const XMLCh* getPrefix(const XMLCh* uri) const;
            Scope *fBaseScopeWithBindings;

        private:
            RefHashTableOf<XMLCh> *fPrefixHash;
            RefHashTableOf<XMLCh> *fUriHash;
            // unimplemented
            Scope ( const Scope& toCopy);
            Scope& operator= (const Scope& other);
        };

    public:    
        InScopeNamespaces(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
        ~InScopeNamespaces();
        void addOrChangeBinding(const XMLCh *prefix, const XMLCh *uri,
                                MemoryManager* const manager  = XMLPlatformUtils::fgMemoryManager);
        void addScope(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
        void removeScope();
        bool isValidBinding(const XMLCh* prefix, const XMLCh* uri) const;
        const XMLCh* getOrDeclarePrefix(const XMLCh* uri);
        const XMLCh* getPrefix(const XMLCh* uri) const;
        const XMLCh* getUri(const XMLCh* prefix) const;
        int size();

    private:
        RefVectorOf<Scope> *fScopes;
        Scope *lastScopeWithBindings;
        // unimplemented
        InScopeNamespaces ( const InScopeNamespaces& toCopy);
        InScopeNamespaces& operator= (const InScopeNamespaces& other);
    };

public:
    DOMNormalizer(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    ~DOMNormalizer();

    /**
     * Main entry method to normalize a document
     */
    void normalizeDocument(DOMDocumentImpl *doc);

    // -----------------------------------------------------------------------
    //  Notification that lazy data has been deleted
    // -----------------------------------------------------------------------
	static void reinitNormalizerMutex();
	static void reinitMsgLoader();

private:
    // unimplemented
    DOMNormalizer ( const DOMNormalizer& toCopy);
    DOMNormalizer& operator= (const DOMNormalizer& other);

    /**
     * Recursively normalizes a node
     */
    DOMNode * normalizeNode(DOMNode *node) const;

    /**
     * Helper method that fixes up the namespace declarations according to the
     * DOM Level 3 psydocode
     */
    void namespaceFixUp(DOMElementImpl *ele) const;

    /**
     * Converts an integer to an XMLCh - max 15 digits long. 
     */
    const XMLCh * integerToXMLCh(unsigned int i) const;

    /**
     * Adds a namespace attribute or replaces the value of existing namespace
     * attribute with the given prefix and value for URI.
     * In case prefix is empty will add/update default namespace declaration.
     */
    void addOrChangeNamespaceDecl(const XMLCh* prefix, const XMLCh* uri, DOMElementImpl *element) const;
    
    /**
     * Adds a custom namespace in the form "NSx" where x is an integer that 
     * has not yet used in the document
     */
    const XMLCh* addCustomNamespaceDecl(const XMLCh* uri, DOMElementImpl *element) const;


    /**
     * Report an error 
     */
    void error(const XMLErrs::Codes code, const DOMNode *node) const;

    //
    // fDocument - the document we are operating on
    //
    // fDOMConfiguration - the configuration from the document
    //
    // fErrorHandler - the errorhandler to be used when reporting errors during normalization
    //
    // fNSScope - the data stucture that holds the prefix-uri information
    //
    // fNewNamespaceCount - the number of custom namespace declarations we have created
    //
    DOMDocumentImpl *fDocument;
    DOMConfigurationImpl *fConfiguration;
    DOMErrorHandler *fErrorHandler;
    InScopeNamespaces *fNSScope;
    unsigned int fNewNamespaceCount;
    MemoryManager* fMemoryManager;
};



XERCES_CPP_NAMESPACE_END

#endif

--- NEW FILE: DOMProcessingInstructionImpl.hpp ---
#ifndef DOMProcessingInstructionImpl_HEADER_GUARD_
#define DOMProcessingInstructionImpl_HEADER_GUARD_
/*
 * 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.
 */

/*
 * $Id: DOMProcessingInstructionImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMProcessingInstruction.hpp>
#include "DOMCharacterDataImpl.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMChildNode.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class    DocumentImpl;


class CDOM_EXPORT DOMProcessingInstructionImpl: public DOMProcessingInstruction {
private:
    DOMNodeImpl   fNode;
    DOMChildNode  fChild;
    // use fCharacterData to store its data so that those character utitlites can be used
    DOMCharacterDataImpl   fCharacterData;

    XMLCh       *fTarget;
    const XMLCh *fBaseURI;

public:
    DOMProcessingInstructionImpl(DOMDocument *ownerDoc,
                              const XMLCh * target,
                              const XMLCh *data);
    DOMProcessingInstructionImpl(const DOMProcessingInstructionImpl &other,
                              bool deep=false);
    virtual ~DOMProcessingInstructionImpl();

    // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;

    virtual const XMLCh *getData() const;
    virtual const XMLCh *getTarget() const;
    virtual void setData(const XMLCh *arg);

    // NON-DOM: set base uri
    virtual void setBaseURI(const XMLCh* baseURI);

    // Non standard extension for the range to work
    void         deleteData(XMLSize_t offset, XMLSize_t count);
    const XMLCh* substringData(XMLSize_t offset, XMLSize_t count) const;
    DOMProcessingInstruction* splitText(XMLSize_t offset);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMProcessingInstructionImpl & operator = (const DOMProcessingInstructionImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMCommentImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMCommentImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMCommentImpl.hpp"
#include "DOMCharacterDataImpl.hpp"
#include "DOMStringPool.hpp"
#include "DOMCasts.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMRangeImpl.hpp"
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

DOMCommentImpl::DOMCommentImpl(DOMDocument *ownerDoc, const XMLCh *dat)
    : fNode(ownerDoc),  fCharacterData(ownerDoc, dat)
{
    fNode.setIsLeafNode(true);
}


DOMCommentImpl::DOMCommentImpl(const DOMCommentImpl &other, bool)

    : fNode(other.fNode),
    fChild(other.fChild),
    fCharacterData(other.fCharacterData)
{
    fNode.setIsLeafNode(true);
}


DOMCommentImpl::~DOMCommentImpl() {
}



DOMNode * DOMCommentImpl::cloneNode(bool deep) const
{
    DOMNode* newNode = new (getOwnerDocument(), DOMDocumentImpl::COMMENT_OBJECT) DOMCommentImpl(*this, deep);
    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
    return newNode;
}


const XMLCh * DOMCommentImpl::getNodeName() const {
    static const XMLCh gComment[] =
        {chPound, chLatin_c, chLatin_o, chLatin_m, chLatin_m, chLatin_e,chLatin_n, chLatin_t, 0};
    return gComment;
}

short DOMCommentImpl::getNodeType() const {
    return DOMNode::COMMENT_NODE;
}

void DOMCommentImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);

    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fCharacterData.releaseBuffer();
        doc->release(this, DOMDocumentImpl::COMMENT_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}


// Non standard extension for the range to work
DOMComment *DOMCommentImpl::splitText(XMLSize_t offset)
{
    if (fNode.isReadOnly())
    {
        throw DOMException(
            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
    }
    XMLSize_t len = fCharacterData.fDataBuf->getLen();
    if (offset > len)
        throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMNodeMemoryManager);

    DOMComment *newText =
                getOwnerDocument()->createComment(
                        this->substringData(offset, len - offset));

    DOMNode *parent = getParentNode();
    if (parent != 0)
        parent->insertBefore(newText, getNextSibling());

    fCharacterData.fDataBuf->chop(offset);

    if (this->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateSplitInfo( this, newText, offset);
                }
            }
        }
    }

    return newText;
}


           DOMNode*         DOMCommentImpl::appendChild(DOMNode *newChild)          {return fNode.appendChild (newChild); }
           DOMNamedNodeMap* DOMCommentImpl::getAttributes() const                   {return fNode.getAttributes (); }
           DOMNodeList*     DOMCommentImpl::getChildNodes() const                   {return fNode.getChildNodes (); }
           DOMNode*         DOMCommentImpl::getFirstChild() const                   {return fNode.getFirstChild (); }
           DOMNode*         DOMCommentImpl::getLastChild() const                    {return fNode.getLastChild (); }
     const XMLCh*           DOMCommentImpl::getLocalName() const                    {return fNode.getLocalName (); }
     const XMLCh*           DOMCommentImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
           DOMNode*         DOMCommentImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
     const XMLCh*           DOMCommentImpl::getNodeValue() const                    {return fCharacterData.getNodeValue (); }
           DOMDocument*     DOMCommentImpl::getOwnerDocument() const                {return fNode.getOwnerDocument (); }
     const XMLCh*           DOMCommentImpl::getPrefix() const                       {return fNode.getPrefix (); }
           DOMNode*         DOMCommentImpl::getParentNode() const                   {return fChild.getParentNode (this); }
           DOMNode*         DOMCommentImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
           bool             DOMCommentImpl::hasChildNodes() const                   {return fNode.hasChildNodes (); }
           DOMNode*         DOMCommentImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
                                                                                    {return fNode.insertBefore (newChild, refChild); }
           void             DOMCommentImpl::normalize()                             {fNode.normalize (); }
           DOMNode*         DOMCommentImpl::removeChild(DOMNode *oldChild)          {return fNode.removeChild (oldChild); }
           DOMNode*         DOMCommentImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
                                                                                    {return fNode.replaceChild (newChild, oldChild); }
           bool             DOMCommentImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                    {return fNode.isSupported (feature, version); }
           void             DOMCommentImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
           bool             DOMCommentImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
           bool             DOMCommentImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
           bool             DOMCommentImpl::isEqualNode(const DOMNode* arg) const   {return fNode.isEqualNode(arg); }
           void*            DOMCommentImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                    {return fNode.setUserData(key, data, handler); }
           void*            DOMCommentImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
           const XMLCh*     DOMCommentImpl::getBaseURI() const                      {return fNode.getBaseURI(); }
           short            DOMCommentImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); }
           const XMLCh*     DOMCommentImpl::getTextContent() const                  {return fNode.getTextContent(); }
           void             DOMCommentImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
           const XMLCh*     DOMCommentImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); }
           bool             DOMCommentImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
           const XMLCh*     DOMCommentImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
           DOMNode*         DOMCommentImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); }



//
//   Delegation of CharacerData functions.
//


           const XMLCh*     DOMCommentImpl::getData() const                         {return fCharacterData.getData();}
           XMLSize_t        DOMCommentImpl::getLength() const                       {return fCharacterData.getLength();}
           const XMLCh*     DOMCommentImpl::substringData(XMLSize_t offset, XMLSize_t count) const
                                                                                    {return fCharacterData.substringData(this, offset, count);}
           void             DOMCommentImpl::appendData(const XMLCh *arg)            {fCharacterData.appendData(this, arg);}
           void             DOMCommentImpl::insertData(XMLSize_t offset, const  XMLCh *arg)
                                                                                    {fCharacterData.insertData(this, offset, arg);}
           void             DOMCommentImpl::deleteData(XMLSize_t offset, XMLSize_t count)
                                                                                    {fCharacterData.deleteData(this, offset, count);}
           void             DOMCommentImpl::replaceData(XMLSize_t offset, XMLSize_t count, const XMLCh *arg)
                                                                                    {fCharacterData.replaceData(this, offset, count, arg);}
           void             DOMCommentImpl::setData(const XMLCh *data)              {fCharacterData.setData(this, data);}
           void             DOMCommentImpl::setNodeValue(const XMLCh  *nodeValue)   {fCharacterData.setNodeValue (this, nodeValue); }

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMTreeWalkerImpl.cpp ---
/*
 * 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.
 */

/*
 * $Id: DOMTreeWalkerImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

#include "DOMTreeWalkerImpl.hpp"
#include "DOMDocumentImpl.hpp"

#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

/** constructor */
DOMTreeWalkerImpl::DOMTreeWalkerImpl (
                                DOMNode* root,
                                unsigned long whatToShow,
                                DOMNodeFilter* nodeFilter,
                                bool expandEntityRef)
:   fWhatToShow(whatToShow),
    fNodeFilter(nodeFilter),    
    fCurrentNode(root),
    fRoot(root),    
    fExpandEntityReferences(expandEntityRef)
{
}


DOMTreeWalkerImpl::DOMTreeWalkerImpl (const DOMTreeWalkerImpl& twi)
:   DOMTreeWalker(twi),
    fWhatToShow(twi.fWhatToShow),
    fNodeFilter(twi.fNodeFilter),
    fCurrentNode(twi.fCurrentNode),
    fRoot(twi.fRoot),    
    fExpandEntityReferences(twi.fExpandEntityReferences)
{
}


DOMTreeWalkerImpl& DOMTreeWalkerImpl::operator= (const DOMTreeWalkerImpl& twi) {
    if (this != &twi)
    {
        fCurrentNode            = twi.fCurrentNode;
        fRoot                   = twi.fRoot;
        fWhatToShow             = twi.fWhatToShow;
        fNodeFilter             = twi.fNodeFilter;
		fExpandEntityReferences = twi.fExpandEntityReferences;
    }

    return *this;
}



/** Return the root node */
DOMNode* DOMTreeWalkerImpl::getRoot () {
    return fRoot;
}


/** Return the whatToShow value */
unsigned long DOMTreeWalkerImpl::getWhatToShow () {
    return fWhatToShow;
}


/** Return the NodeFilter */
DOMNodeFilter* DOMTreeWalkerImpl::getFilter () {
    return fNodeFilter;
}

/** Get the expandEntity reference flag. */
bool DOMTreeWalkerImpl::getExpandEntityReferences() {
    return fExpandEntityReferences;
}



/** Return the current Node. */
DOMNode* DOMTreeWalkerImpl::getCurrentNode () {

    return fCurrentNode;
}


/** Return the current Node. */
void DOMTreeWalkerImpl::setCurrentNode (DOMNode* node) {

    if (!node)
        throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMTreeWalkerMemoryManager);

    fCurrentNode = node;
}


/** Return the parent Node from the current node,
 *  after applying filter, whatToshow.
 *  If result is not null, set the current Node.
 */
DOMNode* DOMTreeWalkerImpl::parentNode () {

    if (!fCurrentNode) return 0;

    DOMNode* node = getParentNode(fCurrentNode);
    if (node != 0) {
        fCurrentNode = node;
    }
    return node;

}


/** Return the first child Node from the current node,
 *  after applying filter, whatToshow.
 *  If result is not null, set the current Node.
 */
DOMNode* DOMTreeWalkerImpl::firstChild () {

    if (!fCurrentNode) return 0;

    if(!fExpandEntityReferences && fCurrentNode->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
        return 0;

    DOMNode* node = getFirstChild(fCurrentNode);

    if (node != 0) {
        fCurrentNode = node;
    }
    return node;
}


/** Return the last child Node from the current node,
 *  after applying filter, whatToshow.
 *  If result is not null, set the current Node.
 */
DOMNode* DOMTreeWalkerImpl::lastChild () {

    if (!fCurrentNode) return 0;

    if(!fExpandEntityReferences && fCurrentNode->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
        return 0;

    DOMNode* node = getLastChild(fCurrentNode);
    if (node != 0) {
        fCurrentNode = node;
    }
    return node;
}


/** Return the previous sibling Node from the current node,
 *  after applying filter, whatToshow.
 *  If result is not null, set the current Node.
 */

DOMNode* DOMTreeWalkerImpl::previousSibling () {
	
    if (!fCurrentNode) return 0;

    DOMNode* node = getPreviousSibling(fCurrentNode);
    if (node != 0) {
        fCurrentNode = node;
    }
    return node;
}


/** Return the next sibling Node from the current node,
 *  after applying filter, whatToshow.
 *  If result is not null, set the current Node.
 */

DOMNode* DOMTreeWalkerImpl::nextSibling () {
		
    if (!fCurrentNode) return 0;

    DOMNode* node = getNextSibling(fCurrentNode);
    if (node != 0) {
        fCurrentNode = node;
    }
    return node;
}


/** Return the previous Node from the current node,
 *  after applying filter, whatToshow.
 *  If result is not null, set the current Node.
 */

DOMNode* DOMTreeWalkerImpl::previousNode () {
	
    if (!fCurrentNode) return 0;

    // get sibling
    DOMNode* node = getPreviousSibling(fCurrentNode);
    if (node == 0) {
        node = getParentNode(fCurrentNode);
        if ( node != 0) {
            fCurrentNode = node;
        }
        return node;
    }
    else {

        // get the lastChild of result.
        DOMNode* lastChild  = getLastChild(node);

        // if there is a lastChild which passes filters return it.
        if (lastChild != 0) {
            fCurrentNode = lastChild;
        }
        else {
            fCurrentNode = node;
        }
        return fCurrentNode;
    }
}


/** Return the next Node from the current node,
 *  after applying filter, whatToshow.
 *  If result is not null, set the current Node.
 */

DOMNode* DOMTreeWalkerImpl::nextNode () {
	
    if (!fCurrentNode) return 0;

    DOMNode* node = getFirstChild(fCurrentNode);

    if (node != 0) {
        fCurrentNode = node;
        return node;
    }
    else {

        node = getNextSibling(fCurrentNode);

        if (node != 0) {
            fCurrentNode = node;
            return node;
        }
        else {

            // return parent's 1st sibling.
            DOMNode* parent = getParentNode(fCurrentNode);
            while ( parent != 0) {
                node = getNextSibling(parent);
                if (node != 0) {
                    fCurrentNode = node;
                    return node;
                } else {
                    parent = getParentNode(parent);
                }
            }
            return node;
        }
    }
}


/** Internal function.
 *  Return the parent Node, from the input node
 *  after applying filter, whatToshow.
 *  The current node is not consulted or set.
 */

DOMNode* DOMTreeWalkerImpl::getParentNode (DOMNode* node) {
	
    if (!node || node == fRoot) return 0;

    DOMNode* newNode = node->getParentNode();
    if (!newNode)  return 0;

    short accept = acceptNode(newNode);

    if (accept == DOMNodeFilter::FILTER_ACCEPT)
        return newNode;

    return getParentNode(newNode);

}


/** Internal function.
 *  Return the nextSibling Node, from the input node
 *  after applying filter, whatToshow.
 *  The current node is not consulted or set.
 */

DOMNode* DOMTreeWalkerImpl::getNextSibling (DOMNode* node) {
	
    if (!node || node == fRoot) return 0;

    DOMNode* newNode = node->getNextSibling();
    if (!newNode) {

        newNode = node->getParentNode();

        if (!newNode || node == fRoot)  return 0;

        short parentAccept = acceptNode(newNode);

        if (parentAccept == DOMNodeFilter::FILTER_SKIP) {
            return getNextSibling(newNode);
        }

        return 0;
    }

    short accept = acceptNode(newNode);

    if (accept == DOMNodeFilter::FILTER_ACCEPT)
        return newNode;
    else
    if (accept == DOMNodeFilter::FILTER_SKIP) {
        DOMNode* fChild =  getFirstChild(newNode);
        if (!fChild && !newNode->hasChildNodes()) {
            return getNextSibling(newNode);
        }
        return fChild;
    }
    return getNextSibling(newNode);

}


/** Internal function.
 *  Return the previous sibling Node, from the input node
 *  after applying filter, whatToshow.
 *  The current node is not consulted or set.
 */

DOMNode* DOMTreeWalkerImpl::getPreviousSibling (DOMNode* node) {
		
    if (!node || node == fRoot) return 0;

    DOMNode* newNode = node->getPreviousSibling();
    if (!newNode) {

        newNode = node->getParentNode();
        if (!newNode || node == fRoot)  return 0;

        short parentAccept = acceptNode(newNode);

        if (parentAccept == DOMNodeFilter::FILTER_SKIP) {
            return getPreviousSibling(newNode);
        }

        return 0;
    }

    short accept = acceptNode(newNode);

    if (accept == DOMNodeFilter::FILTER_ACCEPT)
        return newNode;
    else
    if (accept == DOMNodeFilter::FILTER_SKIP) {
        DOMNode* fChild =  getLastChild(newNode);
        if (!fChild && !newNode->hasChildNodes()) {
            return getPreviousSibling(newNode);
        }
        return fChild;
    }
    return getPreviousSibling(newNode);

}


/** Internal function.
 *  Return the first child Node, from the input node
 *  after applying filter, whatToshow.
 *  The current node is not consulted or set.
 */

DOMNode* DOMTreeWalkerImpl::getFirstChild (DOMNode* node) {
		
    if (!node) return 0;

    if(!fExpandEntityReferences && node->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
        return 0;

    DOMNode* newNode = node->getFirstChild();
    if (!newNode)  return 0;

    short accept = acceptNode(newNode);

    if (accept == DOMNodeFilter::FILTER_ACCEPT)
        return newNode;
    else
    if (accept == DOMNodeFilter::FILTER_SKIP
        && newNode->hasChildNodes())
    {
        return getFirstChild(newNode);
    }
    return getNextSibling(newNode);

}


/** Internal function.
 *  Return the last child Node, from the input node
 *  after applying filter, whatToshow.
 *  The current node is not consulted or set.
 */

DOMNode* DOMTreeWalkerImpl::getLastChild (DOMNode* node) {
	
    if (!node) return 0;

    if(!fExpandEntityReferences && node->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
        return 0;

    DOMNode* newNode = node->getLastChild();
    if (!newNode)  return 0;

    short accept = acceptNode(newNode);

    if (accept == DOMNodeFilter::FILTER_ACCEPT)
        return newNode;
    else
    if (accept == DOMNodeFilter::FILTER_SKIP
        && newNode->hasChildNodes())
    {
        return getLastChild(newNode);
    }
    return getPreviousSibling(newNode);

}


/** The node is accepted if it passes the whatToShow and the filter. */

short DOMTreeWalkerImpl::acceptNode (DOMNode* node) {
	
    if (fNodeFilter == 0) {
        if ( ( fWhatToShow & (1 << (node->getNodeType() - 1))) != 0)
        {
            return DOMNodeFilter::FILTER_ACCEPT;
        }
        else
        {
            return DOMNodeFilter::FILTER_SKIP;
        }
    } else {
        // REVISIT: This logic is unclear from the spec!
        if ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0 ) {
            return fNodeFilter->acceptNode(node);
        } else {
            // what to show has failed!
            if (fNodeFilter->acceptNode(node) == DOMNodeFilter::FILTER_REJECT) {
                return DOMNodeFilter::FILTER_REJECT;
            } else {
                return DOMNodeFilter::FILTER_SKIP;
            }
        }
    }
}


void DOMTreeWalkerImpl::release()
{
    // for performance reason, do not recycle pointer
    // chance that this is allocated again and again is not usual
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMCDATASectionImpl.hpp ---
#ifndef DOMCDATASectionImpl_HEADER_GUARD_
#define DOMCDATASectionImpl_HEADER_GUARD_
/*
 * 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.
 */

/*
 * $Id: DOMCDATASectionImpl.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//


#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMCDATASection.hpp>
#include "DOMNodeImpl.hpp"
#include "DOMChildNode.hpp"
#include "DOMParentNode.hpp"
#include "DOMCharacterDataImpl.hpp"

XERCES_CPP_NAMESPACE_BEGIN


class CDOM_EXPORT DOMCDATASectionImpl: public DOMCDATASection {
private:
    DOMNodeImpl           fNode;
    DOMParentNode         fParent;
    DOMChildNode          fChild;
    DOMCharacterDataImpl  fCharacterData;


public:
    DOMCDATASectionImpl(DOMDocument *ownerDoc, const XMLCh * data);
    DOMCDATASectionImpl(const DOMCDATASectionImpl &other, bool deep = false);

    virtual             ~DOMCDATASectionImpl();

    // Functions inherited from TEXT
    virtual DOMText*     splitText(XMLSize_t offset);
    // DOM Level 3
    virtual bool            getIsWhitespaceInElementContent() const;
    virtual const XMLCh*    getWholeText();
    virtual DOMText*        replaceWholeText(const XMLCh* content);

    // non-standard extension
    virtual bool         isIgnorableWhitespace() const;


    // Declare all of the functions from DOMNode.
    DOMNODE_FUNCTIONS;


    // Functions introduced by DOMCharacterData
    virtual const XMLCh* getData() const;
    virtual XMLSize_t    getLength() const;
    virtual const XMLCh* substringData(XMLSize_t offset,
                                       XMLSize_t count) const;
    virtual void         appendData(const XMLCh *arg);
    virtual void         insertData(XMLSize_t offset, const  XMLCh *arg);
    virtual void         deleteData(XMLSize_t offset,
                                    XMLSize_t count);
    virtual void         replaceData(XMLSize_t offset,
                                     XMLSize_t count,
                                     const XMLCh *arg);
    virtual void         setData(const XMLCh *data);

private:
    // -----------------------------------------------------------------------
    // Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    DOMCDATASectionImpl & operator = (const DOMCDATASectionImpl &);
};

XERCES_CPP_NAMESPACE_END

#endif


--- NEW FILE: DOMNodeImpl.cpp ---
/*
 * Copyright 2001-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.
 */

/*
 * $Id: DOMNodeImpl.cpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */
[...1080 lines suppressed...]
    }

    }
}

DOMNode*         DOMNodeImpl::getInterface(const XMLCh*)      {
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMNodeMemoryManager);
    return 0;
}


// non-standard extension
void DOMNodeImpl::release()
{
    // shouldn't reach here
    throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
}

XERCES_CPP_NAMESPACE_END


--- NEW FILE: DOMNodeIDMap.hpp ---
#ifndef DOMNodeIDMap_HEADER_GUARD_
#define DOMNodeIDMap_HEADER_GUARD_

/*
 * 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.
 */

/*
 * $Id: DOMNodeIDMap.hpp,v 1.1 2008/02/19 20:16:27 zolmol Exp $
 */

//
//  This file is part of the internal implementation of the C++ XML DOM.
//  It should NOT be included or used directly by application programs.
//
//  Applications should include the file <xercesc/dom/DOM.hpp> for the entire
//  DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
//  name is substituded for the *.
//

#include <xercesc/util/XercesDefs.hpp>
XERCES_CPP_NAMESPACE_BEGIN


//
//  Class DOMNodeIDMap is a hash table that is used in the implementation of
//   of DOM_Document::getElementsByID().
//
//  Why Yet Another HashTable implementation?  Becuase it can be significantly
//  smaller when tuned for this exact usage, and the generic RefHashTableOf
//  from the xerces utils project is not a paricularly good fit.
//
class DOMAttr;
class DOMDocument;


class DOMNodeIDMap {
public:

    DOMNodeIDMap(int initialSize, DOMDocument *doc);    // Create a new hash table, sized to hold "initialSize"
                                     //  Entries.  It will automatically grow if need be.

    virtual ~DOMNodeIDMap();

private:
    DOMNodeIDMap(const DOMNodeIDMap &other);   // No copy, assignement, comparison.
    DOMNodeIDMap &operator = (const DOMNodeIDMap &other);
    bool operator == (const DOMNodeIDMap &other);

public:
    void  add(DOMAttr *attr);       // Add the specified attribute to the table.
    void  remove(DOMAttr *other);   // Remove the specified attribute.
                                           //   Does nothing if the node is not in the table.
    DOMAttr *find(const XMLCh *ID);   // Find the attribute node in the table with this ID

private:
    void growTable();

private:
    DOMAttr      **fTable;
    XMLSize_t  fSizeIndex;              // Index of the current table size in the
                                           //   array of possible table sizes.
	XMLSize_t  fSize;                   // The current size of the table array
                                           //   (number of slots, not bytes.)
    XMLSize_t  fNumEntries;             // The number of entries used.
    XMLSize_t  fMaxEntries;             // The max number of entries to use before
                                           //   growing the table.
    DOMDocument *fDoc;                    // The owning document.


};

XERCES_CPP_NAMESPACE_END

#endif



More information about the GME-commit mailing list