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