summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/unotools/tempfile.hxx53
-rw-r--r--package/inc/ZipOutputEntry.hxx3
-rw-r--r--package/source/xstor/owriteablestream.cxx2
-rw-r--r--package/source/xstor/switchpersistencestream.cxx3
-rw-r--r--package/source/xstor/xfactory.cxx5
-rw-r--r--package/source/xstor/xstorage.cxx27
-rw-r--r--package/source/zipapi/ByteGrabber.cxx3
-rw-r--r--package/source/zipapi/ZipFile.cxx11
-rw-r--r--package/source/zipapi/ZipOutputEntry.cxx4
-rw-r--r--package/source/zipapi/ZipOutputStream.cxx1
-rw-r--r--package/source/zippackage/ZipPackage.cxx7
-rw-r--r--package/source/zippackage/ZipPackageStream.cxx24
-rw-r--r--unotools/source/ucbhelper/tempfile.cxx229
13 files changed, 317 insertions, 55 deletions
diff --git a/include/unotools/tempfile.hxx b/include/unotools/tempfile.hxx
index 460f13b96e90..168659d26359 100644
--- a/include/unotools/tempfile.hxx
+++ b/include/unotools/tempfile.hxx
@@ -19,8 +19,16 @@
#pragma once
#include <unotools/unotoolsdllapi.h>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <cppuhelper/implbase.hxx>
#include <tools/stream.hxx>
#include <memory>
+#include <mutex>
+#include <optional>
namespace utl
{
@@ -182,6 +190,51 @@ public:
};
+
+typedef ::cppu::WeakImplHelper<
+ css::io::XStream
+ , css::io::XSeekable
+ , css::io::XInputStream
+ , css::io::XOutputStream
+ , css::io::XTruncate> TempFileFastService_Base;
+class UNOTOOLS_DLLPUBLIC TempFileFastService : public TempFileFastService_Base
+{
+ std::optional<utl::TempFileFast> mpTempFile;
+ std::mutex maMutex;
+ SvStream* mpStream;
+ bool mbInClosed;
+ bool mbOutClosed;
+
+ void checkError () const;
+ void checkConnected ();
+
+public:
+ explicit TempFileFastService ();
+ virtual ~TempFileFastService () override;
+
+ // XInputStream
+ virtual ::sal_Int32 SAL_CALL readBytes( css::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) override;
+ virtual ::sal_Int32 SAL_CALL readSomeBytes( css::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) override;
+ virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) override;
+ virtual ::sal_Int32 SAL_CALL available( ) override;
+ virtual void SAL_CALL closeInput( ) override;
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const css::uno::Sequence< ::sal_Int8 >& aData ) override;
+ virtual void SAL_CALL flush( ) override;
+ virtual void SAL_CALL closeOutput( ) override;
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location ) override;
+ virtual sal_Int64 SAL_CALL getPosition( ) override;
+ virtual sal_Int64 SAL_CALL getLength( ) override;
+ // XStream
+ virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getInputStream( ) override;
+ virtual css::uno::Reference< css::io::XOutputStream > SAL_CALL getOutputStream( ) override;
+ // XTruncate
+ virtual void SAL_CALL truncate() override;
+
+};
+
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index 678a073c6746..fcf25dcadf81 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -28,6 +28,7 @@
#include <package/Deflater.hxx>
#include <comphelper/threadpool.hxx>
+#include <unotools/tempfile.hxx>
#include "CRC32.hxx"
#include <atomic>
@@ -110,7 +111,7 @@ protected:
class ZipOutputEntryInThread final : public ZipOutputEntry
{
class Task;
- css::uno::Reference<css::io::XTempFile> m_xTempFile;
+ rtl::Reference<utl::TempFileFastService> m_xTempFile;
std::exception_ptr m_aParallelDeflateException;
std::atomic<bool> m_bFinished;
diff --git a/package/source/xstor/owriteablestream.cxx b/package/source/xstor/owriteablestream.cxx
index 3437df46f2fd..2d6bda378d34 100644
--- a/package/source/xstor/owriteablestream.cxx
+++ b/package/source/xstor/owriteablestream.cxx
@@ -1320,7 +1320,7 @@ void OWriteStream_Impl::CreateReadonlyCopyBasedOnData( const uno::Reference< io:
{
uno::Reference < io::XStream > xTempFile;
if ( !xTargetStream.is() )
- xTempFile = io::TempFile::create(m_xContext);
+ xTempFile = new utl::TempFileFastService;
else
xTempFile = xTargetStream;
diff --git a/package/source/xstor/switchpersistencestream.cxx b/package/source/xstor/switchpersistencestream.cxx
index f4ccd452b8f9..f27dce18edc5 100644
--- a/package/source/xstor/switchpersistencestream.cxx
+++ b/package/source/xstor/switchpersistencestream.cxx
@@ -22,6 +22,7 @@
#include <com/sun/star/io/NotConnectedException.hpp>
#include <com/sun/star/io/TempFile.hpp>
#include <comphelper/storagehelper.hxx>
+#include <unotools/tempfile.hxx>
#include <utility>
#include "switchpersistencestream.hxx"
@@ -157,7 +158,7 @@ void SwitchablePersistenceStream::CopyAndSwitchPersistenceTo( const uno::Referen
if ( !xTargetStream.is() )
{
- xTargetStream.set( io::TempFile::create(m_xContext), uno::UNO_QUERY_THROW );
+ xTargetStream.set( new utl::TempFileFastService );
xTargetSeek.set( xTargetStream, uno::UNO_QUERY_THROW );
}
else
diff --git a/package/source/xstor/xfactory.cxx b/package/source/xstor/xfactory.cxx
index 38c8d4df29df..0ee4ae0cc51d 100644
--- a/package/source/xstor/xfactory.cxx
+++ b/package/source/xstor/xfactory.cxx
@@ -33,6 +33,7 @@
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/weak.hxx>
#include <osl/diagnose.h>
+#include <unotools/tempfile.hxx>
#include "xfactory.hxx"
#include "xstorage.hxx"
@@ -71,9 +72,7 @@ static bool CheckPackageSignature_Impl( const uno::Reference< io::XInputStream >
uno::Reference< uno::XInterface > SAL_CALL OStorageFactory::createInstance()
{
// TODO: reimplement TempStream service to support XStream interface
- uno::Reference < io::XStream > xTempStream(
- io::TempFile::create(m_xContext),
- uno::UNO_QUERY_THROW );
+ uno::Reference < io::XStream > xTempStream(new utl::TempFileFastService);
return static_cast<OWeakObject*>(new OStorage(xTempStream, embed::ElementModes::READWRITE,
uno::Sequence<beans::PropertyValue>(), m_xContext,
diff --git a/package/source/xstor/xstorage.cxx b/package/source/xstor/xstorage.cxx
index e18c398436b2..5ac7f0618b7d 100644
--- a/package/source/xstor/xstorage.cxx
+++ b/package/source/xstor/xstorage.cxx
@@ -112,10 +112,9 @@ void OStorage_Impl::completeStorageStreamCopy_Impl(
xDestProps->setPropertyValue( rPropName, xSourceProps->getPropertyValue( rPropName ) );
}
-static uno::Reference< io::XInputStream > GetSeekableTempCopy( const uno::Reference< io::XInputStream >& xInStream,
- const uno::Reference< uno::XComponentContext >& xContext )
+static uno::Reference< io::XInputStream > GetSeekableTempCopy( const uno::Reference< io::XInputStream >& xInStream )
{
- uno::Reference < io::XTempFile > xTempFile = io::TempFile::create(xContext);
+ rtl::Reference < utl::TempFileFastService > xTempFile = new utl::TempFileFastService;
uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
uno::Reference < io::XInputStream > xTempIn = xTempFile->getInputStream();
@@ -1318,7 +1317,7 @@ void OStorage_Impl::InsertRawStream( const OUString& aName, const uno::Reference
uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
- GetSeekableTempCopy( xInStream, m_xContext );
+ GetSeekableTempCopy( xInStream );
uno::Sequence< uno::Any > aSeq{ uno::Any(false) };
uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
@@ -3299,18 +3298,17 @@ uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
if ( !xRawInStream.is() )
throw io::IOException( THROW_WHERE );
- uno::Reference < io::XTempFile > xTempFile = io::TempFile::create( m_pImpl->m_xContext );
+ rtl::Reference < utl::TempFileFastService > xTempFile = new utl::TempFileFastService;
uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
xTempIn = xTempFile->getInputStream();
- uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
- if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
+ if ( !xTempOut.is() || !xTempIn.is() )
throw io::IOException( THROW_WHERE );
// Copy temporary file to a new one
::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
xTempOut->closeOutput();
- xSeek->seek( 0 );
+ xTempFile->seek( 0 );
}
catch( const embed::InvalidStorageException& )
{
@@ -3393,18 +3391,17 @@ uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
if ( !xRawInStream.is() )
throw io::IOException( THROW_WHERE );
- uno::Reference < io::XTempFile > xTempFile = io::TempFile::create(m_pImpl->m_xContext);
- uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
- xTempIn = xTempFile->getInputStream();
- uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
+ rtl::Reference < utl::TempFileFastService > xTempFile = new utl::TempFileFastService;
+ uno::Reference < io::XOutputStream > xTempOut = xTempFile;
+ xTempIn = xTempFile;
- if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
+ if ( !xTempFile )
throw io::IOException( THROW_WHERE );
// Copy temporary file to a new one
::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
- xTempOut->closeOutput();
- xSeek->seek( 0 );
+ xTempFile->closeOutput();
+ xTempFile->seek( 0 );
}
catch( const embed::InvalidStorageException& )
diff --git a/package/source/zipapi/ByteGrabber.cxx b/package/source/zipapi/ByteGrabber.cxx
index b58a7087f468..5a491de6509b 100644
--- a/package/source/zipapi/ByteGrabber.cxx
+++ b/package/source/zipapi/ByteGrabber.cxx
@@ -70,9 +70,6 @@ void ByteGrabber::seek( sal_Int64 location )
if (!xSeek.is() )
throw io::IOException(THROW_WHERE );
- sal_Int64 nLen = xSeek->getLength();
- if ( location < 0 || location > nLen )
- throw lang::IllegalArgumentException(THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
xSeek->seek( location );
}
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
index 63ba823e240e..c59035919bb8 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -820,16 +820,9 @@ void ZipFile::readLOC( ZipEntry &rEntry )
try
{
- sal_Int16 nPathLenToRead = nPathLen;
- const sal_Int64 nBytesAvailable = aGrabber.getLength() - aGrabber.getPosition();
- if (nPathLenToRead > nBytesAvailable)
- nPathLenToRead = nBytesAvailable;
- else if (nPathLenToRead < 0)
- nPathLenToRead = 0;
-
// read always in UTF8, some tools seem not to set UTF8 bit
- uno::Sequence<sal_Int8> aNameBuffer(nPathLenToRead);
- sal_Int32 nRead = aGrabber.readBytes(aNameBuffer, nPathLenToRead);
+ uno::Sequence<sal_Int8> aNameBuffer(nPathLen);
+ sal_Int32 nRead = aGrabber.readBytes(aNameBuffer, nPathLen);
if (nRead < aNameBuffer.getLength())
aNameBuffer.realloc(nRead);
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index 2eb5f9db4391..86c8a9782df7 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -250,9 +250,7 @@ void ZipOutputEntryInThread::createBufferFile()
{
assert(!m_xOutStream && !m_xTempFile &&
"should only be called in the threaded mode where there is no existing stream yet");
- m_xTempFile.set(
- io::TempFile::create(m_xContext),
- uno::UNO_SET_THROW );
+ m_xTempFile = new utl::TempFileFastService;
m_xOutStream = m_xTempFile->getOutputStream();
}
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index 33321627b6f9..9b582c4691e8 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -178,7 +178,6 @@ void ZipOutputStream::finish()
delete p;
}
writeEND( nOffset, static_cast < sal_Int32 > (m_aChucker.GetPosition()) - nOffset);
- m_xStream->flush();
m_aZipList.clear();
if (m_aDeflateException)
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 0d9d66970ffd..6316498ef0b8 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -61,6 +61,7 @@
#include <o3tl/string_view.hxx>
#include <osl/diagnose.h>
#include <sal/log.hxx>
+#include <unotools/tempfile.hxx>
#include <com/sun/star/io/XAsyncOutputMonitor.hpp>
#include <string_view>
@@ -1196,9 +1197,9 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
if( bUseTemp )
{
// create temporary file
- uno::Reference < io::XTempFile > xTempFile( io::TempFile::create(m_xContext) );
- xTempOut.set( xTempFile->getOutputStream(), UNO_SET_THROW );
- xTempIn.set( xTempFile->getInputStream(), UNO_SET_THROW );
+ rtl::Reference < utl::TempFileFastService > xTempFile( new utl::TempFileFastService );
+ xTempOut.set( xTempFile );
+ xTempIn.set( xTempFile );
}
// Hand it to the ZipOutputStream:
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 368d687e2886..a63683c771cd 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -49,6 +49,7 @@
#include <comphelper/servicehelper.hxx>
#include <comphelper/storagehelper.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <unotools/tempfile.hxx>
#include <rtl/random.h>
#include <sal/log.hxx>
@@ -173,15 +174,13 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop
m_xBaseEncryptionData->m_aSalt.getLength() + m_xBaseEncryptionData->m_aDigest.getLength() );
// create temporary stream
- uno::Reference < io::XTempFile > xTempFile = io::TempFile::create(m_xContext);
- uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
+ rtl::Reference < utl::TempFileFastService > xTempFile = new utl::TempFileFastService;
uno::Reference < io::XInputStream > xTempIn = xTempFile->getInputStream();
- uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY_THROW );
// copy the raw stream to the temporary file starting from the current position
- ::comphelper::OStorageHelper::CopyInputToOutput( GetOwnSeekStream(), xTempOut );
- xTempOut->closeOutput();
- xTempSeek->seek( 0 );
+ ::comphelper::OStorageHelper::CopyInputToOutput( GetOwnSeekStream(), xTempFile );
+ xTempFile->closeOutput();
+ xTempFile->seek( 0 );
return xTempIn;
}
@@ -276,9 +275,7 @@ uno::Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream(
try
{
// create temporary file
- uno::Reference < io::XStream > xTempStream(
- io::TempFile::create(m_xContext),
- uno::UNO_QUERY_THROW );
+ uno::Reference < io::XStream > xTempStream(new utl::TempFileFastService);
// create a package based on it
rtl::Reference<ZipPackage> pPackage = new ZipPackage( m_xContext );
@@ -322,16 +319,13 @@ uno::Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream(
xInRaw = xNewPackStream->getPlainRawStream();
// create another temporary file
- uno::Reference < io::XOutputStream > xTempOut(
- io::TempFile::create(m_xContext),
- uno::UNO_QUERY_THROW );
- uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY_THROW );
- uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY_THROW );
+ rtl::Reference < utl::TempFileFastService > xTempOut = new utl::TempFileFastService;
+ uno::Reference < io::XInputStream > xTempIn( xTempOut );
// copy the raw stream to the temporary file
::comphelper::OStorageHelper::CopyInputToOutput( xInRaw, xTempOut );
xTempOut->closeOutput();
- xTempSeek->seek( 0 );
+ xTempOut->seek( 0 );
// close raw stream, package stream and folder
xInRaw.clear();
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: */