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