diff options
-rw-r--r-- | comphelper/source/misc/storagehelper.cxx | 48 | ||||
-rw-r--r-- | comphelper/source/streaming/basicio.cxx | 18 | ||||
-rw-r--r-- | comphelper/source/streaming/seqstream.cxx | 24 | ||||
-rw-r--r-- | include/comphelper/bytereader.hxx (renamed from include/unotools/bytereader.hxx) | 19 | ||||
-rw-r--r-- | include/comphelper/seqstream.hxx | 11 | ||||
-rw-r--r-- | include/unotools/streamwrap.hxx | 4 | ||||
-rw-r--r-- | package/source/xstor/owriteablestream.cxx | 82 | ||||
-rw-r--r-- | package/source/xstor/owriteablestream.hxx | 10 | ||||
-rw-r--r-- | ucb/source/ucp/file/filstr.cxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/file/filstr.hxx | 4 | ||||
-rw-r--r-- | unotools/source/streaming/streamhelper.cxx | 10 | ||||
-rw-r--r-- | unotools/source/streaming/streamwrap.cxx | 4 | ||||
-rw-r--r-- | unotools/source/ucbhelper/ucblockbytes.cxx | 6 |
13 files changed, 209 insertions, 35 deletions
diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx index 8e08612b0699..5f8527bcf273 100644 --- a/comphelper/source/misc/storagehelper.cxx +++ b/comphelper/source/misc/storagehelper.cxx @@ -27,6 +27,7 @@ #include <com/sun/star/embed/FileSystemStorageFactory.hpp> #include <com/sun/star/io/IOException.hpp> #include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> #include <com/sun/star/ucb/SimpleFileAccess.hpp> #include <com/sun/star/beans/XPropertySet.hpp> @@ -48,6 +49,7 @@ #include <ucbhelper/content.hxx> +#include <comphelper/bytereader.hxx> #include <comphelper/fileformat.h> #include <comphelper/hash.hxx> #include <comphelper/processfactory.hxx> @@ -173,21 +175,47 @@ void OStorageHelper::CopyInputToOutput( { static const sal_Int32 nConstBufferSize = 32000; - sal_Int32 nRead; - uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize ); + uno::Reference< css::lang::XUnoTunnel > xInputTunnel( xInput, uno::UNO_QUERY ); + comphelper::ByteReader* pByteReader = nullptr; + comphelper::ByteWriter* pByteWriter = nullptr; + if (xInputTunnel) + pByteReader = reinterpret_cast< comphelper::ByteReader* >( xInputTunnel->getSomething( comphelper::ByteReader::getUnoTunnelId() ) ); + if (pByteReader) + { + uno::Reference< css::lang::XUnoTunnel > xOutputTunnel( xOutput, uno::UNO_QUERY ); + if (xOutputTunnel) + pByteWriter = reinterpret_cast< comphelper::ByteWriter* >( xOutputTunnel->getSomething( comphelper::ByteWriter::getUnoTunnelId() ) ); + } - do + if (pByteWriter) { - nRead = xInput->readBytes ( aSequence, nConstBufferSize ); - if ( nRead < nConstBufferSize ) + sal_Int32 nRead; + sal_Int8 aTempBuf[ nConstBufferSize ]; + do { - uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead ); - xOutput->writeBytes ( aTempBuf ); + nRead = pByteReader->readSomeBytes ( aTempBuf, nConstBufferSize ); + pByteWriter->writeSomeBytes ( aTempBuf, nRead ); } - else - xOutput->writeBytes ( aSequence ); + while ( nRead == nConstBufferSize ); + } + else + { + sal_Int32 nRead; + uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize ); + + do + { + nRead = xInput->readBytes ( aSequence, nConstBufferSize ); + if ( nRead < nConstBufferSize ) + { + uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead ); + xOutput->writeBytes ( aTempBuf ); + } + else + xOutput->writeBytes ( aSequence ); + } + while ( nRead == nConstBufferSize ); } - while ( nRead == nConstBufferSize ); } diff --git a/comphelper/source/streaming/basicio.cxx b/comphelper/source/streaming/basicio.cxx index d86427b7de81..b8c0c96e2cfa 100644 --- a/comphelper/source/streaming/basicio.cxx +++ b/comphelper/source/streaming/basicio.cxx @@ -18,6 +18,8 @@ */ #include <comphelper/basicio.hxx> +#include <comphelper/bytereader.hxx> +#include <comphelper/servicehelper.hxx> #include <com/sun/star/awt/FontDescriptor.hpp> namespace comphelper @@ -157,6 +159,22 @@ const css::uno::Reference<css::io::XObjectOutputStream>& operator << (const css: return _rxOutStream; } +ByteReader::~ByteReader() {} + +const css::uno::Sequence< sal_Int8 > & ByteReader::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +ByteWriter::~ByteWriter() {} + +const css::uno::Sequence< sal_Int8 > & ByteWriter::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + } // namespace comphelper diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx index db39a1dc30e8..1f37a7967b04 100644 --- a/comphelper/source/streaming/seqstream.cxx +++ b/comphelper/source/streaming/seqstream.cxx @@ -74,6 +74,30 @@ sal_Int32 SAL_CALL SequenceInputStream::readBytes( Sequence<sal_Int8>& aData, sa return nBytesToRead; } +sal_Int32 SequenceInputStream::readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead ) +{ + if (nBytesToRead < 0) + throw BufferSizeExceededException(OUString(),*this); + + std::scoped_lock aGuard( m_aMutex ); + + sal_Int32 nAvail = avail(); + + if (nAvail < nBytesToRead) + nBytesToRead = nAvail; + + memcpy(pData, m_aData.getConstArray() + m_nPos, nBytesToRead); + m_nPos += nBytesToRead; + + return nBytesToRead; +} + +sal_Int64 SAL_CALL SequenceInputStream::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier ) +{ + if (rIdentifier == comphelper::ByteReader::getUnoTunnelId()) + return reinterpret_cast<sal_Int64>(static_cast<comphelper::ByteReader*>(this)); + return 0; +} sal_Int32 SAL_CALL SequenceInputStream::readSomeBytes( Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead ) { diff --git a/include/unotools/bytereader.hxx b/include/comphelper/bytereader.hxx index 8edf19929eea..a7e899098846 100644 --- a/include/unotools/bytereader.hxx +++ b/include/comphelper/bytereader.hxx @@ -8,16 +8,16 @@ */ #pragma once -#include <unotools/unotoolsdllapi.h> +#include <comphelper/comphelperdllapi.h> #include <com/sun/star/uno/Sequence.hxx> -namespace utl +namespace comphelper { /** * Interface that we can cast to, to bypass the inefficiency of using Sequence<sal_Int8> * when reading via XInputStream. */ -class UNOTOOLS_DLLPUBLIC ByteReader +class COMPHELPER_DLLPUBLIC ByteReader { public: virtual ~ByteReader(); @@ -26,6 +26,19 @@ public: static const css::uno::Sequence<sal_Int8>& getUnoTunnelId(); }; +/** + * Interface that we can cast to, to bypass the inefficiency of using Sequence<sal_Int8> + * when writing via XOutputStream. + */ +class COMPHELPER_DLLPUBLIC ByteWriter +{ +public: + virtual ~ByteWriter(); + virtual sal_Int32 writeSomeBytes(const sal_Int8* aData, sal_Int32 nBytesToWrite) = 0; + + static const css::uno::Sequence<sal_Int8>& getUnoTunnelId(); +}; + } // namespace utl /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx index 6cf22fdb6ebb..c2ba3913432b 100644 --- a/include/comphelper/seqstream.hxx +++ b/include/comphelper/seqstream.hxx @@ -24,8 +24,10 @@ #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> #include <cppuhelper/implbase.hxx> #include <comphelper/comphelperdllapi.h> +#include <comphelper/bytereader.hxx> #include <mutex> namespace comphelper @@ -37,7 +39,8 @@ namespace comphelper class COMPHELPER_DLLPUBLIC SequenceInputStream final - : public ::cppu::WeakImplHelper< css::io::XInputStream, css::io::XSeekable > + : public ::cppu::WeakImplHelper< css::io::XInputStream, css::io::XSeekable, css::lang::XUnoTunnel >, + public comphelper::ByteReader { std::mutex m_aMutex; css::uno::Sequence<sal_Int8> const m_aData; @@ -61,6 +64,12 @@ public: virtual sal_Int64 SAL_CALL getPosition( ) override; virtual sal_Int64 SAL_CALL getLength( ) override; +// css::lang::XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override; + +// comphelper::ByteReader + virtual sal_Int32 readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead ) override; + private: sal_Int32 avail(); }; diff --git a/include/unotools/streamwrap.hxx b/include/unotools/streamwrap.hxx index 15e729f156f3..dc4c51807189 100644 --- a/include/unotools/streamwrap.hxx +++ b/include/unotools/streamwrap.hxx @@ -27,9 +27,9 @@ #include <com/sun/star/io/XTruncate.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> +#include <comphelper/bytereader.hxx> #include <cppuhelper/implbase.hxx> #include <cppuhelper/implbase1.hxx> -#include <unotools/bytereader.hxx> #include <memory> #include <mutex> @@ -42,7 +42,7 @@ namespace utl class SAL_DLLPUBLIC_TEMPLATE OInputStreamWrapper_Base : public cppu::WeakImplHelper< css::io::XInputStream, css::lang::XUnoTunnel > {}; /// helper class for wrapping an SvStream into a com.sun.star.io::XInputStream -class UNOTOOLS_DLLPUBLIC OInputStreamWrapper : public OInputStreamWrapper_Base, public ByteReader +class UNOTOOLS_DLLPUBLIC OInputStreamWrapper : public OInputStreamWrapper_Base, public comphelper::ByteReader { protected: std::mutex m_aMutex; diff --git a/package/source/xstor/owriteablestream.cxx b/package/source/xstor/owriteablestream.cxx index 8f9a93a2cc11..19707a5d4ee5 100644 --- a/package/source/xstor/owriteablestream.cxx +++ b/package/source/xstor/owriteablestream.cxx @@ -2137,6 +2137,88 @@ void SAL_CALL OWriteStream::writeBytes( const uno::Sequence< sal_Int8 >& aData ) ModifyParentUnlockMutex_Impl( aGuard ); } +sal_Int32 OWriteStream::writeSomeBytes( const sal_Int8* pData, sal_Int32 nBytesToWrite ) +{ + osl::ClearableMutexGuard aGuard(m_pData->m_xSharedMutex->GetMutex()); + + // the write method makes initialization itself, since it depends from the aData length + // NO CheckInitOnDemand()! + + if ( !m_pImpl ) + { + SAL_INFO("package.xstor", "Disposed!"); + throw lang::DisposedException(); + } + + if ( !m_bInitOnDemand ) + { + if ( !m_xOutStream.is() || !m_xSeekable.is()) + throw io::NotConnectedException(); + + if ( m_pImpl->m_xCacheStream.is() ) + { + // check whether the cache should be turned off + sal_Int64 nPos = m_xSeekable->getPosition(); + if ( nPos + nBytesToWrite > MAX_STORCACHE_SIZE ) + { + // disconnect the cache and copy the data to the temporary file + m_xSeekable->seek( 0 ); + + // it is enough to copy the cached stream, the cache should already contain everything + if ( !m_pImpl->GetFilledTempFileIfNo( m_xInStream ).isEmpty() ) + { + DeInit(); + // the last position is known and it is differs from the current stream position + m_nInitPosition = nPos; + } + } + } + } + + if ( m_bInitOnDemand ) + { + SAL_INFO( "package.xstor", "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" ); + uno::Reference< io::XStream > xStream = m_pImpl->GetTempFileAsStream(); + if ( xStream.is() ) + { + m_xInStream.set( xStream->getInputStream(), uno::UNO_SET_THROW ); + m_xOutStream.set( xStream->getOutputStream(), uno::UNO_SET_THROW ); + m_xSeekable.set( xStream, uno::UNO_QUERY_THROW ); + m_xSeekable->seek( m_nInitPosition ); + + m_nInitPosition = 0; + m_bInitOnDemand = false; + } + } + + if ( !m_xOutStream.is() ) + throw io::NotConnectedException(); + + uno::Reference< css::lang::XUnoTunnel > xOutputTunnel( m_xOutStream, uno::UNO_QUERY ); + comphelper::ByteWriter* pByteWriter = nullptr; + if (xOutputTunnel) + pByteWriter = reinterpret_cast< comphelper::ByteWriter* >( xOutputTunnel->getSomething( comphelper::ByteWriter::getUnoTunnelId() ) ); + if (pByteWriter) + nBytesToWrite = pByteWriter->writeSomeBytes(pData, nBytesToWrite); + else + { + uno::Sequence<sal_Int8> aData(pData, nBytesToWrite); + m_xOutStream->writeBytes( aData ); + } + m_pImpl->m_bHasDataToFlush = true; + + ModifyParentUnlockMutex_Impl( aGuard ); + + return nBytesToWrite; +} + +sal_Int64 SAL_CALL OWriteStream::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier ) +{ + if (rIdentifier == comphelper::ByteWriter::getUnoTunnelId()) + return reinterpret_cast<sal_Int64>(static_cast<comphelper::ByteWriter*>(this)); + return 0; +} + void SAL_CALL OWriteStream::flush() { // In case stream is flushed its current version becomes visible diff --git a/package/source/xstor/owriteablestream.hxx b/package/source/xstor/owriteablestream.hxx index 5e87aa3e3047..6c2b657e3160 100644 --- a/package/source/xstor/owriteablestream.hxx +++ b/package/source/xstor/owriteablestream.hxx @@ -28,6 +28,7 @@ #include <com/sun/star/packages/XDataSinkEncrSupport.hpp> #include <com/sun/star/lang/XEventListener.hpp> #include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp> #include <com/sun/star/embed/XStorage.hpp> #include <com/sun/star/embed/XRelationshipAccess.hpp> @@ -39,6 +40,7 @@ #include <cppuhelper/weak.hxx> +#include <comphelper/bytereader.hxx> #include <comphelper/refcountedmutex.hxx> #include <comphelper/sequenceashashmap.hxx> @@ -229,7 +231,9 @@ class OWriteStream : public css::lang::XTypeProvider , public css::embed::XTransactedObject , public css::embed::XTransactionBroadcaster , public css::beans::XPropertySet + , public css::lang::XUnoTunnel , public ::cppu::OWeakObject + , public comphelper::ByteWriter { friend struct OWriteStream_Impl; @@ -342,6 +346,12 @@ public: virtual void SAL_CALL removeTransactionListener( const css::uno::Reference< css::embed::XTransactionListener >& aListener ) override; + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override; + + // comphelper::ByteWriter + virtual sal_Int32 writeSomeBytes(const sal_Int8* aData, sal_Int32 nBytesToWrite) override; + }; #endif diff --git a/ucb/source/ucp/file/filstr.cxx b/ucb/source/ucp/file/filstr.cxx index 8e605f7f1cc6..8c88b9fc2e54 100644 --- a/ucb/source/ucp/file/filstr.cxx +++ b/ucb/source/ucp/file/filstr.cxx @@ -167,8 +167,8 @@ XStream_impl::readSomeBytes( sal_Int64 SAL_CALL XStream_impl::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier ) { - if (rIdentifier == utl::ByteReader::getUnoTunnelId()) - return reinterpret_cast<sal_Int64>(static_cast<utl::ByteReader*>(this)); + if (rIdentifier == comphelper::ByteReader::getUnoTunnelId()) + return reinterpret_cast<sal_Int64>(static_cast<comphelper::ByteReader*>(this)); return 0; } diff --git a/ucb/source/ucp/file/filstr.hxx b/ucb/source/ucp/file/filstr.hxx index 65cf4369ce75..7ba43753f261 100644 --- a/ucb/source/ucp/file/filstr.hxx +++ b/ucb/source/ucp/file/filstr.hxx @@ -26,8 +26,8 @@ #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/io/XAsyncOutputMonitor.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> +#include <comphelper/bytereader.hxx> #include <cppuhelper/implbase.hxx> -#include <unotools/bytereader.hxx> #include <mutex> #include "filrec.hxx" @@ -45,7 +45,7 @@ class XStream_impl : public cppu::WeakImplHelper< css::io::XTruncate, css::io::XAsyncOutputMonitor, css::lang::XUnoTunnel >, - public utl::ByteReader + public comphelper::ByteReader { public: diff --git a/unotools/source/streaming/streamhelper.cxx b/unotools/source/streaming/streamhelper.cxx index 39585ec5f369..b5f07e6a6a7f 100644 --- a/unotools/source/streaming/streamhelper.cxx +++ b/unotools/source/streaming/streamhelper.cxx @@ -22,10 +22,8 @@ #include <com/sun/star/io/BufferSizeExceededException.hpp> #include <com/sun/star/io/IOException.hpp> #include <com/sun/star/io/NotConnectedException.hpp> -#include <comphelper/servicehelper.hxx> #include <o3tl/safeint.hxx> #include <unotools/streamhelper.hxx> -#include <unotools/bytereader.hxx> namespace utl { @@ -120,14 +118,6 @@ void SAL_CALL OInputStreamHelper::acquire() SAL_NOEXCEPT cppu::WeakImplHelper<css::io::XInputStream, css::io::XSeekable>::acquire(); } -ByteReader::~ByteReader() {} - -const css::uno::Sequence< sal_Int8 > & ByteReader::getUnoTunnelId() -{ - static const comphelper::UnoIdInit implId; - return implId.getSeq(); -} - } // namespace utl /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unotools/source/streaming/streamwrap.cxx b/unotools/source/streaming/streamwrap.cxx index 0ed933b530e3..6a6cbbd20142 100644 --- a/unotools/source/streaming/streamwrap.cxx +++ b/unotools/source/streaming/streamwrap.cxx @@ -158,8 +158,8 @@ void OInputStreamWrapper::checkError() const sal_Int64 SAL_CALL OInputStreamWrapper::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier ) { - if (rIdentifier == utl::ByteReader::getUnoTunnelId()) - return reinterpret_cast<sal_Int64>(static_cast<utl::ByteReader*>(this)); + if (rIdentifier == comphelper::ByteReader::getUnoTunnelId()) + return reinterpret_cast<sal_Int64>(static_cast<comphelper::ByteReader*>(this)); return 0; } diff --git a/unotools/source/ucbhelper/ucblockbytes.cxx b/unotools/source/ucbhelper/ucblockbytes.cxx index b40be28f2225..9cbee8ef6b95 100644 --- a/unotools/source/ucbhelper/ucblockbytes.cxx +++ b/unotools/source/ucbhelper/ucblockbytes.cxx @@ -56,9 +56,9 @@ #include <com/sun/star/io/XTruncate.hpp> #include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <comphelper/bytereader.hxx> #include <comphelper/storagehelper.hxx> #include <ucbhelper/content.hxx> -#include <unotools/bytereader.hxx> #include <mutex> using namespace ::com::sun::star::uno; @@ -1110,9 +1110,9 @@ ErrCode UcbLockBytes::ReadAt(sal_uInt64 const nPos, } Reference< css::lang::XUnoTunnel > xTunnel( xStream, UNO_QUERY ); - utl::ByteReader* pByteReader = nullptr; + comphelper::ByteReader* pByteReader = nullptr; if (xTunnel) - pByteReader = reinterpret_cast< utl::ByteReader* >( xTunnel->getSomething( utl::ByteReader::getUnoTunnelId() ) ); + pByteReader = reinterpret_cast< comphelper::ByteReader* >( xTunnel->getSomething( comphelper::ByteReader::getUnoTunnelId() ) ); if (pByteReader) { |