⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractcontainernode.cpp

📁 This software aims to create an applet and panel tools to manage a wireless interface card, such as
💻 CPP
字号:
//
// AbstractContainerNode.cpp
//
// $Id: //poco/Main/XML/src/AbstractContainerNode.cpp#5 $
//
// Copyright (c) 2004, Guenter Obiltschnig/Applied Informatics.
// 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. Redistributions in any form must be accompanied by information on
//    how to obtain complete source code for this software and any
//    accompanying software that uses this software.  The source code
//    must either be included in the distribution or be available for no
//    more than the cost of distribution plus a nominal fee, and must be
//    freely redistributable under reasonable conditions.  For an
//    executable file, complete source code means the source code for all
//    modules it contains.  It does not include source code for modules or
//    files that typically accompany the major components of the operating
//    system on which the executable file runs.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS 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
// COPYRIGHT OWNER OR 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.
//


#include "DOM/AbstractContainerNode.h"
#include "DOM/Document.h"
#include "DOM/DOMException.h"


XML_BEGIN


AbstractContainerNode::AbstractContainerNode(Document* pOwnerDocument): 
	AbstractNode(pOwnerDocument),
	_pFirstChild(0)
{
}


AbstractContainerNode::AbstractContainerNode(Document* pOwnerDocument, const AbstractContainerNode& node): 
	AbstractNode(pOwnerDocument, node),
	_pFirstChild(0)
{
}


AbstractContainerNode::~AbstractContainerNode()
{
	AbstractNode* pChild = static_cast<AbstractNode*>(_pFirstChild);
	while (pChild)
	{
		AbstractNode* pDelNode = pChild;
		pChild = pChild->_pNext;
		pDelNode->_pNext   = 0;
		pDelNode->_pParent = 0;
		pDelNode->release();
	}
}


Node* AbstractContainerNode::firstChild() const
{
	return _pFirstChild;
}


Node* AbstractContainerNode::lastChild() const
{
	AbstractNode* pChild = _pFirstChild;
	if (pChild)
	{
		while (pChild->_pNext) pChild = pChild->_pNext;
		return pChild;
	}
	return 0;
}


Node* AbstractContainerNode::insertBefore(Node* newChild, Node* refChild)
{
	poco_check_ptr (newChild);

	if (static_cast<AbstractNode*>(newChild)->_pOwner != _pOwner && static_cast<AbstractNode*>(newChild)->_pOwner != this)
		throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
	if (refChild && static_cast<AbstractNode*>(refChild)->_pParent != this)
		throw DOMException(DOMException::NOT_FOUND_ERR);
	if (newChild == refChild)
		return newChild;
	if (this == newChild)
		throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);

	AbstractNode* pFirst = 0;
	AbstractNode* pLast  = 0;
	if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
	{
		AbstractContainerNode* pFrag = static_cast<AbstractContainerNode*>(newChild);
		pFirst = pFrag->_pFirstChild;
		pLast  = pFirst;
		if (pFirst)
		{
			while (pLast->_pNext)
			{
				pLast->_pParent = this;
				pLast = pLast->_pNext;
			}
			pLast->_pParent = this;
		}
		pFrag->_pFirstChild = 0;
	}
	else
	{
		newChild->duplicate();
		AbstractContainerNode* pParent = static_cast<AbstractNode*>(newChild)->_pParent;
		if (pParent) pParent->removeChild(newChild);
		pFirst = static_cast<AbstractNode*>(newChild);
		pLast  = pFirst;
		pFirst->_pParent = this;
	}
	if (_pFirstChild && pFirst)
	{
		AbstractNode* pCur = _pFirstChild;
		if (pCur == refChild)
		{
			pLast->_pNext = _pFirstChild;
			_pFirstChild  = pFirst;
		}
		else
		{
			while (pCur && pCur->_pNext != refChild) pCur = pCur->_pNext;
			if (pCur)
			{
				pLast->_pNext = pCur->_pNext;
				pCur->_pNext = pFirst;
			}
			else throw DOMException(DOMException::NOT_FOUND_ERR);
		}
	}
	else _pFirstChild = pFirst;

	if (events())
	{
		while (pFirst && pFirst != pLast->_pNext)
		{
			pFirst->dispatchNodeInserted();
			pFirst->dispatchNodeInsertedIntoDocument();
			pFirst = pFirst->_pNext;
		}
		dispatchSubtreeModified();
	}
	return newChild;
}


