summaryrefslogtreecommitdiff
path: root/unotools
diff options
context:
space:
mode:
authorNoel Grandin <noelgrandin@gmail.com>2022-10-20 17:47:21 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-10-21 12:01:05 +0200
commit848f9b2c56ce4c4620f62f1fbf9d12d84ec4da96 (patch)
treee9c81fcc12b292358d5d70010e7794fa2149fa00 /unotools
parent6383362999b72160eab6abdfc6ea6bdbd231b100 (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.cxx229
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: */