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

Generated by: LCOV version 1.10