Node* AbstractContainerNode::replaceChild(Node* newChild, Node* oldChild)
{
	poco_check_ptr (newChild);
	poco_check_ptr (oldChild);

	if (static_cast<AbstractNode*>(newChild)->_pOwner != _pOwner && static_cast<AbstractNode*>(newChild)->_pOwner != this)
		throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
	if (static_cast<AbstractNode*>(oldChild)->_pParent != this)
		throw DOMException(DOMException::NOT_FOUND_ERR);
	if (newChild == oldChild)
		return newChild;
	if (this == newChild)
		throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);

	bool doEvents = events();
	if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
	{
		insertBefore(newChild, oldChild);
		removeChild(oldChild);
	}
	else
	{
		AbstractContainerNode* pParent = static_cast<AbstractNode*>(newChild)->_pParent;
		if (pParent) pParent->removeChild(newChild);

		if (oldChild == _pFirstChild)
		{
			if (doEvents)
			{
				_pFirstChild->dispatchNodeRemoved();
				_pFirstChild->dispatchNodeRemovedFromDocument();
			}
			static_cast<AbstractNode*>(newChild)->_pNext   = static_cast<AbstractNode*>(oldChild)->_pNext;
			static_cast<AbstractNode*>(newChild)->_pParent = this;
			_pFirstChild->_pNext   = 0;
			_pFirstChild->_pParent = 0;
			_pFirstChild = static_cast<AbstractNode*>(newChild);
			if (doEvents)
			{
				static_cast<AbstractNode*>(newChild)->dispatchNodeInserted();
				static_cast<AbstractNode*>(newChild)->dispatchNodeInsertedIntoDocument();
			}
		}
		else
		{
			AbstractNode* pCur = _pFirstChild;
			while (pCur && pCur->_pNext != oldChild) pCur = pCur->_pNext;
			if (pCur)
			{	
				poco_assert_dbg (pCur->_pNext == oldChild);

				if (doEvents)
				{
					static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved();
					static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument();
				}
				static_cast<AbstractNode*>(newChild)->_pNext   = static_cast<AbstractNode*>(oldChild)->_pNext;
				static_cast<AbstractNode*>(newChild)->_pParent = this;
				static_cast<AbstractNode*>(oldChild)->_pNext   = 0;
				static_cast<AbstractNode*>(oldChild)->_pParent = 0;
				pCur->_pNext = static_cast<AbstractNode*>(newChild);
				if (doEvents)
				{
					static_cast<AbstractNode*>(newChild)->dispatchNodeInserted();
					static_cast<AbstractNode*>(newChild)->dispatchNodeInsertedIntoDocument();
				}
			}
			else throw DOMException(DOMException::NOT_FOUND_ERR);
		}
		newChild->duplicate();
		oldChild->autoRelease();
	}
	if (doEvents) dispatchSubtreeModified();
	return oldChild;
}


Node* AbstractContainerNode::removeChild(Node* oldChild)
{
	poco_check_ptr (oldChild);

	bool doEvents = events();
	if (oldChild == _pFirstChild)
	{
		if (doEvents)
		{
			static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved();
			static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument();
		}
		_pFirstChild = _pFirstChild->_pNext;
		static_cast<AbstractNode*>(oldChild)->_pNext   = 0;
		static_cast<AbstractNode*>(oldChild)->_pParent = 0;
	}
	else
	{
		AbstractNode* pCur = _pFirstChild;
		while (pCur && pCur->_pNext != oldChild) pCur = pCur->_pNext;
		if (pCur)
		{
			if (doEvents)
			{
				static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved();
				static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument();
			}
			pCur->_pNext = pCur->_pNext->_pNext;
			static_cast<AbstractNode*>(oldChild)->_pNext   = 0;
			static_cast<AbstractNode*>(oldChild)->_pParent = 0;
		}
		else throw DOMException(DOMException::NOT_FOUND_ERR);
	}
	oldChild->autoRelease();
	if (doEvents) dispatchSubtreeModified();
	return oldChild;
}


Node* AbstractContainerNode::appendChild(Node* newChild)
{
	return insertBefore(newChild, 0);
}


void AbstractContainerNode::dispatchNodeRemovedFromDocument()
{
	AbstractNode::dispatchNodeRemovedFromDocument();
	Node* pChild = firstChild();
	while (pChild)
	{
		static_cast<AbstractNode*>(pChild)->dispatchNodeRemovedFromDocument();
		pChild = pChild->nextSibling();
	}
}


void AbstractContainerNode::dispatchNodeInsertedIntoDocument()
{
	AbstractNode::dispatchNodeInsertedIntoDocument();
	Node* pChild = firstChild();
	while (pChild)
	{
		static_cast<AbstractNode*>(pChild)->dispatchNodeInsertedIntoDocument();
		pChild = pChild->nextSibling();
	}
}


bool AbstractContainerNode::hasChildNodes() const
{
	return _pFirstChild != 0;
}


bool AbstractContainerNode::hasAttributes() const
{
	return false;
}


XML_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -