Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <node.hxx>
21 : :
22 : : #include <stdio.h>
23 : : #include <string.h>
24 : :
25 : : #include <libxml/xmlstring.h>
26 : :
27 : : #include <algorithm>
28 : :
29 : : #include <boost/bind.hpp>
30 : :
31 : : #include <rtl/uuid.h>
32 : : #include <rtl/instance.hxx>
33 : : #include <osl/mutex.hxx>
34 : :
35 : : #include <com/sun/star/xml/sax/FastToken.hpp>
36 : :
37 : : #include <comphelper/servicehelper.hxx>
38 : :
39 : : #include <document.hxx>
40 : : #include <attr.hxx>
41 : : #include <childlist.hxx>
42 : :
43 : : #include "../events/eventdispatcher.hxx"
44 : : #include "../events/mutationevent.hxx"
45 : :
46 : :
47 : :
48 : : using namespace ::com::sun::star;
49 : :
50 : : namespace
51 : : {
52 : : class theCNodeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theCNodeUnoTunnelId > {};
53 : : }
54 : :
55 : : namespace DOM
56 : : {
57 : 2580 : void pushContext(Context& io_rContext)
58 : : {
59 : : // Explicitly use a temp. variable.
60 : : // Windows/VC++ seems to mess up if .back() is directly passed as
61 : : // parameter. i.e. Don't use push_back( .back() );
62 [ + - ][ + - ]: 2580 : Context::NamespaceVectorType::value_type aVal = io_rContext.maNamespaces.back();
63 [ + - ]: 2580 : io_rContext.maNamespaces.push_back( aVal );
64 : 2580 : }
65 : :
66 : 2580 : void popContext(Context& io_rContext)
67 : : {
68 : 2580 : io_rContext.maNamespaces.pop_back();
69 : 2580 : }
70 : :
71 : 2580 : void addNamespaces(Context& io_rContext, xmlNodePtr pNode)
72 : : {
73 : : // add node's namespaces to current context
74 [ + + ]: 2601 : for (xmlNsPtr pNs = pNode->nsDef; pNs != 0; pNs = pNs->next) {
75 : 21 : const xmlChar *pPrefix = pNs->prefix;
76 : : // prefix can be NULL when xmlns attribute is empty (xmlns="")
77 : : OString prefix(reinterpret_cast<const sal_Char*>(pPrefix),
78 [ + - ]: 21 : pPrefix ? strlen(reinterpret_cast<const char*>(pPrefix)) : 0);
79 : 21 : const xmlChar *pHref = pNs->href;
80 : : OUString val(reinterpret_cast<const sal_Char*>(pHref),
81 : 21 : strlen(reinterpret_cast<const char*>(pHref)),
82 [ + - ]: 21 : RTL_TEXTENCODING_UTF8);
83 : :
84 : : OSL_TRACE("Trying to add namespace %s (prefix %s)",
85 : : (const char*)pHref, (const char*)pPrefix);
86 : :
87 : : Context::NamespaceMapType::iterator aIter=
88 [ + - ]: 21 : io_rContext.maNamespaceMap.find(val);
89 [ + - ][ + - ]: 21 : if( aIter != io_rContext.maNamespaceMap.end() )
90 : : {
91 : 21 : Context::Namespace aNS;
92 : 21 : aNS.maPrefix = prefix;
93 [ + - ]: 21 : aNS.mnToken = aIter->second;
94 : 21 : aNS.maNamespaceURL = val;
95 : :
96 [ + - ][ + - ]: 21 : io_rContext.maNamespaces.back().push_back(aNS);
97 : :
98 : 21 : OSL_TRACE("Added with token 0x%x", aIter->second);
99 : : }
100 : 21 : }
101 : 2580 : }
102 : :
103 : 5877 : sal_Int32 getToken( const Context& rContext, const sal_Char* pToken )
104 : : {
105 [ + - ]: 5877 : const Sequence<sal_Int8> aSeq( (sal_Int8*)pToken, strlen( pToken ) );
106 [ + - ][ + - ]: 5877 : return rContext.mxTokenHandler->getTokenFromUTF8( aSeq );
[ + - ]
107 : : }
108 : :
109 : 2580 : sal_Int32 getTokenWithPrefix( const Context& rContext, const sal_Char* pPrefix, const sal_Char* pName )
110 : : {
111 : 2580 : sal_Int32 nNamespaceToken = FastToken::DONTKNOW;
112 : : OString prefix(pPrefix,
113 : 2580 : strlen(reinterpret_cast<const char*>(pPrefix)));
114 : :
115 : : OSL_TRACE("getTokenWithPrefix(): prefix %s, name %s",
116 : : (const char*)pPrefix, (const char*)pName);
117 : :
118 : 2580 : Context::NamespaceVectorType::value_type::const_iterator aIter;
119 [ + - ][ + - ]: 5160 : if( (aIter=std::find_if(rContext.maNamespaces.back().begin(),
[ + - ]
120 [ + - ]: 2580 : rContext.maNamespaces.back().end(),
121 : : boost::bind(std::equal_to<OString>(),
122 : : boost::bind(&Context::Namespace::getPrefix,
123 : : _1),
124 [ + - ][ + - ]: 7740 : boost::cref(prefix)))) != rContext.maNamespaces.back().end() )
[ + - ][ + - ]
[ + - ]
125 : : {
126 : 2580 : nNamespaceToken = aIter->mnToken;
127 [ + - ]: 2580 : sal_Int32 nNameToken = getToken( rContext, pName );
128 [ + - ]: 2580 : if( nNameToken != FastToken::DONTKNOW )
129 : 2580 : nNamespaceToken |= nNameToken;
130 : : }
131 : :
132 : 2580 : return nNamespaceToken;
133 : : }
134 : :
135 : :
136 : 169478 : CNode::CNode(CDocument const& rDocument, ::osl::Mutex const& rMutex,
137 : : NodeType const& reNodeType, xmlNodePtr const& rpNode)
138 : : : m_bUnlinked(false)
139 : : , m_aNodeType(reNodeType)
140 : : , m_aNodePtr(rpNode)
141 : : // keep containing document alive
142 : : // (but not if this is a document; that would create a leak!)
143 : : , m_xDocument( (m_aNodePtr->type != XML_DOCUMENT_NODE)
144 : : ? &const_cast<CDocument&>(rDocument) : 0 )
145 [ + + ]: 169478 : , m_rMutex(const_cast< ::osl::Mutex & >(rMutex))
146 : : {
147 : : OSL_ASSERT(m_aNodePtr);
148 : 169478 : }
149 : :
150 : 168902 : void CNode::invalidate()
151 : : {
152 : : //remove from list if this wrapper goes away
153 [ + + ][ + + ]: 168902 : if (m_aNodePtr != 0 && m_xDocument.is()) {
[ + + ]
154 : 156653 : m_xDocument->RemoveCNode(m_aNodePtr, this);
155 : : }
156 : : // #i113663#: unlinked nodes will not be freed by xmlFreeDoc
157 [ + + ]: 168902 : if (m_bUnlinked) {
158 : 1156 : xmlFreeNode(m_aNodePtr);
159 : : }
160 : 168902 : m_aNodePtr = 0;
161 : 168902 : }
162 : :
163 : 168854 : CNode::~CNode()
164 : : {
165 : : // if this is the document itself, the mutex is already freed!
166 [ + + ]: 168854 : if (NodeType_DOCUMENT_NODE == m_aNodeType) {
167 [ + - ]: 12201 : invalidate();
168 : : } else {
169 [ + - ]: 156653 : ::osl::MutexGuard const g(m_rMutex);
170 [ + - ][ + - ]: 156653 : invalidate(); // other nodes are still alive so must lock mutex
171 : : }
172 [ - + ]: 168854 : }
173 : :
174 : : CNode *
175 : 237723 : CNode::GetImplementation(uno::Reference<uno::XInterface> const& xNode)
176 : : {
177 [ + - ]: 237723 : uno::Reference<lang::XUnoTunnel> const xUnoTunnel(xNode, UNO_QUERY);
178 [ + + ]: 237723 : if (!xUnoTunnel.is()) { return 0; }
179 : : CNode *const pCNode( reinterpret_cast< CNode* >(
180 : : ::sal::static_int_cast< sal_IntPtr >(
181 [ + - ][ + - ]: 237703 : xUnoTunnel->getSomething(theCNodeUnoTunnelId::get().getSeq()))));
[ + - ]
182 : 237723 : return pCNode;
183 : : }
184 : :
185 : 405987 : CDocument & CNode::GetOwnerDocument()
186 : : {
187 : : OSL_ASSERT(m_xDocument.is());
188 : 405987 : return *m_xDocument; // needs overriding in CDocument!
189 : : }
190 : :
191 : :
192 : 35614 : static void lcl_nsexchange(
193 : : xmlNodePtr const aNode, xmlNsPtr const oldNs, xmlNsPtr const newNs)
194 : : {
195 : : // recursively exchange any references to oldNs with references to newNs
196 : 35614 : xmlNodePtr cur = aNode;
197 [ + + ]: 56800 : while (cur != 0)
198 : : {
199 [ + + ]: 21186 : if (cur->ns == oldNs)
200 : 16553 : cur->ns = newNs;
201 [ + + ]: 21186 : if (cur->type == XML_ELEMENT_NODE)
202 : : {
203 : 19050 : xmlAttrPtr curAttr = cur->properties;
204 [ + + ]: 25429 : while(curAttr != 0)
205 : : {
206 [ + + ]: 6379 : if (curAttr->ns == oldNs)
207 : 259 : curAttr->ns = newNs;
208 : 6379 : curAttr = curAttr->next;
209 : : }
210 : 19050 : lcl_nsexchange(cur->children, oldNs, newNs);
211 : : }
212 : 21186 : cur = cur->next;
213 : : }
214 : 35614 : }
215 : :
216 : 88690 : /*static*/ void nscleanup(const xmlNodePtr aNode, const xmlNodePtr aParent)
217 : : {
218 : 88690 : xmlNodePtr cur = aNode;
219 : :
220 : : //handle attributes
221 [ + + ][ + + ]: 88690 : if (cur != NULL && cur->type == XML_ELEMENT_NODE)
222 : : {
223 : 29014 : xmlAttrPtr curAttr = cur->properties;
224 [ + + ]: 46266 : while(curAttr != 0)
225 : : {
226 [ + + ]: 17252 : if (curAttr->ns != NULL)
227 : : {
228 : 13600 : xmlNsPtr ns = xmlSearchNs(cur->doc, aParent, curAttr->ns->prefix);
229 [ + + ]: 13600 : if (ns != NULL)
230 : 70 : curAttr->ns = ns;
231 : : }
232 : 17252 : curAttr = curAttr->next;
233 : : }
234 : : }
235 : :
236 [ + + ]: 136410 : while (cur != NULL)
237 : : {
238 : 47720 : nscleanup(cur->children, cur);
239 [ + + ]: 47720 : if (cur->ns != NULL)
240 : : {
241 : 31857 : xmlNsPtr ns = xmlSearchNs(cur->doc, aParent, cur->ns->prefix);
242 [ + + ][ + - ]: 31857 : if (ns != NULL && ns != cur->ns && strcmp((char*)ns->href, (char*)cur->ns->href)==0)
[ + + ]
243 : : {
244 : 16553 : xmlNsPtr curDef = cur->nsDef;
245 : 16553 : xmlNsPtr *refp = &(cur->nsDef); // insert point
246 [ + + ]: 33117 : while (curDef != NULL)
247 : : {
248 : 16564 : ns = xmlSearchNs(cur->doc, aParent, curDef->prefix);
249 [ + - ][ + - ]: 16564 : if (ns != NULL && ns != curDef && strcmp((char*)ns->href, (char*)curDef->href)==0)
[ + - ]
250 : : {
251 : : // reconnect ns pointers in sub-tree to newly found ns before
252 : : // removing redundant nsdecl to prevent dangling pointers.
253 : 16564 : lcl_nsexchange(cur, curDef, ns);
254 : 16564 : *refp = curDef->next;
255 : 16564 : xmlFreeNs(curDef);
256 : 16564 : curDef = *refp;
257 : : } else {
258 : 0 : refp = &(curDef->next);
259 : 0 : curDef = curDef->next;
260 : : }
261 : : }
262 : : }
263 : : }
264 : 47720 : cur = cur->next;
265 : : }
266 : 88690 : }
267 : :
268 : 0 : void CNode::saxify(const Reference< XDocumentHandler >& i_xHandler)
269 : : {
270 [ # # ][ # # ]: 0 : if (!i_xHandler.is()) throw RuntimeException();
271 : : // default: do nothing
272 : 0 : }
273 : :
274 : 0 : void CNode::fastSaxify(Context& io_rContext)
275 : : {
276 [ # # ][ # # ]: 0 : if (!io_rContext.mxDocHandler.is()) throw RuntimeException();
277 : : // default: do nothing
278 : 0 : }
279 : :
280 : 8 : bool CNode::IsChildTypeAllowed(NodeType const /*nodeType*/)
281 : : {
282 : : // default: no children allowed
283 : 8 : return false;
284 : : }
285 : :
286 : : /**
287 : : Adds the node newChild to the end of the list of children of this node.
288 : : */
289 : 40931 : Reference< XNode > SAL_CALL CNode::appendChild(
290 : : Reference< XNode > const& xNewChild)
291 : : throw (RuntimeException, DOMException)
292 : : {
293 [ + - ]: 40931 : ::osl::ClearableMutexGuard guard(m_rMutex);
294 : :
295 [ - + ][ # # ]: 40931 : if (0 == m_aNodePtr) { return 0; }
296 : :
297 [ + - ]: 40931 : CNode *const pNewChild(CNode::GetImplementation(xNewChild));
298 [ + + ][ + - ]: 40931 : if (!pNewChild) { throw RuntimeException(); }
299 : 40913 : xmlNodePtr const cur = pNewChild->GetNodePtr();
300 [ # # ][ - + ]: 40913 : if (!cur) { throw RuntimeException(); }
301 : :
302 : : // error checks:
303 : : // from other document
304 [ - + ]: 40913 : if (cur->doc != m_aNodePtr->doc) {
305 [ # # ]: 0 : DOMException e;
306 : 0 : e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
307 [ # # ]: 0 : throw e;
308 : : }
309 : : // same node
310 [ - + ]: 40913 : if (cur == m_aNodePtr) {
311 [ # # ]: 0 : DOMException e;
312 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
313 [ # # ]: 0 : throw e;
314 : : }
315 [ - + ]: 40913 : if (cur->parent != NULL) {
316 [ # # ]: 0 : DOMException e;
317 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
318 [ # # ]: 0 : throw e;
319 : : }
320 [ + - ][ + + ]: 40913 : if (!IsChildTypeAllowed(pNewChild->m_aNodeType)) {
321 [ + - ]: 8 : DOMException e;
322 : 8 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
323 [ + - ]: 8 : throw e;
324 : : }
325 : :
326 : : // check whether this is an attribute node; it needs special handling
327 : 40905 : xmlNodePtr res = NULL;
328 [ + + ]: 40905 : if (cur->type == XML_ATTRIBUTE_NODE)
329 : : {
330 : : xmlChar const*const pChildren((cur->children)
331 : : ? cur->children->content
332 [ - + ]: 2 : : reinterpret_cast<xmlChar const*>(""));
333 [ - + ]: 2 : CAttr *const pCAttr(dynamic_cast<CAttr *>(pNewChild));
334 [ - + ][ # # ]: 2 : if (!pCAttr) { throw RuntimeException(); }
335 [ + - ]: 2 : xmlNsPtr const pNs( pCAttr->GetNamespace(m_aNodePtr) );
336 [ - + ]: 2 : if (pNs) {
337 : : res = reinterpret_cast<xmlNodePtr>(
338 [ # # ]: 0 : xmlNewNsProp(m_aNodePtr, pNs, cur->name, pChildren));
339 : : } else {
340 : : res = reinterpret_cast<xmlNodePtr>(
341 [ + - ]: 2 : xmlNewProp(m_aNodePtr, cur->name, pChildren));
342 : : }
343 : : }
344 : : else
345 : : {
346 [ + - ]: 40903 : res = xmlAddChild(m_aNodePtr, cur);
347 : :
348 : : // libxml can do optimization when appending nodes.
349 : : // if res != cur, something was optimized and the newchild-wrapper
350 : : // should be updated
351 [ + - ][ + + ]: 40903 : if (res && (cur != res)) {
352 [ + - ]: 40 : pNewChild->invalidate(); // cur has been freed
353 : : }
354 : : }
355 : :
356 [ - + ][ # # ]: 40905 : if (!res) { return 0; }
357 : :
358 : : // use custom ns cleanup instead of
359 : : // xmlReconciliateNs(m_aNodePtr->doc, m_aNodePtr);
360 : : // because that will not remove unneeded ns decls
361 [ + - ]: 40905 : nscleanup(res, m_aNodePtr);
362 : :
363 [ + - ][ + - ]: 40905 : ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(res);
364 : :
365 [ - + ][ # # ]: 40905 : if (!pNode.is()) { return 0; }
366 : :
367 : : // dispatch DOMNodeInserted event, target is the new node
368 : : // this node is the related node
369 : : // does bubble
370 : 40905 : pNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
371 [ + - ][ + - ]: 40905 : Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
372 [ + - ]: 40905 : Reference< XMutationEvent > event(docevent->createEvent(
373 [ + - ][ + - ]: 40905 : "DOMNodeInserted"), UNO_QUERY);
374 [ + - ]: 40905 : event->initMutationEvent("DOMNodeInserted", sal_True, sal_False, this,
375 [ + - ][ + - ]: 40905 : OUString(), OUString(), OUString(), (AttrChangeType)0 );
376 : :
377 : : // the following dispatch functions use only UNO interfaces
378 : : // and call event listeners, so release mutex to prevent deadlocks.
379 [ + - ]: 40905 : guard.clear();
380 : :
381 [ + - ][ + - ]: 40905 : dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
382 : : // dispatch subtree modified for this node
383 [ + - ]: 40905 : dispatchSubtreeModified();
384 : :
385 [ + - ][ + - ]: 40931 : return pNode.get();
[ + - ]
386 : : }
387 : :
388 : : /**
389 : : Returns a duplicate of this node, i.e., serves as a generic copy
390 : : constructor for nodes.
391 : : */
392 : 32 : Reference< XNode > SAL_CALL CNode::cloneNode(sal_Bool bDeep)
393 : : throw (RuntimeException)
394 : : {
395 [ + - ]: 32 : ::osl::MutexGuard const g(m_rMutex);
396 : :
397 [ - + ]: 32 : if (0 == m_aNodePtr) {
398 [ # # ]: 0 : return 0;
399 : : }
400 [ + - ]: 32 : ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
401 [ + + ][ + - ]: 64 : xmlCopyNode(m_aNodePtr, (bDeep) ? 1 : 0));
[ + - ]
402 [ - + ][ # # ]: 32 : if (!pNode.is()) { return 0; }
403 : 32 : pNode->m_bUnlinked = true; // not linked yet
404 [ + - ][ + - ]: 32 : return pNode.get();
[ + - ]
405 : : }
406 : :
407 : : /**
408 : : A NamedNodeMap containing the attributes of this node (if it is an Element)
409 : : or null otherwise.
410 : : */
411 : 16 : Reference< XNamedNodeMap > SAL_CALL CNode::getAttributes()
412 : : throw (RuntimeException)
413 : : {
414 : : // return empty reference; only element node may override this impl
415 : 16 : return Reference< XNamedNodeMap>();
416 : : }
417 : :
418 : : /**
419 : : A NodeList that contains all children of this node.
420 : : */
421 : 20 : Reference< XNodeList > SAL_CALL CNode::getChildNodes()
422 : : throw (RuntimeException)
423 : : {
424 [ + - ]: 20 : ::osl::MutexGuard const g(m_rMutex);
425 : :
426 [ - + ]: 20 : if (0 == m_aNodePtr) {
427 [ # # ]: 0 : return 0;
428 : : }
429 [ + - ][ + - ]: 20 : Reference< XNodeList > const xNodeList(new CChildList(this, m_rMutex));
[ + - ]
430 [ + - ]: 20 : return xNodeList;
431 : : }
432 : :
433 : : /**
434 : : The first child of this node.
435 : : */
436 : 25994 : Reference< XNode > SAL_CALL CNode::getFirstChild()
437 : : throw (RuntimeException)
438 : : {
439 [ + - ]: 25994 : ::osl::MutexGuard const g(m_rMutex);
440 : :
441 [ - + ]: 25994 : if (0 == m_aNodePtr) {
442 [ # # ]: 0 : return 0;
443 : : }
444 : : Reference< XNode > const xNode(
445 [ + - ][ + - ]: 25994 : GetOwnerDocument().GetCNode(m_aNodePtr->children).get());
[ + + ][ + - ]
446 [ + - ]: 25994 : return xNode;
447 : : }
448 : :
449 : : /**
450 : : The last child of this node.
451 : : */
452 : 40 : Reference< XNode > SAL_CALL CNode::getLastChild()
453 : : throw (RuntimeException)
454 : : {
455 [ + - ]: 40 : ::osl::MutexGuard const g(m_rMutex);
456 : :
457 [ - + ]: 40 : if (0 == m_aNodePtr) {
458 [ # # ]: 0 : return 0;
459 : : }
460 : : Reference< XNode > const xNode(
461 [ + - ][ + - ]: 40 : GetOwnerDocument().GetCNode(xmlGetLastChild(m_aNodePtr)).get());
[ + - ][ + - ]
[ + - ]
462 [ + - ]: 40 : return xNode;
463 : : }
464 : :
465 : : /**
466 : : Returns the local part of the qualified name of this node.
467 : : */
468 : 14 : OUString SAL_CALL CNode::getLocalName()
469 : : throw (RuntimeException)
470 : : {
471 : : // see CElement/CAttr
472 : 14 : return ::rtl::OUString();
473 : : }
474 : :
475 : :
476 : : /**
477 : : The namespace URI of this node, or null if it is unspecified.
478 : : */
479 : 18454 : OUString SAL_CALL CNode::getNamespaceURI()
480 : : throw (RuntimeException)
481 : : {
482 [ + - ]: 18454 : ::osl::MutexGuard const g(m_rMutex);
483 : :
484 : 18454 : OUString aURI;
485 [ + + ][ + + ]: 18454 : if (m_aNodePtr != NULL &&
[ + + ][ + - ]
486 : : (m_aNodePtr->type == XML_ELEMENT_NODE || m_aNodePtr->type == XML_ATTRIBUTE_NODE) &&
487 : : m_aNodePtr->ns != NULL)
488 : : {
489 : 18432 : const xmlChar* xHref = m_aNodePtr->ns->href;
490 [ + - ]: 18432 : aURI = OUString((sal_Char*)xHref, strlen((char*)xHref), RTL_TEXTENCODING_UTF8);
491 : : }
492 [ + - ]: 18454 : return aURI;
493 : : }
494 : :
495 : : /**
496 : : The node immediately following this node.
497 : : */
498 : 1252 : Reference< XNode > SAL_CALL CNode::getNextSibling()
499 : : throw (RuntimeException)
500 : : {
501 [ + - ]: 1252 : ::osl::MutexGuard const g(m_rMutex);
502 : :
503 [ - + ]: 1252 : if (0 == m_aNodePtr) {
504 [ # # ]: 0 : return 0;
505 : : }
506 : : Reference< XNode > const xNode(
507 [ + - ][ + - ]: 1252 : GetOwnerDocument().GetCNode(m_aNodePtr->next).get());
[ + + ][ + - ]
508 [ + - ]: 1252 : return xNode;
509 : : }
510 : :
511 : : /**
512 : : The name of this node, depending on its type; see the table above.
513 : : */
514 : 0 : OUString SAL_CALL CNode::getNodeName()
515 : : throw (RuntimeException)
516 : : {
517 : : /*
518 : : Interface nodeName nodeValue attributes
519 : : --------------------------------------------------------------------------------------
520 : : Attr name of attribute value of attribute null
521 : : CDATASection "#cdata-section" content of the CDATA Section null
522 : : Comment "#comment" content of the comment null
523 : : Document "#document" null null
524 : : DocumentFragment "#document-fragment" null null
525 : : DocumentType document type name null null
526 : : Element tag name null NamedNodeMap
527 : : Entity entity name null null
528 : : EntityReference name of entity null null
529 : : referenced
530 : : Notation notation name null null
531 : : Processing\ target entire content excluding null
532 : : Instruction the target
533 : : Text "#text" content of the text node null
534 : : */
535 : 0 : OUString aName;
536 : 0 : return aName;
537 : : }
538 : :
539 : : /**
540 : : A code representing the type of the underlying object, as defined above.
541 : : */
542 : 5338 : NodeType SAL_CALL CNode::getNodeType()
543 : : throw (RuntimeException)
544 : : {
545 [ + - ]: 5338 : ::osl::MutexGuard const g(m_rMutex);
546 : :
547 [ + - ]: 5338 : return m_aNodeType;
548 : : }
549 : :
550 : : /**
551 : : The value of this node, depending on its type; see the table above.
552 : : */
553 : 0 : OUString SAL_CALL CNode::getNodeValue()
554 : : throw (RuntimeException)
555 : : {
556 : 0 : OUString aValue;
557 : 0 : return aValue;
558 : : }
559 : :
560 : : /**
561 : : The Document object associated with this node.
562 : : */
563 : 226675 : Reference< XDocument > SAL_CALL CNode::getOwnerDocument()
564 : : throw (RuntimeException)
565 : : {
566 [ + - ]: 226675 : ::osl::MutexGuard const g(m_rMutex);
567 : :
568 [ - + ]: 226675 : if (0 == m_aNodePtr) {
569 [ # # ]: 0 : return 0;
570 : : }
571 [ + - ][ + - ]: 226675 : Reference< XDocument > const xDoc(& GetOwnerDocument());
[ + - ]
572 [ + - ]: 226675 : return xDoc;
573 : : }
574 : :
575 : : /**
576 : : The parent of this node.
577 : : */
578 : 1212 : Reference< XNode > SAL_CALL CNode::getParentNode()
579 : : throw (RuntimeException)
580 : : {
581 [ + - ]: 1212 : ::osl::MutexGuard const g(m_rMutex);
582 : :
583 [ - + ]: 1212 : if (0 == m_aNodePtr) {
584 [ # # ]: 0 : return 0;
585 : : }
586 : : Reference< XNode > const xNode(
587 [ + - ][ + - ]: 1212 : GetOwnerDocument().GetCNode(m_aNodePtr->parent).get());
[ + + ][ + - ]
588 [ + - ]: 1212 : return xNode;
589 : : }
590 : :
591 : : /**
592 : : The namespace prefix of this node, or null if it is unspecified.
593 : : */
594 : 4281 : OUString SAL_CALL CNode::getPrefix()
595 : : throw (RuntimeException)
596 : : {
597 [ + - ]: 4281 : ::osl::MutexGuard const g(m_rMutex);
598 : :
599 : 4281 : OUString aPrefix;
600 [ + + ][ + + ]: 4281 : if (m_aNodePtr != NULL &&
[ + + ][ + - ]
601 : : (m_aNodePtr->type == XML_ELEMENT_NODE || m_aNodePtr->type == XML_ATTRIBUTE_NODE) &&
602 : : m_aNodePtr->ns != NULL)
603 : : {
604 : 4259 : const xmlChar* xPrefix = m_aNodePtr->ns->prefix;
605 [ + - ]: 4259 : if( xPrefix != NULL )
606 [ + - ]: 4259 : aPrefix = OUString((sal_Char*)xPrefix, strlen((char*)xPrefix), RTL_TEXTENCODING_UTF8);
607 : : }
608 [ + - ]: 4281 : return aPrefix;
609 : :
610 : : }
611 : :
612 : : /**
613 : : The node immediately preceding this node.
614 : : */
615 : 18 : Reference< XNode > SAL_CALL CNode::getPreviousSibling()
616 : : throw (RuntimeException)
617 : : {
618 [ + - ]: 18 : ::osl::MutexGuard const g(m_rMutex);
619 : :
620 [ - + ]: 18 : if (0 == m_aNodePtr) {
621 [ # # ]: 0 : return 0;
622 : : }
623 : : Reference< XNode > const xNode(
624 [ + - ][ + - ]: 18 : GetOwnerDocument().GetCNode(m_aNodePtr->prev).get());
[ - + ][ + - ]
625 [ + - ]: 18 : return xNode;
626 : : }
627 : :
628 : : /**
629 : : Returns whether this node (if it is an element) has any attributes.
630 : : */
631 : 901 : sal_Bool SAL_CALL CNode::hasAttributes()
632 : : throw (RuntimeException)
633 : : {
634 [ + - ]: 901 : ::osl::MutexGuard const g(m_rMutex);
635 : :
636 [ + - ][ + + ]: 901 : return (m_aNodePtr != NULL && m_aNodePtr->properties != NULL);
[ + - ]
637 : : }
638 : :
639 : : /**
640 : : Returns whether this node has any children.
641 : : */
642 : 72 : sal_Bool SAL_CALL CNode::hasChildNodes()
643 : : throw (RuntimeException)
644 : : {
645 [ + - ]: 72 : ::osl::MutexGuard const g(m_rMutex);
646 : :
647 [ + - ][ + + ]: 72 : return (m_aNodePtr != NULL && m_aNodePtr->children != NULL);
[ + - ]
648 : : }
649 : :
650 : : /**
651 : : Inserts the node newChild before the existing child node refChild.
652 : : */
653 : 48 : Reference< XNode > SAL_CALL CNode::insertBefore(
654 : : const Reference< XNode >& newChild, const Reference< XNode >& refChild)
655 : : throw (RuntimeException, DOMException)
656 : : {
657 [ + + ][ + + ]: 48 : if (!newChild.is() || !refChild.is()) { throw RuntimeException(); }
[ + + ][ + - ]
658 : :
659 [ + - ][ + - ]: 28 : if (newChild->getOwnerDocument() != getOwnerDocument()) {
[ + - ][ + - ]
[ - + ]
660 [ # # ]: 0 : DOMException e;
661 : 0 : e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
662 [ # # ]: 0 : throw e;
663 : : }
664 [ + - ][ + - ]: 28 : if (refChild->getParentNode() != Reference< XNode >(this)) {
[ + - ][ + - ]
[ + + ]
665 [ + - ]: 18 : DOMException e;
666 : 18 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
667 [ + - ]: 18 : throw e;
668 : : }
669 : :
670 [ + - ]: 10 : ::osl::ClearableMutexGuard guard(m_rMutex);
671 : :
672 [ + - ]: 10 : CNode *const pNewNode(CNode::GetImplementation(newChild));
673 [ + - ]: 10 : CNode *const pRefNode(CNode::GetImplementation(refChild));
674 [ + - ][ - + ]: 10 : if (!pNewNode || !pRefNode) { throw RuntimeException(); }
[ # # ]
675 : 10 : xmlNodePtr const pNewChild(pNewNode->GetNodePtr());
676 : 10 : xmlNodePtr const pRefChild(pRefNode->GetNodePtr());
677 [ - + ][ # # ]: 10 : if (!pNewChild || !pRefChild) { throw RuntimeException(); }
[ + - ]
678 : :
679 [ - + ]: 10 : if (pNewChild == m_aNodePtr) {
680 [ # # ]: 0 : DOMException e;
681 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
682 [ # # ]: 0 : throw e;
683 : : }
684 : : // already has parent
685 [ - + ]: 10 : if (pNewChild->parent != NULL)
686 : : {
687 [ # # ]: 0 : DOMException e;
688 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
689 [ # # ]: 0 : throw e;
690 : : }
691 [ + - ][ - + ]: 10 : if (!IsChildTypeAllowed(pNewNode->m_aNodeType)) {
692 [ # # ]: 0 : DOMException e;
693 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
694 [ # # ]: 0 : throw e;
695 : : }
696 : :
697 : : // attributes are unordered anyway, so just do appendChild
698 [ - + ]: 10 : if (XML_ATTRIBUTE_NODE == pNewChild->type) {
699 [ # # ]: 0 : guard.clear();
700 [ # # ]: 0 : return appendChild(newChild);
701 : : }
702 : :
703 : 10 : xmlNodePtr cur = m_aNodePtr->children;
704 : :
705 : : //search child before which to insert
706 [ + - ]: 10 : while (cur != NULL)
707 : : {
708 [ + - ]: 10 : if (cur == pRefChild) {
709 : : // insert before
710 : 10 : pNewChild->next = cur;
711 : 10 : pNewChild->prev = cur->prev;
712 : 10 : cur->prev = pNewChild;
713 [ - + ]: 10 : if (pNewChild->prev != NULL) {
714 : 0 : pNewChild->prev->next = pNewChild;
715 : : }
716 : 10 : pNewChild->parent = cur->parent;
717 [ + - ]: 10 : if (pNewChild->parent->children == cur) {
718 : 10 : pNewChild->parent->children = pNewChild;
719 : : }
720 : : // do not update parent->last here!
721 : 10 : pNewNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
722 : 10 : break;
723 : : }
724 : 0 : cur = cur->next;
725 : : }
726 [ + - ]: 48 : return refChild;
727 : : }
728 : :
729 : : /**
730 : : Tests whether the DOM implementation implements a specific feature and
731 : : that feature is supported by this node.
732 : : */
733 : 18 : sal_Bool SAL_CALL CNode::isSupported(const OUString& /*feature*/, const OUString& /*ver*/)
734 : : throw (RuntimeException)
735 : : {
736 : : OSL_ENSURE(false, "CNode::isSupported: not implemented (#i113683#)");
737 : 18 : return sal_False;
738 : : }
739 : :
740 : : /**
741 : : Puts all Text nodes in the full depth of the sub-tree underneath this
742 : : Node, including attribute nodes, into a "normal" form where only structure
743 : : (e.g., elements, comments, processing instructions, CDATA sections, and
744 : : entity references) separates Text nodes, i.e., there are neither adjacent
745 : : Text nodes nor empty Text nodes.
746 : : */
747 : 18 : void SAL_CALL CNode::normalize()
748 : : throw (RuntimeException)
749 : : {
750 : : //XXX combine adjacent text nodes and remove empty ones
751 : : OSL_ENSURE(false, "CNode::normalize: not implemented (#i113683#)");
752 : 18 : }
753 : :
754 : : /**
755 : : Removes the child node indicated by oldChild from the list of children,
756 : : and returns it.
757 : : */
758 : : Reference< XNode > SAL_CALL
759 : 1130 : CNode::removeChild(const Reference< XNode >& xOldChild)
760 : : throw (RuntimeException, DOMException)
761 : : {
762 [ + + ]: 1130 : if (!xOldChild.is()) {
763 [ + - ]: 18 : throw RuntimeException();
764 : : }
765 : :
766 [ + - ][ + - ]: 1112 : if (xOldChild->getOwnerDocument() != getOwnerDocument()) {
[ + - ][ + - ]
[ - + ]
767 [ # # ]: 0 : DOMException e;
768 : 0 : e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
769 [ # # ]: 0 : throw e;
770 : : }
771 [ + - ][ + - ]: 1112 : if (xOldChild->getParentNode() != Reference< XNode >(this)) {
[ + - ][ + - ]
[ + + ]
772 [ + - ]: 18 : DOMException e;
773 : 18 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
774 [ + - ]: 18 : throw e;
775 : : }
776 : :
777 [ + - ]: 1094 : ::osl::ClearableMutexGuard guard(m_rMutex);
778 : :
779 [ - + ][ # # ]: 1094 : if (!m_aNodePtr) { throw RuntimeException(); }
780 : :
781 : 1094 : Reference<XNode> xReturn( xOldChild );
782 : :
783 [ + - ]: 1094 : ::rtl::Reference<CNode> const pOld(CNode::GetImplementation(xOldChild));
784 [ # # ][ - + ]: 1094 : if (!pOld.is()) { throw RuntimeException(); }
785 : 1094 : xmlNodePtr const old = pOld->GetNodePtr();
786 [ # # ][ - + ]: 1094 : if (!old) { throw RuntimeException(); }
787 : :
788 [ - + ]: 1094 : if( old->type == XML_ATTRIBUTE_NODE )
789 : : {
790 : 0 : xmlAttrPtr pAttr = reinterpret_cast<xmlAttrPtr>(old);
791 [ # # ]: 0 : xmlRemoveProp( pAttr );
792 [ # # ]: 0 : pOld->invalidate(); // freed by xmlRemoveProp
793 : 0 : xReturn.clear();
794 : : }
795 : : else
796 : : {
797 [ + - ]: 1094 : xmlUnlinkNode(old);
798 : 1094 : pOld->m_bUnlinked = true;
799 : : }
800 : :
801 : : /*DOMNodeRemoved
802 : : * Fired when a node is being removed from its parent node.
803 : : * This event is dispatched before the node is removed from the tree.
804 : : * The target of this event is the node being removed.
805 : : * Bubbles: Yes
806 : : * Cancelable: No
807 : : * Context Info: relatedNode holds the parent node
808 : : */
809 [ + - ][ + - ]: 1094 : Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
810 [ + - ]: 1094 : Reference< XMutationEvent > event(docevent->createEvent(
811 [ + - ][ + - ]: 1094 : "DOMNodeRemoved"), UNO_QUERY);
812 [ + - ]: 1094 : event->initMutationEvent("DOMNodeRemoved",
813 : : sal_True,
814 : : sal_False,
815 : : this,
816 [ + - ][ + - ]: 1094 : OUString(), OUString(), OUString(), (AttrChangeType)0 );
817 : :
818 : : // the following dispatch functions use only UNO interfaces
819 : : // and call event listeners, so release mutex to prevent deadlocks.
820 [ + - ]: 1094 : guard.clear();
821 : :
822 [ + - ][ + - ]: 1094 : dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
823 : : // subtree modified for this node
824 [ + - ]: 1094 : dispatchSubtreeModified();
825 : :
826 [ + - ]: 1130 : return xReturn;
827 : : }
828 : :
829 : : /**
830 : : Replaces the child node oldChild with newChild in the list of children,
831 : : and returns the oldChild node.
832 : : */
833 : 58 : Reference< XNode > SAL_CALL CNode::replaceChild(
834 : : Reference< XNode > const& xNewChild,
835 : : Reference< XNode > const& xOldChild)
836 : : throw (RuntimeException, DOMException)
837 : : {
838 [ + + ][ + + ]: 58 : if (!xOldChild.is() || !xNewChild.is()) {
[ + + ]
839 [ + - ]: 20 : throw RuntimeException();
840 : : }
841 : :
842 [ + - ][ + - ]: 38 : if (xNewChild->getOwnerDocument() != getOwnerDocument()) {
[ + - ][ + - ]
[ - + ]
843 [ # # ]: 0 : DOMException e;
844 : 0 : e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
845 [ # # ]: 0 : throw e;
846 : : }
847 [ + - ][ + - ]: 38 : if (xOldChild->getParentNode() != Reference< XNode >(this)) {
[ + - ][ + - ]
[ + + ]
848 [ + - ]: 16 : DOMException e;
849 : 16 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
850 [ + - ]: 16 : throw e;
851 : : }
852 : :
853 [ + - ]: 22 : ::osl::ClearableMutexGuard guard(m_rMutex);
854 : :
855 : : ::rtl::Reference<CNode> const pOldNode(
856 [ + - ]: 22 : CNode::GetImplementation(xOldChild));
857 : : ::rtl::Reference<CNode> const pNewNode(
858 [ + - ]: 22 : CNode::GetImplementation(xNewChild));
859 [ - + ][ - + ]: 22 : if (!pOldNode.is() || !pNewNode.is()) { throw RuntimeException(); }
[ # # ][ + - ]
860 : 22 : xmlNodePtr const pOld = pOldNode->GetNodePtr();
861 : 22 : xmlNodePtr const pNew = pNewNode->GetNodePtr();
862 [ - + ][ # # ]: 22 : if (!pOld || !pNew) { throw RuntimeException(); }
[ + - ]
863 : :
864 [ - + ]: 22 : if (pNew == m_aNodePtr) {
865 [ # # ]: 0 : DOMException e;
866 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
867 [ # # ]: 0 : throw e;
868 : : }
869 : : // already has parent
870 [ + + ]: 22 : if (pNew->parent != NULL) {
871 [ + - ]: 12 : DOMException e;
872 : 12 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
873 [ + - ]: 12 : throw e;
874 : : }
875 [ + - ][ - + ]: 10 : if (!IsChildTypeAllowed(pNewNode->m_aNodeType)) {
876 [ # # ]: 0 : DOMException e;
877 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
878 [ # # ]: 0 : throw e;
879 : : }
880 : :
881 [ - + ]: 10 : if( pOld->type == XML_ATTRIBUTE_NODE )
882 : : {
883 : : // can only replace attribute with attribute
884 [ # # ]: 0 : if ( pOld->type != pNew->type )
885 : : {
886 [ # # ]: 0 : DOMException e;
887 : 0 : e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
888 [ # # ]: 0 : throw e;
889 : : }
890 : :
891 : 0 : xmlAttrPtr pAttr = (xmlAttrPtr)pOld;
892 [ # # ]: 0 : xmlRemoveProp( pAttr );
893 [ # # ]: 0 : pOldNode->invalidate(); // freed by xmlRemoveProp
894 [ # # ]: 0 : appendChild(xNewChild);
895 : : }
896 : : else
897 : : {
898 : :
899 : 10 : xmlNodePtr cur = m_aNodePtr->children;
900 : : //find old node in child list
901 [ + + ]: 22 : while (cur != NULL)
902 : : {
903 [ + + ]: 12 : if(cur == pOld)
904 : : {
905 : : // exchange nodes
906 : 10 : pNew->prev = pOld->prev;
907 [ + + ]: 10 : if (pNew->prev != NULL)
908 : 2 : pNew->prev->next = pNew;
909 : 10 : pNew->next = pOld->next;
910 [ + + ]: 10 : if (pNew->next != NULL)
911 : 8 : pNew->next->prev = pNew;
912 : 10 : pNew->parent = pOld->parent;
913 [ + + ]: 10 : if(pNew->parent->children == pOld)
914 : 8 : pNew->parent->children = pNew;
915 [ + + ]: 10 : if(pNew->parent->last == pOld)
916 : 2 : pNew->parent->last = pNew;
917 : 10 : pOld->next = NULL;
918 : 10 : pOld->prev = NULL;
919 : 10 : pOld->parent = NULL;
920 : 10 : pOldNode->m_bUnlinked = true;
921 : 10 : pNewNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
922 : : }
923 : 12 : cur = cur->next;
924 : : }
925 : : }
926 : :
927 [ + - ]: 10 : guard.clear(); // release for calling event handlers
928 [ + - ]: 10 : dispatchSubtreeModified();
929 : :
930 [ + - ]: 58 : return xOldChild;
931 : : }
932 : :
933 : 62550 : void CNode::dispatchSubtreeModified()
934 : : {
935 : : // only uses UNO interfaces => needs no mutex
936 : :
937 : : // dispatch DOMSubtreeModified
938 : : // target is _this_ node
939 [ + - ][ + - ]: 62550 : Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
940 [ + - ]: 62550 : Reference< XMutationEvent > event(docevent->createEvent(
941 [ + - ][ + - ]: 62550 : "DOMSubtreeModified"), UNO_QUERY);
942 [ + - ]: 62550 : event->initMutationEvent(
943 : : "DOMSubtreeModified", sal_True,
944 : : sal_False, Reference< XNode >(),
945 [ + - ]: 62550 : OUString(), OUString(), OUString(), (AttrChangeType)0 );
946 [ + - ][ + - ]: 62550 : dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
947 : 62550 : }
948 : :
949 : : /**
950 : : The value of this node, depending on its type; see the table above.
951 : : */
952 : 8 : void SAL_CALL CNode::setNodeValue(const OUString& /*nodeValue*/)
953 : : throw (RuntimeException, DOMException)
954 : : {
955 : : // use specific node implememntation
956 : : // if we end up down here, something went wrong
957 [ + - ]: 8 : DOMException e;
958 : 8 : e.Code = DOMExceptionType_NO_MODIFICATION_ALLOWED_ERR;
959 [ + - ]: 8 : throw e;
960 : : }
961 : :
962 : : /**
963 : : The namespace prefix of this node, or null if it is unspecified.
964 : : */
965 : 16 : void SAL_CALL CNode::setPrefix(const OUString& prefix)
966 : : throw (RuntimeException, DOMException)
967 : : {
968 [ + - ]: 16 : ::osl::MutexGuard const g(m_rMutex);
969 : :
970 [ + - ][ + + ]: 16 : if ((0 == m_aNodePtr) ||
[ + - ]
971 : : ((m_aNodePtr->type != XML_ELEMENT_NODE) &&
972 : : (m_aNodePtr->type != XML_ATTRIBUTE_NODE)))
973 : : {
974 [ + - ]: 14 : DOMException e;
975 : 14 : e.Code = DOMExceptionType_NO_MODIFICATION_ALLOWED_ERR;
976 [ + - ]: 14 : throw e;
977 : : }
978 [ + - ]: 2 : OString o1 = OUStringToOString(prefix, RTL_TEXTENCODING_UTF8);
979 : 2 : xmlChar *pBuf = (xmlChar*)o1.getStr();
980 [ + - ][ + - ]: 2 : if (m_aNodePtr != NULL && m_aNodePtr->ns != NULL)
981 : : {
982 [ + - ]: 2 : xmlFree(const_cast<xmlChar *>(m_aNodePtr->ns->prefix));
983 [ + - ]: 2 : m_aNodePtr->ns->prefix = xmlStrdup(pBuf);
984 [ + - ]: 16 : }
985 : :
986 : 2 : }
987 : :
988 : : // --- XEventTarget
989 : 14 : void SAL_CALL CNode::addEventListener(const OUString& eventType,
990 : : const Reference< com::sun::star::xml::dom::events::XEventListener >& listener,
991 : : sal_Bool useCapture)
992 : : throw (RuntimeException)
993 : : {
994 [ + - ]: 14 : ::osl::MutexGuard const g(m_rMutex);
995 : :
996 [ + - ]: 14 : CDocument & rDocument(GetOwnerDocument());
997 [ + - ]: 14 : events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher());
998 [ + - ][ + - ]: 14 : rDispatcher.addListener(m_aNodePtr, eventType, listener, useCapture);
999 : 14 : }
1000 : :
1001 : 0 : void SAL_CALL CNode::removeEventListener(const OUString& eventType,
1002 : : const Reference< com::sun::star::xml::dom::events::XEventListener >& listener,
1003 : : sal_Bool useCapture)
1004 : : throw (RuntimeException)
1005 : : {
1006 [ # # ]: 0 : ::osl::MutexGuard const g(m_rMutex);
1007 : :
1008 [ # # ]: 0 : CDocument & rDocument(GetOwnerDocument());
1009 [ # # ]: 0 : events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher());
1010 [ # # ][ # # ]: 0 : rDispatcher.removeListener(m_aNodePtr, eventType, listener, useCapture);
1011 : 0 : }
1012 : :
1013 : 126487 : sal_Bool SAL_CALL CNode::dispatchEvent(const Reference< XEvent >& evt)
1014 : : throw(RuntimeException, EventException)
1015 : : {
1016 : : CDocument * pDocument;
1017 : : events::CEventDispatcher * pDispatcher;
1018 : : xmlNodePtr pNode;
1019 : : {
1020 [ + - ]: 126487 : ::osl::MutexGuard const g(m_rMutex);
1021 : :
1022 [ + - ]: 126487 : pDocument = & GetOwnerDocument();
1023 [ + - ]: 126487 : pDispatcher = & pDocument->GetEventDispatcher();
1024 [ + - ]: 126487 : pNode = m_aNodePtr;
1025 : : }
1026 : : // this calls event listeners, do not call with locked mutex
1027 [ + - ]: 126487 : pDispatcher->dispatchEvent(*pDocument, m_rMutex, pNode, this, evt);
1028 : 126487 : return sal_True;
1029 : : }
1030 : :
1031 : : ::sal_Int64 SAL_CALL
1032 : 237703 : CNode::getSomething(Sequence< ::sal_Int8 > const& rId)
1033 : : throw (RuntimeException)
1034 : : {
1035 [ + - + - ]: 475406 : if ((rId.getLength() == 16) &&
[ + - ]
1036 : 237703 : (0 == rtl_compareMemory(theCNodeUnoTunnelId::get().getSeq().getConstArray(),
1037 : 475406 : rId.getConstArray(), 16)))
1038 : : {
1039 : : return ::sal::static_int_cast< sal_Int64 >(
1040 : 237703 : reinterpret_cast< sal_IntPtr >(this) );
1041 : : }
1042 : 237703 : return 0;
1043 : : }
1044 [ + - ][ + - ]: 573 : }
1045 : :
1046 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|