diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-05-19 13:46:40 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-05-19 21:04:48 +0200 |
commit | 62531ec1091c7b3f6a3577889a18234790ec716d (patch) | |
tree | 72766dd4a58bbf61e2a56adc870d1a73307a9043 /package | |
parent | 5eb25f6a7ecb215f7bc81116cd930c1dec645e8d (diff) |
add ByteWriter to reduce memory copying when writing data
similarly to ByteReader
move both of them down to comphelper, since we want to use it from
comphelper, and comphelper is "below" unotools in the module dependency
graph
Change-Id: Ic98fa2268e125fd8e4378fb899ad5f97de721713
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134645
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'package')
-rw-r--r-- | package/source/xstor/owriteablestream.cxx | 82 | ||||
-rw-r--r-- | package/source/xstor/owriteablestream.hxx | 10 |
2 files changed, 92 insertions, 0 deletions
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 |