1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 #ifndef INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX 20 #define INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX 21 22 #include <com/sun/star/io/XOutputStream.hpp> 23 #include <com/sun/star/io/XTempFile.hpp> 24 #include <com/sun/star/uno/Reference.hxx> 25 #include <com/sun/star/uno/XComponentContext.hpp> 26 #include <com/sun/star/xml/crypto/XCipherContext.hpp> 27 #include <com/sun/star/xml/crypto/XDigestContext.hpp> 28 29 #include <package/Deflater.hxx> 30 #include <comphelper/threadpool.hxx> 31 #include "CRC32.hxx" 32 #include <atomic> 33 34 struct ZipEntry; 35 class ZipPackageBuffer; 36 class ZipPackageStream; 37 38 class ZipOutputEntryBase 39 { 40 protected: 41 css::uno::Reference< css::uno::XComponentContext > m_xContext; 42 css::uno::Reference< css::io::XOutputStream > m_xOutStream; 43 44 css::uno::Reference< css::xml::crypto::XCipherContext > m_xCipherContext; 45 css::uno::Reference< css::xml::crypto::XDigestContext > m_xDigestContext; 46 47 CRC32 m_aCRC; 48 ZipEntry *m_pCurrentEntry; 49 sal_Int16 m_nDigested; 50 ZipPackageStream* m_pCurrentStream; 51 bool m_bEncryptCurrentEntry; 52 53 public: 54 virtual ~ZipOutputEntryBase() = default; 55 56 virtual void writeStream(const css::uno::Reference< css::io::XInputStream >& xInStream) = 0; 57 getZipEntry()58 ZipEntry* getZipEntry() { return m_pCurrentEntry; } getZipPackageStream()59 ZipPackageStream* getZipPackageStream() { return m_pCurrentStream; } isEncrypt() const60 bool isEncrypt() const { return m_bEncryptCurrentEntry; } 61 62 void closeEntry(); 63 64 protected: 65 ZipOutputEntryBase( 66 const css::uno::Reference< css::io::XOutputStream >& rxOutStream, 67 const css::uno::Reference< css::uno::XComponentContext >& rxContext, 68 ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt, bool checkStream); 69 70 // Inherited classes call this with deflated data buffer. 71 void processDeflated( const css::uno::Sequence< sal_Int8 >& deflateBuffer, sal_Int32 nLength ); 72 // Inherited classes call this with the input buffer. 73 void processInput( const css::uno::Sequence< sal_Int8 >& rBuffer ); 74 75 virtual void finishDeflater() = 0; 76 virtual sal_Int64 getDeflaterTotalIn() const = 0; 77 virtual sal_Int64 getDeflaterTotalOut() const = 0; 78 virtual void deflaterReset() = 0; 79 virtual bool isDeflaterFinished() const = 0; 80 }; 81 82 // Normal non-threaded case. 83 class ZipOutputEntry : public ZipOutputEntryBase 84 { 85 css::uno::Sequence< sal_Int8 > m_aDeflateBuffer; 86 ZipUtils::Deflater m_aDeflater; 87 88 public: 89 ZipOutputEntry( 90 const css::uno::Reference< css::io::XOutputStream >& rxOutStream, 91 const css::uno::Reference< css::uno::XComponentContext >& rxContext, 92 ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt); 93 void writeStream(const css::uno::Reference< css::io::XInputStream >& xInStream) override; 94 void write(const css::uno::Sequence< sal_Int8 >& rBuffer); 95 96 protected: 97 ZipOutputEntry( 98 const css::uno::Reference< css::io::XOutputStream >& rxOutStream, 99 const css::uno::Reference< css::uno::XComponentContext >& rxContext, 100 ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt, bool checkStream); 101 virtual void finishDeflater() override; 102 virtual sal_Int64 getDeflaterTotalIn() const override; 103 virtual sal_Int64 getDeflaterTotalOut() const override; 104 virtual void deflaterReset() override; 105 virtual bool isDeflaterFinished() const override; 106 void doDeflate(); 107 }; 108 109 // Class that runs the compression in a background thread. 110 class ZipOutputEntryInThread final : public ZipOutputEntry 111 { 112 class Task; 113 OUString m_aTempURL; 114 std::exception_ptr m_aParallelDeflateException; 115 std::atomic<bool> m_bFinished; 116 117 public: 118 ZipOutputEntryInThread( 119 const css::uno::Reference< css::uno::XComponentContext >& rxContext, 120 ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt); 121 std::unique_ptr<comphelper::ThreadTask> createTask( 122 const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, 123 const css::uno::Reference< css::io::XInputStream >& xInStream ); 124 /* This block of methods is for threaded zipping, where we compress to a temp stream, whose 125 data is retrieved via getData */ 126 void createBufferFile(); setParallelDeflateException(const std::exception_ptr & exception)127 void setParallelDeflateException(const std::exception_ptr& exception) { m_aParallelDeflateException = exception; } 128 css::uno::Reference< css::io::XInputStream > getData() const; getParallelDeflateException() const129 const std::exception_ptr& getParallelDeflateException() const { return m_aParallelDeflateException; } 130 void closeBufferFile(); 131 void deleteBufferFile(); isFinished() const132 bool isFinished() const { return m_bFinished; } 133 private: setFinished()134 void setFinished() { m_bFinished = true; } 135 }; 136 137 // Class that synchronously runs the compression in multiple threads (using ThreadDeflater). 138 class ZipOutputEntryParallel final : public ZipOutputEntryBase 139 { 140 sal_Int64 totalIn; 141 sal_Int64 totalOut; 142 bool finished; 143 public: 144 ZipOutputEntryParallel( 145 const css::uno::Reference< css::io::XOutputStream >& rxOutStream, 146 const css::uno::Reference< css::uno::XComponentContext >& rxContext, 147 ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt); 148 void writeStream(const css::uno::Reference< css::io::XInputStream >& xInStream) override; 149 private: 150 virtual void finishDeflater() override; 151 virtual sal_Int64 getDeflaterTotalIn() const override; 152 virtual sal_Int64 getDeflaterTotalOut() const override; 153 virtual void deflaterReset() override; 154 virtual bool isDeflaterFinished() const override; 155 }; 156 157 #endif 158 159 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 160