1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sdext.hxx" 26 27 #include "odfemitter.hxx" 28 29 #include <rtl/ustrbuf.hxx> 30 #include <cppuhelper/exc_hlp.hxx> 31 #include <com/sun/star/io/XInputStream.hpp> 32 #include <com/sun/star/io/XOutputStream.hpp> 33 #include <boost/bind.hpp> 34 35 using namespace com::sun::star; 36 37 namespace pdfi 38 { 39 40 class OdfEmitter : public XmlEmitter 41 { 42 private: 43 uno::Reference<io::XOutputStream> m_xOutput; 44 uno::Sequence<sal_Int8> m_aLineFeed; 45 uno::Sequence<sal_Int8> m_aBuf; 46 47 public: 48 explicit OdfEmitter( const uno::Reference<io::XOutputStream>& xOutput ); 49 50 virtual void beginTag( const char* pTag, const PropertyMap& rProperties ); 51 virtual void write( const rtl::OUString& rString ); 52 virtual void endTag( const char* pTag ); 53 }; 54 55 OdfEmitter::OdfEmitter( const uno::Reference<io::XOutputStream>& xOutput ) : 56 m_xOutput( xOutput ), 57 m_aLineFeed(1), 58 m_aBuf() 59 { 60 OSL_PRECOND(m_xOutput.is(), "OdfEmitter(): invalid output stream"); 61 m_aLineFeed[0] = '\n'; 62 63 rtl::OUStringBuffer aElement; 64 aElement.appendAscii("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 65 write(aElement.makeStringAndClear()); 66 } 67 68 void OdfEmitter::beginTag( const char* pTag, const PropertyMap& rProperties ) 69 { 70 OSL_PRECOND(pTag,"Invalid tag string"); 71 72 rtl::OUStringBuffer aElement; 73 aElement.appendAscii("<"); 74 aElement.appendAscii(pTag); 75 aElement.appendAscii(" "); 76 77 std::vector<rtl::OUString> aAttributes; 78 PropertyMap::const_iterator aCurr(rProperties.begin()); 79 const PropertyMap::const_iterator aEnd(rProperties.end()); 80 while( aCurr != aEnd ) 81 { 82 rtl::OUStringBuffer aAttribute; 83 aAttribute.append(aCurr->first); 84 aAttribute.appendAscii("=\""); 85 aAttribute.append(aCurr->second); 86 aAttribute.appendAscii("\" "); 87 aAttributes.push_back(aAttribute.makeStringAndClear()); 88 ++aCurr; 89 } 90 91 // since the hash map's sorting is undefined (and varies across 92 // platforms, and even between different compile-time settings), 93 // sort the attributes. 94 std::sort(aAttributes.begin(), aAttributes.end()); 95 std::for_each(aAttributes.begin(), 96 aAttributes.end(), 97 boost::bind( (rtl::OUStringBuffer& (rtl::OUStringBuffer::*)(const rtl::OUString&)) 98 (&rtl::OUStringBuffer::append), 99 boost::ref(aElement), 100 _1 )); 101 aElement.appendAscii(">"); 102 103 write(aElement.makeStringAndClear()); 104 } 105 106 void OdfEmitter::write( const rtl::OUString& rText ) 107 { 108 const rtl::OString aStr = rtl::OUStringToOString(rText,RTL_TEXTENCODING_UTF8); 109 const sal_Int32 nLen( aStr.getLength() ); 110 m_aBuf.realloc( nLen ); 111 const sal_Char* pStr = aStr.getStr(); 112 std::copy(pStr,pStr+nLen,m_aBuf.getArray()); 113 114 m_xOutput->writeBytes(m_aBuf); 115 m_xOutput->writeBytes(m_aLineFeed); 116 } 117 118 void OdfEmitter::endTag( const char* pTag ) 119 { 120 rtl::OUStringBuffer aElement; 121 aElement.appendAscii("</"); 122 aElement.appendAscii(pTag); 123 aElement.appendAscii(">"); 124 write(aElement.makeStringAndClear()); 125 } 126 127 XmlEmitterSharedPtr createOdfEmitter( const uno::Reference<io::XOutputStream>& xOut ) 128 { 129 return XmlEmitterSharedPtr(new OdfEmitter(xOut)); 130 } 131 132 } 133