LCOV - code coverage report
Current view: top level - unoxml/source/dom - document.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 384 460 83.5 %
Date: 2012-08-25 Functions: 45 49 91.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 377 868 43.4 %

           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 <com/sun/star/uno/Sequence.h>
      21                 :            : 
      22                 :            : #include "document.hxx"
      23                 :            : #include "attr.hxx"
      24                 :            : #include "element.hxx"
      25                 :            : #include "cdatasection.hxx"
      26                 :            : #include "documentfragment.hxx"
      27                 :            : #include "text.hxx"
      28                 :            : #include "cdatasection.hxx"
      29                 :            : #include "comment.hxx"
      30                 :            : #include "processinginstruction.hxx"
      31                 :            : #include "entityreference.hxx"
      32                 :            : #include "documenttype.hxx"
      33                 :            : #include "elementlist.hxx"
      34                 :            : #include "domimplementation.hxx"
      35                 :            : #include <entity.hxx>
      36                 :            : #include <notation.hxx>
      37                 :            : 
      38                 :            : #include "../events/event.hxx"
      39                 :            : #include "../events/mutationevent.hxx"
      40                 :            : #include "../events/uievent.hxx"
      41                 :            : #include "../events/mouseevent.hxx"
      42                 :            : #include "../events/eventdispatcher.hxx"
      43                 :            : 
      44                 :            : #include <string.h>
      45                 :            : 
      46                 :            : #include <com/sun/star/xml/sax/FastToken.hpp>
      47                 :            : #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
      48                 :            : 
      49                 :            : namespace DOM
      50                 :            : {
      51                 :          2 :     static xmlNodePtr lcl_getDocumentType(xmlDocPtr const i_pDocument)
      52                 :            :     {
      53                 :            :         // find the doc type
      54                 :          2 :         xmlNodePtr cur = i_pDocument->children;
      55         [ -  + ]:          2 :         while (cur != NULL)
      56                 :            :         {
      57 [ #  # ][ #  # ]:          0 :             if ((cur->type == XML_DOCUMENT_TYPE_NODE) ||
      58                 :            :                 (cur->type == XML_DTD_NODE)) {
      59                 :          0 :                     return cur;
      60                 :            :             }
      61                 :            :         }
      62                 :          2 :         return 0;
      63                 :            :     }
      64                 :            : 
      65                 :            :     /// get the pointer to the root element node of the document
      66                 :      12060 :     static xmlNodePtr lcl_getDocumentRootPtr(xmlDocPtr const i_pDocument)
      67                 :            :     {
      68                 :            :         // find the document element
      69                 :      12060 :         xmlNodePtr cur = i_pDocument->children;
      70         [ +  + ]:      14168 :         while (cur != NULL)
      71                 :            :         {
      72         [ +  + ]:      10526 :             if (cur->type == XML_ELEMENT_NODE)
      73                 :       8418 :                 break;
      74                 :       2108 :             cur = cur->next;
      75                 :            :         }
      76                 :      12060 :         return cur;
      77                 :            :     }
      78                 :            : 
      79                 :      12369 :     CDocument::CDocument(xmlDocPtr const pDoc)
      80                 :            :         : CDocument_Base(*this, m_Mutex,
      81                 :            :                 NodeType_DOCUMENT_NODE, reinterpret_cast<xmlNodePtr>(pDoc))
      82                 :            :         , m_aDocPtr(pDoc)
      83                 :            :         , m_streamListeners()
      84 [ +  - ][ +  - ]:      12369 :         , m_pEventDispatcher(new events::CEventDispatcher())
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
      85                 :            :     {
      86                 :      12369 :     }
      87                 :            : 
      88                 :      12369 :     ::rtl::Reference<CDocument> CDocument::CreateCDocument(xmlDocPtr const pDoc)
      89                 :            :     {
      90         [ +  - ]:      12369 :         ::rtl::Reference<CDocument> const xDoc(new CDocument(pDoc));
      91                 :            :         // add the doc itself to its nodemap!
      92                 :      12369 :         xDoc->m_NodeMap.insert(
      93                 :            :             nodemap_t::value_type(reinterpret_cast<xmlNodePtr>(pDoc),
      94                 :            :                 ::std::make_pair(
      95         [ +  - ]:      12369 :                     WeakReference<XNode>(static_cast<XDocument*>(xDoc.get())),
      96 [ +  - ][ +  - ]:      37107 :                     xDoc.get())));
                 [ +  - ]
           [ +  -  +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
      97                 :      12369 :         return xDoc;
      98                 :            :     }
      99                 :            : 
     100 [ +  - ][ +  - ]:      12201 :     CDocument::~CDocument()
     101                 :            :     {
     102         [ +  - ]:      12201 :         ::osl::MutexGuard const g(m_Mutex);
     103                 :            : #ifdef DBG_UTIL
     104                 :            :         // node map must be empty now, otherwise CDocument must not die!
     105                 :            :         for (nodemap_t::iterator i = m_NodeMap.begin();
     106                 :            :                 i != m_NodeMap.end(); ++i)
     107                 :            :         {
     108                 :            :             Reference<XNode> const xNode(i->second.first);
     109                 :            :             OSL_ENSURE(!xNode.is(),
     110                 :            :             "CDocument::~CDocument(): ERROR: live node in document node map!");
     111                 :            :         }
     112                 :            : #endif
     113 [ +  - ][ +  - ]:      12201 :         xmlFreeDoc(m_aDocPtr);
     114         [ -  + ]:      24402 :     }
     115                 :            : 
     116                 :            : 
     117                 :     126501 :     events::CEventDispatcher & CDocument::GetEventDispatcher()
     118                 :            :     {
     119                 :     126501 :         return *m_pEventDispatcher;
     120                 :            :     }
     121                 :            : 
     122                 :          8 :     ::rtl::Reference< CElement > CDocument::GetDocumentElement()
     123                 :            :     {
     124                 :          8 :         xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr);
     125                 :            :         ::rtl::Reference< CElement > const xRet(
     126         [ +  + ]:          8 :             dynamic_cast<CElement*>(GetCNode(pNode).get()));
     127                 :          8 :         return xRet;
     128                 :            :     }
     129                 :            : 
     130                 :            :     void
     131                 :     156653 :     CDocument::RemoveCNode(xmlNodePtr const pNode, CNode const*const pCNode)
     132                 :            :     {
     133         [ +  - ]:     156653 :         nodemap_t::iterator const i = m_NodeMap.find(pNode);
     134         [ +  - ]:     156653 :         if (i != m_NodeMap.end()) {
     135                 :            :             // #i113681# consider this scenario:
     136                 :            :             // T1 calls ~CNode
     137                 :            :             // T2 calls getCNode:    lookup will find i->second->first invalid
     138                 :            :             //                       so a new CNode is created and inserted
     139                 :            :             // T1 calls removeCNode: i->second->second now points to a
     140                 :            :             //                       different CNode instance!
     141                 :            :             //
     142                 :            :             // check that the CNode is the right one
     143                 :     156653 :             CNode *const pCurrent = i->second.second;
     144         [ +  - ]:     156653 :             if (pCurrent == pCNode) {
     145         [ +  - ]:     156653 :                 m_NodeMap.erase(i);
     146                 :            :             }
     147                 :            :         }
     148                 :     156653 :     }
     149                 :            : 
     150                 :            :     /** NB: this is the CNode factory.
     151                 :            :         it is the only place where CNodes may be instantiated.
     152                 :            :         all CNodes must be registered at the m_NodeMap.
     153                 :            :      */
     154                 :            :     ::rtl::Reference<CNode>
     155                 :     583248 :     CDocument::GetCNode(xmlNodePtr const pNode, bool const bCreate)
     156                 :            :     {
     157         [ +  + ]:     583248 :         if (0 == pNode) {
     158                 :      66965 :             return 0;
     159                 :            :         }
     160                 :            :         //check whether there is already an instance for this node
     161         [ +  - ]:     516283 :         nodemap_t::const_iterator const i = m_NodeMap.find(pNode);
     162         [ +  + ]:     516283 :         if (i != m_NodeMap.end()) {
     163                 :            :             // #i113681# check that the CNode is still alive
     164         [ +  - ]:     359170 :             uno::Reference<XNode> const xNode(i->second.first);
     165         [ +  - ]:     359170 :             if (xNode.is())
     166                 :            :             {
     167                 :     359170 :                 ::rtl::Reference<CNode> ret(i->second.second);
     168                 :            :                 OSL_ASSERT(ret.is());
     169                 :     359170 :                 return ret;
     170         [ -  + ]:     359170 :             }
     171                 :            :         }
     172                 :            : 
     173         [ +  + ]:     157113 :         if (!bCreate) { return 0; }
     174                 :            : 
     175                 :            :         // there is not yet an instance wrapping this node,
     176                 :            :         // create it and store it in the map
     177                 :            : 
     178                 :     157109 :         ::rtl::Reference<CNode> pCNode;
     179   [ +  +  +  +  :     157109 :         switch (pNode->type)
          -  +  +  -  -  
             +  -  +  - ]
     180                 :            :         {
     181                 :            :             case XML_ELEMENT_NODE:
     182                 :            :                 // m_aNodeType = NodeType::ELEMENT_NODE;
     183                 :            :                 pCNode = static_cast< CNode* >(
     184 [ +  - ][ +  - ]:     108199 :                         new CElement(*this, m_Mutex, pNode));
     185                 :     108199 :             break;
     186                 :            :             case XML_TEXT_NODE:
     187                 :            :                 // m_aNodeType = NodeType::TEXT_NODE;
     188                 :            :                 pCNode = static_cast< CNode* >(
     189 [ +  - ][ +  - ]:      21795 :                         new CText(*this, m_Mutex, pNode));
     190                 :      21795 :             break;
     191                 :            :             case XML_CDATA_SECTION_NODE:
     192                 :            :                 // m_aNodeType = NodeType::CDATA_SECTION_NODE;
     193                 :            :                 pCNode = static_cast< CNode* >(
     194 [ +  - ][ +  - ]:         12 :                         new CCDATASection(*this, m_Mutex, pNode));
     195                 :         12 :             break;
     196                 :            :             case XML_ENTITY_REF_NODE:
     197                 :            :                 // m_aNodeType = NodeType::ENTITY_REFERENCE_NODE;
     198                 :            :                 pCNode = static_cast< CNode* >(
     199 [ +  - ][ +  - ]:         10 :                         new CEntityReference(*this, m_Mutex, pNode));
     200                 :         10 :             break;
     201                 :            :             case XML_ENTITY_NODE:
     202                 :            :                 // m_aNodeType = NodeType::ENTITY_NODE;
     203                 :            :                 pCNode = static_cast< CNode* >(new CEntity(*this, m_Mutex,
     204 [ #  # ][ #  # ]:          0 :                             reinterpret_cast<xmlEntityPtr>(pNode)));
     205                 :          0 :             break;
     206                 :            :             case XML_PI_NODE:
     207                 :            :                 // m_aNodeType = NodeType::PROCESSING_INSTRUCTION_NODE;
     208                 :            :                 pCNode = static_cast< CNode* >(
     209 [ +  - ][ +  - ]:          8 :                         new CProcessingInstruction(*this, m_Mutex, pNode));
     210                 :          8 :             break;
     211                 :            :             case XML_COMMENT_NODE:
     212                 :            :                 // m_aNodeType = NodeType::COMMENT_NODE;
     213                 :            :                 pCNode = static_cast< CNode* >(
     214 [ +  - ][ +  - ]:         18 :                         new CComment(*this, m_Mutex, pNode));
     215                 :         18 :             break;
     216                 :            :             case XML_DOCUMENT_NODE:
     217                 :            :                 // m_aNodeType = NodeType::DOCUMENT_NODE;
     218                 :            :                 OSL_ENSURE(false, "CDocument::GetCNode is not supposed to"
     219                 :            :                         " create a CDocument!!!");
     220                 :            :                 pCNode = static_cast< CNode* >(new CDocument(
     221 [ #  # ][ #  # ]:          0 :                             reinterpret_cast<xmlDocPtr>(pNode)));
     222                 :          0 :             break;
     223                 :            :             case XML_DOCUMENT_TYPE_NODE:
     224                 :            :             case XML_DTD_NODE:
     225                 :            :                 // m_aNodeType = NodeType::DOCUMENT_TYPE_NODE;
     226                 :            :                 pCNode = static_cast< CNode* >(new CDocumentType(*this, m_Mutex,
     227 [ #  # ][ #  # ]:          0 :                             reinterpret_cast<xmlDtdPtr>(pNode)));
     228                 :          0 :             break;
     229                 :            :             case XML_DOCUMENT_FRAG_NODE:
     230                 :            :                 // m_aNodeType = NodeType::DOCUMENT_FRAGMENT_NODE;
     231                 :            :                 pCNode = static_cast< CNode* >(
     232 [ +  - ][ +  - ]:          8 :                         new CDocumentFragment(*this, m_Mutex, pNode));
     233                 :          8 :             break;
     234                 :            :             case XML_NOTATION_NODE:
     235                 :            :                 // m_aNodeType = NodeType::NOTATION_NODE;
     236                 :            :                 pCNode = static_cast< CNode* >(new CNotation(*this, m_Mutex,
     237 [ #  # ][ #  # ]:          0 :                             reinterpret_cast<xmlNotationPtr>(pNode)));
     238                 :          0 :             break;
     239                 :            :             case XML_ATTRIBUTE_NODE:
     240                 :            :                 // m_aNodeType = NodeType::ATTRIBUTE_NODE;
     241                 :            :                 pCNode = static_cast< CNode* >(new CAttr(*this, m_Mutex,
     242 [ +  - ][ +  - ]:      27059 :                             reinterpret_cast<xmlAttrPtr>(pNode)));
     243                 :      27059 :             break;
     244                 :            :             // unsupported node types
     245                 :            :             case XML_HTML_DOCUMENT_NODE:
     246                 :            :             case XML_ELEMENT_DECL:
     247                 :            :             case XML_ATTRIBUTE_DECL:
     248                 :            :             case XML_ENTITY_DECL:
     249                 :            :             case XML_NAMESPACE_DECL:
     250                 :            :             default:
     251                 :          0 :             break;
     252                 :            :         }
     253                 :            : 
     254         [ +  - ]:     157109 :         if (pCNode != 0) {
     255                 :            :             bool const bInserted = m_NodeMap.insert(
     256                 :            :                     nodemap_t::value_type(pNode,
     257         [ +  - ]:     157109 :                         ::std::make_pair(WeakReference<XNode>(pCNode.get()),
     258                 :     157109 :                         pCNode.get()))
     259 [ +  - ][ +  - ]:     157109 :                 ).second;
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     260                 :            :             OSL_ASSERT(bInserted);
     261         [ -  + ]:     157109 :             if (!bInserted) {
     262                 :            :                 // if insertion failed, delete new instance and return null
     263                 :          0 :                 return 0;
     264                 :            :             }
     265                 :            :         }
     266                 :            : 
     267                 :            :         OSL_ENSURE(pCNode.is(), "no node produced during CDocument::GetCNode!");
     268                 :     583248 :         return pCNode;
     269                 :            :     }
     270                 :            : 
     271                 :            : 
     272                 :      45263 :     CDocument & CDocument::GetOwnerDocument()
     273                 :            :     {
     274                 :      45263 :         return *this;
     275                 :            :     }
     276                 :            : 
     277                 :         50 :     void CDocument::saxify(const Reference< XDocumentHandler >& i_xHandler)
     278                 :            :     {
     279                 :         50 :         i_xHandler->startDocument();
     280         [ +  + ]:        100 :         for (xmlNodePtr pChild = m_aNodePtr->children;
     281                 :            :                         pChild != 0; pChild = pChild->next) {
     282         [ +  - ]:         50 :             ::rtl::Reference<CNode> const pNode = GetCNode(pChild);
     283                 :            :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     284         [ +  - ]:         50 :             pNode->saxify(i_xHandler);
     285                 :         50 :         }
     286                 :         50 :         i_xHandler->endDocument();
     287                 :         50 :     }
     288                 :            : 
     289                 :         15 :     void CDocument::fastSaxify( Context& rContext )
     290                 :            :     {
     291                 :         15 :         rContext.mxDocHandler->startDocument();
     292         [ +  + ]:         30 :         for (xmlNodePtr pChild = m_aNodePtr->children;
     293                 :            :                         pChild != 0; pChild = pChild->next) {
     294         [ +  - ]:         15 :             ::rtl::Reference<CNode> const pNode = GetCNode(pChild);
     295                 :            :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     296         [ +  - ]:         15 :             pNode->fastSaxify(rContext);
     297                 :         15 :         }
     298                 :         15 :         rContext.mxDocHandler->endDocument();
     299                 :         15 :     }
     300                 :            : 
     301                 :       3636 :     bool CDocument::IsChildTypeAllowed(NodeType const nodeType)
     302                 :            :     {
     303   [ +  +  -  - ]:       3636 :         switch (nodeType) {
     304                 :            :             case NodeType_PROCESSING_INSTRUCTION_NODE:
     305                 :            :             case NodeType_COMMENT_NODE:
     306                 :          4 :                 return true;
     307                 :            :             case NodeType_ELEMENT_NODE:
     308                 :            :                  // there may be only one!
     309                 :       3632 :                 return 0 == lcl_getDocumentRootPtr(m_aDocPtr);
     310                 :            :             case NodeType_DOCUMENT_TYPE_NODE:
     311                 :            :                  // there may be only one!
     312                 :          0 :                 return 0 == lcl_getDocumentType(m_aDocPtr);
     313                 :            :             default:
     314                 :       3636 :                 return false;
     315                 :            :         }
     316                 :            :     }
     317                 :            : 
     318                 :            : 
     319                 :          0 :     void SAL_CALL CDocument::addListener(const Reference< XStreamListener >& aListener )
     320                 :            :         throw (RuntimeException)
     321                 :            :     {
     322         [ #  # ]:          0 :         ::osl::MutexGuard const g(m_Mutex);
     323                 :            : 
     324 [ #  # ][ #  # ]:          0 :         m_streamListeners.insert(aListener);
     325                 :          0 :     }
     326                 :            : 
     327                 :          0 :     void SAL_CALL CDocument::removeListener(const Reference< XStreamListener >& aListener )
     328                 :            :         throw (RuntimeException)
     329                 :            :     {
     330         [ #  # ]:          0 :         ::osl::MutexGuard const g(m_Mutex);
     331                 :            : 
     332 [ #  # ][ #  # ]:          0 :         m_streamListeners.erase(aListener);
     333                 :          0 :     }
     334                 :            : 
     335                 :            :     // IO context functions for libxml2 interaction
     336                 :            :     typedef struct {
     337                 :            :         Reference< XOutputStream > stream;
     338                 :            :         bool allowClose;
     339                 :       3308 :     } IOContext;
     340                 :            : 
     341                 :            :     extern "C" {
     342                 :            :     // write callback
     343                 :            :     // int xmlOutputWriteCallback (void * context, const char * buffer, int len)
     344                 :       5416 :     static int writeCallback(void *context, const char* buffer, int len){
     345                 :            :         // create a sequence and write it to the stream
     346                 :       5416 :         IOContext *pContext = static_cast<IOContext*>(context);
     347         [ +  - ]:       5416 :         Sequence<sal_Int8> bs(reinterpret_cast<const sal_Int8*>(buffer), len);
     348 [ +  - ][ +  - ]:       5416 :         pContext->stream->writeBytes(bs);
     349         [ +  - ]:       5416 :         return len;
     350                 :            :     }
     351                 :            : 
     352                 :            :     // clsoe callback
     353                 :            :     //int xmlOutputCloseCallback (void * context)
     354                 :       3308 :     static int closeCallback(void *context)
     355                 :            :     {
     356                 :       3308 :         IOContext *pContext = static_cast<IOContext*>(context);
     357         [ -  + ]:       3308 :         if (pContext->allowClose) {
     358                 :          0 :             pContext->stream->closeOutput();
     359                 :            :         }
     360                 :       3308 :         return 0;
     361                 :            :     }
     362                 :            :     } // extern "C"
     363                 :            : 
     364                 :       3308 :     void SAL_CALL CDocument::start()
     365                 :            :         throw (RuntimeException)
     366                 :            :     {
     367         [ +  - ]:       3308 :         listenerlist_t streamListeners;
     368                 :            :         {
     369         [ +  - ]:       3308 :             ::osl::MutexGuard const g(m_Mutex);
     370                 :            : 
     371 [ -  + ][ #  # ]:       3308 :             if (! m_rOutputStream.is()) { throw RuntimeException(); }
     372 [ +  - ][ +  - ]:       3308 :             streamListeners = m_streamListeners;
     373                 :            :         }
     374                 :            : 
     375                 :            :         // notify listeners about start
     376                 :       3308 :         listenerlist_t::const_iterator iter1 = streamListeners.begin();
     377         [ -  + ]:       3308 :         while (iter1 != streamListeners.end()) {
     378                 :          0 :             Reference< XStreamListener > aListener = *iter1;
     379 [ #  # ][ #  # ]:          0 :             aListener->started();
     380                 :          0 :             ++iter1;
     381                 :          0 :         }
     382                 :            : 
     383                 :            :         {
     384         [ +  - ]:       3308 :             ::osl::MutexGuard const g(m_Mutex);
     385                 :            : 
     386                 :            :             // check again! could have been reset...
     387 [ -  + ][ #  # ]:       3308 :             if (! m_rOutputStream.is()) { throw RuntimeException(); }
     388                 :            : 
     389                 :            :             // setup libxml IO and write data to output stream
     390                 :       3308 :             IOContext ioctx = {m_rOutputStream, false};
     391                 :            :             xmlOutputBufferPtr pOut = xmlOutputBufferCreateIO(
     392         [ +  - ]:       3308 :                 writeCallback, closeCallback, &ioctx, NULL);
     393 [ +  - ][ +  - ]:       3308 :             xmlSaveFileTo(pOut, m_aNodePtr->doc, NULL);
                 [ +  - ]
     394                 :            :         }
     395                 :            : 
     396                 :            :         // call listeners
     397                 :       3308 :         listenerlist_t::const_iterator iter2 = streamListeners.begin();
     398         [ -  + ]:       3308 :         while (iter2 != streamListeners.end()) {
     399                 :          0 :             Reference< XStreamListener > aListener = *iter2;
     400 [ #  # ][ #  # ]:          0 :             aListener->closed();
     401                 :          0 :             ++iter2;
     402                 :       3308 :         }
     403                 :       3308 :     }
     404                 :            : 
     405                 :          0 :     void SAL_CALL CDocument::terminate()
     406                 :            :         throw (RuntimeException)
     407                 :            :     {
     408                 :            :         // not supported
     409                 :          0 :     }
     410                 :            : 
     411                 :       3308 :     void SAL_CALL CDocument::setOutputStream( const Reference< XOutputStream >& aStream )
     412                 :            :         throw (RuntimeException)
     413                 :            :     {
     414         [ +  - ]:       3308 :         ::osl::MutexGuard const g(m_Mutex);
     415                 :            : 
     416 [ +  - ][ +  - ]:       3308 :         m_rOutputStream = aStream;
     417                 :       3308 :     }
     418                 :            : 
     419                 :          0 :     Reference< XOutputStream > SAL_CALL  CDocument::getOutputStream() throw (RuntimeException)
     420                 :            :     {
     421         [ #  # ]:          0 :         ::osl::MutexGuard const g(m_Mutex);
     422                 :            : 
     423         [ #  # ]:          0 :         return m_rOutputStream;
     424                 :            :     }
     425                 :            : 
     426                 :            :     // Creates an Attr of the given name.
     427                 :         10 :     Reference< XAttr > SAL_CALL CDocument::createAttribute(const OUString& name)
     428                 :            :         throw (RuntimeException, DOMException)
     429                 :            :     {
     430         [ +  - ]:         10 :         ::osl::MutexGuard const g(m_Mutex);
     431                 :            : 
     432         [ +  - ]:         10 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     433                 :         10 :         xmlChar *xName = (xmlChar*)o1.getStr();
     434         [ +  - ]:         10 :         xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr, xName, NULL);
     435                 :            :         ::rtl::Reference< CAttr > const pCAttr(
     436                 :            :             dynamic_cast< CAttr* >(GetCNode(
     437 [ +  - ][ -  + ]:         10 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()));
     438                 :         10 :         pCAttr->m_bUnlinked = true;
     439 [ +  - ][ +  - ]:         10 :         return pCAttr.get();
                 [ +  - ]
     440                 :            :     };
     441                 :            : 
     442                 :            :     // Creates an attribute of the given qualified name and namespace URI.
     443                 :         10 :     Reference< XAttr > SAL_CALL CDocument::createAttributeNS(
     444                 :            :             const OUString& ns, const OUString& qname)
     445                 :            :         throw (RuntimeException, DOMException)
     446                 :            :     {
     447         [ +  - ]:         10 :         ::osl::MutexGuard const g(m_Mutex);
     448                 :            : 
     449                 :            :         // libxml does not allow a NS definition to be attached to an
     450                 :            :         // attribute node - which is a good thing, since namespaces are
     451                 :            :         // only defined as parts of element nodes
     452                 :            :         // thus the namespace data is stored in CAttr::m_pNamespace
     453                 :         10 :         sal_Int32 i = qname.indexOf(':');
     454                 :         10 :         OString oPrefix, oName, oUri;
     455         [ +  + ]:         10 :         if (i != -1)
     456                 :            :         {
     457         [ +  - ]:          6 :             oPrefix = OUStringToOString(qname.copy(0, i), RTL_TEXTENCODING_UTF8);
     458         [ +  - ]:          6 :             oName = OUStringToOString(qname.copy(i+1, qname.getLength()-i-1), RTL_TEXTENCODING_UTF8);
     459                 :            :         }
     460                 :            :         else
     461                 :            :         {
     462         [ +  - ]:          4 :             oName = OUStringToOString(qname, RTL_TEXTENCODING_UTF8);
     463                 :            :         }
     464         [ +  - ]:         10 :         oUri = OUStringToOString(ns, RTL_TEXTENCODING_UTF8);
     465                 :            :         xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr,
     466         [ +  - ]:         10 :                 reinterpret_cast<xmlChar const*>(oName.getStr()), 0);
     467                 :            :         ::rtl::Reference< CAttr > const pCAttr(
     468                 :            :             dynamic_cast< CAttr* >(GetCNode(
     469 [ +  - ][ -  + ]:         10 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()));
     470 [ #  # ][ -  + ]:         10 :         if (!pCAttr.is()) { throw RuntimeException(); }
     471                 :            :         // store the namespace data!
     472         [ +  - ]:         10 :         pCAttr->m_pNamespace.reset( new stringpair_t(oUri, oPrefix) );
     473                 :         10 :         pCAttr->m_bUnlinked = true;
     474                 :            : 
     475 [ +  - ][ +  - ]:         10 :         return pCAttr.get();
                 [ +  - ]
     476                 :            :     };
     477                 :            : 
     478                 :            :     // Creates a CDATASection node whose value is the specified string.
     479                 :          8 :     Reference< XCDATASection > SAL_CALL CDocument::createCDATASection(const OUString& data)
     480                 :            :         throw (RuntimeException)
     481                 :            :     {
     482         [ +  - ]:          8 :         ::osl::MutexGuard const g(m_Mutex);
     483                 :            : 
     484                 :            :         OString const oData(
     485         [ +  - ]:          8 :                 ::rtl::OUStringToOString(data, RTL_TEXTENCODING_UTF8));
     486                 :            :         xmlChar const*const pData =
     487                 :          8 :             reinterpret_cast<xmlChar const*>(oData.getStr());
     488                 :            :         xmlNodePtr const pText =
     489         [ +  - ]:          8 :             xmlNewCDataBlock(m_aDocPtr, pData, strlen(oData.getStr()));
     490                 :            :         Reference< XCDATASection > const xRet(
     491 [ +  - ][ +  - ]:         16 :             static_cast< XNode* >(GetCNode(pText).get()),
     492         [ +  - ]:          8 :             UNO_QUERY_THROW);
     493         [ +  - ]:          8 :         return xRet;
     494                 :            :     }
     495                 :            : 
     496                 :            :     // Creates a Comment node given the specified string.
     497                 :         14 :     Reference< XComment > SAL_CALL CDocument::createComment(const OUString& data)
     498                 :            :         throw (RuntimeException)
     499                 :            :     {
     500         [ +  - ]:         14 :         ::osl::MutexGuard const g(m_Mutex);
     501                 :            : 
     502         [ +  - ]:         14 :         OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8);
     503                 :         14 :         xmlChar *xData = (xmlChar*)o1.getStr();
     504         [ +  - ]:         14 :         xmlNodePtr pComment = xmlNewDocComment(m_aDocPtr, xData);
     505                 :            :         Reference< XComment > const xRet(
     506 [ +  - ][ +  - ]:         28 :             static_cast< XNode* >(GetCNode(pComment).get()),
     507         [ +  - ]:         14 :             UNO_QUERY_THROW);
     508         [ +  - ]:         14 :         return xRet;
     509                 :            :     }
     510                 :            : 
     511                 :            :     //Creates an empty DocumentFragment object.
     512                 :          4 :     Reference< XDocumentFragment > SAL_CALL CDocument::createDocumentFragment()
     513                 :            :         throw (RuntimeException)
     514                 :            :     {
     515         [ +  - ]:          4 :         ::osl::MutexGuard const g(m_Mutex);
     516                 :            : 
     517         [ +  - ]:          4 :         xmlNodePtr pFrag = xmlNewDocFragment(m_aDocPtr);
     518                 :            :         Reference< XDocumentFragment > const xRet(
     519 [ +  - ][ +  - ]:          8 :             static_cast< XNode* >(GetCNode(pFrag).get()),
     520         [ +  - ]:          4 :             UNO_QUERY_THROW);
     521         [ +  - ]:          4 :         return xRet;
     522                 :            :     }
     523                 :            : 
     524                 :            :     // Creates an element of the type specified.
     525                 :         62 :     Reference< XElement > SAL_CALL CDocument::createElement(const OUString& tagName)
     526                 :            :         throw (RuntimeException, DOMException)
     527                 :            :     {
     528         [ +  - ]:         62 :         ::osl::MutexGuard const g(m_Mutex);
     529                 :            : 
     530         [ +  - ]:         62 :         OString o1 = OUStringToOString(tagName, RTL_TEXTENCODING_UTF8);
     531                 :         62 :         xmlChar *xName = (xmlChar*)o1.getStr();
     532         [ +  - ]:         62 :         xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL);
     533                 :            :         Reference< XElement > const xRet(
     534 [ +  - ][ +  - ]:        124 :             static_cast< XNode* >(GetCNode(pNode).get()),
     535         [ +  - ]:         62 :             UNO_QUERY_THROW);
     536         [ +  - ]:         62 :         return xRet;
     537                 :            :     }
     538                 :            : 
     539                 :            :     // Creates an element of the given qualified name and namespace URI.
     540                 :      27671 :     Reference< XElement > SAL_CALL CDocument::createElementNS(
     541                 :            :             const OUString& ns, const OUString& qname)
     542                 :            :         throw (RuntimeException, DOMException)
     543                 :            :     {
     544         [ +  - ]:      27671 :         ::osl::MutexGuard const g(m_Mutex);
     545                 :            : 
     546                 :      27671 :         sal_Int32 i = qname.indexOf(':');
     547 [ #  # ][ -  + ]:      27671 :         if (ns.isEmpty()) throw RuntimeException();
     548                 :            :         xmlChar *xPrefix;
     549                 :            :         xmlChar *xName;
     550                 :      27671 :         OString o1, o2, o3;
     551         [ +  + ]:      27671 :         if ( i != -1) {
     552         [ +  - ]:      27669 :             o1 = OUStringToOString(qname.copy(0, i), RTL_TEXTENCODING_UTF8);
     553                 :      27669 :             xPrefix = (xmlChar*)o1.getStr();
     554         [ +  - ]:      27669 :             o2 = OUStringToOString(qname.copy(i+1, qname.getLength()-i-1), RTL_TEXTENCODING_UTF8);
     555                 :      27669 :             xName = (xmlChar*)o2.getStr();
     556                 :            :         } else {
     557                 :            :             // default prefix
     558                 :          2 :             xPrefix = (xmlChar*)"";
     559         [ +  - ]:          2 :             o2 = OUStringToOString(qname, RTL_TEXTENCODING_UTF8);
     560                 :          2 :             xName = (xmlChar*)o2.getStr();
     561                 :            :         }
     562         [ +  - ]:      27671 :         o3 = OUStringToOString(ns, RTL_TEXTENCODING_UTF8);
     563                 :      27671 :         xmlChar *xUri = (xmlChar*)o3.getStr();
     564                 :            : 
     565                 :            :         // xmlNsPtr aNsPtr = xmlNewReconciledNs?
     566                 :            :         // xmlNsPtr aNsPtr = xmlNewGlobalNs?
     567         [ +  - ]:      27671 :         xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL);
     568         [ +  - ]:      27671 :         xmlNsPtr const pNs = xmlNewNs(pNode, xUri, xPrefix);
     569         [ +  - ]:      27671 :         xmlSetNs(pNode, pNs);
     570                 :            :         Reference< XElement > const xRet(
     571 [ +  - ][ +  - ]:      55342 :             static_cast< XNode* >(GetCNode(pNode).get()),
     572         [ +  - ]:      27671 :             UNO_QUERY_THROW);
     573         [ +  - ]:      27671 :         return xRet;
     574                 :            :     }
     575                 :            : 
     576                 :            :     //Creates an EntityReference object.
     577                 :          6 :     Reference< XEntityReference > SAL_CALL CDocument::createEntityReference(const OUString& name)
     578                 :            :         throw (RuntimeException, DOMException)
     579                 :            :     {
     580         [ +  - ]:          6 :         ::osl::MutexGuard const g(m_Mutex);
     581                 :            : 
     582         [ +  - ]:          6 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     583                 :          6 :         xmlChar *xName = (xmlChar*)o1.getStr();
     584         [ +  - ]:          6 :         xmlNodePtr const pNode = xmlNewReference(m_aDocPtr, xName);
     585                 :            :         Reference< XEntityReference > const xRet(
     586 [ +  - ][ +  - ]:         12 :             static_cast< XNode* >(GetCNode(pNode).get()),
     587         [ +  - ]:          6 :             UNO_QUERY_THROW);
     588         [ +  - ]:          6 :         return xRet;
     589                 :            :     }
     590                 :            : 
     591                 :            :     // Creates a ProcessingInstruction node given the specified name and
     592                 :            :     // data strings.
     593                 :          4 :     Reference< XProcessingInstruction > SAL_CALL CDocument::createProcessingInstruction(
     594                 :            :             const OUString& target, const OUString& data)
     595                 :            :         throw (RuntimeException, DOMException)
     596                 :            :     {
     597         [ +  - ]:          4 :         ::osl::MutexGuard const g(m_Mutex);
     598                 :            : 
     599         [ +  - ]:          4 :         OString o1 = OUStringToOString(target, RTL_TEXTENCODING_UTF8);
     600                 :          4 :         xmlChar *xTarget = (xmlChar*)o1.getStr();
     601         [ +  - ]:          4 :         OString o2 = OUStringToOString(data, RTL_TEXTENCODING_UTF8);
     602                 :          4 :         xmlChar *xData = (xmlChar*)o2.getStr();
     603         [ +  - ]:          4 :         xmlNodePtr const pNode = xmlNewDocPI(m_aDocPtr, xTarget, xData);
     604                 :          4 :         pNode->doc = m_aDocPtr;
     605                 :            :         Reference< XProcessingInstruction > const xRet(
     606 [ +  - ][ +  - ]:          8 :             static_cast< XNode* >(GetCNode(pNode).get()),
     607         [ +  - ]:          4 :             UNO_QUERY_THROW);
     608         [ +  - ]:          4 :         return xRet;
     609                 :            :     }
     610                 :            : 
     611                 :            :     // Creates a Text node given the specified string.
     612                 :      13200 :     Reference< XText > SAL_CALL CDocument::createTextNode(const OUString& data)
     613                 :            :         throw (RuntimeException)
     614                 :            :     {
     615         [ +  - ]:      13200 :         ::osl::MutexGuard const g(m_Mutex);
     616                 :            : 
     617         [ +  - ]:      13200 :         OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8);
     618                 :      13200 :         xmlChar *xData = (xmlChar*)o1.getStr();
     619         [ +  - ]:      13200 :         xmlNodePtr const pNode = xmlNewDocText(m_aDocPtr, xData);
     620                 :            :         Reference< XText > const xRet(
     621 [ +  - ][ +  - ]:      26400 :             static_cast< XNode* >(GetCNode(pNode).get()),
     622         [ +  - ]:      13200 :             UNO_QUERY_THROW);
     623         [ +  - ]:      13200 :         return xRet;
     624                 :            :     }
     625                 :            : 
     626                 :            :     // The Document Type Declaration (see DocumentType) associated with this
     627                 :            :     // document.
     628                 :          2 :     Reference< XDocumentType > SAL_CALL CDocument::getDoctype()
     629                 :            :         throw (RuntimeException)
     630                 :            :     {
     631         [ +  - ]:          2 :         ::osl::MutexGuard const g(m_Mutex);
     632                 :            : 
     633                 :          2 :         xmlNodePtr const pDocType(lcl_getDocumentType(m_aDocPtr));
     634                 :            :         Reference< XDocumentType > const xRet(
     635 [ -  + ][ +  - ]:          4 :             static_cast< XNode* >(GetCNode(pDocType).get()),
     636         [ +  - ]:          2 :             UNO_QUERY);
     637         [ +  - ]:          2 :         return xRet;
     638                 :            :     }
     639                 :            : 
     640                 :            :     // This is a convenience attribute that allows direct access to the child
     641                 :            :     // node that is the root element of the document.
     642                 :       8351 :     Reference< XElement > SAL_CALL CDocument::getDocumentElement()
     643                 :            :         throw (RuntimeException)
     644                 :            :     {
     645         [ +  - ]:       8351 :         ::osl::MutexGuard const g(m_Mutex);
     646                 :            : 
     647                 :       8351 :         xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr);
     648 [ +  - ][ +  + ]:       8351 :         if (!pNode) { return 0; }
     649                 :            :         Reference< XElement > const xRet(
     650 [ +  - ][ +  - ]:      16694 :             static_cast< XNode* >(GetCNode(pNode).get()),
     651         [ +  - ]:       8347 :             UNO_QUERY);
     652         [ +  - ]:       8351 :         return xRet;
     653                 :            :     }
     654                 :            : 
     655                 :            :     static xmlNodePtr
     656                 :          4 :     lcl_search_element_by_id(const xmlNodePtr cur, const xmlChar* id)
     657                 :            :     {
     658         [ -  + ]:          4 :         if (cur == NULL)
     659                 :          0 :             return NULL;
     660                 :            :         // look in current node
     661         [ +  - ]:          4 :         if (cur->type == XML_ELEMENT_NODE)
     662                 :            :         {
     663                 :          4 :             xmlAttrPtr a = cur->properties;
     664         [ +  + ]:          4 :             while (a != NULL)
     665                 :            :             {
     666         [ +  - ]:          2 :                 if (a->atype == XML_ATTRIBUTE_ID) {
     667         [ +  - ]:          2 :                     if (strcmp((char*)a->children->content, (char*)id) == 0)
     668                 :          2 :                         return cur;
     669                 :            :                 }
     670                 :          0 :                 a = a->next;
     671                 :            :             }
     672                 :            :         }
     673                 :            :         // look in children
     674                 :          2 :         xmlNodePtr result = lcl_search_element_by_id(cur->children, id);
     675         [ +  - ]:          2 :         if (result != NULL)
     676                 :          2 :             return result;
     677                 :          0 :         result = lcl_search_element_by_id(cur->next, id);
     678                 :          4 :             return result;
     679                 :            :     }
     680                 :            : 
     681                 :            :     // Returns the Element whose ID is given by elementId.
     682                 :            :     Reference< XElement > SAL_CALL
     683                 :          4 :     CDocument::getElementById(const OUString& elementId)
     684                 :            :         throw (RuntimeException)
     685                 :            :     {
     686         [ +  - ]:          4 :         ::osl::MutexGuard const g(m_Mutex);
     687                 :            : 
     688                 :            :         // search the tree for an element with the given ID
     689         [ +  - ]:          4 :         OString o1 = OUStringToOString(elementId, RTL_TEXTENCODING_UTF8);
     690                 :          4 :         xmlChar *xId = (xmlChar*)o1.getStr();
     691                 :          4 :         xmlNodePtr const pStart = lcl_getDocumentRootPtr(m_aDocPtr);
     692 [ +  - ][ +  + ]:          4 :         if (!pStart) { return 0; }
     693         [ +  - ]:          2 :         xmlNodePtr const pNode = lcl_search_element_by_id(pStart, xId);
     694                 :            :         Reference< XElement > const xRet(
     695 [ +  - ][ +  - ]:          4 :             static_cast< XNode* >(GetCNode(pNode).get()),
     696         [ +  - ]:          2 :             UNO_QUERY);
     697         [ +  - ]:          4 :         return xRet;
     698                 :            :     }
     699                 :            : 
     700                 :            : 
     701                 :            :     Reference< XNodeList > SAL_CALL
     702                 :          4 :     CDocument::getElementsByTagName(OUString const& rTagname)
     703                 :            :             throw (RuntimeException)
     704                 :            :     {
     705         [ +  - ]:          4 :         ::osl::MutexGuard const g(m_Mutex);
     706                 :            : 
     707                 :            :         Reference< XNodeList > const xRet(
     708 [ +  - ][ +  - ]:          4 :             new CElementList(this->GetDocumentElement(), m_Mutex, rTagname));
         [ +  - ][ +  - ]
     709         [ +  - ]:          4 :         return xRet;
     710                 :            :     }
     711                 :            : 
     712                 :          4 :     Reference< XNodeList > SAL_CALL CDocument::getElementsByTagNameNS(
     713                 :            :             OUString const& rNamespaceURI, OUString const& rLocalName)
     714                 :            :         throw (RuntimeException)
     715                 :            :     {
     716         [ +  - ]:          4 :         ::osl::MutexGuard const g(m_Mutex);
     717                 :            : 
     718                 :            :         Reference< XNodeList > const xRet(
     719                 :            :             new CElementList(this->GetDocumentElement(), m_Mutex,
     720 [ +  - ][ +  - ]:          4 :                 rLocalName, &rNamespaceURI));
         [ +  - ][ +  - ]
     721         [ +  - ]:          4 :         return xRet;
     722                 :            :     }
     723                 :            : 
     724                 :          2 :     Reference< XDOMImplementation > SAL_CALL CDocument::getImplementation()
     725                 :            :         throw (RuntimeException)
     726                 :            :     {
     727                 :            :         // does not need mutex currently
     728         [ +  - ]:          2 :         return Reference< XDOMImplementation >(CDOMImplementation::get());
     729                 :            :     }
     730                 :            : 
     731                 :            :     // helper function to recursively import siblings
     732                 :        752 :     static void lcl_ImportSiblings(
     733                 :            :         Reference< XDocument > const& xTargetDocument,
     734                 :            :         Reference< XNode > const& xTargetParent,
     735                 :            :         Reference< XNode > const& xChild)
     736                 :            :     {
     737                 :        752 :         Reference< XNode > xSibling = xChild;
     738         [ +  + ]:       1986 :         while (xSibling.is())
     739                 :            :         {
     740                 :            :             Reference< XNode > const xTmp(
     741 [ +  - ][ +  - ]:       1234 :                     xTargetDocument->importNode(xSibling, sal_True));
     742 [ +  - ][ +  - ]:       1234 :             xTargetParent->appendChild(xTmp);
     743 [ +  - ][ +  - ]:       1234 :             xSibling = xSibling->getNextSibling();
                 [ +  - ]
     744                 :       1986 :         }
     745                 :        752 :     }
     746                 :            : 
     747                 :            :     static Reference< XNode >
     748                 :       1397 :     lcl_ImportNode( Reference< XDocument > const& xDocument,
     749                 :            :             Reference< XNode > const& xImportedNode, sal_Bool deep)
     750                 :            :     {
     751                 :       1397 :         Reference< XNode > xNode;
     752 [ +  - ][ +  - ]:       1397 :         NodeType aNodeType = xImportedNode->getNodeType();
     753   [ -  -  -  -  :       1397 :         switch (aNodeType)
             +  -  -  +  
                      - ]
     754                 :            :         {
     755                 :            :         case NodeType_ATTRIBUTE_NODE:
     756                 :            :         {
     757         [ #  # ]:          0 :             Reference< XAttr > const xAttr(xImportedNode, UNO_QUERY_THROW);
     758                 :            :             Reference< XAttr > const xNew =
     759 [ #  # ][ #  # ]:          0 :                 xDocument->createAttribute(xAttr->getName());
         [ #  # ][ #  # ]
     760 [ #  # ][ #  # ]:          0 :             xNew->setValue(xAttr->getValue());
         [ #  # ][ #  # ]
     761         [ #  # ]:          0 :             xNode.set(xNew, UNO_QUERY);
     762                 :          0 :             break;
     763                 :            :         }
     764                 :            :         case NodeType_CDATA_SECTION_NODE:
     765                 :            :         {
     766                 :            :             Reference< XCDATASection > const xCData(xImportedNode,
     767         [ #  # ]:          0 :                     UNO_QUERY_THROW);
     768                 :            :             Reference< XCDATASection > const xNewCData =
     769 [ #  # ][ #  # ]:          0 :                 xDocument->createCDATASection(xCData->getData());
         [ #  # ][ #  # ]
     770         [ #  # ]:          0 :             xNode.set(xNewCData, UNO_QUERY);
     771                 :          0 :             break;
     772                 :            :         }
     773                 :            :         case NodeType_COMMENT_NODE:
     774                 :            :         {
     775                 :            :             Reference< XComment > const xComment(xImportedNode,
     776         [ #  # ]:          0 :                     UNO_QUERY_THROW);
     777                 :            :             Reference< XComment > const xNewComment =
     778 [ #  # ][ #  # ]:          0 :                 xDocument->createComment(xComment->getData());
         [ #  # ][ #  # ]
     779         [ #  # ]:          0 :             xNode.set(xNewComment, UNO_QUERY);
     780                 :          0 :             break;
     781                 :            :         }
     782                 :            :         case NodeType_DOCUMENT_FRAGMENT_NODE:
     783                 :            :         {
     784                 :            :             Reference< XDocumentFragment > const xFrag(xImportedNode,
     785         [ #  # ]:          0 :                     UNO_QUERY_THROW);
     786                 :            :             Reference< XDocumentFragment > const xNewFrag =
     787 [ #  # ][ #  # ]:          0 :                 xDocument->createDocumentFragment();
     788         [ #  # ]:          0 :             xNode.set(xNewFrag, UNO_QUERY);
     789                 :          0 :             break;
     790                 :            :         }
     791                 :            :         case NodeType_ELEMENT_NODE:
     792                 :            :         {
     793                 :            :             Reference< XElement > const xElement(xImportedNode,
     794         [ +  - ]:        881 :                     UNO_QUERY_THROW);
     795 [ +  - ][ +  - ]:        881 :             OUString const aNsUri = xImportedNode->getNamespaceURI();
     796 [ +  - ][ +  - ]:        881 :             OUString const aNsPrefix = xImportedNode->getPrefix();
     797 [ +  - ][ +  - ]:        881 :             OUString aQName = xElement->getTagName();
     798                 :        881 :             Reference< XElement > xNewElement;
     799         [ +  + ]:        881 :             if (!aNsUri.isEmpty())
     800                 :            :             {
     801         [ +  - ]:        873 :                 if (!aNsPrefix.isEmpty()) {
     802                 :        873 :                     aQName = aNsPrefix + ":" + aQName;
     803                 :            :                 }
     804 [ +  - ][ +  - ]:        873 :                 xNewElement = xDocument->createElementNS(aNsUri, aQName);
                 [ +  - ]
     805                 :            :             } else {
     806 [ +  - ][ +  - ]:          8 :                 xNewElement = xDocument->createElement(aQName);
                 [ +  - ]
     807                 :            :             }
     808                 :            : 
     809                 :            :             // get attributes
     810 [ +  - ][ +  - ]:        881 :             if (xElement->hasAttributes())
                 [ +  + ]
     811                 :            :             {
     812 [ +  - ][ +  - ]:        328 :                 Reference< XNamedNodeMap > attribs = xElement->getAttributes();
     813 [ +  - ][ +  - ]:       1013 :                 for (sal_Int32 i = 0; i < attribs->getLength(); i++)
                 [ +  + ]
     814                 :            :                 {
     815         [ +  - ]:        685 :                     Reference< XAttr > const curAttr(attribs->item(i),
     816 [ +  - ][ +  - ]:        685 :                             UNO_QUERY_THROW);
     817 [ +  - ][ +  - ]:        685 :                     OUString const aAttrUri = curAttr->getNamespaceURI();
     818 [ +  - ][ +  - ]:        685 :                     OUString const aAttrPrefix = curAttr->getPrefix();
     819 [ +  - ][ +  - ]:        685 :                     OUString aAttrName = curAttr->getName();
     820 [ +  - ][ +  - ]:        685 :                     OUString const sValue = curAttr->getValue();
     821         [ +  + ]:        685 :                     if (!aAttrUri.isEmpty())
     822                 :            :                     {
     823         [ +  - ]:        681 :                         if (!aAttrPrefix.isEmpty()) {
     824                 :        681 :                             aAttrName = aAttrPrefix + ":" + aAttrName;
     825                 :            :                         }
     826         [ +  - ]:        681 :                         xNewElement->setAttributeNS(
     827         [ +  - ]:        681 :                                 aAttrUri, aAttrName, sValue);
     828                 :            :                     } else {
     829 [ +  - ][ +  - ]:          4 :                         xNewElement->setAttribute(aAttrName, sValue);
     830                 :            :                     }
     831                 :       1013 :                 }
     832                 :            :             }
     833         [ +  - ]:        881 :             xNode.set(xNewElement, UNO_QUERY);
     834                 :        881 :             break;
     835                 :            :         }
     836                 :            :         case NodeType_ENTITY_REFERENCE_NODE:
     837                 :            :         {
     838                 :            :             Reference< XEntityReference > const xRef(xImportedNode,
     839         [ #  # ]:          0 :                     UNO_QUERY_THROW);
     840                 :            :             Reference< XEntityReference > const xNewRef(
     841 [ #  # ][ #  # ]:          0 :                 xDocument->createEntityReference(xRef->getNodeName()));
         [ #  # ][ #  # ]
     842         [ #  # ]:          0 :             xNode.set(xNewRef, UNO_QUERY);
     843                 :          0 :             break;
     844                 :            :         }
     845                 :            :         case NodeType_PROCESSING_INSTRUCTION_NODE:
     846                 :            :         {
     847                 :            :             Reference< XProcessingInstruction > const xPi(xImportedNode,
     848         [ #  # ]:          0 :                     UNO_QUERY_THROW);
     849                 :            :             Reference< XProcessingInstruction > const xNewPi(
     850         [ #  # ]:          0 :                 xDocument->createProcessingInstruction(
     851 [ #  # ][ #  # ]:          0 :                     xPi->getTarget(), xPi->getData()));
         [ #  # ][ #  # ]
                 [ #  # ]
     852         [ #  # ]:          0 :             xNode.set(xNewPi, UNO_QUERY);
     853                 :          0 :             break;
     854                 :            :         }
     855                 :            :         case NodeType_TEXT_NODE:
     856                 :            :         {
     857         [ +  - ]:        516 :             Reference< XText > const xText(xImportedNode, UNO_QUERY_THROW);
     858                 :            :             Reference< XText > const xNewText(
     859 [ +  - ][ +  - ]:        516 :                 xDocument->createTextNode(xText->getData()));
         [ +  - ][ +  - ]
     860         [ +  - ]:        516 :             xNode.set(xNewText, UNO_QUERY);
     861                 :        516 :             break;
     862                 :            :         }
     863                 :            :         case NodeType_ENTITY_NODE:
     864                 :            :         case NodeType_DOCUMENT_NODE:
     865                 :            :         case NodeType_DOCUMENT_TYPE_NODE:
     866                 :            :         case NodeType_NOTATION_NODE:
     867                 :            :         default:
     868                 :            :             // can't be imported
     869         [ #  # ]:          0 :             throw RuntimeException();
     870                 :            : 
     871                 :            :         }
     872         [ +  + ]:       1397 :         if (deep)
     873                 :            :         {
     874                 :            :             // get children and import them
     875 [ +  - ][ +  - ]:       1395 :             Reference< XNode > const xChild = xImportedNode->getFirstChild();
     876         [ +  + ]:       1395 :             if (xChild.is())
     877                 :            :             {
     878         [ +  - ]:        752 :                 lcl_ImportSiblings(xDocument, xNode, xChild);
     879                 :       1395 :             }
     880                 :            :         }
     881                 :            : 
     882                 :            :         /* DOMNodeInsertedIntoDocument
     883                 :            :          * Fired when a node is being inserted into a document,
     884                 :            :          * either through direct insertion of the Node or insertion of a
     885                 :            :          * subtree in which it is contained. This event is dispatched after
     886                 :            :          * the insertion has taken place. The target of this event is the node
     887                 :            :          * being inserted. If the Node is being directly inserted the DOMNodeInserted
     888                 :            :          * event will fire before the DOMNodeInsertedIntoDocument event.
     889                 :            :          *   Bubbles: No
     890                 :            :          *   Cancelable: No
     891                 :            :          *   Context Info: None
     892                 :            :          */
     893         [ +  - ]:       1397 :         if (xNode.is())
     894                 :            :         {
     895         [ +  - ]:       1397 :             Reference< XDocumentEvent > const xDocevent(xDocument, UNO_QUERY);
     896         [ +  - ]:       1397 :             Reference< XMutationEvent > const event(xDocevent->createEvent(
     897 [ +  - ][ +  - ]:       1397 :                 "DOMNodeInsertedIntoDocument"), UNO_QUERY_THROW);
     898         [ +  - ]:       1397 :             event->initMutationEvent(
     899                 :            :                 "DOMNodeInsertedIntoDocument", sal_True, sal_False, Reference< XNode >(),
     900         [ +  - ]:       1397 :                 OUString(), OUString(), OUString(), (AttrChangeType)0 );
     901         [ +  - ]:       1397 :             Reference< XEventTarget > const xDocET(xDocument, UNO_QUERY);
     902 [ +  - ][ +  - ]:       1397 :             xDocET->dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
                 [ +  - ]
     903                 :            :         }
     904                 :            : 
     905                 :       1397 :         return xNode;
     906                 :            :     }
     907                 :            : 
     908                 :       1401 :     Reference< XNode > SAL_CALL CDocument::importNode(
     909                 :            :             Reference< XNode > const& xImportedNode, sal_Bool deep)
     910                 :            :         throw (RuntimeException, DOMException)
     911                 :            :     {
     912 [ +  + ][ +  - ]:       1401 :         if (!xImportedNode.is()) { throw RuntimeException(); }
     913                 :            : 
     914                 :            :         // NB: this whole operation inherently accesses 2 distinct documents.
     915                 :            :         // The imported node could even be from a different DOM implementation,
     916                 :            :         // so this implementation cannot make any assumptions about the
     917                 :            :         // locking strategy of the imported node.
     918                 :            :         // So the import takes no lock on this document;
     919                 :            :         // it only calls UNO methods on this document that temporarily
     920                 :            :         // lock the document, and UNO methods on the imported node that
     921                 :            :         // may temporarily lock the other document.
     922                 :            :         // As a consequence, the import is not atomic with regard to
     923                 :            :         // concurrent modifications of either document, but it should not
     924                 :            :         // deadlock.
     925                 :            :         // To ensure that no members are accessed, the implementation is in
     926                 :            :         // static non-member functions.
     927                 :            : 
     928         [ +  - ]:       1399 :         Reference< XDocument > const xDocument(this);
     929                 :            :         // already in doc?
     930 [ +  - ][ +  - ]:       1399 :         if (xImportedNode->getOwnerDocument() == xDocument) {
         [ +  - ][ +  + ]
     931                 :          2 :             return xImportedNode;
     932                 :            :         }
     933                 :            : 
     934                 :            :         Reference< XNode > const xNode(
     935         [ +  - ]:       1397 :             lcl_ImportNode(xDocument, xImportedNode, deep) );
     936                 :       1401 :         return xNode;
     937                 :            :     }
     938                 :            : 
     939                 :          2 :     OUString SAL_CALL CDocument::getNodeName()throw (RuntimeException)
     940                 :            :     {
     941                 :            :         // does not need mutex currently
     942                 :          2 :         return OUString("#document");
     943                 :            :     }
     944                 :            : 
     945                 :          2 :     OUString SAL_CALL CDocument::getNodeValue() throw (RuntimeException)
     946                 :            :     {
     947                 :            :         // does not need mutex currently
     948                 :          2 :         return OUString();
     949                 :            :     }
     950                 :            : 
     951                 :          4 :     Reference< XNode > SAL_CALL CDocument::cloneNode(sal_Bool bDeep)
     952                 :            :         throw (RuntimeException)
     953                 :            :     {
     954         [ +  - ]:          4 :         ::osl::MutexGuard const g(m_rMutex);
     955                 :            : 
     956                 :            :         OSL_ASSERT(0 != m_aNodePtr);
     957         [ -  + ]:          4 :         if (0 == m_aNodePtr) {
     958         [ #  # ]:          0 :             return 0;
     959                 :            :         }
     960 [ +  + ][ +  - ]:          4 :         xmlDocPtr const pClone(xmlCopyDoc(m_aDocPtr, (bDeep) ? 1 : 0));
     961 [ -  + ][ #  # ]:          4 :         if (0 == pClone) { return 0; }
     962                 :            :         Reference< XNode > const xRet(
     963 [ +  - ][ +  - ]:          4 :             static_cast<CNode*>(CDocument::CreateCDocument(pClone).get()));
                 [ +  - ]
     964         [ +  - ]:          4 :         return xRet;
     965                 :            :     }
     966                 :            : 
     967                 :     126487 :     Reference< XEvent > SAL_CALL CDocument::createEvent(const OUString& aType) throw (RuntimeException)
     968                 :            :     {
     969                 :            :         // does not need mutex currently
     970                 :     126487 :         events::CEvent *pEvent = 0;
     971 [ +  + ][ +  + ]:     191103 :         if ( aType == "DOMSubtreeModified" || aType == "DOMNodeInserted" || aType == "DOMNodeRemoved"
           [ +  +  +  -  
          +  +  +  +  +  
              - ][ +  - ]
     972                 :      64417 :           || aType == "DOMNodeRemovedFromDocument" || aType == "DOMNodeInsertedIntoDocument" || aType == "DOMAttrModified"
     973                 :        199 :           || aType == "DOMCharacterDataModified")
     974                 :            :         {
     975         [ +  - ]:     126487 :             pEvent = new events::CMutationEvent;
     976                 :            : 
     977 [ #  # ][ #  # ]:          0 :         } else if ( aType == "DOMFocusIn" || aType == "DOMFocusOut" || aType == "DOMActivate")
         [ #  # ][ #  # ]
     978                 :            :         {
     979         [ #  # ]:          0 :             pEvent = new events::CUIEvent;
     980 [ #  # ][ #  # ]:          0 :         } else if ( aType == "click"     || aType == "mousedown" || aType == "mouseup"
           [ #  #  #  #  
             #  #  #  # ]
                 [ #  # ]
     981                 :          0 :                  || aType == "mouseover" || aType == "mousemove" || aType == "mouseout" )
     982                 :            :         {
     983         [ #  # ]:          0 :             pEvent = new events::CMouseEvent;
     984                 :            :         }
     985                 :            :         else // generic event
     986                 :            :         {
     987         [ #  # ]:          0 :             pEvent = new events::CEvent;
     988                 :            :         }
     989         [ +  - ]:     126487 :         return Reference< XEvent >(pEvent);
     990                 :            :     }
     991                 :            : 
     992                 :            :     // ::com::sun::star::xml::sax::XSAXSerializable
     993                 :         50 :     void SAL_CALL CDocument::serialize(
     994                 :            :             const Reference< XDocumentHandler >& i_xHandler,
     995                 :            :             const Sequence< beans::StringPair >& i_rNamespaces)
     996                 :            :         throw (RuntimeException, SAXException)
     997                 :            :     {
     998         [ +  - ]:         50 :         ::osl::MutexGuard const g(m_Mutex);
     999                 :            : 
    1000                 :            :         // add new namespaces to root node
    1001                 :         50 :         xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr);
    1002         [ +  - ]:         50 :         if (0 != pRoot) {
    1003                 :         50 :             const beans::StringPair * pSeq = i_rNamespaces.getConstArray();
    1004         [ +  + ]:       1038 :             for (const beans::StringPair *pNsDef = pSeq;
    1005                 :        519 :                  pNsDef < pSeq + i_rNamespaces.getLength(); ++pNsDef) {
    1006                 :            :                 OString prefix = OUStringToOString(pNsDef->First,
    1007         [ +  - ]:        469 :                                     RTL_TEXTENCODING_UTF8);
    1008                 :            :                 OString href   = OUStringToOString(pNsDef->Second,
    1009         [ +  - ]:        469 :                                     RTL_TEXTENCODING_UTF8);
    1010                 :            :                 // this will only add the ns if it does not exist already
    1011                 :        469 :                 xmlNewNs(pRoot, reinterpret_cast<const xmlChar*>(href.getStr()),
    1012         [ +  - ]:        938 :                          reinterpret_cast<const xmlChar*>(prefix.getStr()));
    1013                 :        469 :             }
    1014                 :            :             // eliminate duplicate namespace declarations
    1015         [ +  - ]:         50 :             nscleanup(pRoot->children, pRoot);
    1016                 :            :         }
    1017 [ +  - ][ +  - ]:         50 :         saxify(i_xHandler);
    1018                 :         50 :     }
    1019                 :            : 
    1020                 :            :     // ::com::sun::star::xml::sax::XFastSAXSerializable
    1021                 :         15 :     void SAL_CALL CDocument::fastSerialize( const Reference< XFastDocumentHandler >& i_xHandler,
    1022                 :            :                                             const Reference< XFastTokenHandler >& i_xTokenHandler,
    1023                 :            :                                             const Sequence< beans::StringPair >& i_rNamespaces,
    1024                 :            :                                             const Sequence< beans::Pair< rtl::OUString, sal_Int32 > >& i_rRegisterNamespaces )
    1025                 :            :         throw (SAXException, RuntimeException)
    1026                 :            :     {
    1027         [ +  - ]:         15 :         ::osl::MutexGuard const g(m_Mutex);
    1028                 :            : 
    1029                 :            :         // add new namespaces to root node
    1030                 :         15 :         xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr);
    1031         [ +  - ]:         15 :         if (0 != pRoot) {
    1032                 :         15 :             const beans::StringPair * pSeq = i_rNamespaces.getConstArray();
    1033         [ -  + ]:         30 :             for (const beans::StringPair *pNsDef = pSeq;
    1034                 :         15 :                  pNsDef < pSeq + i_rNamespaces.getLength(); ++pNsDef) {
    1035                 :            :                 OString prefix = OUStringToOString(pNsDef->First,
    1036         [ #  # ]:          0 :                                     RTL_TEXTENCODING_UTF8);
    1037                 :            :                 OString href   = OUStringToOString(pNsDef->Second,
    1038         [ #  # ]:          0 :                                     RTL_TEXTENCODING_UTF8);
    1039                 :            :                 // this will only add the ns if it does not exist already
    1040                 :          0 :                 xmlNewNs(pRoot, reinterpret_cast<const xmlChar*>(href.getStr()),
    1041         [ #  # ]:          0 :                          reinterpret_cast<const xmlChar*>(prefix.getStr()));
    1042                 :          0 :             }
    1043                 :            :             // eliminate duplicate namespace declarations
    1044         [ +  - ]:         15 :             nscleanup(pRoot->children, pRoot);
    1045                 :            :         }
    1046                 :            : 
    1047                 :            :         Context aContext(i_xHandler,
    1048         [ +  - ]:         15 :                          i_xTokenHandler);
    1049                 :            : 
    1050                 :            :         // register namespace ids
    1051                 :         15 :         const beans::Pair<OUString,sal_Int32>* pSeq = i_rRegisterNamespaces.getConstArray();
    1052         [ +  + ]:        660 :         for (const beans::Pair<OUString,sal_Int32>* pNs = pSeq;
    1053                 :        330 :              pNs < pSeq + i_rRegisterNamespaces.getLength(); ++pNs)
    1054                 :            :         {
    1055                 :            :             OSL_ENSURE(pNs->Second >= FastToken::NAMESPACE,
    1056                 :            :                        "CDocument::fastSerialize(): invalid NS token id");
    1057         [ +  - ]:        315 :             aContext.maNamespaceMap[ pNs->First ] = pNs->Second;
    1058                 :            :         }
    1059                 :            : 
    1060 [ +  - ][ +  - ]:         15 :         fastSaxify(aContext);
                 [ +  - ]
    1061                 :         15 :     }
    1062                 :            : }
    1063                 :            : 
    1064                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10