/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * Version: MPL 1.1 / GPLv3+ / LGPLv3+ * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Initial Developer of the Original Code is * [ Peter Jentsch ] * Portions created by the Initial Developer are Copyright (C) 2011 the * Initial Developer. All Rights Reserved. * * Contributor(s): Peter Jentsch * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 3 or later (the "GPLv3+"), or * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable * instead of those above. */ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_filter.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::io; using namespace ::com::sun::star::embed; using namespace ::rtl; namespace XSLT { Reference SAL_CALL OleHandler::createTempFile() { Reference tempFile( m_msf->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ))), UNO_QUERY); OSL_ASSERT(tempFile.is()); return tempFile; } void SAL_CALL OleHandler::ensureCreateRootStorage() { if (m_storage == NULL || m_rootStream == NULL) { m_rootStream = createTempFile(); Sequence args(1); args[0] <<= m_rootStream->getInputStream(); OUString serviceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.OLESimpleStorage")); Reference cont(m_msf->createInstanceWithArguments(serviceName, args), UNO_QUERY); m_storage = cont; } } void SAL_CALL OleHandler::initRootStorageFromBase64(const OString& content) { Sequence oleData; SvXMLUnitConverter::decodeBase64(oleData, ::rtl::OStringToOUString(content, RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS)); m_rootStream = createTempFile(); Reference xOutput = m_rootStream->getOutputStream(); xOutput->writeBytes(oleData); xOutput->flush(); //Get the input stream and seek to begin Reference xSeek(m_rootStream->getInputStream(), UNO_QUERY); xSeek->seek(0); //create an com.sun.star.embed.OLESimpleStorage from the temp stream Sequence args(1); args[0] <<= xSeek; Reference cont(m_msf->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLESimpleStorage" )), args), UNO_QUERY); m_storage = cont; } OString SAL_CALL OleHandler::encodeSubStorage(const OUString& streamName) { if (!m_storage->hasByName(streamName)) { return "Not Found:";// + streamName; } ; Reference subStream((*(Reference< XInterface > *) m_storage->getByName(streamName).getValue()), UNO_QUERY); if (!subStream.is()) { return "Not Found:";// + streamName; } //The first four byte are the length of the uncompressed data Sequence pLength(4); Reference xSeek(subStream, UNO_QUERY); xSeek->seek(0); //Get the uncompressed length int readbytes = subStream->readBytes(pLength, 4); if (4 != readbytes) { return "Can not read the length."; } int oleLength = (pLength[0] << 0) + (pLength[1] << 8) + (pLength[2] << 16) + (pLength[3] << 24); Sequence content(oleLength); //Read all bytes. The compressed length should less then the uncompressed length readbytes = subStream->readBytes(content, oleLength); if (oleLength < readbytes) { return "oleLength";// +oleLength + readBytes; } // Decompress the bytes ::ZipUtils::Inflater* decompresser = new ::ZipUtils::Inflater(sal_False); decompresser->setInput(content); Sequence result(oleLength); decompresser->doInflateSegment(result, 0, oleLength); decompresser->end(); delete decompresser; //return the base64 string of the uncompressed data OUStringBuffer buf(oleLength); SvXMLUnitConverter::encodeBase64(buf, result); return ::rtl::OUStringToOString(buf.toString(), RTL_TEXTENCODING_UTF8); } void SAL_CALL OleHandler::insertByName(const OUString& streamName, const OString& content) { if (streamName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("oledata.mso"))) { initRootStorageFromBase64(content); } else { ensureCreateRootStorage(); insertSubStorage(streamName, content); } } const OString SAL_CALL OleHandler::getByName(const OUString& streamName) { if (streamName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("oledata.mso"))) { //get the length and seek to 0 Reference xSeek (m_rootStream, UNO_QUERY); int oleLength = (int) xSeek->getLength(); xSeek->seek(0); //read all bytes Reference xInput = m_rootStream->getInputStream(); Sequence oledata(oleLength); xInput->readBytes(oledata, oleLength); //return the base64 encoded string OUStringBuffer buf(oleLength); SvXMLUnitConverter::encodeBase64(buf, oledata); return ::rtl::OUStringToOString(buf.toString(), RTL_TEXTENCODING_UTF8); } return encodeSubStorage(streamName); } void SAL_CALL OleHandler::insertSubStorage(const OUString& streamName, const OString& content) { //decode the base64 string Sequence oledata; SvXMLUnitConverter::decodeBase64(oledata, rtl::OStringToOUString(content, RTL_TEXTENCODING_ASCII_US)); //create a temp stream to write data to Reference subStream = createTempFile(); Reference xInput = subStream->getInputStream(); Reference xOutput = subStream->getOutputStream(); //write the length to the temp stream Sequence header(4); header[0] = (sal_Int8) (oledata.getLength() >> 0) & 0xFF; header[1] = (sal_Int8) (oledata.getLength() >> 8) & 0xFF; header[2] = (sal_Int8) (oledata.getLength() >> 16) & 0xFF; header[3] = (sal_Int8) (oledata.getLength() >> 24) & 0xFF; xOutput->writeBytes(header); // Compress the bytes Sequence output(oledata.getLength()); ::ZipUtils::Deflater* compresser = new ::ZipUtils::Deflater((sal_Int32) 3, sal_False); compresser->setInputSegment(oledata, 0, oledata.getLength()); compresser->finish(); int compressedDataLength = compresser->doDeflateSegment(output, 0, oledata.getLength()); delete(compresser); //realloc the data length Sequence compressed(compressedDataLength); for (int i = 0; i < compressedDataLength; i++) { compressed[i] = output[i]; } //write the compressed data to the temp stream xOutput->writeBytes(compressed); //seek to 0 Reference xSeek(xInput, UNO_QUERY); xSeek->seek(0); //insert the temp stream as a sub stream and use an XTransactedObject to commit it immediately Reference xTransact(m_storage, UNO_QUERY); Any entry; entry <<= xInput; m_storage->insertByName(streamName, entry); xTransact->commit(); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */