IDDocumentImpl.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:31k
源码类别:
xml/soap/webservice
开发平台:
C/C++
- /*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 2001, International
- * Business Machines, Inc., http://www.ibm.com . For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- /*
- * $Id: IDDocumentImpl.cpp,v 1.13 2001/12/07 01:37:24 tng Exp $
- */
- #include <util/XMLUniDefs.hpp>
- #include "IDOM_Document.hpp"
- #include "IDDocumentImpl.hpp"
- #include "IDOM_DocumentType.hpp"
- #include "IDOM_DOMException.hpp"
- #include "IDOM_DOMImplementation.hpp"
- #include "IDOM_NamedNodeMap.hpp"
- #include "IDOM_Node.hpp"
- #include "IDCasts.hpp"
- #include "IDDocumentTypeImpl.hpp"
- #include "IDAttrImpl.hpp"
- #include "IDAttrNSImpl.hpp"
- #include "IDCDATASectionImpl.hpp"
- #include "IDCommentImpl.hpp"
- #include "IDDeepNodeListImpl.hpp"
- #include "IDDocumentFragmentImpl.hpp"
- #include "IDElementImpl.hpp"
- #include "IDElementNSImpl.hpp"
- #include "IDEntityImpl.hpp"
- #include "IDEntityReferenceImpl.hpp"
- #include "IDNamedNodeMapImpl.hpp"
- #include "IDNotationImpl.hpp"
- #include "IDProcessingInstructionImpl.hpp"
- #include "IDTextImpl.hpp"
- #include "IDStringPool.hpp"
- #include "IDTreeWalkerImpl.hpp"
- #include "IDNodeIteratorImpl.hpp"
- #include "IDNodeIDMap.hpp"
- #include "IDRangeImpl.hpp"
- #include <internal/XMLReader.hpp>
- #include <util/HashPtr.hpp>
- //idom_revisit. These can go away once all of the include files above are really there.
- class IDOM_TreeWalker;
- class IDOM_NodeFilter;
- //
- // Constructors. Warning - be very careful with the ordering of initialization
- // of the heap. Ordering depends on the order of declaration
- // in the .hpp file, not on the order of initializers here
- // in the constructor. The heap declaration can not be
- // first - fNode and fParent must be first for the casting
- // functions in IDCasts to work correctly. This means that
- // fNode and fParent constructors used here can not
- // allocate.
- //
- IDDocumentImpl::IDDocumentImpl()
- : fNode(this),
- fParent(this),
- fCurrentBlock(0),
- fFreePtr(0),
- fFreeBytesRemaining(0),
- fDocType(0),
- fDocElement(0),
- fNamePool(0),
- fIterators(0L),
- fTreeWalkers(0L),
- fNodeIDMap(0),
- fUserData(0),
- fRanges(0),
- fChanges(0),
- fNodeListPool(0)
- {
- fNamePool = new (this) IDStringPool(257, this);
- };
- //DOM Level 2
- IDDocumentImpl::IDDocumentImpl(const XMLCh *fNamespaceURI,
- const XMLCh *qualifiedName,
- IDOM_DocumentType *doctype)
- : fNode(this),
- fParent(this),
- fCurrentBlock(0),
- fFreePtr(0),
- fFreeBytesRemaining(0),
- fDocType(0),
- fDocElement(0),
- fNamePool(0),
- fIterators(0L),
- fTreeWalkers(0L),
- fNodeIDMap(0),
- fUserData(0),
- fRanges(0),
- fChanges(0),
- fNodeListPool(0)
- {
- fNamePool = new (this) IDStringPool(257, this);
- setDocumentType(doctype);
- appendChild(createElementNS(fNamespaceURI, qualifiedName)); //root element
- }
- void IDDocumentImpl::setDocumentType(IDOM_DocumentType *doctype)
- {
- if (!doctype)
- return;
- // New doctypes can be created either with the factory methods on DOMImplementation, in
- // which case ownerDocument will be 0, or with methods on DocumentImpl, in which case
- // ownerDocument will be set, but the DocType won't yet be a child of the document.
- if (doctype->getOwnerDocument() != 0 && doctype->getOwnerDocument() != this)
- throw IDOM_DOMException( //one doctype can belong to only one IDDocumentImpl
- IDOM_DOMException::WRONG_DOCUMENT_ERR, 0);
- IDDocumentTypeImpl* doctypeImpl = (IDDocumentTypeImpl*) doctype;
- doctypeImpl->setOwnerDocument(this);
- // The doctype can not have any Entities or Notations yet, because they can not
- // be created except through factory methods on a document.
- // idom_revisit. What if this doctype is already a child of the document?
- appendChild(doctype);
- }
- IDDocumentImpl::~IDDocumentImpl()
- {
- // Delete the heap for this document. This uncerimoniously yanks the storage
- // out from under all of the nodes in the document. Destructors are NOT called.
- this->deleteHeap();
- };
- IDOM_Node *IDDocumentImpl::cloneNode(bool deep) const {
- // clone the node itself
- // idom_revisit -- this doesn't look right. What about entities, doctype?
- // Note: the cloned document node goes on the system heap. All other
- // nodes added to the new document will go on that document's heap,
- // but we need to construct the document first, before its heap exists.
- IDDocumentImpl *newdoc = new IDDocumentImpl();
- // then the children by _importing_ them
- if (deep)
- for (IDOM_Node *n = this->getFirstChild(); n != 0; n = n->getNextSibling()) {
- newdoc->appendChild(newdoc->importNode(n, true));
- }
- return newdoc;
- };
- const XMLCh * IDDocumentImpl::getNodeName() const {
- static const XMLCh nam[] = // "#document"
- {chPound, chLatin_d, chLatin_o, chLatin_c, chLatin_u, chLatin_m, chLatin_e, chLatin_n, chLatin_t, 0};
- return nam;
- }
- short IDDocumentImpl::getNodeType() const {
- return IDOM_Node::DOCUMENT_NODE;
- };
- // even though ownerDocument refers to this in this implementation
- // the DOM Level 2 spec says it must be 0, so make it appear so
- IDOM_Document * IDDocumentImpl::getOwnerDocument() const {
- return 0;
- }
- IDOM_Attr *IDDocumentImpl::createAttribute(const XMLCh *nam)
- {
- if(!isXMLName(nam))
- throw IDOM_DOMException(IDOM_DOMException::INVALID_CHARACTER_ERR,0);
- return new (this) IDAttrImpl(this,nam);
- };
- IDOM_CDATASection *IDDocumentImpl::createCDATASection(const XMLCh *data) {
- return new (this) IDCDATASectionImpl(this,data);
- };
- IDOM_Comment *IDDocumentImpl::createComment(const XMLCh *data)
- {
- return new (this) IDCommentImpl(this, data);
- };
- IDOM_DocumentFragment *IDDocumentImpl::createDocumentFragment()
- {
- return new (this) IDDocumentFragmentImpl(this);
- };
- IDOM_DocumentType *IDDocumentImpl::createDocumentType(const XMLCh *nam)
- {
- if (!isXMLName(nam))
- throw IDOM_DOMException(
- IDOM_DOMException::INVALID_CHARACTER_ERR, 0);
- return new (this) IDDocumentTypeImpl(this, nam);
- };
- IDOM_DocumentType *
- IDDocumentImpl::createDocumentType(const XMLCh *qualifiedName,
- const XMLCh *publicId,
- const XMLCh *systemId)
- {
- if (!isXMLName(qualifiedName))
- throw IDOM_DOMException(
- IDOM_DOMException::INVALID_CHARACTER_ERR, 0);
- return new (this) IDDocumentTypeImpl(this, qualifiedName, publicId, systemId);
- };
- IDOM_Element *IDDocumentImpl::createElement(const XMLCh *tagName)
- {
- if(!isXMLName(tagName))
- throw IDOM_DOMException(IDOM_DOMException::INVALID_CHARACTER_ERR,0);
- return new (this) IDElementImpl(this,tagName);
- };
- IDOM_Element *IDDocumentImpl::createElementNoCheck(const XMLCh *tagName)
- {
- return new (this) IDElementImpl(this, tagName);
- };
- IDOM_Entity *IDDocumentImpl::createEntity(const XMLCh *nam)
- {
- if (!isXMLName(nam))
- throw IDOM_DOMException(
- IDOM_DOMException::INVALID_CHARACTER_ERR, 0);
- return new (this) IDEntityImpl(this, nam);
- };
- IDOM_EntityReference *IDDocumentImpl::createEntityReference(const XMLCh *nam)
- {
- if (!isXMLName(nam))
- throw IDOM_DOMException(
- IDOM_DOMException::INVALID_CHARACTER_ERR, 0);
- return new (this) IDEntityReferenceImpl(this, nam);
- };
- IDOM_Notation *IDDocumentImpl::createNotation(const XMLCh *nam)
- {
- if (!isXMLName(nam))
- throw IDOM_DOMException(
- IDOM_DOMException::INVALID_CHARACTER_ERR, 0);
- return new (this) IDNotationImpl(this, nam);
- };
- IDOM_ProcessingInstruction *IDDocumentImpl::createProcessingInstruction(
- const XMLCh *target, const XMLCh *data)
- {
- if(!isXMLName(target))
- throw IDOM_DOMException(IDOM_DOMException::INVALID_CHARACTER_ERR,0);
- return new (this) IDProcessingInstructionImpl(this,target,data);
- };
- IDOM_Text *IDDocumentImpl::createTextNode(const XMLCh *data)
- {
- return new (this) IDTextImpl(this,data);
- };
- IDOM_NodeIterator* IDDocumentImpl::createNodeIterator (
- IDOM_Node *root, unsigned long whatToShow, IDOM_NodeFilter* filter, bool entityReferenceExpansion)
- {
- // Create the node iterator implementation object.
- // Add it to the vector of fIterators that must be synchronized when a node is deleted.
- // The vector of fIterators is kept in the "owner document" if there is one. If there isn't one, I assume that root is the
- // owner document.
- IDNodeIteratorImpl* iter = new (this) IDNodeIteratorImpl(root, whatToShow, filter, entityReferenceExpansion);
- IDOM_Document* doc = root->getOwnerDocument();
- IDDocumentImpl* impl;
- if (doc != 0) {
- impl = (IDDocumentImpl *) doc;
- }
- else
- impl = (IDDocumentImpl *) root;
- if (impl->fIterators == 0L) {
- impl->fIterators = new (this) NodeIterators(1, false);
- impl->fIterators->addElement(iter);
- }
- return iter;
- }
- IDOM_TreeWalker* IDDocumentImpl::createTreeWalker (IDOM_Node *root, unsigned long whatToShow, IDOM_NodeFilter* filter, bool entityReferenceExpansion)
- {
- // See notes for createNodeIterator...
- IDTreeWalkerImpl* twi = new (this) IDTreeWalkerImpl(root, whatToShow, filter, entityReferenceExpansion);
- IDOM_Document* doc = root->getOwnerDocument();
- IDDocumentImpl* impl;
- if ( doc != 0) {
- impl = (IDDocumentImpl *) doc;
- }
- else
- impl = (IDDocumentImpl *) root;
- if (impl->fTreeWalkers == 0L) {
- impl->fTreeWalkers = new (this) TreeWalkers(1, false);
- impl->fTreeWalkers->addElement(twi);
- }
- return twi;
- }
- IDOM_DocumentType *IDDocumentImpl::getDoctype() const
- {
- return fDocType;
- };
- IDOM_Element *IDDocumentImpl::getDocumentElement() const
- {
- return fDocElement;
- };
- IDOM_NodeList *IDDocumentImpl::getElementsByTagName(const XMLCh *tagname) const
- {
- // cast off the const of this because we will update the fNodeListPool
- return ((IDDocumentImpl*)this)->getDeepNodeList(this,tagname);
- };
- IDOM_DOMImplementation *IDDocumentImpl::getImplementation() const {
- return IDOM_DOMImplementation::getImplementation();
- }
- IDOM_Node *IDDocumentImpl::insertBefore(IDOM_Node *newChild, IDOM_Node *refChild)
- {
- // Only one such child permitted
- if(
- (newChild->getNodeType() == IDOM_Node::ELEMENT_NODE && fDocElement!=0)
- ||
- (newChild->getNodeType() == IDOM_Node::DOCUMENT_TYPE_NODE && fDocType!=0)
- )
- throw IDOM_DOMException(IDOM_DOMException::HIERARCHY_REQUEST_ERR,0);
- fParent.insertBefore(newChild,refChild);
- // If insert succeeded, cache the kid appropriately
- if(newChild->getNodeType() == IDOM_Node::ELEMENT_NODE)
- fDocElement=(IDOM_Element *)newChild;
- else if(newChild->getNodeType() == IDOM_Node::DOCUMENT_TYPE_NODE)
- fDocType=(IDOM_DocumentType *)newChild;
- return newChild;
- };
- bool IDDocumentImpl::isXMLName(const XMLCh *s)
- {
- // idom_revist. This function probably already exists in the scanner.
- if (!XMLReader::isFirstNameChar(s[0]))
- return false;
- const XMLCh *p;
- for (p=s+1; *p!=0; p++)
- {
- if (!XMLReader::isNameChar(*p))
- return false;
- }
- return true;
- };
- IDOM_Node *IDDocumentImpl::removeChild(IDOM_Node *oldChild)
- {
- fParent.removeChild(oldChild);
- // If remove succeeded, un-cache the kid appropriately
- if(oldChild->getNodeType() == IDOM_Node::ELEMENT_NODE)
- fDocElement=0;
- else if(oldChild->getNodeType() == IDOM_Node::DOCUMENT_TYPE_NODE)
- fDocType=0;
- return oldChild;
- };
- void IDDocumentImpl::setNodeValue(const XMLCh *x)
- {
- fNode.setNodeValue(x);
- };
- //Introduced in DOM Level 2
- IDOM_Node *IDDocumentImpl::importNode(IDOM_Node *source, bool deep)
- {
- IDOM_Node *newnode=0;
- switch (source->getNodeType())
- {
- case IDOM_Node::ELEMENT_NODE :
- {
- IDOM_Element *newelement;
- if (source->getLocalName() == 0)
- newelement = createElement(source->getNodeName());
- else
- newelement = createElementNS(source->getNamespaceURI(),
- source->getNodeName());
- IDOM_NamedNodeMap *srcattr=source->getAttributes();
- if(srcattr!=0)
- for(unsigned int i=0;i<srcattr->getLength();++i)
- {
- IDOM_Attr *attr = (IDOM_Attr *) srcattr->item(i);
- if (attr -> getSpecified()) { // not a default attribute
- IDOM_Attr *nattr = (IDOM_Attr *) importNode(attr, true);
- if (attr -> getLocalName() == 0)
- newelement->setAttributeNode(nattr);
- else
- newelement->setAttributeNodeNS(nattr);
- }
- }
- newnode=newelement;
- }
- break;
- case IDOM_Node::ATTRIBUTE_NODE :
- if (source->getLocalName() == 0)
- newnode = createAttribute(source->getNodeName());
- else
- newnode = createAttributeNS(source->getNamespaceURI(),
- source->getNodeName());
- deep = true;
- // Kids carry value
- break;
- case IDOM_Node::TEXT_NODE :
- newnode = createTextNode(source->getNodeValue());
- break;
- case IDOM_Node::CDATA_SECTION_NODE :
- newnode = createCDATASection(source->getNodeValue());
- break;
- case IDOM_Node::ENTITY_REFERENCE_NODE :
- newnode = createEntityReference(source->getNodeName());
- castToNodeImpl(newnode) -> isReadOnly(false); //allow deep import temporarily
- break;
- case IDOM_Node::ENTITY_NODE :
- {
- IDOM_Entity *srcentity=(IDOM_Entity *)source;
- IDEntityImpl *newentity = (IDEntityImpl *)createEntity(source->getNodeName());
- newentity->setPublicId(srcentity->getPublicId());
- newentity->setSystemId(srcentity->getSystemId());
- newentity->setNotationName(srcentity->getNotationName());
- // Kids carry additional value
- newnode=newentity;
- castToNodeImpl(newentity)->isReadOnly(false);// allow deep import temporarily
- }
- break;
- case IDOM_Node::PROCESSING_INSTRUCTION_NODE :
- newnode = createProcessingInstruction(source->getNodeName(),
- source->getNodeValue());
- break;
- case IDOM_Node::COMMENT_NODE :
- newnode = createComment(source->getNodeValue());
- break;
- case IDOM_Node::DOCUMENT_TYPE_NODE :
- {
- IDOM_DocumentType *srcdoctype = (IDOM_DocumentType *)source;
- IDOM_DocumentType *newdoctype = (IDOM_DocumentType *)
- createDocumentType(srcdoctype->getNodeName(),
- srcdoctype->getPublicId(),
- srcdoctype->getSystemId());
- // Values are on NamedNodeMaps
- IDOM_NamedNodeMap *smap = srcdoctype->getEntities();
- IDOM_NamedNodeMap *tmap = newdoctype->getEntities();
- if(smap != 0) {
- for(unsigned int i = 0; i < smap->getLength(); i++) {
- tmap->setNamedItem(importNode(smap->item(i), true));
- }
- }
- smap = srcdoctype->getNotations();
- tmap = newdoctype->getNotations();
- if (smap != 0) {
- for(unsigned int i = 0; i < smap->getLength(); i++) {
- tmap->setNamedItem(importNode(smap->item(i), true));
- }
- }
- // NOTE: At this time, the DOM definition of DocumentType
- // doesn't cover Elements and their Attributes. domimpl's
- // extentions in that area will not be preserved, even if
- // copying from domimpl to domimpl. We could special-case
- // that here. Arguably we should. Consider. ?????
- newnode = newdoctype;
- }
- break;
- case IDOM_Node::DOCUMENT_FRAGMENT_NODE :
- newnode = createDocumentFragment();
- // No name, kids carry value
- break;
- case IDOM_Node::NOTATION_NODE :
- {
- IDOM_Notation *srcnotation=(IDOM_Notation *)source;
- IDNotationImpl *newnotation = (IDNotationImpl *)createNotation(source->getNodeName());
- newnotation->setPublicId(srcnotation->getPublicId());
- newnotation->setSystemId(srcnotation->getSystemId());
- // Kids carry additional value
- newnode=newnotation;
- // No name, no value
- break;
- }
- case IDOM_Node::DOCUMENT_NODE : // Document can't be child of Document
- default: // Unknown node type
- throw IDOM_DOMException(IDOM_DOMException::NOT_SUPPORTED_ERR, 0);
- }
- // If deep, replicate and attach the kids.
- if (deep)
- for (IDOM_Node *srckid = source->getFirstChild();
- srckid != 0;
- srckid = srckid->getNextSibling()) {
- newnode->appendChild(importNode(srckid, true));
- }
- if (newnode->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE
- || newnode->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE)
- castToNodeImpl(newnode)->isReadOnly(true);
- return newnode;
- }
- IDOM_Element *IDDocumentImpl::createElementNS(const XMLCh *fNamespaceURI,
- const XMLCh *qualifiedName)
- {
- if(!isXMLName(qualifiedName))
- throw IDOM_DOMException(IDOM_DOMException::INVALID_CHARACTER_ERR,0);
- //XMLCh * pooledTagName = this->fNamePool->getPooledString(qualifiedName);
- return new (this) IDElementNSImpl(this, fNamespaceURI, qualifiedName);
- }
- IDOM_Attr *IDDocumentImpl::createAttributeNS(const XMLCh *fNamespaceURI,
- const XMLCh *qualifiedName)
- {
- if(!isXMLName(qualifiedName))
- throw IDOM_DOMException(IDOM_DOMException::INVALID_CHARACTER_ERR,0);
- return new (this) IDAttrNSImpl(this, fNamespaceURI, qualifiedName);
- }
- IDOM_NodeList *IDDocumentImpl::getElementsByTagNameNS(const XMLCh *fNamespaceURI,
- const XMLCh *fLocalName) const
- {
- // cast off the const of this because we will update the fNodeListPool
- return ((IDDocumentImpl*)this)->getDeepNodeList(this, fNamespaceURI, fLocalName);
- }
- IDOM_Element *IDDocumentImpl::getElementById(const XMLCh *elementId) const
- {
- if (fNodeIDMap == 0)
- return 0;
- IDOM_Attr *theAttr = fNodeIDMap->find(elementId);
- if (theAttr == 0)
- return 0;
- return theAttr->getOwnerElement();
- }
- //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".
- int IDDocumentImpl::indexofQualifiedName(const XMLCh * qName)
- {
- //Check if s = prefix:localName, name or malformed
- int firstOccurence = XMLString::indexOf(qName, chColon);
- int lastOccurence = XMLString::lastIndexOf(qName, chColon);
- if (firstOccurence != lastOccurence || firstOccurence == 0) {
- // Error. More than two ':'s, or ':' is first char.
- return -1;
- }
- if (firstOccurence == -1) {
- // No colons in the name
- firstOccurence = 0;
- }
- return firstOccurence;
- }
- IDOM_Range* IDDocumentImpl::createRange()
- {
- IDRangeImpl* range = new (this) IDRangeImpl(this);
- if (fRanges == 0L) {
- fRanges = new (this) Ranges(1, false);
- }
- fRanges->addElement(range);
- return range;
- }
- Ranges* IDDocumentImpl::getRanges() const
- {
- return fRanges;
- }
- void IDDocumentImpl::removeRange(IDRangeImpl* range)
- {
- if (fRanges != 0) {
- unsigned int sz = fRanges->size();
- if (sz !=0) {
- for (unsigned int i =0; i<sz; i++) {
- if (fRanges->elementAt(i) == range) {
- fRanges->removeElementAt(i);
- break;
- }
- }
- }
- }
- }
- /** Uses the kidOK lookup table to check whether the proposed
- tree structure is legal.
- ????? It feels like there must be a more efficient solution,
- but for the life of me I can't think what it would be.
- */
- bool IDDocumentImpl::isKidOK(IDOM_Node *parent, IDOM_Node *child)
- {
- static int kidOK[14];
- if (kidOK[IDOM_Node::ATTRIBUTE_NODE] == 0)
- {
- kidOK[IDOM_Node::DOCUMENT_NODE] =
- 1 << IDOM_Node::ELEMENT_NODE |
- 1 << IDOM_Node::PROCESSING_INSTRUCTION_NODE |
- 1 << IDOM_Node::COMMENT_NODE |
- 1 << IDOM_Node::DOCUMENT_TYPE_NODE |
- 1 << IDOM_Node::XML_DECL_NODE;
- kidOK[IDOM_Node::DOCUMENT_FRAGMENT_NODE] =
- kidOK[IDOM_Node::ENTITY_NODE] =
- kidOK[IDOM_Node::ENTITY_REFERENCE_NODE] =
- kidOK[IDOM_Node::ELEMENT_NODE] =
- 1 << IDOM_Node::ELEMENT_NODE |
- 1 << IDOM_Node::PROCESSING_INSTRUCTION_NODE |
- 1 << IDOM_Node::COMMENT_NODE |
- 1 << IDOM_Node::TEXT_NODE |
- 1 << IDOM_Node::CDATA_SECTION_NODE |
- 1 << IDOM_Node::ENTITY_REFERENCE_NODE |
- 1 << IDOM_Node::XML_DECL_NODE;
- kidOK[IDOM_Node::ATTRIBUTE_NODE] =
- 1 << IDOM_Node::TEXT_NODE |
- 1 << IDOM_Node::ENTITY_REFERENCE_NODE;
- kidOK[IDOM_Node::PROCESSING_INSTRUCTION_NODE] =
- kidOK[IDOM_Node::COMMENT_NODE] =
- kidOK[IDOM_Node::TEXT_NODE] =
- kidOK[IDOM_Node::CDATA_SECTION_NODE] =
- kidOK[IDOM_Node::NOTATION_NODE] =
- 0;
- };
- int p=parent->getNodeType();
- int ch = child->getNodeType();
- return (kidOK[p] & 1<<ch) != 0;
- }
- void IDDocumentImpl::setUserData(IDOM_Node* n, void* data)
- {
- if (!fUserData && data)
- fUserData = new (this) RefHashTableOf<void>(29, false, new (this) HashPtr());
- if (!data && fUserData)
- fUserData->removeKey((void*)n);
- else
- fUserData->put((void*)n,data);
- }
- void* IDDocumentImpl::getUserData(const IDOM_Node* n) const
- {
- if (fUserData)
- return fUserData->get((void*)n);
- else
- return 0;
- }
- void* IDDocumentImpl::getUserData() const
- {
- return (fNode.hasUserData()) ? getUserData(this) : 0;
- }
- void IDDocumentImpl::setUserData(void* val)
- {
- setUserData(this, val);
- if (val)
- fNode.hasUserData(true);
- else
- fNode.hasUserData(false);
- };
- void IDDocumentImpl::changed()
- {
- fChanges++;
- }
- int IDDocumentImpl::changes() const{
- return fChanges;
- };
- //
- // Delegation for functions inherited from IDOM_Node
- //
- IDOM_Node *IDDocumentImpl::appendChild(IDOM_Node *newChild) {return insertBefore(newChild, 0); };
- IDOM_NamedNodeMap *IDDocumentImpl::getAttributes() const {return fNode.getAttributes (); };
- IDOM_NodeList *IDDocumentImpl::getChildNodes() const {return fParent.getChildNodes (); };
- IDOM_Node *IDDocumentImpl::getFirstChild() const {return fParent.getFirstChild (); };
- IDOM_Node *IDDocumentImpl::getLastChild() const {return fParent.getLastChild (); };
- const XMLCh *IDDocumentImpl::getLocalName() const {return fNode.getLocalName (); };
- const XMLCh *IDDocumentImpl::getNamespaceURI() const {return fNode.getNamespaceURI (); };
- IDOM_Node *IDDocumentImpl::getNextSibling() const {return fNode.getNextSibling (); };
- const XMLCh *IDDocumentImpl::getNodeValue() const {return fNode.getNodeValue (); };
- const XMLCh *IDDocumentImpl::getPrefix() const {return fNode.getPrefix (); };
- IDOM_Node *IDDocumentImpl::getParentNode() const {return fNode.getParentNode (); };
- IDOM_Node *IDDocumentImpl::getPreviousSibling() const {return fNode.getPreviousSibling (); };
- bool IDDocumentImpl::hasChildNodes() const {return fParent.hasChildNodes (); };
- void IDDocumentImpl::normalize() {fNode.normalize (); };
- IDOM_Node *IDDocumentImpl::replaceChild(IDOM_Node *newChild, IDOM_Node *oldChild)
- {return fParent.replaceChild (newChild, oldChild); };
- bool IDDocumentImpl::supports(const XMLCh *feature, const XMLCh *version) const
- {return fNode.supports (feature, version); };
- void IDDocumentImpl::setPrefix(const XMLCh *prefix) {fNode.setPrefix(prefix); };
- //-----------------------------------------------------------------------
- //
- // Per Document Heap and Heap Helper functions
- //
- // idom_revisit - this stuff should be a class of its own, rather than
- // just lying around naked in DocumentImpl.
- //
- //-----------------------------------------------------------------------
- XMLCh * IDDocumentImpl::cloneString(const XMLCh *src)
- {
- size_t len = XMLString::stringLen(src);
- len = (len + 1) * sizeof(XMLCh);
- len = (len % 4) + len;
- XMLCh *newStr = (XMLCh *)this->allocate(len);
- XMLString::copyString(newStr, src);
- return newStr;
- }
- const XMLCh * IDDocumentImpl::getPooledString(const XMLCh *src)
- {
- return this->fNamePool->getPooledString(src);
- }
- static const int kHeapAllocSize = 0x10000; // The chunk size to allocate from the
- // system allocator.
- static const int kMaxSubAllocationSize = 4096; // Any request for more bytes
- // than this will be handled by
- // allocating directly with system.
- void * IDDocumentImpl::allocate(size_t amount)
- {
- size_t sizeOfPointer = sizeof(void *);
- if (amount%sizeOfPointer!=0)
- amount = amount + (sizeOfPointer - (amount % sizeOfPointer));
- // If the request is for a largish block, hand it off to the system
- // allocator. The block still must be linked into the list of
- // allocated blocks so that it will be deleted when the time comes.
- if (amount > kMaxSubAllocationSize)
- {
- void* newBlock = 0;
- try {
- newBlock = new char[amount + sizeof(void *)];
- }
- catch (...) {
- ThrowXML(RuntimeException, XMLExcepts::Out_Of_Memory);
- }
- if (!newBlock)
- ThrowXML(RuntimeException, XMLExcepts::Out_Of_Memory);
- if (fCurrentBlock)
- {
- *(void **)newBlock = *(void **)fCurrentBlock;
- *(void **)fCurrentBlock = newBlock;
- }
- else
- {
- fCurrentBlock = newBlock;
- fFreePtr = 0;
- fFreeBytesRemaining = 0;
- }
- void *retPtr = (char *)newBlock + sizeOfPointer;
- return retPtr;
- }
- // It's a normal (sub-allocatable) request.
- if (amount > fFreeBytesRemaining)
- {
- // Request doesn't fit in the current block.
- // Get a new one from the system allocator.
- void* newBlock = 0;
- try {
- newBlock = new char[kHeapAllocSize];
- }
- catch (...) {
- ThrowXML(RuntimeException, XMLExcepts::Out_Of_Memory);
- }
- if (!newBlock)
- ThrowXML(RuntimeException, XMLExcepts::Out_Of_Memory);
- *(void **)newBlock = fCurrentBlock;
- fCurrentBlock = newBlock;
- fFreePtr = (char *)newBlock + sizeof(void *);
- fFreeBytesRemaining = kHeapAllocSize - sizeof(void *);
- }
- void *retPtr = fFreePtr;
- fFreePtr += amount;
- fFreeBytesRemaining -= amount;
- return retPtr;
- }
- void IDDocumentImpl::deleteHeap()
- {
- void *block = fCurrentBlock;
- while (fCurrentBlock != 0)
- {
- void *nextBlock = *(void **)fCurrentBlock;
- delete [] fCurrentBlock;
- fCurrentBlock = nextBlock;
- }
- }
- IDOM_NodeList *IDDocumentImpl::getDeepNodeList(const IDOM_Node *rootNode, const XMLCh *tagName)
- {
- if(!fNodeListPool) {
- fNodeListPool = new (this) IDDeepNodeListPool<IDDeepNodeListImpl>(109, false);
- }
- IDDeepNodeListImpl* retList = fNodeListPool->getByKey(rootNode, tagName, 0);
- if (!retList) {
- int id = fNodeListPool->put((void*) rootNode, (XMLCh*) tagName, 0, new (this) IDDeepNodeListImpl(rootNode, tagName));
- retList = fNodeListPool->getById(id);
- }
- return retList;
- }
- IDOM_NodeList *IDDocumentImpl::getDeepNodeList(const IDOM_Node *rootNode, //DOM Level 2
- const XMLCh *namespaceURI,
- const XMLCh *localName)
- {
- if(!fNodeListPool) {
- fNodeListPool = new (this) IDDeepNodeListPool<IDDeepNodeListImpl>(109, false);
- }
- IDDeepNodeListImpl* retList = fNodeListPool->getByKey(rootNode, localName, namespaceURI);
- if (!retList) {
- // the pool will adopt the IDDeepNodeListImpl
- int id = fNodeListPool->put((void*) rootNode, (XMLCh*) localName, (XMLCh*) namespaceURI, new (this) IDDeepNodeListImpl(rootNode, namespaceURI, localName));
- retList = fNodeListPool->getById(id);
- }
- return retList;
- }