source: XMLIO_V2/external/src/POCO/XML/AbstractContainerNode.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 8.6 KB
Line 
1//
2// AbstractContainerNode.cpp
3//
4// $Id: //poco/1.3/XML/src/AbstractContainerNode.cpp#1 $
5//
6// Library: XML
7// Package: DOM
8// Module:  DOM
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include <Poco/DOM/AbstractContainerNode.h>
38#include <Poco/DOM/Document.h>
39#include <Poco/DOM/DOMException.h>
40
41
42namespace Poco {
43namespace XML {
44
45
46AbstractContainerNode::AbstractContainerNode(Document* pOwnerDocument): 
47        AbstractNode(pOwnerDocument),
48        _pFirstChild(0)
49{
50}
51
52
53AbstractContainerNode::AbstractContainerNode(Document* pOwnerDocument, const AbstractContainerNode& node): 
54        AbstractNode(pOwnerDocument, node),
55        _pFirstChild(0)
56{
57}
58
59
60AbstractContainerNode::~AbstractContainerNode()
61{
62        AbstractNode* pChild = static_cast<AbstractNode*>(_pFirstChild);
63        while (pChild)
64        {
65                AbstractNode* pDelNode = pChild;
66                pChild = pChild->_pNext;
67                pDelNode->_pNext   = 0;
68                pDelNode->_pParent = 0;
69                pDelNode->release();
70        }
71}
72
73
74Node* AbstractContainerNode::firstChild() const
75{
76        return _pFirstChild;
77}
78
79
80Node* AbstractContainerNode::lastChild() const
81{
82        AbstractNode* pChild = _pFirstChild;
83        if (pChild)
84        {
85                while (pChild->_pNext) pChild = pChild->_pNext;
86                return pChild;
87        }
88        return 0;
89}
90
91
92Node* AbstractContainerNode::insertBefore(Node* newChild, Node* refChild)
93{
94        poco_check_ptr (newChild);
95
96        if (static_cast<AbstractNode*>(newChild)->_pOwner != _pOwner && static_cast<AbstractNode*>(newChild)->_pOwner != this)
97                throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
98        if (refChild && static_cast<AbstractNode*>(refChild)->_pParent != this)
99                throw DOMException(DOMException::NOT_FOUND_ERR);
100        if (newChild == refChild)
101                return newChild;
102        if (this == newChild)
103                throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);
104
105        AbstractNode* pFirst = 0;
106        AbstractNode* pLast  = 0;
107        if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
108        {
109                AbstractContainerNode* pFrag = static_cast<AbstractContainerNode*>(newChild);
110                pFirst = pFrag->_pFirstChild;
111                pLast  = pFirst;
112                if (pFirst)
113                {
114                        while (pLast->_pNext)
115                        {
116                                pLast->_pParent = this;
117                                pLast = pLast->_pNext;
118                        }
119                        pLast->_pParent = this;
120                }
121                pFrag->_pFirstChild = 0;
122        }
123        else
124        {
125                newChild->duplicate();
126                AbstractContainerNode* pParent = static_cast<AbstractNode*>(newChild)->_pParent;
127                if (pParent) pParent->removeChild(newChild);
128                pFirst = static_cast<AbstractNode*>(newChild);
129                pLast  = pFirst;
130                pFirst->_pParent = this;
131        }
132        if (_pFirstChild && pFirst)
133        {
134                AbstractNode* pCur = _pFirstChild;
135                if (pCur == refChild)
136                {
137                        pLast->_pNext = _pFirstChild;
138                        _pFirstChild  = pFirst;
139                }
140                else
141                {
142                        while (pCur && pCur->_pNext != refChild) pCur = pCur->_pNext;
143                        if (pCur)
144                        {
145                                pLast->_pNext = pCur->_pNext;
146                                pCur->_pNext = pFirst;
147                        }
148                        else throw DOMException(DOMException::NOT_FOUND_ERR);
149                }
150        }
151        else _pFirstChild = pFirst;
152
153        if (events())
154        {
155                while (pFirst && pFirst != pLast->_pNext)
156                {
157                        pFirst->dispatchNodeInserted();
158                        pFirst->dispatchNodeInsertedIntoDocument();
159                        pFirst = pFirst->_pNext;
160                }
161                dispatchSubtreeModified();
162        }
163        return newChild;
164}
165
166
167Node* AbstractContainerNode::replaceChild(Node* newChild, Node* oldChild)
168{
169        poco_check_ptr (newChild);
170        poco_check_ptr (oldChild);
171
172        if (static_cast<AbstractNode*>(newChild)->_pOwner != _pOwner && static_cast<AbstractNode*>(newChild)->_pOwner != this)
173                throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
174        if (static_cast<AbstractNode*>(oldChild)->_pParent != this)
175                throw DOMException(DOMException::NOT_FOUND_ERR);
176        if (newChild == oldChild)
177                return newChild;
178        if (this == newChild)
179                throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);
180
181        bool doEvents = events();
182        if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
183        {
184                insertBefore(newChild, oldChild);
185                removeChild(oldChild);
186        }
187        else
188        {
189                AbstractContainerNode* pParent = static_cast<AbstractNode*>(newChild)->_pParent;
190                if (pParent) pParent->removeChild(newChild);
191
192                if (oldChild == _pFirstChild)
193                {
194                        if (doEvents)
195                        {
196                                _pFirstChild->dispatchNodeRemoved();
197                                _pFirstChild->dispatchNodeRemovedFromDocument();
198                        }
199                        static_cast<AbstractNode*>(newChild)->_pNext   = static_cast<AbstractNode*>(oldChild)->_pNext;
200                        static_cast<AbstractNode*>(newChild)->_pParent = this;
201                        _pFirstChild->_pNext   = 0;
202                        _pFirstChild->_pParent = 0;
203                        _pFirstChild = static_cast<AbstractNode*>(newChild);
204                        if (doEvents)
205                        {
206                                static_cast<AbstractNode*>(newChild)->dispatchNodeInserted();
207                                static_cast<AbstractNode*>(newChild)->dispatchNodeInsertedIntoDocument();
208                        }
209                }
210                else
211                {
212                        AbstractNode* pCur = _pFirstChild;
213                        while (pCur && pCur->_pNext != oldChild) pCur = pCur->_pNext;
214                        if (pCur)
215                        {       
216                                poco_assert_dbg (pCur->_pNext == oldChild);
217
218                                if (doEvents)
219                                {
220                                        static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved();
221                                        static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument();
222                                }
223                                static_cast<AbstractNode*>(newChild)->_pNext   = static_cast<AbstractNode*>(oldChild)->_pNext;
224                                static_cast<AbstractNode*>(newChild)->_pParent = this;
225                                static_cast<AbstractNode*>(oldChild)->_pNext   = 0;
226                                static_cast<AbstractNode*>(oldChild)->_pParent = 0;
227                                pCur->_pNext = static_cast<AbstractNode*>(newChild);
228                                if (doEvents)
229                                {
230                                        static_cast<AbstractNode*>(newChild)->dispatchNodeInserted();
231                                        static_cast<AbstractNode*>(newChild)->dispatchNodeInsertedIntoDocument();
232                                }
233                        }
234                        else throw DOMException(DOMException::NOT_FOUND_ERR);
235                }
236                newChild->duplicate();
237                oldChild->autoRelease();
238        }
239        if (doEvents) dispatchSubtreeModified();
240        return oldChild;
241}
242
243
244Node* AbstractContainerNode::removeChild(Node* oldChild)
245{
246        poco_check_ptr (oldChild);
247
248        bool doEvents = events();
249        if (oldChild == _pFirstChild)
250        {
251                if (doEvents)
252                {
253                        static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved();
254                        static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument();
255                }
256                _pFirstChild = _pFirstChild->_pNext;
257                static_cast<AbstractNode*>(oldChild)->_pNext   = 0;
258                static_cast<AbstractNode*>(oldChild)->_pParent = 0;
259        }
260        else
261        {
262                AbstractNode* pCur = _pFirstChild;
263                while (pCur && pCur->_pNext != oldChild) pCur = pCur->_pNext;
264                if (pCur)
265                {
266                        if (doEvents)
267                        {
268                                static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved();
269                                static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument();
270                        }
271                        pCur->_pNext = pCur->_pNext->_pNext;
272                        static_cast<AbstractNode*>(oldChild)->_pNext   = 0;
273                        static_cast<AbstractNode*>(oldChild)->_pParent = 0;
274                }
275                else throw DOMException(DOMException::NOT_FOUND_ERR);
276        }
277        oldChild->autoRelease();
278        if (doEvents) dispatchSubtreeModified();
279        return oldChild;
280}
281
282
283Node* AbstractContainerNode::appendChild(Node* newChild)
284{
285        return insertBefore(newChild, 0);
286}
287
288
289void AbstractContainerNode::dispatchNodeRemovedFromDocument()
290{
291        AbstractNode::dispatchNodeRemovedFromDocument();
292        Node* pChild = firstChild();
293        while (pChild)
294        {
295                static_cast<AbstractNode*>(pChild)->dispatchNodeRemovedFromDocument();
296                pChild = pChild->nextSibling();
297        }
298}
299
300
301void AbstractContainerNode::dispatchNodeInsertedIntoDocument()
302{
303        AbstractNode::dispatchNodeInsertedIntoDocument();
304        Node* pChild = firstChild();
305        while (pChild)
306        {
307                static_cast<AbstractNode*>(pChild)->dispatchNodeInsertedIntoDocument();
308                pChild = pChild->nextSibling();
309        }
310}
311
312
313bool AbstractContainerNode::hasChildNodes() const
314{
315        return _pFirstChild != 0;
316}
317
318
319bool AbstractContainerNode::hasAttributes() const
320{
321        return false;
322}
323
324
325} } // namespace Poco::XML
Note: See TracBrowser for help on using the repository browser.