diff options
Diffstat (limited to 'package/source/zipapi/ZipOutputEntry.cxx')
-rw-r--r-- | package/source/zipapi/ZipOutputEntry.cxx | 172 |
1 files changed, 116 insertions, 56 deletions
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx index 2b1447bd3246..74281fd063dd 100644 --- a/package/source/zipapi/ZipOutputEntry.cxx +++ b/package/source/zipapi/ZipOutputEntry.cxx @@ -46,7 +46,8 @@ ZipOutputEntry::ZipOutputEntry( const uno::Reference< uno::XComponentContext >& rxContext, ZipEntry& rEntry, ZipPackageStream* pStream, - bool bEncrypt) + bool bEncrypt, + bool checkStream) : m_aDeflateBuffer(n_ConstBufferSize) , m_aDeflater(DEFAULT_COMPRESSION, true) , m_xContext(rxContext) @@ -55,10 +56,10 @@ ZipOutputEntry::ZipOutputEntry( , m_nDigested(0) , m_pCurrentStream(pStream) , m_bEncryptCurrentEntry(bEncrypt) -, m_bFinished(false) { assert(m_pCurrentEntry->nMethod == DEFLATED && "Use ZipPackageStream::rawWrite() for STORED entries"); - assert(m_xOutStream.is()); + (void)checkStream; + assert(!checkStream || m_xOutStream.is()); if (m_bEncryptCurrentEntry) { m_xCipherContext = ZipFile::StaticGetCipher( m_xContext, pStream->GetEncryptionData(), true ); @@ -67,64 +68,13 @@ ZipOutputEntry::ZipOutputEntry( } ZipOutputEntry::ZipOutputEntry( + const css::uno::Reference< css::io::XOutputStream >& rxOutput, const uno::Reference< uno::XComponentContext >& rxContext, ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt) -: m_aDeflateBuffer(n_ConstBufferSize) -, m_aDeflater(DEFAULT_COMPRESSION, true) -, m_xContext(rxContext) -, m_pCurrentEntry(&rEntry) -, m_nDigested(0) -, m_pCurrentStream(pStream) -, m_bEncryptCurrentEntry(bEncrypt) -, m_bFinished(false) +: ZipOutputEntry( rxOutput, rxContext, rEntry, pStream, bEncrypt, true) { - assert(m_pCurrentEntry->nMethod == DEFLATED && "Use ZipPackageStream::rawWrite() for STORED entries"); - if (m_bEncryptCurrentEntry) - { - m_xCipherContext = ZipFile::StaticGetCipher( m_xContext, pStream->GetEncryptionData(), true ); - m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( m_xContext, pStream->GetEncryptionData() ); - } -} - -ZipOutputEntry::~ZipOutputEntry() -{ -} - -void ZipOutputEntry::createBufferFile() -{ - assert(!m_xOutStream.is() && m_aTempURL.isEmpty() && - "should only be called in the threaded mode where there is no existing stream yet"); - uno::Reference < beans::XPropertySet > xTempFileProps( - io::TempFile::create(m_xContext), - uno::UNO_QUERY_THROW ); - xTempFileProps->setPropertyValue("RemoveFile", uno::makeAny(false)); - uno::Any aUrl = xTempFileProps->getPropertyValue( "Uri" ); - aUrl >>= m_aTempURL; - assert(!m_aTempURL.isEmpty()); - - uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(ucb::SimpleFileAccess::create(m_xContext)); - m_xOutStream = xTempAccess->openFileWrite(m_aTempURL); -} - -void ZipOutputEntry::closeBufferFile() -{ - m_xOutStream->closeOutput(); - m_xOutStream.clear(); -} - -void ZipOutputEntry::deleteBufferFile() -{ - assert(!m_xOutStream.is() && !m_aTempURL.isEmpty()); - uno::Reference < ucb::XSimpleFileAccess3 > xAccess(ucb::SimpleFileAccess::create(m_xContext)); - xAccess->kill(m_aTempURL); -} - -uno::Reference< io::XInputStream > ZipOutputEntry::getData() const -{ - uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(ucb::SimpleFileAccess::create(m_xContext)); - return xTempAccess->openFileRead(m_aTempURL); } void ZipOutputEntry::closeEntry() @@ -241,4 +191,114 @@ void ZipOutputEntry::doDeflate() } } +ZipOutputEntryInThread::ZipOutputEntryInThread( + const uno::Reference< uno::XComponentContext >& rxContext, + ZipEntry& rEntry, + ZipPackageStream* pStream, + bool bEncrypt) +: ZipOutputEntry( uno::Reference< css::io::XOutputStream >(), rxContext, rEntry, pStream, bEncrypt, false ) +, m_bFinished(false) +{ +} + +void ZipOutputEntryInThread::createBufferFile() +{ + assert(!m_xOutStream.is() && m_aTempURL.isEmpty() && + "should only be called in the threaded mode where there is no existing stream yet"); + uno::Reference < beans::XPropertySet > xTempFileProps( + io::TempFile::create(m_xContext), + uno::UNO_QUERY_THROW ); + xTempFileProps->setPropertyValue("RemoveFile", uno::makeAny(false)); + uno::Any aUrl = xTempFileProps->getPropertyValue( "Uri" ); + aUrl >>= m_aTempURL; + assert(!m_aTempURL.isEmpty()); + + uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(ucb::SimpleFileAccess::create(m_xContext)); + m_xOutStream = xTempAccess->openFileWrite(m_aTempURL); +} + +void ZipOutputEntryInThread::closeBufferFile() +{ + m_xOutStream->closeOutput(); + m_xOutStream.clear(); +} + +void ZipOutputEntryInThread::deleteBufferFile() +{ + assert(!m_xOutStream.is() && !m_aTempURL.isEmpty()); + uno::Reference < ucb::XSimpleFileAccess3 > xAccess(ucb::SimpleFileAccess::create(m_xContext)); + xAccess->kill(m_aTempURL); +} + +uno::Reference< io::XInputStream > ZipOutputEntryInThread::getData() const +{ + uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(ucb::SimpleFileAccess::create(m_xContext)); + return xTempAccess->openFileRead(m_aTempURL); +} + +class ZipOutputEntryInThread::Task : public comphelper::ThreadTask +{ + ZipOutputEntryInThread *mpEntry; + uno::Reference< io::XInputStream > mxInStream; + +public: + Task( const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, ZipOutputEntryInThread *pEntry, + const uno::Reference< io::XInputStream >& xInStream ) + : comphelper::ThreadTask(pTag) + , mpEntry(pEntry) + , mxInStream(xInStream) + {} + +private: + virtual void doWork() override + { + try + { + mpEntry->createBufferFile(); + mpEntry->writeStream(mxInStream); + mxInStream.clear(); + mpEntry->closeBufferFile(); + mpEntry->setFinished(); + } + catch (...) + { + mpEntry->setParallelDeflateException(std::current_exception()); + try + { + if (mpEntry->m_xOutStream.is()) + mpEntry->closeBufferFile(); + if (!mpEntry->m_aTempURL.isEmpty()) + mpEntry->deleteBufferFile(); + } + catch (uno::Exception const&) + { + } + mpEntry->setFinished(); + } + } +}; + +std::unique_ptr<comphelper::ThreadTask> ZipOutputEntryInThread::createTask( + const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, + const uno::Reference< io::XInputStream >& xInStream ) +{ + return std::make_unique<Task>(pTag, this, xInStream); +} + +void ZipOutputEntry::writeStream(const uno::Reference< io::XInputStream >& xInStream) +{ + sal_Int32 nLength = 0; + uno::Sequence< sal_Int8 > aSeq(n_ConstBufferSize); + do + { + nLength = xInStream->readBytes(aSeq, n_ConstBufferSize); + if (nLength != n_ConstBufferSize) + aSeq.realloc(nLength); + + write(aSeq); + } + while (nLength == n_ConstBufferSize); + closeEntry(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |