"src/xercesc/util/Transcoders/Win32/Win32TransService.hpp" did not exist on "a0abc2b432aad2b97f971c6a2c946ece367d89e1"
Newer
Older
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id$
*/
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
#include "DOMConfigurationImpl.hpp"
#include "DOMDocumentTypeImpl.hpp"
#include "DOMAttrImpl.hpp"
#include "DOMAttrNSImpl.hpp"
#include "DOMCDATASectionImpl.hpp"
#include "DOMCommentImpl.hpp"
#include "DOMDeepNodeListImpl.hpp"
#include "DOMDocumentFragmentImpl.hpp"
#include "DOMElementImpl.hpp"
#include "XSDElementNSImpl.hpp"
#include "DOMEntityImpl.hpp"
#include "DOMEntityReferenceImpl.hpp"
#include "DOMNotationImpl.hpp"
#include "DOMProcessingInstructionImpl.hpp"
#include "DOMTextImpl.hpp"
#include "DOMStringPool.hpp"
#include "DOMTreeWalkerImpl.hpp"
#include "DOMNodeIteratorImpl.hpp"
#include "DOMNodeIDMap.hpp"
#include "DOMRangeImpl.hpp"
Alberto Massari
committed
#include "DOMTypeInfoImpl.hpp"
Alberto Massari
committed
#include "DOMXPathExpressionImpl.hpp"
#include "DOMXPathNSResolverImpl.hpp"
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/framework/MemoryManager.hpp>
Neil Graham
committed
#include <xercesc/util/OutOfMemoryException.hpp>
Alberto Massari
committed
// The chunk size to allocate from the system allocator.
static const XMLSize_t kInitialHeapAllocSize = 0x2000;
static const XMLSize_t kMaxHeapAllocSize = 0x10000;
static const XMLSize_t kMaxSubAllocationSize = 0x1000; // Any request for more bytes
// than this will be handled by
// allocating directly with system.
//
// 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 DOMCasts to work correctly. This means that
// fNode and fParent constructors used here can not
// allocate.
//
Alberto Massari
committed
DOMDocumentImpl::DOMDocumentImpl(DOMImplementation* domImpl, MemoryManager* const manager)
: fNode(this),
fParent(this),
fNodeIDMap(0),
fInputEncoding(0),
fXmlEncoding(0),
fXmlStandalone(false),
fXmlVersion(0),
David Abram Cargill
committed
fDOMConfiguration(0),
fUserDataTableKeys(17, manager),
David Abram Cargill
committed
fCurrentBlock(0),
fFreePtr(0),
fFreeBytesRemaining(0),
Alberto Massari
committed
fHeapAllocSize(kInitialHeapAllocSize),
fRecycleNodePtr(0),
David Abram Cargill
committed
fNodeListPool(0),
fDocType(0),
fDocElement(0),
fNamePool(0),
fNormalizer(0),
fRanges(0),
fNodeIterators(0),
fMemoryManager(manager),
Alberto Massari
committed
fDOMImplementation(domImpl),
David Abram Cargill
committed
fChanges(0),
{
fNamePool = new (this) DOMStringPool(257, this);
David Abram Cargill
committed
}
//DOM Level 2
DOMDocumentImpl::DOMDocumentImpl(const XMLCh *fNamespaceURI,
const XMLCh *qualifiedName,
DOMDocumentType *doctype,
Alberto Massari
committed
DOMImplementation* domImpl,
MemoryManager* const manager)
: fNode(this),
fParent(this),
fNodeIDMap(0),
fInputEncoding(0),
fXmlEncoding(0),
fXmlStandalone(false),
fXmlVersion(0),
David Abram Cargill
committed
fDOMConfiguration(0),
fUserDataTableKeys(17, manager),
David Abram Cargill
committed
fCurrentBlock(0),
fFreePtr(0),
fFreeBytesRemaining(0),
Alberto Massari
committed
fHeapAllocSize(kInitialHeapAllocSize),
fRecycleNodePtr(0),
fRecycleBufferPtr(0),
David Abram Cargill
committed
fNodeListPool(0),
fDocType(0),
fDocElement(0),
fNamePool(0),
fNormalizer(0),
fRanges(0),
fNodeIterators(0),
fMemoryManager(manager),
Alberto Massari
committed
fDOMImplementation(domImpl),
David Abram Cargill
committed
fChanges(0),
{
fNamePool = new (this) DOMStringPool(257, this);
try {
setDocumentType(doctype);
if (qualifiedName)
appendChild(createElementNS(fNamespaceURI, qualifiedName)); //root element
else if (fNamespaceURI)
throw DOMException(DOMException::NAMESPACE_ERR, 0, getMemoryManager());
}
Neil Graham
committed
catch(const OutOfMemoryException&)
{
throw;
}
catch (...) {
this->deleteHeap();
throw;
}
}
void DOMDocumentImpl::setDocumentType(DOMDocumentType *doctype)
{
// 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 DOMException( //one doctype can belong to only one DOMDocumentImpl
DOMException::WRONG_DOCUMENT_ERR, 0, getMemoryManager());
DOMDocumentTypeImpl* doctypeImpl = (DOMDocumentTypeImpl*) 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.
// revisit. What if this doctype is already a child of the document?
}
DOMDocumentImpl::~DOMDocumentImpl()
{
// Clean up the fNodeListPool
if (fNodeListPool)
fNodeListPool->cleanup();
if (fRanges)
delete fRanges; //fRanges->cleanup();
if (fNodeIterators)
delete fNodeIterators;//fNodeIterators->cleanup();
delete fUserDataTable;//fUserDataTable->cleanup();
if (fRecycleNodePtr) {
fRecycleNodePtr->deleteAllElements();
delete fRecycleNodePtr;
}
if (fRecycleBufferPtr) {
delete fRecycleBufferPtr;
}
// 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();
David Abram Cargill
committed
}
DOMNode *DOMDocumentImpl::cloneNode(bool deep) const {
Alberto Massari
committed
// Note: the cloned document node goes on the same heap we live in.
Alberto Massari
committed
DOMDocumentImpl *newdoc = new (fMemoryManager) DOMDocumentImpl(fDOMImplementation, fMemoryManager);
if(fXmlEncoding && *fXmlEncoding)
newdoc->setXmlEncoding(fXmlEncoding);
if(fXmlVersion && *fXmlVersion)
newdoc->setXmlVersion(fXmlVersion);
newdoc->setXmlStandalone(fXmlStandalone);
// then the children by _importing_ them
if (deep)
for (DOMNode *n = this->getFirstChild(); n != 0; n = n->getNextSibling()) {
newdoc->appendChild(newdoc->importNode(n, true, true));
}
fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newdoc);
return newdoc;
David Abram Cargill
committed
}
const XMLCh * DOMDocumentImpl::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 DOMDocumentImpl::getNodeType() const {
return DOMNode::DOCUMENT_NODE;
David Abram Cargill
committed
}
// even though ownerDocument refers to this in this implementation
// the DOM Level 2 spec says it must be 0, so make it appear so
DOMDocument * DOMDocumentImpl::getOwnerDocument() const {
return 0;
}
DOMAttr *DOMDocumentImpl::createAttribute(const XMLCh *nam)
{
throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::ATTR_OBJECT) DOMAttrImpl(this,nam);
David Abram Cargill
committed
}
DOMCDATASection *DOMDocumentImpl::createCDATASection(const XMLCh *data) {
Alberto Massari
committed
return new (this, DOMMemoryManager::CDATA_SECTION_OBJECT) DOMCDATASectionImpl(this,data);
David Abram Cargill
committed
}
DOMComment *DOMDocumentImpl::createComment(const XMLCh *data)
{
Alberto Massari
committed
return new (this, DOMMemoryManager::COMMENT_OBJECT) DOMCommentImpl(this, data);
David Abram Cargill
committed
}
DOMDocumentFragment *DOMDocumentImpl::createDocumentFragment()
{
Alberto Massari
committed
return new (this, DOMMemoryManager::DOCUMENT_FRAGMENT_OBJECT) DOMDocumentFragmentImpl(this);
David Abram Cargill
committed
}
DOMDocumentType *DOMDocumentImpl::createDocumentType(const XMLCh *nam)
{
throw DOMException(
DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(this, nam, false);
David Abram Cargill
committed
}
DOMDocumentType *
DOMDocumentImpl::createDocumentType(const XMLCh *qualifiedName,
const XMLCh *publicId,
const XMLCh *systemId)
{
throw DOMException(
DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(this, qualifiedName, publicId, systemId, false);
David Abram Cargill
committed
}
DOMElement *DOMDocumentImpl::createElement(const XMLCh *tagName)
{
throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::ELEMENT_OBJECT) DOMElementImpl(this,tagName);
David Abram Cargill
committed
}
DOMElement *DOMDocumentImpl::createElementNoCheck(const XMLCh *tagName)
{
Alberto Massari
committed
return new (this, DOMMemoryManager::ELEMENT_OBJECT) DOMElementImpl(this, tagName);
David Abram Cargill
committed
}
DOMEntity *DOMDocumentImpl::createEntity(const XMLCh *nam)
{
throw DOMException(
DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::ENTITY_OBJECT) DOMEntityImpl(this, nam);
David Abram Cargill
committed
}
DOMEntityReference *DOMDocumentImpl::createEntityReference(const XMLCh *nam)
{
throw DOMException(
DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::ENTITY_REFERENCE_OBJECT) DOMEntityReferenceImpl(this, nam);
David Abram Cargill
committed
}
DOMEntityReference *DOMDocumentImpl::createEntityReferenceByParser(const XMLCh *nam)
{
if (!nam || !isXMLName(nam))
throw DOMException(
DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::ENTITY_REFERENCE_OBJECT) DOMEntityReferenceImpl(this, nam, false);
David Abram Cargill
committed
}
DOMNotation *DOMDocumentImpl::createNotation(const XMLCh *nam)
{
throw DOMException(
DOMException::INVALID_CHARACTER_ERR, 0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::NOTATION_OBJECT) DOMNotationImpl(this, nam);
David Abram Cargill
committed
}
DOMProcessingInstruction *DOMDocumentImpl::createProcessingInstruction(
const XMLCh *target, const XMLCh *data)
{
throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::PROCESSING_INSTRUCTION_OBJECT) DOMProcessingInstructionImpl(this,target,data);
David Abram Cargill
committed
}
DOMText *DOMDocumentImpl::createTextNode(const XMLCh *data)
{
Alberto Massari
committed
return new (this, DOMMemoryManager::TEXT_OBJECT) DOMTextImpl(this,data);
David Abram Cargill
committed
}
DOMNodeIterator* DOMDocumentImpl::createNodeIterator (
DOMNode *root, unsigned long whatToShow, DOMNodeFilter* filter, bool entityReferenceExpansion)
{
if (!root) {
throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager());
return 0;
}
DOMNodeIteratorImpl* nodeIterator = new (this) DOMNodeIteratorImpl(this, root, whatToShow, filter, entityReferenceExpansion);
if (fNodeIterators == 0L) {
//fNodeIterators = new (this) NodeIterators(1, false);
fNodeIterators = new (fMemoryManager) NodeIterators(1, false, fMemoryManager);
}
fNodeIterators->addElement(nodeIterator);
return nodeIterator;
}
NodeIterators* DOMDocumentImpl::getNodeIterators() const
{
return fNodeIterators;
}
void DOMDocumentImpl::removeNodeIterator(DOMNodeIteratorImpl* nodeIterator)
{
if (fNodeIterators != 0) {
Alberto Massari
committed
unsigned int sz = fNodeIterators->size();
if (sz !=0) {
Alberto Massari
committed
for (unsigned int i =0; i<sz; i++) {
if (fNodeIterators->elementAt(i) == nodeIterator) {
fNodeIterators->removeElementAt(i);
break;
}
}
}
}
}
Gareth Reakes
committed
Alberto Massari
committed
const DOMXPathExpression* DOMDocumentImpl::createExpression(const XMLCh * expression, const DOMXPathNSResolver *resolver)
Gareth Reakes
committed
{
Alberto Massari
committed
return new (getMemoryManager()) DOMXPathExpressionImpl(expression, resolver, getMemoryManager());
Gareth Reakes
committed
}
Alberto Massari
committed
const DOMXPathNSResolver* DOMDocumentImpl::createNSResolver(DOMNode *nodeResolver)
Gareth Reakes
committed
{
Alberto Massari
committed
return new (this) DOMXPathNSResolverImpl(nodeResolver);
Gareth Reakes
committed
}
Alberto Massari
committed
void* DOMDocumentImpl::evaluate(const XMLCh *expression, DOMNode *contextNode, const DOMXPathNSResolver *resolver,
unsigned short type, void* result)
Gareth Reakes
committed
{
Alberto Massari
committed
const DOMXPathExpression* expr=createExpression(expression, resolver);
result=expr->evaluate(contextNode, type, result);
expr->release();
return result;
Gareth Reakes
committed
}
DOMTreeWalker* DOMDocumentImpl::createTreeWalker (DOMNode *root, unsigned long whatToShow, DOMNodeFilter* filter, bool entityReferenceExpansion)
{
if (!root) {
throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager());
return 0;
}
return new (this) DOMTreeWalkerImpl(root, whatToShow, filter, entityReferenceExpansion);
}
DOMDocumentType *DOMDocumentImpl::getDoctype() const
{
return fDocType;
David Abram Cargill
committed
}
DOMElement *DOMDocumentImpl::getDocumentElement() const
{
return fDocElement;
David Abram Cargill
committed
}
DOMNodeList *DOMDocumentImpl::getElementsByTagName(const XMLCh *tagname) const
{
// cast off the const of this because we will update the fNodeListPool
return ((DOMDocumentImpl*)this)->getDeepNodeList(this,tagname);
David Abram Cargill
committed
}
DOMImplementation *DOMDocumentImpl::getImplementation() const {
Alberto Massari
committed
return fDOMImplementation;
}
DOMNode *DOMDocumentImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
{
// Only one such child permitted
if(
(newChild->getNodeType() == DOMNode::ELEMENT_NODE && fDocElement!=0)
||
(newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE && fDocType!=0)
)
throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, getMemoryManager());
// if the newChild is a documenttype node created from domimplementation, set the ownerDoc first
if ((newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE) && !newChild->getOwnerDocument())
fParent.insertBefore(newChild,refChild);
// If insert succeeded, cache the kid appropriately
if(newChild->getNodeType() == DOMNode::ELEMENT_NODE)
fDocElement=(DOMElement *)newChild;
else if(newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)
fDocType=(DOMDocumentType *)newChild;
return newChild;
David Abram Cargill
committed
}
DOMNode* DOMDocumentImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild) {
DOMDocumentType* tempDocType = fDocType;
DOMElement* tempDocElement = fDocElement;
if(oldChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)
fDocType=0;
else if(oldChild->getNodeType() == DOMNode::ELEMENT_NODE)
fDocElement=0;
try {
insertBefore(newChild, oldChild);
// changed() already done.
if((oldChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)
|| (oldChild->getNodeType() == DOMNode::ELEMENT_NODE))
return fParent.removeChild(oldChild);
else
return removeChild(oldChild);
}
Neil Graham
committed
catch(const OutOfMemoryException&)
{
throw;
}
catch(...) {
fDocType = tempDocType;
fDocElement = tempDocElement;
throw;
}
bool DOMDocumentImpl::isXMLName(const XMLCh *s)
{
if (XMLString::equals(fXmlVersion, XMLUni::fgVersion1_1))
return XMLChar1_1::isValidName(s, XMLString::stringLen(s));
else
return XMLChar1_0::isValidName(s, XMLString::stringLen(s));
David Abram Cargill
committed
}
DOMNode *DOMDocumentImpl::removeChild(DOMNode *oldChild)
{
fParent.removeChild(oldChild);
// If remove succeeded, un-cache the kid appropriately
if(oldChild->getNodeType() == DOMNode::ELEMENT_NODE)
fDocElement=0;
else if(oldChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)
fDocType=0;
return oldChild;
David Abram Cargill
committed
}
void DOMDocumentImpl::setNodeValue(const XMLCh *x)
{
fNode.setNodeValue(x);
David Abram Cargill
committed
}
//Introduced in DOM Level 2
DOMNode *DOMDocumentImpl::importNode(const DOMNode *source, bool deep)
{
}
DOMElement *DOMDocumentImpl::createElementNS(const XMLCh *fNamespaceURI,
{
throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());
//XMLCh * pooledTagName = this->fNamePool->getPooledString(qualifiedName);
Alberto Massari
committed
return new (this, DOMMemoryManager::ELEMENT_NS_OBJECT) DOMElementNSImpl(this, fNamespaceURI, qualifiedName);
}
DOMElement *DOMDocumentImpl::createElementNS(const XMLCh *fNamespaceURI,
const XMLCh *qualifiedName,
Tinny Ng
committed
const XMLSSize_t lineNo,
const XMLSSize_t columnNo)
{
throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());
return new (this) XSDElementNSImpl(this, fNamespaceURI, qualifiedName, lineNo, columnNo);
}
DOMAttr *DOMDocumentImpl::createAttributeNS(const XMLCh *fNamespaceURI,
{
throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, getMemoryManager());
Alberto Massari
committed
return new (this, DOMMemoryManager::ATTR_NS_OBJECT) DOMAttrNSImpl(this, fNamespaceURI, qualifiedName);
}
DOMNodeList *DOMDocumentImpl::getElementsByTagNameNS(const XMLCh *fNamespaceURI,
{
// cast off the const of this because we will update the fNodeListPool
return ((DOMDocumentImpl*)this)->getDeepNodeList(this, fNamespaceURI, fLocalName);
}
DOMElement *DOMDocumentImpl::getElementById(const XMLCh *elementId) const
{
if (fNodeIDMap == 0)
return 0;
DOMAttr *theAttr = fNodeIDMap->find(elementId);
if (theAttr == 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" or "abcd:".
int DOMDocumentImpl::indexofQualifiedName(const XMLCh * qName)
{
int qNameLen = XMLString::stringLen(qName);
int index = -1, count = 0;
for (int i = 0; i < qNameLen; ++i) {
if (qName[i] == chColon) {
index = i;
}
}
if (qNameLen == 0 || count > 1 || index == 0 || index == qNameLen-1)
return -1;
return count == 0 ? 0 : index;
}
const XMLCh* DOMDocumentImpl::getBaseURI() const
{
return fDocumentURI;
David Abram Cargill
committed
}
DOMRange* DOMDocumentImpl::createRange()
{
DOMRangeImpl* range = new (this) DOMRangeImpl(this, fMemoryManager);
if (fRanges == 0L) {
//fRanges = new (this) Ranges(1, false);
fRanges = new (fMemoryManager) Ranges(1, false, fMemoryManager); // XMemory
}
fRanges->addElement(range);
return range;
}
Ranges* DOMDocumentImpl::getRanges() const
{
return fRanges;
}
void DOMDocumentImpl::removeRange(DOMRangeImpl* range)
{
if (fRanges != 0) {
Alberto Massari
committed
unsigned int sz = fRanges->size();
if (sz !=0) {
Alberto Massari
committed
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 DOMDocumentImpl::isKidOK(DOMNode *parent, DOMNode *child)
{
static int kidOK[14];
if (kidOK[DOMNode::ATTRIBUTE_NODE] == 0)
{
kidOK[DOMNode::DOCUMENT_NODE] =
1 << DOMNode::ELEMENT_NODE |
1 << DOMNode::PROCESSING_INSTRUCTION_NODE |
1 << DOMNode::COMMENT_NODE |
kidOK[DOMNode::DOCUMENT_FRAGMENT_NODE] =
kidOK[DOMNode::ENTITY_NODE] =
kidOK[DOMNode::ENTITY_REFERENCE_NODE] =
kidOK[DOMNode::ELEMENT_NODE] =
1 << DOMNode::ELEMENT_NODE |
1 << DOMNode::PROCESSING_INSTRUCTION_NODE |
1 << DOMNode::COMMENT_NODE |
1 << DOMNode::TEXT_NODE |
1 << DOMNode::CDATA_SECTION_NODE |
kidOK[DOMNode::ATTRIBUTE_NODE] =
1 << DOMNode::TEXT_NODE |
1 << DOMNode::ENTITY_REFERENCE_NODE;
kidOK[DOMNode::PROCESSING_INSTRUCTION_NODE] =
kidOK[DOMNode::COMMENT_NODE] =
kidOK[DOMNode::TEXT_NODE] =
kidOK[DOMNode::CDATA_SECTION_NODE] =
kidOK[DOMNode::NOTATION_NODE] =
0;
David Abram Cargill
committed
}
int p=parent->getNodeType();
int ch = child->getNodeType();
return ((kidOK[p] & 1<<ch) != 0) ||
(p==DOMNode::DOCUMENT_NODE && ch==DOMNode::TEXT_NODE &&
((XMLString::equals(((DOMDocument*)parent)->getXmlVersion(), XMLUni::fgVersion1_1))?
XMLChar1_1::isAllSpaces(child->getNodeValue(), XMLString::stringLen(child->getNodeValue())):
XMLChar1_0::isAllSpaces(child->getNodeValue(), XMLString::stringLen(child->getNodeValue())))
);
}
void DOMDocumentImpl::changed()
{
fChanges++;
}
int DOMDocumentImpl::changes() const{
return fChanges;
David Abram Cargill
committed
}
//
// Delegation for functions inherited from DOMNode
//
David Abram Cargill
committed
DOMNode* DOMDocumentImpl::appendChild(DOMNode *newChild) {return insertBefore(newChild, 0); }
DOMNamedNodeMap* DOMDocumentImpl::getAttributes() const {return fNode.getAttributes (); }
DOMNodeList* DOMDocumentImpl::getChildNodes() const {return fParent.getChildNodes (); }
DOMNode* DOMDocumentImpl::getFirstChild() const {return fParent.getFirstChild (); }
DOMNode* DOMDocumentImpl::getLastChild() const {return fParent.getLastChild (); }
const XMLCh* DOMDocumentImpl::getLocalName() const {return fNode.getLocalName (); }
const XMLCh* DOMDocumentImpl::getNamespaceURI() const {return fNode.getNamespaceURI (); }
DOMNode* DOMDocumentImpl::getNextSibling() const {return fNode.getNextSibling (); }
const XMLCh* DOMDocumentImpl::getNodeValue() const {return fNode.getNodeValue (); }
const XMLCh* DOMDocumentImpl::getPrefix() const {return fNode.getPrefix (); }
DOMNode* DOMDocumentImpl::getParentNode() const {return fNode.getParentNode (); }
DOMNode* DOMDocumentImpl::getPreviousSibling() const {return fNode.getPreviousSibling (); }
bool DOMDocumentImpl::hasChildNodes() const {return fParent.hasChildNodes (); }
void DOMDocumentImpl::normalize() {fParent.normalize (); }
void DOMDocumentImpl::setPrefix(const XMLCh *prefix) {fNode.setPrefix(prefix); }
bool DOMDocumentImpl::hasAttributes() const {return fNode.hasAttributes(); }
bool DOMDocumentImpl::isSameNode(const DOMNode* other) const {return fNode.isSameNode(other);}
bool DOMDocumentImpl::isEqualNode(const DOMNode* arg) const {return fParent.isEqualNode(arg);}
void* DOMDocumentImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
David Abram Cargill
committed
{return fNode.setUserData(key, data, handler); }
void* DOMDocumentImpl::getUserData(const XMLCh* key) const {return fNode.getUserData(key); }
short DOMDocumentImpl::compareDocumentPosition(const DOMNode* other) const {return fNode.compareDocumentPosition(other); }
David Abram Cargill
committed
const XMLCh* DOMDocumentImpl::getTextContent() const {return fNode.getTextContent(); }
void DOMDocumentImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
const XMLCh* DOMDocumentImpl::lookupPrefix(const XMLCh* namespaceURI) const {return fNode.lookupPrefix(namespaceURI); }
David Abram Cargill
committed
bool DOMDocumentImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
const XMLCh* DOMDocumentImpl::lookupNamespaceURI(const XMLCh* prefix) const {return fNode.lookupNamespaceURI(prefix); }
//-----------------------------------------------------------------------
//
// Per Document Heap and Heap Helper functions
//
// revisit - this stuff should be a class of its own, rather than
// just lying around naked in DocumentImpl.
//
//-----------------------------------------------------------------------
XMLCh * DOMDocumentImpl::cloneString(const XMLCh *src)
{
if (!src) return 0;
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 * DOMDocumentImpl::getPooledString(const XMLCh *src)
{
if (!src) return 0;
else return this->fNamePool->getPooledString(src);
}
Alberto Massari
committed
XMLSize_t DOMDocumentImpl::getMemoryAllocationBlockSize() const
{
return fHeapAllocSize;
}
Alberto Massari
committed
void DOMDocumentImpl::setMemoryAllocationBlockSize(XMLSize_t size)
{
// the new size must be bigger than the maximum amount of each allocation
if(size>kMaxSubAllocationSize)
fHeapAllocSize=size;
}
Alberto Massari
committed
void * DOMDocumentImpl::allocate(XMLSize_t amount)
James David Berry
committed
{
// Align the request size so that suballocated blocks
// beyond this one will be maintained at the same alignment.
amount = XMLPlatformUtils::alignPointerForNewBlockAllocation(amount);
// 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)
{
James David Berry
committed
// The size of the header we add to our raw blocks
size_t sizeOfHeader = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(void *));
// Try to allocate the block
Neil Graham
committed
void* newBlock;
newBlock = fMemoryManager->allocate((sizeOfHeader + amount) * sizeof(char)); //new char[amount + sizeOfHeader];
James David Berry
committed
// Link it into the list beyond current block, as current block
// is still being subdivided. If there is no current block
// then track that we have no bytes to further divide.
if (fCurrentBlock)
{
*(void **)newBlock = *(void **)fCurrentBlock;
*(void **)fCurrentBlock = newBlock;
}
else
{
fCurrentBlock = newBlock;
fFreePtr = 0;
fFreeBytesRemaining = 0;
}
James David Berry
committed
void *retPtr = (char *)newBlock + sizeOfHeader;
return retPtr;
}
James David Berry
committed
// It's a normal (sub-allocatable) request.
// Are we out of room in our current block?
if (amount > fFreeBytesRemaining)
{
// Request doesn't fit in the current block.
James David Berry
committed
// The size of the header we add to our raw blocks
size_t sizeOfHeader = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(void *));
// Get a new block from the system allocator.
Neil Graham
committed
void* newBlock;
Alberto Massari
committed
newBlock = fMemoryManager->allocate(fHeapAllocSize * sizeof(char)); //new char[kHeapAllocSize];
Neil Graham
committed
*(void **)newBlock = fCurrentBlock;
fCurrentBlock = newBlock;
James David Berry
committed
fFreePtr = (char *)newBlock + sizeOfHeader;
Alberto Massari
committed
fFreeBytesRemaining = fHeapAllocSize - sizeOfHeader;
if(fHeapAllocSize<kMaxHeapAllocSize)
fHeapAllocSize*=2;
}
James David Berry
committed
// Subdivide the request off current block
void *retPtr = fFreePtr;
fFreePtr += amount;
fFreeBytesRemaining -= amount;
James David Berry
committed
return retPtr;
}
void DOMDocumentImpl::deleteHeap()
{
while (fCurrentBlock != 0)
{
void *nextBlock = *(void **)fCurrentBlock;
fMemoryManager->deallocate(fCurrentBlock); //delete [] (char*) fCurrentBlock;
fCurrentBlock = nextBlock;
}
}
James David Berry
committed
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
DOMNodeList *DOMDocumentImpl::getDeepNodeList(const DOMNode *rootNode, const XMLCh *tagName)
{
if(!fNodeListPool) {
fNodeListPool = new (this) DOMDeepNodeListPool<DOMDeepNodeListImpl>(109, false);
}
DOMDeepNodeListImpl* retList = fNodeListPool->getByKey(rootNode, tagName, 0);
if (!retList) {
int id = fNodeListPool->put((void*) rootNode, (XMLCh*) tagName, 0, new (this) DOMDeepNodeListImpl(rootNode, tagName));
retList = fNodeListPool->getById(id);
}
return retList;
}
DOMNodeList *DOMDocumentImpl::getDeepNodeList(const DOMNode *rootNode, //DOM Level 2
const XMLCh *namespaceURI,
const XMLCh *localName)
{
if(!fNodeListPool) {
fNodeListPool = new (this) DOMDeepNodeListPool<DOMDeepNodeListImpl>(109, false);
}
DOMDeepNodeListImpl* retList = fNodeListPool->getByKey(rootNode, localName, namespaceURI);
if (!retList) {
// the pool will adopt the DOMDeepNodeListImpl
int id = fNodeListPool->put((void*) rootNode, (XMLCh*) localName, (XMLCh*) namespaceURI, new (this) DOMDeepNodeListImpl(rootNode, namespaceURI, localName));
retList = fNodeListPool->getById(id);
}
return retList;
}
const XMLCh* DOMDocumentImpl::getInputEncoding() const {
return fInputEncoding;
void DOMDocumentImpl::setInputEncoding(const XMLCh* actualEncoding){
fInputEncoding = cloneString(actualEncoding);
const XMLCh* DOMDocumentImpl::getXmlEncoding() const {
return fXmlEncoding;
void DOMDocumentImpl::setXmlEncoding(const XMLCh* encoding){
fXmlEncoding = cloneString(encoding);
bool DOMDocumentImpl::getXmlStandalone() const{
return fXmlStandalone;
void DOMDocumentImpl::setXmlStandalone(bool standalone){
fXmlStandalone = standalone;
const XMLCh* DOMDocumentImpl::getXmlVersion() const {
return fXmlVersion;
void DOMDocumentImpl::setXmlVersion(const XMLCh* version){
if ((version && *version) &&
!XMLString::equals(version, XMLUni::fgVersion1_0) &&
!XMLString::equals(version, XMLUni::fgVersion1_1))
throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager());
const XMLCh* DOMDocumentImpl::getDocumentURI() const
{
return fDocumentURI;
}
void DOMDocumentImpl::setDocumentURI(const XMLCh* documentURI){
if (documentURI && *documentURI) {
XMLCh* temp = (XMLCh*) this->allocate((XMLString::stringLen(documentURI) + 9)*sizeof(XMLCh));
XMLString::fixURI(documentURI, temp);
fDocumentURI = temp;
}
else
fDocumentURI = 0;
bool DOMDocumentImpl::getStrictErrorChecking() const {
return getErrorChecking();
}
void DOMDocumentImpl::setStrictErrorChecking(bool strictErrorChecking) {
setErrorChecking(strictErrorChecking);
}
DOMNode* DOMDocumentImpl::adoptNode(DOMNode* sourceNode) {