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

Generated by: LCOV version 1.11