1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sdext.hxx" 30 31 #include "odfemitter.hxx" 32 33 #include <rtl/ustrbuf.hxx> 34 #include <cppuhelper/exc_hlp.hxx> 35 #include <com/sun/star/io/XInputStream.hpp> 36 #include <com/sun/star/io/XOutputStream.hpp> 37 #include <boost/bind.hpp> 38 39 using namespace com::sun::star; 40 41 namespace pdfi 42 { 43 44 class OdfEmitter : public XmlEmitter 45 { 46 private: 47 uno::Reference<io::XOutputStream> m_xOutput; 48 uno::Sequence<sal_Int8> m_aLineFeed; 49 uno::Sequence<sal_Int8> m_aBuf; 50 51 public: 52 explicit OdfEmitter( const uno::Reference<io::XOutputStream>& xOutput ); 53 54 virtual void beginTag( const char* pTag, const PropertyMap& rProperties ); 55 virtual void write( const rtl::OUString& rString ); 56 virtual void endTag( const char* pTag ); 57 }; 58 59 OdfEmitter::OdfEmitter( const uno::Reference<io::XOutputStream>& xOutput ) : 60 m_xOutput( xOutput ), 61 m_aLineFeed(1), 62 m_aBuf() 63 { 64 OSL_PRECOND(m_xOutput.is(), "OdfEmitter(): invalid output stream"); 65 m_aLineFeed[0] = '\n'; 66 67 rtl::OUStringBuffer aElement; 68 aElement.appendAscii("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 69 write(aElement.makeStringAndClear()); 70 } 71 72 void OdfEmitter::beginTag( const char* pTag, const PropertyMap& rProperties ) 73 { 74 OSL_PRECOND(pTag,"Invalid tag string"); 75 76 rtl::OUStringBuffer aElement; 77 aElement.appendAscii("<"); 78 aElement.appendAscii(pTag); 79 aElement.appendAscii(" "); 80 81 std::vector<rtl::OUString> aAttributes; 82 PropertyMap::const_iterator aCurr(rProperties.begin()); 83 const PropertyMap::const_iterator aEnd(rProperties.end()); 84 while( aCurr != aEnd ) 85 { 86 rtl::OUStringBuffer aAttribute; 87 aAttribute.append(aCurr->first); 88 aAttribute.appendAscii("=\""); 89 aAttribute.append(aCurr->second); 90 aAttribute.appendAscii("\" "); 91 aAttributes.push_back(aAttribute.makeStringAndClear()); 92 ++aCurr; 93 } 94 95 // since the hash map's sorting is undefined (and varies across 96 // platforms, and even between different compile-time settings), 97 // sort the attributes. 98 std::sort(aAttributes.begin(), aAttributes.end()); 99 std::for_each(aAttributes.begin(), 100 aAttributes.end(), 101 boost::bind( (rtl::OUStringBuffer& (rtl::OUStringBuffer::*)(const rtl::OUString&)) 102 (&rtl::OUStringBuffer::append), 103 boost::ref(aElement), 104 _1 )); 105 aElement.appendAscii(">"); 106 107 write(aElement.makeStringAndClear()); 108 } 109 110 void OdfEmitter::write( const rtl::OUString& rText ) 111 { 112 const rtl::OString aStr = rtl::OUStringToOString(rText,RTL_TEXTENCODING_UTF8); 113 const sal_Int32 nLen( aStr.getLength() ); 114 m_aBuf.realloc( nLen ); 115 const sal_Char* pStr = aStr.getStr(); 116 std::copy(pStr,pStr+nLen,m_aBuf.getArray()); 117 118 m_xOutput->writeBytes(m_aBuf); 119 m_xOutput->writeBytes(m_aLineFeed); 120 } 121 122 void OdfEmitter::endTag( const char* pTag ) 123 { 124 rtl::OUStringBuffer aElement; 125 aElement.appendAscii("</"); 126 aElement.appendAscii(pTag); 127 aElement.appendAscii(">"); 128 write(aElement.makeStringAndClear()); 129 } 130 131 XmlEmitterSharedPtr createOdfEmitter( const uno::Reference<io::XOutputStream>& xOut ) 132 { 133 return XmlEmitterSharedPtr(new OdfEmitter(xOut)); 134 } 135 136 } 137