LCOV - code coverage report
Current view: top level - libreoffice/unoxml/source/dom - document.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 206 460 44.8 %
Date: 2012-12-27 Functions: 21 49 42.9 %
Legend: Lines: hit not hit

          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           0 :     static xmlNodePtr lcl_getDocumentType(xmlDocPtr const i_pDocument)
      52             :     {
      53             :         // find the doc type
      54           0 :         xmlNodePtr cur = i_pDocument->children;
      55           0 :         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           0 :         return 0;
      63             :     }
      64             : 
      65             :     /// get the pointer to the root element node of the document
      66        1227 :     static xmlNodePtr lcl_getDocumentRootPtr(xmlDocPtr const i_pDocument)
      67             :     {
      68             :         // find the document element
      69        1227 :         xmlNodePtr cur = i_pDocument->children;
      70        2454 :         while (cur != NULL)
      71             :         {
      72          69 :             if (cur->type == XML_ELEMENT_NODE)
      73          69 :                 break;
      74           0 :             cur = cur->next;
      75             :         }
      76        1227 :         return cur;
      77             :     }
      78             : 
      79        1164 :     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        1164 :         , m_pEventDispatcher(new events::CEventDispatcher())
      85             :     {
      86        1164 :     }
      87             : 
      88        1164 :     ::rtl::Reference<CDocument> CDocument::CreateCDocument(xmlDocPtr const pDoc)
      89             :     {
      90        1164 :         ::rtl::Reference<CDocument> const xDoc(new CDocument(pDoc));
      91             :         // add the doc itself to its nodemap!
      92        1164 :         xDoc->m_NodeMap.insert(
      93             :             nodemap_t::value_type(reinterpret_cast<xmlNodePtr>(pDoc),
      94             :                 ::std::make_pair(
      95        1164 :                     WeakReference<XNode>(static_cast<XDocument*>(xDoc.get())),
      96        3492 :                     xDoc.get())));
      97        1164 :         return xDoc;
      98             :     }
      99             : 
     100        2811 :     CDocument::~CDocument()
     101             :     {
     102         937 :         ::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         937 :         xmlFreeDoc(m_aDocPtr);
     114        1874 :     }
     115             : 
     116             : 
     117       17573 :     events::CEventDispatcher & CDocument::GetEventDispatcher()
     118             :     {
     119       17573 :         return *m_pEventDispatcher;
     120             :     }
     121             : 
     122           0 :     ::rtl::Reference< CElement > CDocument::GetDocumentElement()
     123             :     {
     124           0 :         xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr);
     125             :         ::rtl::Reference< CElement > const xRet(
     126           0 :             dynamic_cast<CElement*>(GetCNode(pNode).get()));
     127           0 :         return xRet;
     128             :     }
     129             : 
     130             :     void
     131       17652 :     CDocument::RemoveCNode(xmlNodePtr const pNode, CNode const*const pCNode)
     132             :     {
     133       17652 :         nodemap_t::iterator const i = m_NodeMap.find(pNode);
     134       17652 :         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       17652 :             CNode *const pCurrent = i->second.second;
     144       17652 :             if (pCurrent == pCNode) {
     145       17652 :                 m_NodeMap.erase(i);
     146             :             }
     147             :         }
     148       17652 :     }
     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       80102 :     CDocument::GetCNode(xmlNodePtr const pNode, bool const bCreate)
     156             :     {
     157       80102 :         if (0 == pNode) {
     158       20836 :             return 0;
     159             :         }
     160             :         //check whether there is already an instance for this node
     161       59266 :         nodemap_t::const_iterator const i = m_NodeMap.find(pNode);
     162       59266 :         if (i != m_NodeMap.end()) {
     163             :             // #i113681# check that the CNode is still alive
     164       40716 :             uno::Reference<XNode> const xNode(i->second.first);
     165       40716 :             if (xNode.is())
     166             :             {
     167       40716 :                 ::rtl::Reference<CNode> ret(i->second.second);
     168             :                 OSL_ASSERT(ret.is());
     169       40716 :                 return ret;
     170       40716 :             }
     171             :         }
     172             : 
     173       18550 :         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       18550 :         ::rtl::Reference<CNode> pCNode;
     179       18550 :         switch (pNode->type)
     180             :         {
     181             :             case XML_ELEMENT_NODE:
     182             :                 // m_aNodeType = NodeType::ELEMENT_NODE;
     183             :                 pCNode = static_cast< CNode* >(
     184       11584 :                         new CElement(*this, m_Mutex, pNode));
     185       11584 :             break;
     186             :             case XML_TEXT_NODE:
     187             :                 // m_aNodeType = NodeType::TEXT_NODE;
     188             :                 pCNode = static_cast< CNode* >(
     189        2695 :                         new CText(*this, m_Mutex, pNode));
     190        2695 :             break;
     191             :             case XML_CDATA_SECTION_NODE:
     192             :                 // m_aNodeType = NodeType::CDATA_SECTION_NODE;
     193             :                 pCNode = static_cast< CNode* >(
     194           0 :                         new CCDATASection(*this, m_Mutex, pNode));
     195           0 :             break;
     196             :             case XML_ENTITY_REF_NODE:
     197             :                 // m_aNodeType = NodeType::ENTITY_REFERENCE_NODE;
     198             :                 pCNode = static_cast< CNode* >(
     199           0 :                         new CEntityReference(*this, m_Mutex, pNode));
     200           0 :             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           0 :                         new CProcessingInstruction(*this, m_Mutex, pNode));
     210           0 :             break;
     211             :             case XML_COMMENT_NODE:
     212             :                 // m_aNodeType = NodeType::COMMENT_NODE;
     213             :                 pCNode = static_cast< CNode* >(
     214           0 :                         new CComment(*this, m_Mutex, pNode));
     215           0 :             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           0 :                         new CDocumentFragment(*this, m_Mutex, pNode));
     233           0 :             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        4271 :                             reinterpret_cast<xmlAttrPtr>(pNode)));
     243        4271 :             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       18550 :         if (pCNode != 0) {
     255             :             bool const bInserted = m_NodeMap.insert(
     256             :                     nodemap_t::value_type(pNode,
     257       18550 :                         ::std::make_pair(WeakReference<XNode>(pCNode.get()),
     258       18550 :                         pCNode.get()))
     259       37100 :                 ).second;
     260             :             OSL_ASSERT(bInserted);
     261       18550 :             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       18550 :         return pCNode;
     269             :     }
     270             : 
     271             : 
     272        8576 :     CDocument & CDocument::GetOwnerDocument()
     273             :     {
     274        8576 :         return *this;
     275             :     }
     276             : 
     277           4 :     void CDocument::saxify(const Reference< XDocumentHandler >& i_xHandler)
     278             :     {
     279           4 :         i_xHandler->startDocument();
     280           8 :         for (xmlNodePtr pChild = m_aNodePtr->children;
     281             :                         pChild != 0; pChild = pChild->next) {
     282           4 :             ::rtl::Reference<CNode> const pNode = GetCNode(pChild);
     283             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     284           4 :             pNode->saxify(i_xHandler);
     285           4 :         }
     286           4 :         i_xHandler->endDocument();
     287           4 :     }
     288             : 
     289           6 :     void CDocument::fastSaxify( Context& rContext )
     290             :     {
     291           6 :         rContext.mxDocHandler->startDocument();
     292          12 :         for (xmlNodePtr pChild = m_aNodePtr->children;
     293             :                         pChild != 0; pChild = pChild->next) {
     294           6 :             ::rtl::Reference<CNode> const pNode = GetCNode(pChild);
     295             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     296           6 :             pNode->fastSaxify(rContext);
     297           6 :         }
     298           6 :         rContext.mxDocHandler->endDocument();
     299           6 :     }
     300             : 
     301        1158 :     bool CDocument::IsChildTypeAllowed(NodeType const nodeType)
     302             :     {
     303        1158 :         switch (nodeType) {
     304             :             case NodeType_PROCESSING_INSTRUCTION_NODE:
     305             :             case NodeType_COMMENT_NODE:
     306           0 :                 return true;
     307             :             case NodeType_ELEMENT_NODE:
     308             :                  // there may be only one!
     309        1158 :                 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           0 :                 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           0 :     } IOContext;
     340             : 
     341             :     extern "C" {
     342             :     // write callback
     343             :     // int xmlOutputWriteCallback (void * context, const char * buffer, int len)
     344           0 :     static int writeCallback(void *context, const char* buffer, int len){
     345             :         // create a sequence and write it to the stream
     346           0 :         IOContext *pContext = static_cast<IOContext*>(context);
     347           0 :         Sequence<sal_Int8> bs(reinterpret_cast<const sal_Int8*>(buffer), len);
     348           0 :         pContext->stream->writeBytes(bs);
     349           0 :         return len;
     350             :     }
     351             : 
     352             :     // clsoe callback
     353             :     //int xmlOutputCloseCallback (void * context)
     354           0 :     static int closeCallback(void *context)
     355             :     {
     356           0 :         IOContext *pContext = static_cast<IOContext*>(context);
     357           0 :         if (pContext->allowClose) {
     358           0 :             pContext->stream->closeOutput();
     359             :         }
     360           0 :         return 0;
     361             :     }
     362             :     } // extern "C"
     363             : 
     364           0 :     void SAL_CALL CDocument::start()
     365             :         throw (RuntimeException)
     366             :     {
     367           0 :         listenerlist_t streamListeners;
     368             :         {
     369           0 :             ::osl::MutexGuard const g(m_Mutex);
     370             : 
     371           0 :             if (! m_rOutputStream.is()) { throw RuntimeException(); }
     372           0 :             streamListeners = m_streamListeners;
     373             :         }
     374             : 
     375             :         // notify listeners about start
     376           0 :         listenerlist_t::const_iterator iter1 = streamListeners.begin();
     377           0 :         while (iter1 != streamListeners.end()) {
     378           0 :             Reference< XStreamListener > aListener = *iter1;
     379           0 :             aListener->started();
     380           0 :             ++iter1;
     381           0 :         }
     382             : 
     383             :         {
     384           0 :             ::osl::MutexGuard const g(m_Mutex);
     385             : 
     386             :             // check again! could have been reset...
     387           0 :             if (! m_rOutputStream.is()) { throw RuntimeException(); }
     388             : 
     389             :             // setup libxml IO and write data to output stream
     390           0 :             IOContext ioctx = {m_rOutputStream, false};
     391             :             xmlOutputBufferPtr pOut = xmlOutputBufferCreateIO(
     392           0 :                 writeCallback, closeCallback, &ioctx, NULL);
     393           0 :             xmlSaveFileTo(pOut, m_aNodePtr->doc, NULL);
     394             :         }
     395             : 
     396             :         // call listeners
     397           0 :         listenerlist_t::const_iterator iter2 = streamListeners.begin();
     398           0 :         while (iter2 != streamListeners.end()) {
     399           0 :             Reference< XStreamListener > aListener = *iter2;
     400           0 :             aListener->closed();
     401           0 :             ++iter2;
     402           0 :         }
     403           0 :     }
     404             : 
     405           0 :     void SAL_CALL CDocument::terminate()
     406             :         throw (RuntimeException)
     407             :     {
     408             :         // not supported
     409           0 :     }
     410             : 
     411           0 :     void SAL_CALL CDocument::setOutputStream( const Reference< XOutputStream >& aStream )
     412             :         throw (RuntimeException)
     413             :     {
     414           0 :         ::osl::MutexGuard const g(m_Mutex);
     415             : 
     416           0 :         m_rOutputStream = aStream;
     417           0 :     }
     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           0 :     Reference< XAttr > SAL_CALL CDocument::createAttribute(const OUString& name)
     428             :         throw (RuntimeException, DOMException)
     429             :     {
     430           0 :         ::osl::MutexGuard const g(m_Mutex);
     431             : 
     432           0 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     433           0 :         xmlChar *xName = (xmlChar*)o1.getStr();
     434           0 :         xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr, xName, NULL);
     435             :         ::rtl::Reference< CAttr > const pCAttr(
     436             :             dynamic_cast< CAttr* >(GetCNode(
     437           0 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()));
     438           0 :         pCAttr->m_bUnlinked = true;
     439           0 :         return pCAttr.get();
     440             :     };
     441             : 
     442             :     // Creates an attribute of the given qualified name and namespace URI.
     443           0 :     Reference< XAttr > SAL_CALL CDocument::createAttributeNS(
     444             :             const OUString& ns, const OUString& qname)
     445             :         throw (RuntimeException, DOMException)
     446             :     {
     447           0 :         ::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           0 :         sal_Int32 i = qname.indexOf(':');
     454           0 :         OString oPrefix, oName, oUri;
     455           0 :         if (i != -1)
     456             :         {
     457           0 :             oPrefix = OUStringToOString(qname.copy(0, i), RTL_TEXTENCODING_UTF8);
     458           0 :             oName = OUStringToOString(qname.copy(i+1, qname.getLength()-i-1), RTL_TEXTENCODING_UTF8);
     459             :         }
     460             :         else
     461             :         {
     462           0 :             oName = OUStringToOString(qname, RTL_TEXTENCODING_UTF8);
     463             :         }
     464           0 :         oUri = OUStringToOString(ns, RTL_TEXTENCODING_UTF8);
     465             :         xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr,
     466           0 :                 reinterpret_cast<xmlChar const*>(oName.getStr()), 0);
     467             :         ::rtl::Reference< CAttr > const pCAttr(
     468             :             dynamic_cast< CAttr* >(GetCNode(
     469           0 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()));
     470           0 :         if (!pCAttr.is()) { throw RuntimeException(); }
     471             :         // store the namespace data!
     472           0 :         pCAttr->m_pNamespace.reset( new stringpair_t(oUri, oPrefix) );
     473           0 :         pCAttr->m_bUnlinked = true;
     474             : 
     475           0 :         return pCAttr.get();
     476             :     };
     477             : 
     478             :     // Creates a CDATASection node whose value is the specified string.
     479           0 :     Reference< XCDATASection > SAL_CALL CDocument::createCDATASection(const OUString& data)
     480             :         throw (RuntimeException)
     481             :     {
     482           0 :         ::osl::MutexGuard const g(m_Mutex);
     483             : 
     484             :         OString const oData(
     485           0 :                 ::rtl::OUStringToOString(data, RTL_TEXTENCODING_UTF8));
     486             :         xmlChar const*const pData =
     487           0 :             reinterpret_cast<xmlChar const*>(oData.getStr());
     488             :         xmlNodePtr const pText =
     489           0 :             xmlNewCDataBlock(m_aDocPtr, pData, strlen(oData.getStr()));
     490             :         Reference< XCDATASection > const xRet(
     491           0 :             static_cast< XNode* >(GetCNode(pText).get()),
     492           0 :             UNO_QUERY_THROW);
     493           0 :         return xRet;
     494             :     }
     495             : 
     496             :     // Creates a Comment node given the specified string.
     497           0 :     Reference< XComment > SAL_CALL CDocument::createComment(const OUString& data)
     498             :         throw (RuntimeException)
     499             :     {
     500           0 :         ::osl::MutexGuard const g(m_Mutex);
     501             : 
     502           0 :         OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8);
     503           0 :         xmlChar *xData = (xmlChar*)o1.getStr();
     504           0 :         xmlNodePtr pComment = xmlNewDocComment(m_aDocPtr, xData);
     505             :         Reference< XComment > const xRet(
     506           0 :             static_cast< XNode* >(GetCNode(pComment).get()),
     507           0 :             UNO_QUERY_THROW);
     508           0 :         return xRet;
     509             :     }
     510             : 
     511             :     //Creates an empty DocumentFragment object.
     512           0 :     Reference< XDocumentFragment > SAL_CALL CDocument::createDocumentFragment()
     513             :         throw (RuntimeException)
     514             :     {
     515           0 :         ::osl::MutexGuard const g(m_Mutex);
     516             : 
     517           0 :         xmlNodePtr pFrag = xmlNewDocFragment(m_aDocPtr);
     518             :         Reference< XDocumentFragment > const xRet(
     519           0 :             static_cast< XNode* >(GetCNode(pFrag).get()),
     520           0 :             UNO_QUERY_THROW);
     521           0 :         return xRet;
     522             :     }
     523             : 
     524             :     // Creates an element of the type specified.
     525           0 :     Reference< XElement > SAL_CALL CDocument::createElement(const OUString& tagName)
     526             :         throw (RuntimeException, DOMException)
     527             :     {
     528           0 :         ::osl::MutexGuard const g(m_Mutex);
     529             : 
     530           0 :         OString o1 = OUStringToOString(tagName, RTL_TEXTENCODING_UTF8);
     531           0 :         xmlChar *xName = (xmlChar*)o1.getStr();
     532           0 :         xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL);
     533             :         Reference< XElement > const xRet(
     534           0 :             static_cast< XNode* >(GetCNode(pNode).get()),
     535           0 :             UNO_QUERY_THROW);
     536           0 :         return xRet;
     537             :     }
     538             : 
     539             :     // Creates an element of the given qualified name and namespace URI.
     540        4252 :     Reference< XElement > SAL_CALL CDocument::createElementNS(
     541             :             const OUString& ns, const OUString& qname)
     542             :         throw (RuntimeException, DOMException)
     543             :     {
     544        4252 :         ::osl::MutexGuard const g(m_Mutex);
     545             : 
     546        4252 :         sal_Int32 i = qname.indexOf(':');
     547        4252 :         if (ns.isEmpty()) throw RuntimeException();
     548             :         xmlChar *xPrefix;
     549             :         xmlChar *xName;
     550        4252 :         OString o1, o2, o3;
     551        4252 :         if ( i != -1) {
     552        4252 :             o1 = OUStringToOString(qname.copy(0, i), RTL_TEXTENCODING_UTF8);
     553        4252 :             xPrefix = (xmlChar*)o1.getStr();
     554        4252 :             o2 = OUStringToOString(qname.copy(i+1, qname.getLength()-i-1), RTL_TEXTENCODING_UTF8);
     555        4252 :             xName = (xmlChar*)o2.getStr();
     556             :         } else {
     557             :             // default prefix
     558           0 :             xPrefix = (xmlChar*)"";
     559           0 :             o2 = OUStringToOString(qname, RTL_TEXTENCODING_UTF8);
     560           0 :             xName = (xmlChar*)o2.getStr();
     561             :         }
     562        4252 :         o3 = OUStringToOString(ns, RTL_TEXTENCODING_UTF8);
     563        4252 :         xmlChar *xUri = (xmlChar*)o3.getStr();
     564             : 
     565             :         // xmlNsPtr aNsPtr = xmlNewReconciledNs?
     566             :         // xmlNsPtr aNsPtr = xmlNewGlobalNs?
     567        4252 :         xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL);
     568        4252 :         xmlNsPtr const pNs = xmlNewNs(pNode, xUri, xPrefix);
     569        4252 :         xmlSetNs(pNode, pNs);
     570             :         Reference< XElement > const xRet(
     571        8504 :             static_cast< XNode* >(GetCNode(pNode).get()),
     572        4252 :             UNO_QUERY_THROW);
     573        4252 :         return xRet;
     574             :     }
     575             : 
     576             :     //Creates an EntityReference object.
     577           0 :     Reference< XEntityReference > SAL_CALL CDocument::createEntityReference(const OUString& name)
     578             :         throw (RuntimeException, DOMException)
     579             :     {
     580           0 :         ::osl::MutexGuard const g(m_Mutex);
     581             : 
     582           0 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     583           0 :         xmlChar *xName = (xmlChar*)o1.getStr();
     584           0 :         xmlNodePtr const pNode = xmlNewReference(m_aDocPtr, xName);
     585             :         Reference< XEntityReference > const xRet(
     586           0 :             static_cast< XNode* >(GetCNode(pNode).get()),
     587           0 :             UNO_QUERY_THROW);
     588           0 :         return xRet;
     589             :     }
     590             : 
     591             :     // Creates a ProcessingInstruction node given the specified name and
     592             :     // data strings.
     593           0 :     Reference< XProcessingInstruction > SAL_CALL CDocument::createProcessingInstruction(
     594             :             const OUString& target, const OUString& data)
     595             :         throw (RuntimeException, DOMException)
     596             :     {
     597           0 :         ::osl::MutexGuard const g(m_Mutex);
     598             : 
     599           0 :         OString o1 = OUStringToOString(target, RTL_TEXTENCODING_UTF8);
     600           0 :         xmlChar *xTarget = (xmlChar*)o1.getStr();
     601           0 :         OString o2 = OUStringToOString(data, RTL_TEXTENCODING_UTF8);
     602           0 :         xmlChar *xData = (xmlChar*)o2.getStr();
     603           0 :         xmlNodePtr const pNode = xmlNewDocPI(m_aDocPtr, xTarget, xData);
     604           0 :         pNode->doc = m_aDocPtr;
     605             :         Reference< XProcessingInstruction > const xRet(
     606           0 :             static_cast< XNode* >(GetCNode(pNode).get()),
     607           0 :             UNO_QUERY_THROW);
     608           0 :         return xRet;
     609             :     }
     610             : 
     611             :     // Creates a Text node given the specified string.
     612        1622 :     Reference< XText > SAL_CALL CDocument::createTextNode(const OUString& data)
     613             :         throw (RuntimeException)
     614             :     {
     615        1622 :         ::osl::MutexGuard const g(m_Mutex);
     616             : 
     617        1622 :         OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8);
     618        1622 :         xmlChar *xData = (xmlChar*)o1.getStr();
     619        1622 :         xmlNodePtr const pNode = xmlNewDocText(m_aDocPtr, xData);
     620             :         Reference< XText > const xRet(
     621        3244 :             static_cast< XNode* >(GetCNode(pNode).get()),
     622        1622 :             UNO_QUERY_THROW);
     623        1622 :         return xRet;
     624             :     }
     625             : 
     626             :     // The Document Type Declaration (see DocumentType) associated with this
     627             :     // document.
     628           0 :     Reference< XDocumentType > SAL_CALL CDocument::getDoctype()
     629             :         throw (RuntimeException)
     630             :     {
     631           0 :         ::osl::MutexGuard const g(m_Mutex);
     632             : 
     633           0 :         xmlNodePtr const pDocType(lcl_getDocumentType(m_aDocPtr));
     634             :         Reference< XDocumentType > const xRet(
     635           0 :             static_cast< XNode* >(GetCNode(pDocType).get()),
     636           0 :             UNO_QUERY);
     637           0 :         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          59 :     Reference< XElement > SAL_CALL CDocument::getDocumentElement()
     643             :         throw (RuntimeException)
     644             :     {
     645          59 :         ::osl::MutexGuard const g(m_Mutex);
     646             : 
     647          59 :         xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr);
     648          59 :         if (!pNode) { return 0; }
     649             :         Reference< XElement > const xRet(
     650         118 :             static_cast< XNode* >(GetCNode(pNode).get()),
     651          59 :             UNO_QUERY);
     652          59 :         return xRet;
     653             :     }
     654             : 
     655             :     static xmlNodePtr
     656           0 :     lcl_search_element_by_id(const xmlNodePtr cur, const xmlChar* id)
     657             :     {
     658           0 :         if (cur == NULL)
     659           0 :             return NULL;
     660             :         // look in current node
     661           0 :         if (cur->type == XML_ELEMENT_NODE)
     662             :         {
     663           0 :             xmlAttrPtr a = cur->properties;
     664           0 :             while (a != NULL)
     665             :             {
     666           0 :                 if (a->atype == XML_ATTRIBUTE_ID) {
     667           0 :                     if (strcmp((char*)a->children->content, (char*)id) == 0)
     668           0 :                         return cur;
     669             :                 }
     670           0 :                 a = a->next;
     671             :             }
     672             :         }
     673             :         // look in children
     674           0 :         xmlNodePtr result = lcl_search_element_by_id(cur->children, id);
     675           0 :         if (result != NULL)
     676           0 :             return result;
     677           0 :         result = lcl_search_element_by_id(cur->next, id);
     678           0 :             return result;
     679             :     }
     680             : 
     681             :     // Returns the Element whose ID is given by elementId.
     682             :     Reference< XElement > SAL_CALL
     683           0 :     CDocument::getElementById(const OUString& elementId)
     684             :         throw (RuntimeException)
     685             :     {
     686           0 :         ::osl::MutexGuard const g(m_Mutex);
     687             : 
     688             :         // search the tree for an element with the given ID
     689           0 :         OString o1 = OUStringToOString(elementId, RTL_TEXTENCODING_UTF8);
     690           0 :         xmlChar *xId = (xmlChar*)o1.getStr();
     691           0 :         xmlNodePtr const pStart = lcl_getDocumentRootPtr(m_aDocPtr);
     692           0 :         if (!pStart) { return 0; }
     693           0 :         xmlNodePtr const pNode = lcl_search_element_by_id(pStart, xId);
     694             :         Reference< XElement > const xRet(
     695           0 :             static_cast< XNode* >(GetCNode(pNode).get()),
     696           0 :             UNO_QUERY);
     697           0 :         return xRet;
     698             :     }
     699             : 
     700             : 
     701             :     Reference< XNodeList > SAL_CALL
     702           0 :     CDocument::getElementsByTagName(OUString const& rTagname)
     703             :             throw (RuntimeException)
     704             :     {
     705           0 :         ::osl::MutexGuard const g(m_Mutex);
     706             : 
     707             :         Reference< XNodeList > const xRet(
     708           0 :             new CElementList(this->GetDocumentElement(), m_Mutex, rTagname));
     709           0 :         return xRet;
     710             :     }
     711             : 
     712           0 :     Reference< XNodeList > SAL_CALL CDocument::getElementsByTagNameNS(
     713             :             OUString const& rNamespaceURI, OUString const& rLocalName)
     714             :         throw (RuntimeException)
     715             :     {
     716           0 :         ::osl::MutexGuard const g(m_Mutex);
     717             : 
     718             :         Reference< XNodeList > const xRet(
     719             :             new CElementList(this->GetDocumentElement(), m_Mutex,
     720           0 :                 rLocalName, &rNamespaceURI));
     721           0 :         return xRet;
     722             :     }
     723             : 
     724           0 :     Reference< XDOMImplementation > SAL_CALL CDocument::getImplementation()
     725             :         throw (RuntimeException)
     726             :     {
     727             :         // does not need mutex currently
     728           0 :         return Reference< XDOMImplementation >(CDOMImplementation::get());
     729             :     }
     730             : 
     731             :     // helper function to recursively import siblings
     732         310 :     static void lcl_ImportSiblings(
     733             :         Reference< XDocument > const& xTargetDocument,
     734             :         Reference< XNode > const& xTargetParent,
     735             :         Reference< XNode > const& xChild)
     736             :     {
     737         310 :         Reference< XNode > xSibling = xChild;
     738        1134 :         while (xSibling.is())
     739             :         {
     740             :             Reference< XNode > const xTmp(
     741         514 :                     xTargetDocument->importNode(xSibling, sal_True));
     742         514 :             xTargetParent->appendChild(xTmp);
     743         514 :             xSibling = xSibling->getNextSibling();
     744         824 :         }
     745         310 :     }
     746             : 
     747             :     static Reference< XNode >
     748         573 :     lcl_ImportNode( Reference< XDocument > const& xDocument,
     749             :             Reference< XNode > const& xImportedNode, sal_Bool deep)
     750             :     {
     751         573 :         Reference< XNode > xNode;
     752         573 :         NodeType aNodeType = xImportedNode->getNodeType();
     753         573 :         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         359 :                     UNO_QUERY_THROW);
     795         359 :             OUString const aNsUri = xImportedNode->getNamespaceURI();
     796         359 :             OUString const aNsPrefix = xImportedNode->getPrefix();
     797         359 :             OUString aQName = xElement->getTagName();
     798         359 :             Reference< XElement > xNewElement;
     799         359 :             if (!aNsUri.isEmpty())
     800             :             {
     801         359 :                 if (!aNsPrefix.isEmpty()) {
     802         359 :                     aQName = aNsPrefix + ":" + aQName;
     803             :                 }
     804         359 :                 xNewElement = xDocument->createElementNS(aNsUri, aQName);
     805             :             } else {
     806           0 :                 xNewElement = xDocument->createElement(aQName);
     807             :             }
     808             : 
     809             :             // get attributes
     810         359 :             if (xElement->hasAttributes())
     811             :             {
     812         132 :                 Reference< XNamedNodeMap > attribs = xElement->getAttributes();
     813         428 :                 for (sal_Int32 i = 0; i < attribs->getLength(); i++)
     814             :                 {
     815         296 :                     Reference< XAttr > const curAttr(attribs->item(i),
     816         296 :                             UNO_QUERY_THROW);
     817         296 :                     OUString const aAttrUri = curAttr->getNamespaceURI();
     818         296 :                     OUString const aAttrPrefix = curAttr->getPrefix();
     819         296 :                     OUString aAttrName = curAttr->getName();
     820         296 :                     OUString const sValue = curAttr->getValue();
     821         296 :                     if (!aAttrUri.isEmpty())
     822             :                     {
     823         296 :                         if (!aAttrPrefix.isEmpty()) {
     824         296 :                             aAttrName = aAttrPrefix + ":" + aAttrName;
     825             :                         }
     826         296 :                         xNewElement->setAttributeNS(
     827         296 :                                 aAttrUri, aAttrName, sValue);
     828             :                     } else {
     829           0 :                         xNewElement->setAttribute(aAttrName, sValue);
     830             :                     }
     831         428 :                 }
     832             :             }
     833         359 :             xNode.set(xNewElement, UNO_QUERY);
     834         359 :             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         214 :             Reference< XText > const xText(xImportedNode, UNO_QUERY_THROW);
     858             :             Reference< XText > const xNewText(
     859         214 :                 xDocument->createTextNode(xText->getData()));
     860         214 :             xNode.set(xNewText, UNO_QUERY);
     861         214 :             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         573 :         if (deep)
     873             :         {
     874             :             // get children and import them
     875         573 :             Reference< XNode > const xChild = xImportedNode->getFirstChild();
     876         573 :             if (xChild.is())
     877             :             {
     878         310 :                 lcl_ImportSiblings(xDocument, xNode, xChild);
     879         573 :             }
     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         573 :         if (xNode.is())
     894             :         {
     895         573 :             Reference< XDocumentEvent > const xDocevent(xDocument, UNO_QUERY);
     896         573 :             Reference< XMutationEvent > const event(xDocevent->createEvent(
     897         573 :                 "DOMNodeInsertedIntoDocument"), UNO_QUERY_THROW);
     898         573 :             event->initMutationEvent(
     899             :                 "DOMNodeInsertedIntoDocument", sal_True, sal_False, Reference< XNode >(),
     900         573 :                 OUString(), OUString(), OUString(), (AttrChangeType)0 );
     901         573 :             Reference< XEventTarget > const xDocET(xDocument, UNO_QUERY);
     902         573 :             xDocET->dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
     903             :         }
     904             : 
     905         573 :         return xNode;
     906             :     }
     907             : 
     908         573 :     Reference< XNode > SAL_CALL CDocument::importNode(
     909             :             Reference< XNode > const& xImportedNode, sal_Bool deep)
     910             :         throw (RuntimeException, DOMException)
     911             :     {
     912         573 :         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         573 :         Reference< XDocument > const xDocument(this);
     929             :         // already in doc?
     930         573 :         if (xImportedNode->getOwnerDocument() == xDocument) {
     931           0 :             return xImportedNode;
     932             :         }
     933             : 
     934             :         Reference< XNode > const xNode(
     935         573 :             lcl_ImportNode(xDocument, xImportedNode, deep) );
     936         573 :         return xNode;
     937             :     }
     938             : 
     939           0 :     OUString SAL_CALL CDocument::getNodeName()throw (RuntimeException)
     940             :     {
     941             :         // does not need mutex currently
     942           0 :         return OUString("#document");
     943             :     }
     944             : 
     945           0 :     OUString SAL_CALL CDocument::getNodeValue() throw (RuntimeException)
     946             :     {
     947             :         // does not need mutex currently
     948           0 :         return OUString();
     949             :     }
     950             : 
     951           0 :     Reference< XNode > SAL_CALL CDocument::cloneNode(sal_Bool bDeep)
     952             :         throw (RuntimeException)
     953             :     {
     954           0 :         ::osl::MutexGuard const g(m_rMutex);
     955             : 
     956             :         OSL_ASSERT(0 != m_aNodePtr);
     957           0 :         if (0 == m_aNodePtr) {
     958           0 :             return 0;
     959             :         }
     960           0 :         xmlDocPtr const pClone(xmlCopyDoc(m_aDocPtr, (bDeep) ? 1 : 0));
     961           0 :         if (0 == pClone) { return 0; }
     962             :         Reference< XNode > const xRet(
     963           0 :             static_cast<CNode*>(CDocument::CreateCDocument(pClone).get()));
     964           0 :         return xRet;
     965             :     }
     966             : 
     967       17573 :     Reference< XEvent > SAL_CALL CDocument::createEvent(const OUString& aType) throw (RuntimeException)
     968             :     {
     969             :         // does not need mutex currently
     970       17573 :         events::CEvent *pEvent = 0;
     971       26099 :         if ( aType == "DOMSubtreeModified" || aType == "DOMNodeInserted" || aType == "DOMNodeRemoved"
     972        8484 :           || aType == "DOMNodeRemovedFromDocument" || aType == "DOMNodeInsertedIntoDocument" || aType == "DOMAttrModified"
     973          42 :           || aType == "DOMCharacterDataModified")
     974             :         {
     975       17573 :             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       17573 :         return Reference< XEvent >(pEvent);
     990             :     }
     991             : 
     992             :     // ::com::sun::star::xml::sax::XSAXSerializable
     993           4 :     void SAL_CALL CDocument::serialize(
     994             :             const Reference< XDocumentHandler >& i_xHandler,
     995             :             const Sequence< beans::StringPair >& i_rNamespaces)
     996             :         throw (RuntimeException, SAXException)
     997             :     {
     998           4 :         ::osl::MutexGuard const g(m_Mutex);
     999             : 
    1000             :         // add new namespaces to root node
    1001           4 :         xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr);
    1002           4 :         if (0 != pRoot) {
    1003           4 :             const beans::StringPair * pSeq = i_rNamespaces.getConstArray();
    1004          56 :             for (const beans::StringPair *pNsDef = pSeq;
    1005          28 :                  pNsDef < pSeq + i_rNamespaces.getLength(); ++pNsDef) {
    1006             :                 OString prefix = OUStringToOString(pNsDef->First,
    1007          24 :                                     RTL_TEXTENCODING_UTF8);
    1008             :                 OString href   = OUStringToOString(pNsDef->Second,
    1009          24 :                                     RTL_TEXTENCODING_UTF8);
    1010             :                 // this will only add the ns if it does not exist already
    1011          24 :                 xmlNewNs(pRoot, reinterpret_cast<const xmlChar*>(href.getStr()),
    1012          48 :                          reinterpret_cast<const xmlChar*>(prefix.getStr()));
    1013          24 :             }
    1014             :             // eliminate duplicate namespace declarations
    1015           4 :             nscleanup(pRoot->children, pRoot);
    1016             :         }
    1017           4 :         saxify(i_xHandler);
    1018           4 :     }
    1019             : 
    1020             :     // ::com::sun::star::xml::sax::XFastSAXSerializable
    1021           6 :     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           6 :         ::osl::MutexGuard const g(m_Mutex);
    1028             : 
    1029             :         // add new namespaces to root node
    1030           6 :         xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr);
    1031           6 :         if (0 != pRoot) {
    1032           6 :             const beans::StringPair * pSeq = i_rNamespaces.getConstArray();
    1033          12 :             for (const beans::StringPair *pNsDef = pSeq;
    1034           6 :                  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           6 :             nscleanup(pRoot->children, pRoot);
    1045             :         }
    1046             : 
    1047             :         Context aContext(i_xHandler,
    1048           6 :                          i_xTokenHandler);
    1049             : 
    1050             :         // register namespace ids
    1051           6 :         const beans::Pair<OUString,sal_Int32>* pSeq = i_rRegisterNamespaces.getConstArray();
    1052         264 :         for (const beans::Pair<OUString,sal_Int32>* pNs = pSeq;
    1053         132 :              pNs < pSeq + i_rRegisterNamespaces.getLength(); ++pNs)
    1054             :         {
    1055             :             OSL_ENSURE(pNs->Second >= FastToken::NAMESPACE,
    1056             :                        "CDocument::fastSerialize(): invalid NS token id");
    1057         126 :             aContext.maNamespaceMap[ pNs->First ] = pNs->Second;
    1058             :         }
    1059             : 
    1060           6 :         fastSaxify(aContext);
    1061           6 :     }
    1062             : }
    1063             : 
    1064             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10