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

Generated by: LCOV version 1.10