LCOV - code coverage report
Current view: top level - unoxml/source/dom - element.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 343 372 92.2 %
Date: 2015-06-13 12:38:46 Functions: 25 25 100.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 <element.hxx>
      21             : 
      22             : #include <string.h>
      23             : 
      24             : #include <boost/shared_ptr.hpp>
      25             : 
      26             : #include <osl/diagnose.h>
      27             : #include <rtl/ustrbuf.hxx>
      28             : 
      29             : #include <com/sun/star/xml/sax/FastToken.hpp>
      30             : 
      31             : #include <comphelper/attributelist.hxx>
      32             : 
      33             : #include <node.hxx>
      34             : #include <attr.hxx>
      35             : #include <elementlist.hxx>
      36             : #include <attributesmap.hxx>
      37             : #include <document.hxx>
      38             : 
      39             : #include "../events/mutationevent.hxx"
      40             : 
      41             : using namespace css::uno;
      42             : using namespace css::xml::dom;
      43             : using namespace css::xml::dom::events;
      44             : using namespace css::xml::sax;
      45             : 
      46             : namespace DOM
      47             : {
      48             : 
      49      597947 :     CElement::CElement(CDocument const& rDocument, ::osl::Mutex const& rMutex,
      50             :             xmlNodePtr const pNode)
      51      597947 :         : CElement_Base(rDocument, rMutex, NodeType_ELEMENT_NODE, pNode)
      52             :     {
      53      597947 :     }
      54             : 
      55      107606 :     void CElement::saxify(const Reference< XDocumentHandler >& i_xHandler)
      56             :     {
      57      107606 :         if (!i_xHandler.is()) throw RuntimeException();
      58             :         comphelper::AttributeList *pAttrs =
      59      107606 :             new comphelper::AttributeList();
      60      107606 :         OUString type = "";
      61             :         // add namespace definitions to attributes
      62      113051 :         for (xmlNsPtr pNs = m_aNodePtr->nsDef; pNs != 0; pNs = pNs->next) {
      63        5445 :             const xmlChar *pPrefix = pNs->prefix ? pNs->prefix : reinterpret_cast<const xmlChar*>("");
      64             :             OUString prefix(reinterpret_cast<const sal_Char*>(pPrefix),
      65        5445 :                 strlen(reinterpret_cast<const char*>(pPrefix)),
      66        5445 :                 RTL_TEXTENCODING_UTF8);
      67        5445 :             OUString name = (prefix.isEmpty())
      68       10890 :                 ? OUString( "xmlns" ) : "xmlns:" + prefix;
      69        5445 :             const xmlChar *pHref = pNs->href;
      70             :             OUString val(reinterpret_cast<const sal_Char*>(pHref),
      71        5445 :                 strlen(reinterpret_cast<const char*>(pHref)),
      72       10890 :                 RTL_TEXTENCODING_UTF8);
      73        5445 :             pAttrs->AddAttribute(name, type, val);
      74        5445 :         }
      75             :         // add attributes
      76      252654 :         for (xmlAttrPtr pAttr = m_aNodePtr->properties;
      77             :                         pAttr != 0; pAttr = pAttr->next) {
      78      145048 :             ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
      79      290096 :                     reinterpret_cast<xmlNodePtr>(pAttr));
      80             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
      81      290096 :             OUString prefix = pNode->getPrefix();
      82      145048 :             OUString name = (prefix.isEmpty())
      83      125068 :                 ? pNode->getLocalName()
      84      415164 :                 : prefix + ":" + pNode->getLocalName();
      85      290096 :             OUString val  = pNode->getNodeValue();
      86      145048 :             pAttrs->AddAttribute(name, type, val);
      87      145048 :         }
      88      215212 :         OUString prefix = getPrefix();
      89      107606 :         OUString name = (prefix.isEmpty())
      90         562 :             ? getLocalName()
      91      215774 :             : prefix + ":" + getLocalName();
      92      215212 :         Reference< XAttributeList > xAttrList(pAttrs);
      93      107606 :         i_xHandler->startElement(name, xAttrList);
      94             :         // recurse
      95      216379 :         for (xmlNodePtr pChild = m_aNodePtr->children;
      96             :                         pChild != 0; pChild = pChild->next) {
      97             :             ::rtl::Reference<CNode> const pNode(
      98      108773 :                     GetOwnerDocument().GetCNode(pChild));
      99             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     100      108773 :             pNode->saxify(i_xHandler);
     101      108773 :         }
     102      215212 :         i_xHandler->endElement(name);
     103      107606 :     }
     104             : 
     105      317841 :     void CElement::fastSaxify( Context& i_rContext )
     106             :     {
     107      317841 :         if (!i_rContext.mxDocHandler.is()) throw RuntimeException();
     108      317841 :         pushContext(i_rContext);
     109      317841 :         addNamespaces(i_rContext,m_aNodePtr);
     110             : 
     111             :         // add attributes
     112      317841 :         i_rContext.mxAttribList->clear();
     113      708184 :         for (xmlAttrPtr pAttr = m_aNodePtr->properties;
     114             :                         pAttr != 0; pAttr = pAttr->next) {
     115      390343 :             ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
     116      780686 :                     reinterpret_cast<xmlNodePtr>(pAttr));
     117             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     118             : 
     119      390343 :             const xmlChar* xName = pAttr->name;
     120      390343 :             sal_Int32 nAttributeToken=FastToken::DONTKNOW;
     121             : 
     122      390343 :             if( pAttr->ns && strlen(reinterpret_cast<char const *>(pAttr->ns->prefix)) )
     123             :                 nAttributeToken = getTokenWithPrefix( i_rContext,
     124             :                                                       reinterpret_cast<char const *>(pAttr->ns->prefix),
     125         120 :                                                       reinterpret_cast<char const *>(xName) );
     126             :             else
     127      390223 :                 nAttributeToken = getToken( i_rContext, reinterpret_cast<char const *>(xName) );
     128             : 
     129      390343 :             if( nAttributeToken != FastToken::DONTKNOW )
     130             :                 i_rContext.mxAttribList->add( nAttributeToken,
     131      390244 :                                               OUStringToOString(pNode->getNodeValue(),
     132      390244 :                                                                 RTL_TEXTENCODING_UTF8));
     133      390343 :         }
     134             : 
     135      317841 :         const xmlChar* xPrefix = m_aNodePtr->ns ? m_aNodePtr->ns->prefix : reinterpret_cast<const xmlChar*>("");
     136      317841 :         const xmlChar* xName = m_aNodePtr->name;
     137      317841 :         sal_Int32 nElementToken=FastToken::DONTKNOW;
     138      317841 :         if( strlen(reinterpret_cast<char const *>(xPrefix)) )
     139      317840 :             nElementToken = getTokenWithPrefix( i_rContext, reinterpret_cast<char const *>(xPrefix), reinterpret_cast<char const *>(xName) );
     140             :         else
     141           1 :             nElementToken = getToken( i_rContext, reinterpret_cast<char const *>(xName) );
     142             : 
     143      317841 :         Reference<XFastContextHandler> xParentHandler(i_rContext.mxCurrentHandler);
     144             :         try
     145             :         {
     146      317841 :             Reference< XFastAttributeList > xAttr( i_rContext.mxAttribList.get() );
     147      317841 :             if( nElementToken == FastToken::DONTKNOW )
     148             :             {
     149         139 :                 const OUString aNamespace;
     150             :                 const OUString aElementName( reinterpret_cast<char const *>(xPrefix),
     151         139 :                                              strlen(reinterpret_cast<char const *>(xPrefix)),
     152         278 :                                              RTL_TEXTENCODING_UTF8 );
     153             : 
     154         139 :                 if( xParentHandler.is() )
     155          36 :                     i_rContext.mxCurrentHandler = xParentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
     156             :                 else
     157         103 :                     i_rContext.mxCurrentHandler = i_rContext.mxDocHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
     158             : 
     159         139 :                 if( i_rContext.mxCurrentHandler.is() )
     160         139 :                     i_rContext.mxCurrentHandler->startUnknownElement( aNamespace, aElementName, xAttr );
     161             :             }
     162             :             else
     163             :             {
     164      317702 :                 if( xParentHandler.is() )
     165      306266 :                     i_rContext.mxCurrentHandler = xParentHandler->createFastChildContext( nElementToken, xAttr );
     166             :                 else
     167       11436 :                     i_rContext.mxCurrentHandler = i_rContext.mxDocHandler->createFastChildContext( nElementToken, xAttr );
     168             : 
     169      317702 :                 if( i_rContext.mxCurrentHandler.is() )
     170      162602 :                     i_rContext.mxCurrentHandler->startFastElement( nElementToken, xAttr );
     171      317841 :             }
     172             :         }
     173           0 :         catch( Exception& )
     174             :         {}
     175             : 
     176             :         // recurse
     177      642586 :         for (xmlNodePtr pChild = m_aNodePtr->children;
     178             :                         pChild != 0; pChild = pChild->next) {
     179             :             ::rtl::Reference<CNode> const pNode(
     180      324745 :                     GetOwnerDocument().GetCNode(pChild));
     181             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     182      324745 :             pNode->fastSaxify(i_rContext);
     183      324745 :         }
     184             : 
     185      317841 :         if( i_rContext.mxCurrentHandler.is() ) try
     186             :         {
     187      162602 :             if( nElementToken != FastToken::DONTKNOW )
     188      162602 :                 i_rContext.mxCurrentHandler->endFastElement( nElementToken );
     189             :             else
     190             :             {
     191           0 :                 const OUString aNamespace;
     192             :                 const OUString aElementName( reinterpret_cast<char const *>(xPrefix),
     193           0 :                                              strlen(reinterpret_cast<char const *>(xPrefix)),
     194           0 :                                              RTL_TEXTENCODING_UTF8 );
     195             : 
     196           0 :                 i_rContext.mxCurrentHandler->endUnknownElement( aNamespace, aElementName );
     197             :             }
     198             :         }
     199           0 :         catch( Exception& )
     200             :         {}
     201             : 
     202             :         // restore after children have been processed
     203      317841 :         i_rContext.mxCurrentHandler = xParentHandler;
     204      317841 :         popContext(i_rContext);
     205      317841 :     }
     206             : 
     207       75032 :     bool CElement::IsChildTypeAllowed(NodeType const nodeType)
     208             :     {
     209       75032 :         switch (nodeType) {
     210             :             case NodeType_ELEMENT_NODE:
     211             :             case NodeType_TEXT_NODE:
     212             :             case NodeType_COMMENT_NODE:
     213             :             case NodeType_PROCESSING_INSTRUCTION_NODE:
     214             :             case NodeType_CDATA_SECTION_NODE:
     215             :             case NodeType_ENTITY_REFERENCE_NODE:
     216       75031 :                 return true;
     217             :             case NodeType_ATTRIBUTE_NODE:
     218             :                 /* this is not relly allowed by the DOM spec, but this
     219             :                    implementation has evidently supported it (by special case
     220             :                    handling, so the attribute does not actually become a child)
     221             :                    so allow it for backward compatibility */
     222           1 :                 return true;
     223             :             default:
     224           0 :                 return false;
     225             :         }
     226             :     }
     227             : 
     228             : 
     229             :     /**
     230             :         Retrieves an attribute value by name.
     231             :         return empty string if attribute is not set
     232             :     */
     233           6 :     OUString SAL_CALL CElement::getAttribute(OUString const& name)
     234             :         throw (RuntimeException, std::exception)
     235             :     {
     236           6 :         ::osl::MutexGuard const g(m_rMutex);
     237             : 
     238           6 :         if (0 == m_aNodePtr) {
     239           0 :             return OUString();
     240             :         }
     241             :         // search properties
     242          12 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     243             :         ::boost::shared_ptr<xmlChar const> const pValue(
     244          12 :             xmlGetProp(m_aNodePtr, reinterpret_cast<xmlChar const *>(o1.getStr())), xmlFree);
     245             :         OUString const ret( (pValue)
     246           5 :             ?   OUString(reinterpret_cast<sal_Char const*>(pValue.get()),
     247           5 :                         strlen(reinterpret_cast<char const*>(pValue.get())),
     248             :                         RTL_TEXTENCODING_UTF8)
     249          22 :             :   OUString() );
     250          12 :         return ret;
     251             :     }
     252             : 
     253             :     /**
     254             :     Retrieves an attribute node by name.
     255             :     */
     256          14 :     Reference< XAttr > SAL_CALL CElement::getAttributeNode(OUString const& name)
     257             :         throw (RuntimeException, std::exception)
     258             :     {
     259          14 :         ::osl::MutexGuard const g(m_rMutex);
     260             : 
     261          14 :         if (0 == m_aNodePtr) {
     262           0 :             return 0;
     263             :         }
     264          28 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     265             :         xmlChar const*const pName =
     266          14 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     267          14 :         xmlAttrPtr const pAttr = xmlHasProp(m_aNodePtr, pName);
     268          14 :         if (0 == pAttr) {
     269           2 :             return 0;
     270             :         }
     271             :         Reference< XAttr > const xRet(
     272          12 :             static_cast< XNode* >(GetOwnerDocument().GetCNode(
     273          36 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()),
     274          24 :             UNO_QUERY_THROW);
     275          26 :         return xRet;
     276             :     }
     277             : 
     278             :     /**
     279             :     Retrieves an Attr node by local name and namespace URI.
     280             :     */
     281       50660 :     Reference< XAttr > SAL_CALL CElement::getAttributeNodeNS(
     282             :             const OUString& namespaceURI, const OUString& localName)
     283             :         throw (RuntimeException, std::exception)
     284             :     {
     285       50660 :         ::osl::MutexGuard const g(m_rMutex);
     286             : 
     287       50660 :         if (0 == m_aNodePtr) {
     288           0 :             return 0;
     289             :         }
     290      101320 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     291             :         xmlChar const*const pName =
     292       50660 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     293      101320 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     294             :         xmlChar const*const pNS =
     295       50660 :             reinterpret_cast<xmlChar const*>(o2.getStr());
     296       50660 :         xmlAttrPtr const pAttr = xmlHasNsProp(m_aNodePtr, pName, pNS);
     297       50660 :         if (0 == pAttr) {
     298           2 :             return 0;
     299             :         }
     300             :         Reference< XAttr > const xRet(
     301       50658 :             static_cast< XNode* >(GetOwnerDocument().GetCNode(
     302      151974 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()),
     303      101316 :             UNO_QUERY_THROW);
     304      101318 :         return xRet;
     305             :     }
     306             : 
     307             :     /**
     308             :     Retrieves an attribute value by local name and namespace URI.
     309             :     return empty string if attribute is not set
     310             :     */
     311             :     OUString SAL_CALL
     312      108648 :     CElement::getAttributeNS(
     313             :             OUString const& namespaceURI, OUString const& localName)
     314             :         throw (RuntimeException, std::exception)
     315             :     {
     316      108648 :         ::osl::MutexGuard const g(m_rMutex);
     317             : 
     318      108648 :         if (0 == m_aNodePtr) {
     319           0 :             return OUString();
     320             :         }
     321      217296 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     322             :         xmlChar const*const pName =
     323      108648 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     324      217296 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     325             :         xmlChar const*const pNS =
     326      108648 :             reinterpret_cast<xmlChar const*>(o2.getStr());
     327             :         ::boost::shared_ptr<xmlChar const> const pValue(
     328      217296 :                 xmlGetNsProp(m_aNodePtr, pName, pNS), xmlFree);
     329      108648 :         if (0 == pValue) {
     330       82101 :             return OUString();
     331             :         }
     332       26547 :         OUString const ret(reinterpret_cast<sal_Char const*>(pValue.get()),
     333       26547 :                         strlen(reinterpret_cast<char const*>(pValue.get())),
     334       79641 :                         RTL_TEXTENCODING_UTF8);
     335      135195 :         return ret;
     336             :     }
     337             : 
     338             :     /**
     339             :     Returns a NodeList of all descendant Elements with a given tag name,
     340             :     in the order in which they are
     341             :     encountered in a preorder traversal of this Element tree.
     342             :     */
     343             :     Reference< XNodeList > SAL_CALL
     344           3 :     CElement::getElementsByTagName(OUString const& rLocalName)
     345             :         throw (RuntimeException, std::exception)
     346             :     {
     347           3 :         ::osl::MutexGuard const g(m_rMutex);
     348             : 
     349             :         Reference< XNodeList > const xList(
     350           3 :                 new CElementList(this, m_rMutex, rLocalName));
     351           3 :         return xList;
     352             :     }
     353             : 
     354             :     /**
     355             :     Returns a NodeList of all the descendant Elements with a given local
     356             :     name and namespace URI in the order in which they are encountered in
     357             :     a preorder traversal of this Element tree.
     358             :     */
     359             :     Reference< XNodeList > SAL_CALL
     360           2 :     CElement::getElementsByTagNameNS(
     361             :             OUString const& rNamespaceURI, OUString const& rLocalName)
     362             :         throw (RuntimeException, std::exception)
     363             :     {
     364           2 :         ::osl::MutexGuard const g(m_rMutex);
     365             : 
     366             :         Reference< XNodeList > const xList(
     367           2 :             new CElementList(this, m_rMutex, rLocalName, &rNamespaceURI));
     368           2 :         return xList;
     369             :     }
     370             : 
     371             :     /**
     372             :     The name of the element.
     373             :     */
     374       14760 :     OUString SAL_CALL CElement::getTagName()
     375             :         throw (RuntimeException, std::exception)
     376             :     {
     377       14760 :         ::osl::MutexGuard const g(m_rMutex);
     378             : 
     379       14760 :         if (0 == m_aNodePtr) {
     380           0 :             return OUString();
     381             :         }
     382             :         OUString const ret(reinterpret_cast<char const *>(m_aNodePtr->name),
     383       29520 :                 strlen(reinterpret_cast<char const *>(m_aNodePtr->name)), RTL_TEXTENCODING_UTF8);
     384       29520 :         return ret;
     385             :     }
     386             : 
     387             : 
     388             :     /**
     389             :     Returns true when an attribute with a given name is specified on this
     390             :     element or has a default value, false otherwise.
     391             :     */
     392           2 :     sal_Bool SAL_CALL CElement::hasAttribute(OUString const& name)
     393             :         throw (RuntimeException, std::exception)
     394             :     {
     395           2 :         ::osl::MutexGuard const g(m_rMutex);
     396             : 
     397           4 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     398           2 :         xmlChar const *xName = reinterpret_cast<xmlChar const *>(o1.getStr());
     399           4 :         return (m_aNodePtr != NULL && xmlHasProp(m_aNodePtr, xName) != NULL);
     400             :     }
     401             : 
     402             :     /**
     403             :     Returns true when an attribute with a given local name and namespace
     404             :     URI is specified on this element or has a default value, false otherwise.
     405             :     */
     406           2 :     sal_Bool SAL_CALL CElement::hasAttributeNS(
     407             :             OUString const& namespaceURI, OUString const& localName)
     408             :         throw (RuntimeException, std::exception)
     409             :     {
     410           2 :         ::osl::MutexGuard const g(m_rMutex);
     411             : 
     412           4 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     413           2 :         xmlChar const *xName = reinterpret_cast<xmlChar const *>(o1.getStr());
     414           4 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     415           2 :         xmlChar const *xNs = reinterpret_cast<xmlChar const *>(o2.getStr());
     416           4 :         return (m_aNodePtr != NULL && xmlHasNsProp(m_aNodePtr, xName, xNs) != NULL);
     417             :     }
     418             : 
     419             :     /**
     420             :     Removes an attribute by name.
     421             :     */
     422           2 :     void SAL_CALL CElement::removeAttribute(OUString const& name)
     423             :         throw (RuntimeException, DOMException, std::exception)
     424             :     {
     425           2 :         ::osl::MutexGuard const g(m_rMutex);
     426             : 
     427           2 :         if (0 == m_aNodePtr) {
     428           2 :             return;
     429             :         }
     430           4 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     431             :         xmlChar const*const pName =
     432           2 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     433           2 :         xmlAttrPtr const pAttr = xmlHasProp(m_aNodePtr, pName);
     434           2 :         if (0 == xmlUnsetProp(m_aNodePtr, pName)) {
     435           1 :             ::rtl::Reference<CNode> const pCNode(GetOwnerDocument().GetCNode(
     436           2 :                     reinterpret_cast<xmlNodePtr>(pAttr), false));
     437           1 :             if (pCNode.is()) {
     438           0 :                 pCNode->invalidate(); // freed by xmlUnsetProp
     439           1 :             }
     440           2 :         }
     441             :     }
     442             : 
     443             :     /**
     444             :     Removes an attribute by local name and namespace URI.
     445             :     */
     446           2 :     void SAL_CALL CElement::removeAttributeNS(
     447             :             OUString const& namespaceURI, OUString const& localName)
     448             :         throw (RuntimeException, DOMException, std::exception)
     449             :     {
     450           2 :         ::osl::MutexGuard const g(m_rMutex);
     451             : 
     452           2 :         if (0 == m_aNodePtr) {
     453           2 :             return;
     454             :         }
     455           4 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     456             :         xmlChar const*const pName =
     457           2 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     458           4 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     459             :         xmlChar const*const pURI =
     460           2 :             reinterpret_cast<xmlChar const*>(o2.getStr());
     461             :         xmlNsPtr const pNs =
     462           2 :             xmlSearchNsByHref(m_aNodePtr->doc, m_aNodePtr, pURI);
     463           2 :         xmlAttrPtr const pAttr = xmlHasNsProp(m_aNodePtr, pName, pURI);
     464           2 :         if (0 == xmlUnsetNsProp(m_aNodePtr, pNs, pName)) {
     465           1 :             ::rtl::Reference<CNode> const pCNode(GetOwnerDocument().GetCNode(
     466           2 :                     reinterpret_cast<xmlNodePtr>(pAttr), false));
     467           1 :             if (pCNode.is()) {
     468           0 :                 pCNode->invalidate(); // freed by xmlUnsetNsProp
     469           1 :             }
     470           2 :         }
     471             :     }
     472             : 
     473             :     /**
     474             :     Removes the specified attribute node.
     475             :     */
     476             :     Reference< XAttr > SAL_CALL
     477           6 :     CElement::removeAttributeNode(Reference< XAttr > const& oldAttr)
     478             :         throw (RuntimeException, DOMException, std::exception)
     479             :     {
     480           6 :         ::osl::MutexGuard const g(m_rMutex);
     481             : 
     482           6 :         if (0 == m_aNodePtr) {
     483           0 :             return 0;
     484             :         }
     485             : 
     486             :         ::rtl::Reference<CNode> const pCNode(
     487          12 :             CNode::GetImplementation(Reference<XNode>(oldAttr.get())));
     488           6 :         if (!pCNode.is()) { throw RuntimeException(); }
     489             : 
     490           5 :         xmlNodePtr const pNode = pCNode->GetNodePtr();
     491           5 :         xmlAttrPtr const pAttr = reinterpret_cast<xmlAttrPtr>(pNode);
     492           5 :         if (!pAttr) { throw RuntimeException(); }
     493             : 
     494           5 :         if (pAttr->parent != m_aNodePtr)
     495             :         {
     496           1 :             DOMException e;
     497           1 :             e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
     498           1 :             throw e;
     499             :         }
     500           4 :         if (pAttr->doc != m_aNodePtr->doc)
     501             :         {
     502           0 :             DOMException e;
     503           0 :             e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
     504           0 :             throw e;
     505             :         }
     506             : 
     507           8 :         Reference< XAttr > aAttr;
     508           4 :         if (!oldAttr->getNamespaceURI().isEmpty()) {
     509           2 :             OUStringBuffer qname(oldAttr->getPrefix());
     510           2 :             if (!qname.isEmpty()) {
     511           1 :                 qname.append(':');
     512             :             }
     513           2 :             qname.append(oldAttr->getName());
     514          10 :             aAttr = GetOwnerDocument().createAttributeNS(
     515          10 :                 oldAttr->getNamespaceURI(), qname.makeStringAndClear());
     516             :         } else {
     517           2 :             aAttr = GetOwnerDocument().createAttribute(oldAttr->getName());
     518             :         }
     519           4 :         aAttr->setValue(oldAttr->getValue());
     520           4 :         xmlRemoveProp(pAttr);
     521           4 :         pCNode->invalidate(); // freed by xmlRemoveProp
     522             : 
     523          10 :         return aAttr;
     524             :     }
     525             : 
     526             :     /**
     527             :     Adds a new attribute node.
     528             :     */
     529             :     Reference< XAttr >
     530           6 :     CElement::setAttributeNode_Impl_Lock(
     531             :             Reference< XAttr > const& xNewAttr, bool const bNS)
     532             :     {
     533           6 :         if (xNewAttr->getOwnerDocument() != getOwnerDocument()) {
     534           0 :             DOMException e;
     535           0 :             e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
     536           0 :             throw e;
     537             :         }
     538             : 
     539           6 :         ::osl::ClearableMutexGuard guard(m_rMutex);
     540             : 
     541           6 :         if (0 == m_aNodePtr) {
     542           0 :             throw RuntimeException();
     543             :         }
     544             : 
     545             :         // get the implementation
     546             :         CAttr *const pCAttr = dynamic_cast<CAttr*>(
     547           6 :                 CNode::GetImplementation(xNewAttr));
     548           6 :         if (!pCAttr) { throw RuntimeException(); }
     549             :         xmlAttrPtr const pAttr =
     550           6 :             reinterpret_cast<xmlAttrPtr>(pCAttr->GetNodePtr());
     551           6 :         if (!pAttr) { throw RuntimeException(); }
     552             : 
     553             :         // check whether the attribute is not in use by another element
     554           6 :         if (pAttr->parent) {
     555           2 :             DOMException e;
     556           2 :             e.Code = DOMExceptionType_INUSE_ATTRIBUTE_ERR;
     557           2 :             throw e;
     558             :         }
     559             : 
     560           4 :         xmlAttrPtr res = NULL;
     561             :         xmlChar const*const pContent(
     562           4 :                 (pAttr->children) ? pAttr->children->content : 0);
     563             : 
     564           4 :         if (bNS) {
     565           2 :             xmlNsPtr const pNs( pCAttr->GetNamespace(m_aNodePtr) );
     566           2 :             res = xmlNewNsProp(m_aNodePtr, pNs, pAttr->name, pContent);
     567             :         } else {
     568           2 :             res = xmlNewProp(m_aNodePtr, pAttr->name, pContent);
     569             :         }
     570             : 
     571             :         // get the new attr node
     572             :         Reference< XAttr > const xAttr(
     573           4 :             static_cast< XNode* >(GetOwnerDocument().GetCNode(
     574          12 :                     reinterpret_cast<xmlNodePtr>(res)).get()),
     575           4 :             UNO_QUERY_THROW);
     576             : 
     577             :         // attribute addition event
     578             :         // dispatch DOMAttrModified event
     579           8 :         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
     580           4 :         Reference< XMutationEvent > event(docevent->createEvent(
     581           8 :             "DOMAttrModified"), UNO_QUERY);
     582           4 :         event->initMutationEvent("DOMAttrModified",
     583             :             sal_True, sal_False, xAttr,
     584           8 :             OUString(), xAttr->getValue(), xAttr->getName(),
     585          12 :             AttrChangeType_ADDITION);
     586             : 
     587           4 :         guard.clear(); // release mutex before calling event handlers
     588             : 
     589           4 :         dispatchEvent(event);
     590           4 :         dispatchSubtreeModified();
     591             : 
     592          10 :         return xAttr;
     593             :     }
     594             : 
     595             :     Reference< XAttr >
     596           3 :     CElement::setAttributeNode(const Reference< XAttr >& newAttr)
     597             :         throw (RuntimeException, DOMException, std::exception)
     598             :     {
     599           3 :         return setAttributeNode_Impl_Lock(newAttr, false);
     600             :     }
     601             : 
     602             :     /**
     603             :     Adds a new attribute.
     604             :     */
     605             :     Reference< XAttr >
     606           3 :     CElement::setAttributeNodeNS(const Reference< XAttr >& newAttr)
     607             :         throw (RuntimeException, DOMException, std::exception)
     608             :     {
     609           3 :         return setAttributeNode_Impl_Lock(newAttr, true);
     610             :     }
     611             : 
     612             :     /**
     613             :     Adds a new attribute.
     614             :     */
     615             :     void SAL_CALL
     616           9 :     CElement::setAttribute(OUString const& name, OUString const& value)
     617             :         throw (RuntimeException, DOMException, std::exception)
     618             :     {
     619           9 :         ::osl::ClearableMutexGuard guard(m_rMutex);
     620             : 
     621          18 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     622           9 :         xmlChar const *xName = reinterpret_cast<xmlChar const *>(o1.getStr());
     623          18 :         OString o2 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
     624           9 :         xmlChar const *xValue = reinterpret_cast<xmlChar const *>(o2.getStr());
     625             : 
     626           9 :         if (0 == m_aNodePtr) {
     627           0 :             throw RuntimeException();
     628             :         }
     629          18 :         OUString oldValue;
     630           9 :         AttrChangeType aChangeType = AttrChangeType_MODIFICATION;
     631             :         ::boost::shared_ptr<xmlChar const> const pOld(
     632          18 :             xmlGetProp(m_aNodePtr, xName), xmlFree);
     633           9 :         if (pOld == 0) {
     634           9 :             aChangeType = AttrChangeType_ADDITION;
     635           9 :             xmlNewProp(m_aNodePtr, xName, xValue);
     636             :         } else {
     637           0 :             oldValue = OUString(reinterpret_cast<sal_Char const*>(pOld.get()),
     638           0 :                         strlen(reinterpret_cast<char const*>(pOld.get())),
     639           0 :                         RTL_TEXTENCODING_UTF8);
     640           0 :             xmlSetProp(m_aNodePtr, xName, xValue);
     641             :         }
     642             : 
     643             :         // dispatch DOMAttrModified event
     644          18 :         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
     645           9 :         Reference< XMutationEvent > event(docevent->createEvent(
     646          18 :             "DOMAttrModified"), UNO_QUERY);
     647           9 :         event->initMutationEvent("DOMAttrModified",
     648             :             sal_True, sal_False,
     649           9 :             Reference< XNode >(getAttributeNode(name), UNO_QUERY),
     650          18 :             oldValue, value, name, aChangeType);
     651             : 
     652           9 :         guard.clear(); // release mutex before calling event handlers
     653           9 :         dispatchEvent(event);
     654          18 :         dispatchSubtreeModified();
     655           9 :     }
     656             : 
     657             :     /**
     658             :     Adds a new attribute.
     659             :     */
     660             :     void SAL_CALL
     661       50655 :     CElement::setAttributeNS(OUString const& namespaceURI,
     662             :             OUString const& qualifiedName, OUString const& value)
     663             :         throw (RuntimeException, DOMException, std::exception)
     664             :     {
     665       50655 :         if (namespaceURI.isEmpty()) throw RuntimeException();
     666             : 
     667       50655 :         ::osl::ClearableMutexGuard guard(m_rMutex);
     668             : 
     669      101310 :         OString o1, o2, o3, o4, o5;
     670       50655 :         xmlChar const *xPrefix = NULL;
     671       50655 :         xmlChar const *xLName = NULL;
     672       50655 :         o1 = OUStringToOString(qualifiedName, RTL_TEXTENCODING_UTF8);
     673       50655 :         xmlChar const *xQName = reinterpret_cast<xmlChar const *>(o1.getStr());
     674       50655 :         sal_Int32 idx = qualifiedName.indexOf(':');
     675       50655 :         if (idx != -1)
     676             :         {
     677      101306 :             o2 = OUStringToOString(
     678             :                 qualifiedName.copy(0,idx),
     679       50653 :                 RTL_TEXTENCODING_UTF8);
     680       50653 :             xPrefix = reinterpret_cast<xmlChar const *>(o2.getStr());
     681      101306 :             o3 = OUStringToOString(
     682             :                 qualifiedName.copy(idx+1),
     683       50653 :                 RTL_TEXTENCODING_UTF8);
     684       50653 :             xLName = reinterpret_cast<xmlChar const *>(o3.getStr());
     685             :         }  else {
     686           2 :             xPrefix = reinterpret_cast<xmlChar const *>("");
     687           2 :             xLName = xQName;
     688             :         }
     689       50655 :         o4 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     690       50655 :         o5 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
     691       50655 :         xmlChar const *xURI= reinterpret_cast<xmlChar const *>(o4.getStr());
     692       50655 :         xmlChar const *xValue = reinterpret_cast<xmlChar const *>(o5.getStr());
     693             : 
     694       50655 :         if (0 == m_aNodePtr) {
     695           0 :             throw RuntimeException();
     696             :         }
     697             : 
     698             :         //find the right namespace
     699       50655 :         xmlNsPtr pNs = xmlSearchNs(m_aNodePtr->doc, m_aNodePtr, xPrefix);
     700             :         // if no namespace found, create a new one
     701       50655 :         if (pNs == NULL) {
     702         990 :             pNs = xmlNewNs(m_aNodePtr, xURI, xPrefix);
     703             :         }
     704             : 
     705       50655 :         if (strcmp(reinterpret_cast<char const *>(pNs->href), reinterpret_cast<char const *>(xURI)) != 0) {
     706             :             // ambiguous ns prefix
     707           0 :             throw RuntimeException();
     708             :         }
     709             : 
     710             :         // found namespace matches
     711             : 
     712      101310 :         OUString oldValue;
     713       50655 :         AttrChangeType aChangeType = AttrChangeType_MODIFICATION;
     714             :         ::boost::shared_ptr<xmlChar const> const pOld(
     715      101310 :                 xmlGetNsProp(m_aNodePtr, xLName, pNs->href), xmlFree);
     716       50655 :         if (pOld == 0) {
     717       50639 :             aChangeType = AttrChangeType_ADDITION;
     718       50639 :             xmlNewNsProp(m_aNodePtr, pNs, xLName, xValue);
     719             :         } else {
     720          32 :             oldValue = OUString(reinterpret_cast<sal_Char const*>(pOld.get()),
     721          16 :                         strlen(reinterpret_cast<char const*>(pOld.get())),
     722          16 :                         RTL_TEXTENCODING_UTF8);
     723          16 :             xmlSetNsProp(m_aNodePtr, pNs, xLName, xValue);
     724             :         }
     725             :         // dispatch DOMAttrModified event
     726      101310 :         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
     727       50655 :         Reference< XMutationEvent > event(docevent->createEvent(
     728      101310 :             "DOMAttrModified"), UNO_QUERY);
     729       50655 :         event->initMutationEvent(
     730             :             "DOMAttrModified", sal_True, sal_False,
     731       50655 :             Reference< XNode >(getAttributeNodeNS(namespaceURI, OUString(reinterpret_cast<char const *>(xLName), strlen(reinterpret_cast<char const *>(xLName)), RTL_TEXTENCODING_UTF8)), UNO_QUERY),
     732      101310 :             oldValue, value, qualifiedName, aChangeType);
     733             : 
     734       50655 :         guard.clear(); // release mutex before calling event handlers
     735       50655 :         dispatchEvent(event);
     736      101310 :         dispatchSubtreeModified();
     737       50655 :     }
     738             : 
     739             :     Reference< XNamedNodeMap > SAL_CALL
     740       41891 :     CElement::getAttributes() throw (RuntimeException, std::exception)
     741             :     {
     742       41891 :         ::osl::MutexGuard const g(m_rMutex);
     743             : 
     744             :         Reference< XNamedNodeMap > const xMap(
     745       41891 :                 new CAttributesMap(this, m_rMutex));
     746       41891 :         return xMap;
     747             :     }
     748             : 
     749        7201 :     OUString SAL_CALL CElement::getNodeName()throw (RuntimeException, std::exception)
     750             :     {
     751        7201 :         return getLocalName();
     752             :     }
     753             : 
     754      114830 :     OUString SAL_CALL CElement::getLocalName()throw (RuntimeException, std::exception)
     755             :     {
     756      114830 :         ::osl::MutexGuard const g(m_rMutex);
     757             : 
     758      114830 :         OUString aName;
     759      114830 :         if (m_aNodePtr != NULL)
     760             :         {
     761      114830 :             const xmlChar* xName = m_aNodePtr->name;
     762      114830 :             aName = OUString(reinterpret_cast<const char*>(xName), strlen(reinterpret_cast<const char*>(xName)), RTL_TEXTENCODING_UTF8);
     763             :         }
     764      114830 :         return aName;
     765             :     }
     766             : 
     767           1 :     OUString SAL_CALL CElement::getNodeValue() throw (RuntimeException, std::exception)
     768             :     {
     769           1 :         return OUString();
     770             :     }
     771             : }
     772             : 
     773             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11