LCOV - code coverage report
Current view: top level - unoxml/source/dom - node.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 366 444 82.4 %
Date: 2012-08-25 Functions: 42 48 87.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 391 794 49.2 %

           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: */

Generated by: LCOV version 1.10