diff options
author | Noel Grandin <noelgrandin@gmail.com> | 2022-10-20 17:47:21 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-10-21 12:01:05 +0200 |
commit | 848f9b2c56ce4c4620f62f1fbf9d12d84ec4da96 (patch) | |
tree | e9c81fcc12b292358d5d70010e7794fa2149fa00 /unotools | |
parent | 6383362999b72160eab6abdfc6ea6bdbd231b100 (diff) |
tdf#133767 new service TempFileFastService
to use in places where we know we can use the TempFileFast mechanism.
Speeds up export to EPUB from 43s to 17s on my windows machine.
This is essentially a copy of OTempFileService, but it does not
implement XTempFile (because these temp files have no name on Windows).
Also remove a couple of calls to Flush() (which is not necessary now),
and TellEnd(), which is a little slow on Windows.
Change-Id: Iced300bf8121eae08c7a011d62ec68b93330d84c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141598
Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'unotools')
-rw-r--r-- | unotools/source/ucbhelper/tempfile.cxx | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/unotools/source/ucbhelper/tempfile.cxx b/unotools/source/ucbhelper/tempfile.cxx index 406f08130dbd..09e3eda62e22 100644 --- a/unotools/source/ucbhelper/tempfile.cxx +++ b/unotools/source/ucbhelper/tempfile.cxx @@ -22,8 +22,12 @@ #include <cassert> #include <utility> +#include <com/sun/star/io/BufferSizeExceededException.hpp> +#include <com/sun/star/io/NotConnectedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> #include <unotools/tempfile.hxx> #include <rtl/ustring.hxx> +#include <o3tl/safeint.hxx> #include <osl/mutex.hxx> #include <osl/detail/file.h> #include <osl/file.hxx> @@ -534,6 +538,231 @@ OUString GetTempNameBaseDirectory() return ConstructTempDir_Impl(nullptr, false); } + +TempFileFastService::TempFileFastService() +: mbInClosed( false ) +, mbOutClosed( false ) +{ + mpTempFile.emplace(); + mpStream = mpTempFile->GetStream(StreamMode::READWRITE); +} + +TempFileFastService::~TempFileFastService () +{ +} + +// XInputStream + +sal_Int32 SAL_CALL TempFileFastService::readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) +{ + std::unique_lock aGuard( maMutex ); + if ( mbInClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + checkConnected(); + if (nBytesToRead < 0) + throw css::io::BufferSizeExceededException( OUString(), static_cast< css::uno::XWeak * >(this)); + + if (aData.getLength() < nBytesToRead) + aData.realloc(nBytesToRead); + + sal_uInt32 nRead = mpStream->ReadBytes(static_cast<void*>(aData.getArray()), nBytesToRead); + checkError(); + + if (nRead < o3tl::make_unsigned(aData.getLength())) + aData.realloc( nRead ); + + return nRead; +} + +sal_Int32 SAL_CALL TempFileFastService::readSomeBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) +{ + { + std::unique_lock aGuard( maMutex ); + if ( mbInClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + checkConnected(); + checkError(); + + if (nMaxBytesToRead < 0) + throw css::io::BufferSizeExceededException( OUString(), static_cast < css::uno::XWeak * >( this ) ); + + if (mpStream->eof()) + { + aData.realloc(0); + return 0; + } + } + return readBytes(aData, nMaxBytesToRead); +} + +void SAL_CALL TempFileFastService::skipBytes( sal_Int32 nBytesToSkip ) +{ + std::unique_lock aGuard( maMutex ); + if ( mbInClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + checkConnected(); + checkError(); + mpStream->SeekRel(nBytesToSkip); + checkError(); +} + +sal_Int32 SAL_CALL TempFileFastService::available() +{ + std::unique_lock aGuard( maMutex ); + if ( mbInClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + checkConnected(); + + sal_Int64 nAvailable = mpStream->remainingSize(); + checkError(); + + return std::min<sal_Int64>(SAL_MAX_INT32, nAvailable); +} + +void SAL_CALL TempFileFastService::closeInput() +{ + std::unique_lock aGuard( maMutex ); + if ( mbInClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + mbInClosed = true; + + if ( mbOutClosed ) + { + // stream will be deleted by TempFile implementation + mpStream = nullptr; + mpTempFile.reset(); + } +} + +// XOutputStream + +void SAL_CALL TempFileFastService::writeBytes( const css::uno::Sequence< sal_Int8 >& aData ) +{ + std::unique_lock aGuard( maMutex ); + if ( mbOutClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + checkConnected(); + sal_uInt32 nWritten = mpStream->WriteBytes(aData.getConstArray(), aData.getLength()); + checkError(); + if ( nWritten != static_cast<sal_uInt32>(aData.getLength())) + throw css::io::BufferSizeExceededException( OUString(),static_cast < css::uno::XWeak * > ( this ) ); +} + +void SAL_CALL TempFileFastService::flush() +{ + std::unique_lock aGuard( maMutex ); + if ( mbOutClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + checkConnected(); + mpStream->Flush(); + checkError(); +} + +void SAL_CALL TempFileFastService::closeOutput() +{ + std::unique_lock aGuard( maMutex ); + if ( mbOutClosed ) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); + + mbOutClosed = true; + if (mpStream) + { + // so that if you then open the InputStream, you can read the content + mpStream->FlushBuffer(); + mpStream->Seek(0); + } + + if ( mbInClosed ) + { + // stream will be deleted by TempFile implementation + mpStream = nullptr; + mpTempFile.reset(); + } +} + +void TempFileFastService::checkError() const +{ + if (!mpStream || mpStream->SvStream::GetError () != ERRCODE_NONE ) + throw css::io::NotConnectedException ( OUString(), const_cast < css::uno::XWeak * > ( static_cast < const css::uno::XWeak * > (this ) ) ); +} + +void TempFileFastService::checkConnected() +{ + if (!mpStream) + throw css::io::NotConnectedException ( OUString(), static_cast < css::uno::XWeak * > (this ) ); +} + +// XSeekable + +void SAL_CALL TempFileFastService::seek( sal_Int64 nLocation ) +{ + std::unique_lock aGuard( maMutex ); + checkConnected(); + checkError(); + if ( nLocation < 0 ) + throw css::lang::IllegalArgumentException(); + + sal_Int64 nNewLoc = mpStream->Seek(static_cast<sal_uInt32>(nLocation) ); + if ( nNewLoc != nLocation ) + throw css::lang::IllegalArgumentException(); + checkError(); +} + +sal_Int64 SAL_CALL TempFileFastService::getPosition() +{ + std::unique_lock aGuard( maMutex ); + checkConnected(); + + sal_uInt32 nPos = mpStream->Tell(); + checkError(); + return static_cast<sal_Int64>(nPos); +} + +sal_Int64 SAL_CALL TempFileFastService::getLength() +{ + std::unique_lock aGuard( maMutex ); + checkConnected(); + + checkError(); + + sal_Int64 nEndPos = mpStream->TellEnd(); + + return nEndPos; +} + +// XStream + +css::uno::Reference< css::io::XInputStream > SAL_CALL TempFileFastService::getInputStream() +{ + return css::uno::Reference< css::io::XInputStream >( *this, css::uno::UNO_QUERY ); +} + +css::uno::Reference< css::io::XOutputStream > SAL_CALL TempFileFastService::getOutputStream() +{ + return css::uno::Reference< css::io::XOutputStream >( this ); +} + +// XTruncate + +void SAL_CALL TempFileFastService::truncate() +{ + std::unique_lock aGuard( maMutex ); + checkConnected(); + // SetStreamSize() call does not change the position + mpStream->Seek( 0 ); + mpStream->SetStreamSize( 0 ); + checkError(); +} + + + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |