summaryrefslogtreecommitdiff
path: root/comphelper/source/streaming
diff options
context:
space:
mode:
Diffstat (limited to 'comphelper/source/streaming')
-rw-r--r--comphelper/source/streaming/basicio.cxx174
-rw-r--r--comphelper/source/streaming/makefile.mk54
-rw-r--r--comphelper/source/streaming/memorystream.cxx247
-rw-r--r--comphelper/source/streaming/oslfile2streamwrap.cxx198
-rw-r--r--comphelper/source/streaming/otransactedfilestream.cxx824
-rw-r--r--comphelper/source/streaming/seekableinput.cxx267
-rw-r--r--comphelper/source/streaming/seqinputstreamserv.cxx251
-rw-r--r--comphelper/source/streaming/seqoutputstreamserv.cxx172
-rw-r--r--comphelper/source/streaming/seqstream.cxx243
-rw-r--r--comphelper/source/streaming/streamsection.cxx122
10 files changed, 2552 insertions, 0 deletions
diff --git a/comphelper/source/streaming/basicio.cxx b/comphelper/source/streaming/basicio.cxx
new file mode 100644
index 000000000000..eef5c6b844fa
--- /dev/null
+++ b/comphelper/source/streaming/basicio.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <comphelper/basicio.hxx>
+
+//.........................................................................
+namespace comphelper
+{
+//.........................................................................
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectOutputStream>& operator << (
+ const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream,
+ const starawt::FontDescriptor& _rFont)
+{
+ _rxOutStream->writeUTF( _rFont.Name );
+ _rxOutStream->writeShort( _rFont.Height );
+ _rxOutStream->writeShort( _rFont.Width );
+ _rxOutStream->writeUTF( _rFont.StyleName );
+ _rxOutStream->writeShort( _rFont.Family );
+ _rxOutStream->writeShort( _rFont.CharSet );
+ _rxOutStream->writeShort( _rFont.Pitch );
+ _rxOutStream->writeDouble( _rFont.CharacterWidth );
+ _rxOutStream->writeDouble( _rFont.Weight );
+ _rxOutStream->writeShort( static_cast< sal_Int16 >(_rFont.Slant) );
+ _rxOutStream->writeShort( _rFont.Underline );
+ _rxOutStream->writeShort( _rFont.Strikeout );
+ _rxOutStream->writeDouble( _rFont.Orientation );
+ _rxOutStream->writeBoolean( _rFont.Kerning );
+ _rxOutStream->writeBoolean( _rFont.WordLineMode );
+ _rxOutStream->writeShort( _rFont.Type );
+ return _rxOutStream;
+}
+
+// FontDescriptor
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectInputStream>& operator >> (
+ const staruno::Reference<stario::XObjectInputStream>& _rxInStream,
+ starawt::FontDescriptor& _rFont)
+{
+ // schreiben des Fontdescriptors
+ _rFont.Name = _rxInStream->readUTF();
+ _rFont.Height = _rxInStream->readShort();
+ _rFont.Width = _rxInStream->readShort();
+ _rFont.StyleName = _rxInStream->readUTF();
+ _rFont.Family = _rxInStream->readShort();
+ _rFont.CharSet = _rxInStream->readShort();
+ _rFont.Pitch = _rxInStream->readShort();
+ _rFont.CharacterWidth = static_cast< float >(_rxInStream->readDouble());
+ _rFont.Weight = static_cast< float >(_rxInStream->readDouble());
+ _rFont.Slant = (starawt::FontSlant)_rxInStream->readShort();
+ _rFont.Underline = _rxInStream->readShort();
+ _rFont.Strikeout = _rxInStream->readShort();
+ _rFont.Orientation = static_cast< float >(_rxInStream->readDouble());
+ _rFont.Kerning = _rxInStream->readBoolean();
+ _rFont.WordLineMode = _rxInStream->readBoolean();
+ _rFont.Type = _rxInStream->readShort();
+ return _rxInStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Bool& _rVal)
+{
+ _rVal = _rxInStream->readBoolean();
+ return _rxInStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Bool _bVal)
+{
+ _rxOutStream->writeBoolean(_bVal);
+ return _rxOutStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, ::rtl::OUString& rStr)
+{
+ rStr = _rxInStream->readUTF();
+ return _rxInStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, const ::rtl::OUString& rStr)
+{
+ _rxOutStream->writeUTF(rStr);
+ return _rxOutStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Int16& _rValue)
+{
+ _rValue = _rxInStream->readShort();
+ return _rxInStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Int16 _nValue)
+{
+ _rxOutStream->writeShort(_nValue);
+ return _rxOutStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_uInt16& _rValue)
+{
+ _rValue = _rxInStream->readShort();
+ return _rxInStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_uInt16 _nValue)
+{
+ _rxOutStream->writeShort(_nValue);
+ return _rxOutStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_uInt32& _rValue)
+{
+ _rValue = _rxInStream->readLong();
+ return _rxInStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_uInt32 _nValue)
+{
+ _rxOutStream->writeLong(_nValue);
+ return _rxOutStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Int32& _rValue)
+{
+ _rValue = _rxInStream->readLong();
+ return _rxInStream;
+}
+
+//------------------------------------------------------------------------------
+const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Int32 _nValue)
+{
+ _rxOutStream->writeLong(_nValue);
+ return _rxOutStream;
+}
+
+//.........................................................................
+} // namespace comphelper
+//.........................................................................
+
diff --git a/comphelper/source/streaming/makefile.mk b/comphelper/source/streaming/makefile.mk
new file mode 100644
index 000000000000..2a6ea38ca65e
--- /dev/null
+++ b/comphelper/source/streaming/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=comphelper
+TARGET=streaming
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES= $(SLO)$/basicio.obj \
+ $(SLO)$/oslfile2streamwrap.obj \
+ $(SLO)$/seqstream.obj \
+ $(SLO)$/seqinputstreamserv.obj \
+ $(SLO)$/seqoutputstreamserv.obj \
+ $(SLO)$/streamsection.obj \
+ $(SLO)$/seekableinput.obj \
+ $(SLO)$/otransactedfilestream.obj \
+ $(SLO)$/memorystream.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/comphelper/source/streaming/memorystream.cxx b/comphelper/source/streaming/memorystream.cxx
new file mode 100644
index 000000000000..5298b7511f09
--- /dev/null
+++ b/comphelper/source/streaming/memorystream.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+
+#include "comphelper_module.hxx"
+
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekableInputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase4.hxx>
+
+#include <string.h>
+#include <vector>
+
+using ::rtl::OUString;
+using ::cppu::OWeakObject;
+using ::cppu::WeakImplHelper4;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::osl;
+
+namespace comphelper
+{
+
+class UNOMemoryStream : public WeakImplHelper4 < XStream, XSeekableInputStream, XOutputStream, XTruncate >
+{
+public:
+ UNOMemoryStream();
+ virtual ~UNOMemoryStream();
+
+ // XStream
+ virtual Reference< XInputStream > SAL_CALL getInputStream( ) throw (RuntimeException);
+ virtual Reference< XOutputStream > SAL_CALL getOutputStream( ) throw (RuntimeException);
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
+ virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
+ virtual sal_Int32 SAL_CALL available() throw (NotConnectedException, IOException, RuntimeException);
+ virtual void SAL_CALL closeInput() throw (NotConnectedException, IOException, RuntimeException);
+
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition() throw (IOException, RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength() throw (IOException, RuntimeException);
+
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& aData ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
+ virtual void SAL_CALL flush() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
+ virtual void SAL_CALL closeOutput() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
+
+ // XTruncate
+ virtual void SAL_CALL truncate() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo - static versions (used for component registration)
+ static ::rtl::OUString SAL_CALL getImplementationName_static();
+ static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static();
+ static Reference< XInterface > SAL_CALL Create( const Reference< ::com::sun::star::uno::XComponentContext >& );
+
+private:
+ std::vector< sal_Int8 > maData;
+ sal_Int32 mnCursor;
+};
+
+UNOMemoryStream::UNOMemoryStream()
+: mnCursor(0)
+{
+}
+
+UNOMemoryStream::~UNOMemoryStream()
+{
+}
+
+// XStream
+Reference< XInputStream > SAL_CALL UNOMemoryStream::getInputStream( ) throw (RuntimeException)
+{
+ return this;
+}
+
+Reference< XOutputStream > SAL_CALL UNOMemoryStream::getOutputStream( ) throw (RuntimeException)
+{
+ return this;
+}
+
+// XInputStream
+sal_Int32 SAL_CALL UNOMemoryStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ if( nBytesToRead < 0 )
+ throw IOException();
+
+ nBytesToRead = std::min( nBytesToRead, available() );
+ aData.realloc( nBytesToRead );
+
+ if( nBytesToRead )
+ {
+ sal_Int8* pData = static_cast<sal_Int8*>(&(*maData.begin()));
+ sal_Int8* pCursor = &((pData)[mnCursor]);
+ memcpy( (void*)aData.getArray(), (void*)pCursor, nBytesToRead );
+
+ mnCursor += nBytesToRead;
+ }
+
+ return nBytesToRead;
+}
+
+sal_Int32 SAL_CALL UNOMemoryStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ return readBytes( aData, nMaxBytesToRead );
+}
+
+void SAL_CALL UNOMemoryStream::skipBytes( sal_Int32 nBytesToSkip ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ if( nBytesToSkip < 0 )
+ throw IOException();
+
+ mnCursor += std::min( nBytesToSkip, available() );
+}
+
+sal_Int32 SAL_CALL UNOMemoryStream::available() throw (NotConnectedException, IOException, RuntimeException)
+{
+ return static_cast< sal_Int32 >( maData.size() ) - mnCursor;
+}
+
+void SAL_CALL UNOMemoryStream::closeInput() throw (NotConnectedException, IOException, RuntimeException)
+{
+ mnCursor = 0;
+}
+
+// XSeekable
+void SAL_CALL UNOMemoryStream::seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException)
+{
+ if( (location < 0) || (location > SAL_MAX_INT32) )
+ throw IllegalArgumentException( OUString(RTL_CONSTASCII_USTRINGPARAM("this implementation does not support more than 2GB!")), Reference< XInterface >(static_cast<OWeakObject*>(this)), 0 );
+
+ // seek operation should be able to resize the stream
+ if ( location > static_cast< sal_Int64 >( maData.size() ) )
+ maData.resize( static_cast< sal_Int32 >( location ) );
+
+ if ( location > static_cast< sal_Int64 >( maData.size() ) )
+ maData.resize( static_cast< sal_Int32 >( location ) );
+
+ mnCursor = static_cast< sal_Int32 >( location );
+}
+
+sal_Int64 SAL_CALL UNOMemoryStream::getPosition() throw (IOException, RuntimeException)
+{
+ return static_cast< sal_Int64 >( mnCursor );
+}
+
+sal_Int64 SAL_CALL UNOMemoryStream::getLength() throw (IOException, RuntimeException)
+{
+ return static_cast< sal_Int64 >( maData.size() );
+}
+
+// XOutputStream
+void SAL_CALL UNOMemoryStream::writeBytes( const Sequence< sal_Int8 >& aData ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ const sal_Int32 nBytesToWrite( aData.getLength() );
+ if( nBytesToWrite )
+ {
+ sal_Int64 nNewSize = static_cast< sal_Int64 >( mnCursor + nBytesToWrite );
+ if( nNewSize > SAL_MAX_INT32 )
+ {
+ OSL_ASSERT(false);
+ throw IOException( OUString(RTL_CONSTASCII_USTRINGPARAM("this implementation does not support more than 2GB!")), Reference< XInterface >(static_cast<OWeakObject*>(this)) );
+ }
+
+ if( static_cast< sal_Int32 >( nNewSize ) > static_cast< sal_Int32 >( maData.size() ) )
+ maData.resize( static_cast< sal_Int32 >( nNewSize ) );
+
+ sal_Int8* pData = static_cast<sal_Int8*>(&(*maData.begin()));
+ sal_Int8* pCursor = &(pData[mnCursor]);
+ memcpy( (void*)pCursor, (void*)aData.getConstArray(), nBytesToWrite );
+
+ mnCursor += nBytesToWrite;
+ }
+}
+
+void SAL_CALL UNOMemoryStream::flush() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+}
+
+void SAL_CALL UNOMemoryStream::closeOutput() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ mnCursor = 0;
+}
+
+//XTruncate
+void SAL_CALL UNOMemoryStream::truncate() throw (IOException, RuntimeException)
+{
+ maData.resize( 0 );
+ mnCursor = 0;
+}
+
+::rtl::OUString SAL_CALL UNOMemoryStream::getImplementationName_static()
+{
+ static const OUString sImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.MemoryStream" ) );
+ return sImplName;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL UNOMemoryStream::getSupportedServiceNames_static()
+{
+ Sequence< OUString > aSeq(1);
+ aSeq[0] = getImplementationName_static();
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL UNOMemoryStream::Create(
+ const Reference< XComponentContext >& )
+{
+ return static_cast<OWeakObject*>(new UNOMemoryStream());
+}
+
+} // namespace comphelper
+
+void createRegistryInfo_UNOMemoryStream()
+{
+ static ::comphelper::module::OAutoRegistration< ::comphelper::UNOMemoryStream > aAutoRegistration;
+}
diff --git a/comphelper/source/streaming/oslfile2streamwrap.cxx b/comphelper/source/streaming/oslfile2streamwrap.cxx
new file mode 100644
index 000000000000..9cf8eeaaf08a
--- /dev/null
+++ b/comphelper/source/streaming/oslfile2streamwrap.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <comphelper/oslfile2streamwrap.hxx>
+
+#include <algorithm>
+
+namespace comphelper
+{
+ using namespace osl;
+
+//------------------------------------------------------------------
+OSLInputStreamWrapper::OSLInputStreamWrapper( File& _rFile )
+ :m_pFile(&_rFile)
+ ,m_bFileOwner(sal_False)
+{
+}
+
+//------------------------------------------------------------------
+OSLInputStreamWrapper::OSLInputStreamWrapper( File* pStream, sal_Bool bOwner )
+ :m_pFile( pStream )
+ ,m_bFileOwner( bOwner )
+{
+}
+
+//------------------------------------------------------------------
+OSLInputStreamWrapper::~OSLInputStreamWrapper()
+{
+ if( m_bFileOwner )
+ delete m_pFile;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSLInputStreamWrapper::readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
+ throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ if (nBytesToRead < 0)
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ aData.realloc(nBytesToRead);
+
+ sal_uInt64 nRead = 0;
+ FileBase::RC eError = m_pFile->read((void*)aData.getArray(), nBytesToRead, nRead);
+ if (eError != FileBase::E_None)
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ // Wenn gelesene Zeichen < MaxLength, staruno::Sequence anpassen
+ if (nRead < (sal_uInt32)nBytesToRead)
+ aData.realloc( sal::static_int_cast< sal_Int32 >(nRead) );
+
+ return sal::static_int_cast< sal_Int32 >(nRead);
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSLInputStreamWrapper::readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ if (nMaxBytesToRead < 0)
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ /*
+ if (m_pFile->IsEof())
+ {
+ aData.realloc(0);
+ return 0;
+ }
+ else
+ */
+ return readBytes(aData, nMaxBytesToRead);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OSLInputStreamWrapper::skipBytes(sal_Int32 nBytesToSkip) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nCurrentPos;
+ m_pFile->getPos(nCurrentPos);
+
+ sal_uInt64 nNewPos = nCurrentPos + nBytesToSkip;
+ FileBase::RC eError = m_pFile->setPos(osl_Pos_Absolut, nNewPos);
+ if (eError != FileBase::E_None)
+ {
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+ }
+
+#ifdef DBG_UTIL
+ m_pFile->getPos(nCurrentPos);
+// volatile int dummy = 0; // to take a look at last changes ;-)
+#endif
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSLInputStreamWrapper::available() throw( stario::NotConnectedException, staruno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nPos;
+ FileBase::RC eError = m_pFile->getPos(nPos);
+ if (eError != FileBase::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nDummy = 0;
+ eError = m_pFile->setPos(Pos_End, nDummy);
+ if (eError != FileBase::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nAvailable;
+ eError = m_pFile->getPos(nAvailable);
+ if (eError != FileBase::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ nAvailable = nAvailable - nPos;
+ eError = m_pFile->setPos(Pos_Absolut, nPos);
+ if (eError != FileBase::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+ return sal::static_int_cast< sal_Int32 >(
+ std::max(nAvailable, sal::static_int_cast< sal_uInt64 >(SAL_MAX_INT32)));
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OSLInputStreamWrapper::closeInput() throw( stario::NotConnectedException, staruno::RuntimeException )
+{
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ m_pFile->close();
+ if (m_bFileOwner)
+ delete m_pFile;
+
+ m_pFile = NULL;
+}
+
+/*************************************************************************/
+// stario::XOutputStream
+//------------------------------------------------------------------------------
+void SAL_CALL OSLOutputStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ sal_uInt64 nWritten;
+ FileBase::RC eError = rFile.write(aData.getConstArray(),aData.getLength(), nWritten);
+ if (eError != FileBase::E_None
+ || nWritten != sal::static_int_cast< sal_uInt32 >(aData.getLength()))
+ {
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+ }
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OSLOutputStreamWrapper::flush() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OSLOutputStreamWrapper::closeOutput() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ rFile.close();
+}
+
+} // namespace comphelper
+
+
diff --git a/comphelper/source/streaming/otransactedfilestream.cxx b/comphelper/source/streaming/otransactedfilestream.cxx
new file mode 100644
index 000000000000..03539a12305b
--- /dev/null
+++ b/comphelper/source/streaming/otransactedfilestream.cxx
@@ -0,0 +1,824 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <osl/diagnose.h>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/io/XAsyncOutputMonitor.hpp>
+#include <com/sun/star/embed/UseBackupException.hpp>
+
+#include <comphelper/otransactedfilestream.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+using namespace ::com::sun::star;
+
+namespace comphelper
+{
+
+// ========================================================================
+class OTransactionHelper : public ::cppu::WeakImplHelper1 < embed::XTransactedObject >
+{
+ OTruncatedTransactedFileStream* m_pFileStream;
+ uno::Reference< io::XStream > m_xStreamHolder;
+
+public:
+ OTransactionHelper( OTruncatedTransactedFileStream* pStream )
+ : m_pFileStream( pStream )
+ {
+ m_xStreamHolder = static_cast< io::XStream* >( pStream );
+ if ( !m_xStreamHolder.is() )
+ throw uno::RuntimeException();
+ }
+
+ virtual void SAL_CALL commit( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException);
+ virtual void SAL_CALL revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException);
+};
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTransactionHelper::commit( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_pFileStream->Commit_Impl();
+}
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTransactionHelper::revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_pFileStream->Revert_Impl();
+}
+
+// ========================================================================
+struct TTFileStreamData_Impl
+{
+ uno::Reference< ucb::XSimpleFileAccess > m_xFileAccess;
+ sal_Bool m_bDelete;
+ ::rtl::OUString m_aURL;
+
+ // the streams below are not visible from outside so there is no need to remember position
+
+ // original stream related members
+ uno::Reference< io::XStream > m_xOrigStream;
+ uno::Reference< io::XTruncate > m_xOrigTruncate;
+ uno::Reference< io::XSeekable > m_xOrigSeekable;
+ uno::Reference< io::XInputStream > m_xOrigInStream;
+ uno::Reference< io::XOutputStream > m_xOrigOutStream;
+
+ // temporary stream related members
+ uno::Reference< io::XStream > m_xTempStream;
+ uno::Reference< io::XTruncate > m_xTempTruncate;
+ uno::Reference< io::XSeekable > m_xTempSeekable;
+ uno::Reference< io::XInputStream > m_xTempInStream;
+ uno::Reference< io::XOutputStream > m_xTempOutStream;
+
+ sal_Bool m_bInOpen;
+ sal_Bool m_bOutOpen;
+
+ sal_Bool m_bTransacted;
+
+
+ TTFileStreamData_Impl(
+ const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
+ sal_Bool bDelete,
+ const ::rtl::OUString& aURL,
+ const uno::Reference< io::XStream >& xOrigStream,
+ const uno::Reference< io::XTruncate >& xOrigTruncate,
+ const uno::Reference< io::XSeekable >& xOrigSeekable,
+ const uno::Reference< io::XInputStream >& xOrigInStream,
+ const uno::Reference< io::XOutputStream >& xOrigOutStream,
+ const uno::Reference< io::XStream >& xTempStream,
+ const uno::Reference< io::XTruncate >& xTempTruncate,
+ const uno::Reference< io::XSeekable >& xTempSeekable,
+ const uno::Reference< io::XInputStream >& xTempInStream,
+ const uno::Reference< io::XOutputStream >& xTempOutStream )
+ : m_xFileAccess( xFileAccess )
+ , m_bDelete( bDelete )
+ , m_aURL( aURL )
+ , m_xOrigStream( xOrigStream )
+ , m_xOrigTruncate( xOrigTruncate )
+ , m_xOrigSeekable( xOrigSeekable )
+ , m_xOrigInStream( xOrigInStream )
+ , m_xOrigOutStream( xOrigOutStream )
+ , m_xTempStream( xTempStream )
+ , m_xTempTruncate( xTempTruncate )
+ , m_xTempSeekable( xTempSeekable )
+ , m_xTempInStream( xTempInStream )
+ , m_xTempOutStream( xTempOutStream )
+ , m_bInOpen( sal_False )
+ , m_bOutOpen( sal_False )
+ , m_bTransacted( sal_True )
+ {}
+
+ void NoTransaction()
+ {
+ m_bDelete = sal_False;
+ m_bTransacted = sal_False;
+ m_xTempStream = uno::Reference< io::XStream >();
+ m_xTempTruncate = uno::Reference< io::XTruncate >();
+ m_xTempSeekable = uno::Reference< io::XSeekable >();
+ m_xTempInStream = uno::Reference< io::XInputStream >();
+ m_xTempOutStream = uno::Reference< io::XOutputStream >();
+ }
+
+ void FreeOriginal()
+ {
+ m_bDelete = sal_False;
+ m_bTransacted = sal_False;
+
+ m_xOrigStream = m_xTempStream;
+ m_xTempStream = uno::Reference< io::XStream >();
+
+ m_xOrigTruncate = m_xTempTruncate;
+ m_xTempTruncate = uno::Reference< io::XTruncate >();
+
+ m_xOrigSeekable = m_xTempSeekable;
+ m_xTempSeekable = uno::Reference< io::XSeekable >();
+
+ m_xOrigInStream = m_xTempInStream;
+ m_xTempInStream = uno::Reference< io::XInputStream >();
+
+ m_xOrigOutStream = m_xTempOutStream;
+ m_xTempOutStream = uno::Reference< io::XOutputStream >();
+ }
+};
+
+// ========================================================================
+// ------------------------------------------------------------------------
+OTruncatedTransactedFileStream::OTruncatedTransactedFileStream(
+ const ::rtl::OUString& aURL,
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+: m_pStreamData( NULL )
+{
+ uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
+ xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
+ uno::UNO_QUERY_THROW );
+
+ CommonInit_Impl( aURL, xSimpleFileAccess, xFactory, sal_False );
+}
+
+// ------------------------------------------------------------------------
+OTruncatedTransactedFileStream::OTruncatedTransactedFileStream(
+ const ::rtl::OUString& aURL,
+ const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+: m_pStreamData( NULL )
+{
+ CommonInit_Impl( aURL, xFileAccess, xFactory, sal_False );
+}
+
+// ------------------------------------------------------------------------
+OTruncatedTransactedFileStream::OTruncatedTransactedFileStream(
+ const ::rtl::OUString& aURL,
+ const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory,
+ sal_Bool bDeleteIfNotCommited )
+: m_pStreamData( NULL )
+{
+ CommonInit_Impl( aURL, xFileAccess, xFactory, sal_True );
+ if ( m_pStreamData )
+ m_pStreamData->m_bDelete = bDeleteIfNotCommited;
+}
+
+// ------------------------------------------------------------------------
+OTruncatedTransactedFileStream::~OTruncatedTransactedFileStream()
+{
+ CloseAll_Impl();
+}
+
+// ------------------------------------------------------------------------
+void OTruncatedTransactedFileStream::CloseAll_Impl()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pStreamData )
+ {
+ sal_Bool bDelete = m_pStreamData->m_bDelete;
+ ::rtl::OUString aURL = m_pStreamData->m_aURL;
+ uno::Reference< ucb::XSimpleFileAccess > xFileAccess = m_pStreamData->m_xFileAccess;
+
+ delete m_pStreamData;
+ m_pStreamData = NULL;
+
+ if ( bDelete && xFileAccess.is() && aURL.getLength() )
+ {
+ // delete the file
+ try
+ {
+ xFileAccess->kill( aURL );
+ } catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Could not remove the file!" );
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+void OTruncatedTransactedFileStream::CommonInit_Impl(
+ const ::rtl::OUString& aURL,
+ const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory,
+ sal_Bool bDeleteOptionIsProvided )
+{
+ sal_Bool bDelete = sal_False;
+ if ( !bDeleteOptionIsProvided )
+ bDelete = !xFileAccess->exists( aURL );
+
+ uno::Reference< io::XStream > xOrigStream = xFileAccess->openFileReadWrite( aURL );
+ uno::Reference< io::XTruncate > xOrigTruncate( xOrigStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XSeekable > xOrigSeekable( xOrigStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XInputStream > xOrigInStream = xOrigStream->getInputStream();
+ uno::Reference< io::XOutputStream > xOrigOutStream = xOrigStream->getOutputStream();
+ if ( !xOrigInStream.is() || !xOrigOutStream.is() )
+ throw uno::RuntimeException();
+
+ // temporary stream related members
+ uno::Reference< io::XStream > xTempStream( xFactory->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< io::XTruncate > xTempTruncate( xTempStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XSeekable > xTempSeekable( xTempStream, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XInputStream > xTempInStream = xTempStream->getInputStream();
+ uno::Reference< io::XOutputStream > xTempOutStream = xTempStream->getOutputStream();
+ if ( !xTempInStream.is() || !xTempOutStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData = new TTFileStreamData_Impl( xFileAccess, bDelete, aURL,
+ xOrigStream, xOrigTruncate, xOrigSeekable, xOrigInStream, xOrigOutStream,
+ xTempStream, xTempTruncate, xTempSeekable, xTempInStream, xTempOutStream );
+}
+
+// ------------------------------------------------------------------------
+void OTruncatedTransactedFileStream::Commit_Impl()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ sal_Int64 nPos = m_pStreamData->m_xTempSeekable->getPosition();
+ m_pStreamData->m_xTempSeekable->seek( 0 );
+
+ // after the following step fails the information might be lost, throw an exception with URL of temporary file
+ try
+ {
+ m_pStreamData->m_xOrigTruncate->truncate();
+ OStorageHelper::CopyInputToOutput( m_pStreamData->m_xTempInStream, m_pStreamData->m_xOrigOutStream );
+ m_pStreamData->m_xOrigOutStream->flush();
+
+ // in case the stream is based on a file it will implement the following interface
+ // the call should be used to be sure that the contents are written to the file system
+ uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( m_pStreamData->m_xOrigOutStream, uno::UNO_QUERY );
+ if ( asyncOutputMonitor.is() )
+ asyncOutputMonitor->waitForCompletion();
+ }
+ catch( uno::Exception& )
+ {
+ ::rtl::OUString aTempURL;
+ try {
+ uno::Reference< beans::XPropertySet > xTempFile( m_pStreamData->m_xTempStream, uno::UNO_QUERY_THROW );
+ uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
+ aUrl >>= aTempURL;
+ xTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ),
+ uno::makeAny( sal_False ) );
+
+ m_pStreamData->m_xTempSeekable->seek( nPos );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "These calls are pretty simple, they should not fail!\n" );
+ }
+
+ m_pStreamData->FreeOriginal();
+
+ ::rtl::OUString aErrTxt( RTL_CONSTASCII_USTRINGPARAM ( "Writing file failed!" ) );
+ embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), aTempURL );
+ throw lang::WrappedTargetException( aErrTxt,
+ static_cast < OWeakObject * > ( this ),
+ uno::makeAny ( aException ) );
+ }
+
+ m_pStreamData->m_xOrigSeekable->seek( nPos );
+ m_pStreamData->NoTransaction();
+ }
+ else
+ throw io::NotConnectedException();
+}
+
+// ------------------------------------------------------------------------
+void OTruncatedTransactedFileStream::Revert_Impl()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ m_pStreamData->m_xTempTruncate->truncate();
+ else
+ throw io::NotConnectedException();
+}
+
+// com::sun::star::io::XStream
+// ------------------------------------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL OTruncatedTransactedFileStream::getInputStream( )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pStreamData )
+ m_pStreamData->m_bInOpen = sal_True;
+ return static_cast< io::XInputStream* >( this );
+}
+
+
+// ------------------------------------------------------------------------
+uno::Reference< io::XOutputStream > SAL_CALL OTruncatedTransactedFileStream::getOutputStream( )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pStreamData )
+ m_pStreamData->m_bOutOpen = sal_True;
+ return static_cast< io::XOutputStream* >( this );
+}
+
+
+
+// com::sun::star::io::XInputStream
+// ------------------------------------------------------------------------
+::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xTempInStream->readBytes( aData, nBytesToRead );
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead );
+ }
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xTempInStream->readSomeBytes( aData, nMaxBytesToRead );
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigInStream->readSomeBytes( aData, nMaxBytesToRead );
+ }
+}
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::skipBytes( ::sal_Int32 nBytesToSkip )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempInStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xTempInStream->skipBytes( nBytesToSkip );
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip );
+ }
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::available( )
+ throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xTempInStream->available();
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigInStream->available();
+ }
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::closeInput()
+ throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ m_pStreamData->m_bInOpen = sal_False;
+ if ( !m_pStreamData->m_bOutOpen )
+ CloseAll_Impl();
+}
+
+
+
+// com::sun::star::io::XOutputStream
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempOutStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xTempOutStream->writeBytes( aData );
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigOutStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigOutStream->writeBytes( aData );
+ }
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::flush( )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ {
+ OSL_ENSURE( sal_False, "flush() call on closed stream!\n" );
+ return;
+ // in future throw exception, for now some code might call flush() on closed stream
+ // since file ucp implementation allows it
+ // throw io::NotConnectedException();
+ }
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempOutStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xTempOutStream->flush();
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigOutStream.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigOutStream->flush();
+ }
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::closeOutput( )
+ throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ m_pStreamData->m_bOutOpen = sal_False;
+ if ( !m_pStreamData->m_bInOpen )
+ CloseAll_Impl();
+}
+
+
+
+// com::sun::star::io::XTruncate
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::truncate( )
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempTruncate.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xTempTruncate->truncate();
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigTruncate.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigTruncate->truncate();
+ }
+}
+
+
+
+// com::sun::star::io::XSeekable
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::seek( ::sal_Int64 location )
+ throw (lang::IllegalArgumentException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempSeekable.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xTempSeekable->seek( location );
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigSeekable.is() )
+ throw uno::RuntimeException();
+
+ m_pStreamData->m_xOrigSeekable->seek( location );
+ }
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getPosition( )
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xTempSeekable->getPosition();
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigSeekable->getPosition();
+ }
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getLength( )
+ throw (io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ if ( m_pStreamData->m_bTransacted )
+ {
+ // temporary stream data should be provided
+ if ( !m_pStreamData->m_xTempSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xTempSeekable->getLength();
+ }
+ else
+ {
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigSeekable.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_xOrigSeekable->getLength();
+ }
+}
+
+// com::sun::star::beans::XPropertySetInfo
+// ------------------------------------------------------------------------
+uno::Sequence< beans::Property > SAL_CALL OTruncatedTransactedFileStream::getProperties()
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Sequence< beans::Property > aProps( 1 );
+ aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
+ aProps[0].Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) );
+ aProps[0].Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY;
+
+ return aProps;
+}
+
+
+// ------------------------------------------------------------------------
+beans::Property SAL_CALL OTruncatedTransactedFileStream::getPropertyByName( const ::rtl::OUString& aName )
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
+
+ if ( !aName.equals( aTransactionPropName ) )
+ throw beans::UnknownPropertyException();
+
+ beans::Property aProp;
+ aProp.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
+ aProp.Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) );
+ aProp.Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY;
+
+ return aProp;
+}
+
+
+// ------------------------------------------------------------------------
+::sal_Bool SAL_CALL OTruncatedTransactedFileStream::hasPropertyByName( const ::rtl::OUString& Name )
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
+ return ( Name.equals( aTransactionPropName ) );
+}
+
+
+
+// com::sun::star::beans::XPropertySet
+// ------------------------------------------------------------------------
+uno::Reference< beans::XPropertySetInfo > SAL_CALL OTruncatedTransactedFileStream::getPropertySetInfo()
+ throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ return static_cast< beans::XPropertySetInfo* >( this );
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& )
+ throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
+ if ( aPropertyName.equals( aTransactionPropName ) )
+ throw beans::PropertyVetoException();
+
+ throw beans::UnknownPropertyException();
+}
+
+
+// ------------------------------------------------------------------------
+uno::Any SAL_CALL OTruncatedTransactedFileStream::getPropertyValue( const ::rtl::OUString& PropertyName )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
+ if ( PropertyName.equals( aTransactionPropName ) )
+ {
+ uno::Reference< embed::XTransactedObject > xObj;
+ if ( m_pStreamData->m_bTransacted )
+ xObj = static_cast< embed::XTransactedObject* >( new OTransactionHelper( this ) );
+
+ return uno::makeAny( xObj );
+ }
+
+ throw beans::UnknownPropertyException();
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::addPropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ // not implemented
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::removePropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ // not implemented
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::addVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ // not implemented
+}
+
+
+// ------------------------------------------------------------------------
+void SAL_CALL OTruncatedTransactedFileStream::removeVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ // not implemented
+}
+
+
+} // namespace comphelper
+
diff --git a/comphelper/source/streaming/seekableinput.cxx b/comphelper/source/streaming/seekableinput.cxx
new file mode 100644
index 000000000000..abaf46faf014
--- /dev/null
+++ b/comphelper/source/streaming/seekableinput.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <com/sun/star/io/XOutputStream.hpp>
+
+
+#include <comphelper/seekableinput.hxx>
+
+using namespace ::com::sun::star;
+
+namespace comphelper
+{
+
+const sal_Int32 nConstBufferSize = 32000;
+
+//---------------------------------------------------------------------------
+void copyInputToOutput_Impl( const uno::Reference< io::XInputStream >& xIn,
+ const uno::Reference< io::XOutputStream >& xOut )
+{
+ sal_Int32 nRead;
+ uno::Sequence< sal_Int8 > aSequence( nConstBufferSize );
+
+ do
+ {
+ nRead = xIn->readBytes( aSequence, nConstBufferSize );
+ if ( nRead < nConstBufferSize )
+ {
+ uno::Sequence< sal_Int8 > aTempBuf( aSequence.getConstArray(), nRead );
+ xOut->writeBytes( aTempBuf );
+ }
+ else
+ xOut->writeBytes( aSequence );
+ }
+ while ( nRead == nConstBufferSize );
+}
+
+//---------------------------------------------------------------------------
+OSeekableInputWrapper::OSeekableInputWrapper(
+ const uno::Reference< io::XInputStream >& xInStream,
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+: m_xFactory( xFactory )
+, m_xOriginalStream( xInStream )
+{
+ if ( !m_xFactory.is() )
+ throw uno::RuntimeException();
+}
+
+//---------------------------------------------------------------------------
+OSeekableInputWrapper::~OSeekableInputWrapper()
+{
+}
+
+//---------------------------------------------------------------------------
+uno::Reference< io::XInputStream > OSeekableInputWrapper::CheckSeekableCanWrap(
+ const uno::Reference< io::XInputStream >& xInStream,
+ const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+{
+ // check that the stream is seekable and just wrap it if it is not
+ uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
+ if ( xSeek.is() )
+ return xInStream;
+
+ uno::Reference< io::XInputStream > xNewStream(
+ static_cast< io::XInputStream* >(
+ new OSeekableInputWrapper( xInStream, xFactory ) ) );
+ return xNewStream;
+}
+
+//---------------------------------------------------------------------------
+void OSeekableInputWrapper::PrepareCopy_Impl()
+{
+ if ( !m_xCopyInput.is() )
+ {
+ if ( !m_xFactory.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XOutputStream > xTempOut(
+ m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY );
+
+ if ( xTempOut.is() )
+ {
+ copyInputToOutput_Impl( m_xOriginalStream, xTempOut );
+ xTempOut->closeOutput();
+
+ uno::Reference< io::XSeekable > xTempSeek( xTempOut, uno::UNO_QUERY );
+ if ( xTempSeek.is() )
+ {
+ xTempSeek->seek( 0 );
+ m_xCopyInput = uno::Reference< io::XInputStream >( xTempOut, uno::UNO_QUERY );
+ if ( m_xCopyInput.is() )
+ m_xCopySeek = xTempSeek;
+ }
+ }
+ }
+
+ if ( !m_xCopyInput.is() )
+ throw io::IOException();
+}
+
+// XInputStream
+//---------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSeekableInputWrapper::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ return m_xCopyInput->readBytes( aData, nBytesToRead );
+}
+
+//---------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSeekableInputWrapper::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ return m_xCopyInput->readSomeBytes( aData, nMaxBytesToRead );
+}
+
+//---------------------------------------------------------------------------
+void SAL_CALL OSeekableInputWrapper::skipBytes( sal_Int32 nBytesToSkip )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ m_xCopyInput->skipBytes( nBytesToSkip );
+}
+
+//---------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSeekableInputWrapper::available()
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ return m_xCopyInput->available();
+}
+
+//---------------------------------------------------------------------------
+void SAL_CALL OSeekableInputWrapper::closeInput()
+ throw ( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ m_xOriginalStream->closeInput();
+ m_xOriginalStream = uno::Reference< io::XInputStream >();
+
+ if ( m_xCopyInput.is() )
+ {
+ m_xCopyInput->closeInput();
+ m_xCopyInput = uno::Reference< io::XInputStream >();
+ }
+
+ m_xCopySeek = uno::Reference< io::XSeekable >();
+}
+
+
+// XSeekable
+//---------------------------------------------------------------------------
+void SAL_CALL OSeekableInputWrapper::seek( sal_Int64 location )
+ throw ( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ m_xCopySeek->seek( location );
+}
+
+//---------------------------------------------------------------------------
+sal_Int64 SAL_CALL OSeekableInputWrapper::getPosition()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ return m_xCopySeek->getPosition();
+}
+
+//---------------------------------------------------------------------------
+sal_Int64 SAL_CALL OSeekableInputWrapper::getLength()
+ throw ( io::IOException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ return m_xCopySeek->getLength();
+}
+
+} // namespace comphelper
+
diff --git a/comphelper/source/streaming/seqinputstreamserv.cxx b/comphelper/source/streaming/seqinputstreamserv.cxx
new file mode 100644
index 000000000000..015387b9894d
--- /dev/null
+++ b/comphelper/source/streaming/seqinputstreamserv.cxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER( update_precomp.py ): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+
+#include "comphelper_module.hxx"
+
+#include <sal/config.h>
+#include <osl/mutex.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <comphelper/seqstream.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/io/XSeekableInputStream.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class SequenceInputStreamService:
+ public ::cppu::WeakImplHelper3<
+ lang::XServiceInfo,
+ io::XSeekableInputStream,
+ lang::XInitialization>
+{
+public:
+ explicit SequenceInputStreamService();
+
+ // ::com::sun::star::lang::XServiceInfo:
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( uno::RuntimeException );
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString & ServiceName ) throw ( uno::RuntimeException );
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( uno::RuntimeException );
+
+ // XServiceInfo - static versions (used for component registration)
+ static ::rtl::OUString SAL_CALL getImplementationName_static();
+ static uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static();
+ static uno::Reference< uno::XInterface > SAL_CALL Create( const uno::Reference< uno::XComponentContext >& );
+
+ // ::com::sun::star::io::XInputStream:
+ virtual ::sal_Int32 SAL_CALL readBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException );
+ virtual ::sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nMaxBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException );
+ virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException );
+ virtual ::sal_Int32 SAL_CALL available() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException );
+ virtual void SAL_CALL closeInput() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException );
+
+ // ::com::sun::star::io::XSeekable:
+ virtual void SAL_CALL seek( ::sal_Int64 location ) throw ( uno::RuntimeException, lang::IllegalArgumentException, io::IOException );
+ virtual ::sal_Int64 SAL_CALL getPosition() throw ( uno::RuntimeException, io::IOException );
+ virtual ::sal_Int64 SAL_CALL getLength() throw ( uno::RuntimeException, io::IOException );
+
+ // ::com::sun::star::lang::XInitialization:
+ virtual void SAL_CALL initialize( const uno::Sequence< ::com::sun::star::uno::Any > & aArguments ) throw ( uno::RuntimeException, uno::Exception );
+
+private:
+ SequenceInputStreamService( SequenceInputStreamService & ); // not defined
+ void operator =( SequenceInputStreamService & ); // not defined
+
+ virtual ~SequenceInputStreamService() {}
+
+
+ ::osl::Mutex m_aMutex;
+ sal_Bool m_bInitialized;
+ uno::Reference< io::XInputStream > m_xInputStream;
+ uno::Reference< io::XSeekable > m_xSeekable;
+};
+
+SequenceInputStreamService::SequenceInputStreamService()
+: m_bInitialized( sal_False )
+{}
+
+// com.sun.star.uno.XServiceInfo:
+::rtl::OUString SAL_CALL SequenceInputStreamService::getImplementationName() throw ( uno::RuntimeException )
+{
+ return getImplementationName_static();
+}
+
+::rtl::OUString SAL_CALL SequenceInputStreamService::getImplementationName_static()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.SequenceInputStreamService" ) );
+}
+
+::sal_Bool SAL_CALL SequenceInputStreamService::supportsService( ::rtl::OUString const & serviceName ) throw ( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > serviceNames = getSupportedServiceNames();
+ for ( ::sal_Int32 i = 0; i < serviceNames.getLength(); ++i ) {
+ if ( serviceNames[i] == serviceName )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL SequenceInputStreamService::getSupportedServiceNames() throw ( uno::RuntimeException )
+{
+ return getSupportedServiceNames_static();
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL SequenceInputStreamService::getSupportedServiceNames_static()
+{
+ uno::Sequence< ::rtl::OUString > s( 1 );
+ s[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.io.SequenceInputStream" ) );
+ return s;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SequenceInputStreamService::Create(
+ const uno::Reference< uno::XComponentContext >& )
+{
+ return static_cast< ::cppu::OWeakObject * >( new SequenceInputStreamService() );
+}
+
+// ::com::sun::star::io::XInputStream:
+::sal_Int32 SAL_CALL SequenceInputStreamService::readBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xInputStream.is() )
+ throw io::NotConnectedException();
+
+ return m_xInputStream->readBytes( aData, nBytesToRead );
+}
+
+::sal_Int32 SAL_CALL SequenceInputStreamService::readSomeBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nMaxBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xInputStream.is() )
+ throw io::NotConnectedException();
+
+ return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead );
+}
+
+void SAL_CALL SequenceInputStreamService::skipBytes( ::sal_Int32 nBytesToSkip ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xInputStream.is() )
+ throw io::NotConnectedException();
+
+ return m_xInputStream->skipBytes( nBytesToSkip );
+}
+
+::sal_Int32 SAL_CALL SequenceInputStreamService::available() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xInputStream.is() )
+ throw io::NotConnectedException();
+
+ return m_xInputStream->available();
+}
+
+void SAL_CALL SequenceInputStreamService::closeInput() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xInputStream.is() )
+ throw io::NotConnectedException();
+
+ m_xInputStream->closeInput();
+ m_xInputStream = uno::Reference< io::XInputStream >();
+ m_xSeekable = uno::Reference< io::XSeekable >();
+}
+
+// ::com::sun::star::io::XSeekable:
+void SAL_CALL SequenceInputStreamService::seek( ::sal_Int64 location ) throw ( uno::RuntimeException, lang::IllegalArgumentException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xSeekable.is() )
+ throw io::NotConnectedException();
+
+ m_xSeekable->seek( location );
+}
+
+::sal_Int64 SAL_CALL SequenceInputStreamService::getPosition() throw ( uno::RuntimeException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xSeekable.is() )
+ throw io::NotConnectedException();
+
+ return m_xSeekable->getPosition();
+}
+
+::sal_Int64 SAL_CALL SequenceInputStreamService::getLength() throw ( uno::RuntimeException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xSeekable.is() )
+ throw io::NotConnectedException();
+
+ return m_xSeekable->getLength();
+}
+
+// ::com::sun::star::lang::XInitialization:
+void SAL_CALL SequenceInputStreamService::initialize( const uno::Sequence< ::com::sun::star::uno::Any > & aArguments ) throw ( uno::RuntimeException, uno::Exception )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bInitialized )
+ throw frame::DoubleInitializationException();
+
+ if ( aArguments.getLength() != 1 )
+ throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong number of arguments!\n" ),
+ uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
+ 1 );
+
+ uno::Sequence< sal_Int8 > aSeq;
+ if ( aArguments[0] >>= aSeq )
+ {
+ uno::Reference< io::XInputStream > xInputStream(
+ static_cast< ::cppu::OWeakObject* >( new ::comphelper::SequenceInputStream( aSeq ) ),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< io::XSeekable > xSeekable( xInputStream, uno::UNO_QUERY_THROW );
+ m_xInputStream = xInputStream;
+ m_xSeekable = xSeekable;
+ m_bInitialized = sal_True;
+ }
+ else
+ throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Unexpected type of argument!\n" ),
+ uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
+ 1 );
+}
+
+} // anonymous namespace
+
+void createRegistryInfo_SequenceInputStream()
+{
+ static ::comphelper::module::OAutoRegistration< SequenceInputStreamService > aAutoRegistration;
+}
diff --git a/comphelper/source/streaming/seqoutputstreamserv.cxx b/comphelper/source/streaming/seqoutputstreamserv.cxx
new file mode 100644
index 000000000000..a51653e6e419
--- /dev/null
+++ b/comphelper/source/streaming/seqoutputstreamserv.cxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#include "precompiled_comphelper.hxx"
+
+#include "comphelper_module.hxx"
+
+#include <sal/config.h>
+#include <osl/mutex.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <comphelper/seqstream.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/io/XSequenceOutputStream.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+using namespace ::com::sun::star;
+
+
+namespace {
+
+class SequenceOutputStreamService:
+public ::cppu::WeakImplHelper2 < lang::XServiceInfo, io::XSequenceOutputStream >
+{
+public:
+ explicit SequenceOutputStreamService();
+
+ // ::com::sun::star::lang::XServiceInfo:
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( uno::RuntimeException );
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString & ServiceName ) throw ( uno::RuntimeException );
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( uno::RuntimeException );
+
+ // XServiceInfo - static versions (used for component registration)
+ static ::rtl::OUString SAL_CALL getImplementationName_static();
+ static uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static();
+ static uno::Reference< uno::XInterface > SAL_CALL Create( const uno::Reference< uno::XComponentContext >& );
+
+ // ::com::sun::star::io::XOutputStream:
+ virtual void SAL_CALL writeBytes( const uno::Sequence< ::sal_Int8 > & aData ) throw ( io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException );
+ virtual void SAL_CALL flush() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException );
+ virtual void SAL_CALL closeOutput() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException );
+
+ // ::com::sun::star::io::XSequenceOutputStream:
+ virtual uno::Sequence< ::sal_Int8 > SAL_CALL getWrittenBytes( ) throw ( io::NotConnectedException, io::IOException, uno::RuntimeException);
+
+private:
+ SequenceOutputStreamService( SequenceOutputStreamService & ); //not defined
+ void operator =( SequenceOutputStreamService & ); //not defined
+
+ virtual ~SequenceOutputStreamService() {};
+
+
+ ::osl::Mutex m_aMutex;
+ uno::Reference< io::XOutputStream > m_xOutputStream;
+ uno::Sequence< ::sal_Int8 > m_aSequence;
+};
+SequenceOutputStreamService::SequenceOutputStreamService()
+{
+ m_xOutputStream.set( static_cast < ::cppu::OWeakObject* >( new ::comphelper::OSequenceOutputStream( m_aSequence ) ), uno::UNO_QUERY_THROW );
+}
+
+// com.sun.star.uno.XServiceInfo:
+::rtl::OUString SAL_CALL SequenceOutputStreamService::getImplementationName() throw ( uno::RuntimeException )
+{
+ return getImplementationName_static();
+}
+
+::rtl::OUString SAL_CALL SequenceOutputStreamService::getImplementationName_static()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.SequenceOutputStreamService" ) );
+}
+
+::sal_Bool SAL_CALL SequenceOutputStreamService::supportsService( ::rtl::OUString const & serviceName ) throw ( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > serviceNames = getSupportedServiceNames();
+ for ( ::sal_Int32 i = 0; i < serviceNames.getLength(); ++i ) {
+ if ( serviceNames[i] == serviceName )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL SequenceOutputStreamService::getSupportedServiceNames() throw ( uno::RuntimeException )
+{
+ return getSupportedServiceNames_static();
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL SequenceOutputStreamService::getSupportedServiceNames_static()
+{
+ uno::Sequence< ::rtl::OUString > s( 1 );
+ s[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.SequenceOutputStream" ) );
+ return s;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SequenceOutputStreamService::Create(
+ const uno::Reference< uno::XComponentContext >& )
+{
+ return static_cast< ::cppu::OWeakObject * >( new SequenceOutputStreamService());
+}
+
+// ::com::sun::star::io::XOutputStream:
+void SAL_CALL SequenceOutputStreamService::writeBytes( const uno::Sequence< ::sal_Int8 > & aData ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xOutputStream.is() )
+ throw io::NotConnectedException();
+
+ m_xOutputStream->writeBytes( aData );
+ m_aSequence = aData;
+}
+
+void SAL_CALL SequenceOutputStreamService::flush() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xOutputStream.is() )
+ throw io::NotConnectedException();
+
+ m_xOutputStream->flush();
+};
+
+void SAL_CALL SequenceOutputStreamService::closeOutput() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xOutputStream.is() )
+ throw io::NotConnectedException();
+
+ m_xOutputStream->closeOutput();
+ m_xOutputStream = uno::Reference< io::XOutputStream >();
+}
+
+// ::com::sun::star::io::XSequenceOutputStream:
+uno::Sequence< ::sal_Int8 > SAL_CALL SequenceOutputStreamService::getWrittenBytes() throw ( io::NotConnectedException, io::IOException, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xOutputStream.is() )
+ throw io::NotConnectedException();
+
+ m_xOutputStream->flush();
+ return m_aSequence;
+}
+
+} // anonymous namespace
+
+void createRegistryInfo_SequenceOutputStream()
+{
+ static ::comphelper::module::OAutoRegistration< SequenceOutputStreamService > aAutoRegistration;
+}
diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx
new file mode 100644
index 000000000000..5c8a32b1f6e5
--- /dev/null
+++ b/comphelper/source/streaming/seqstream.cxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <comphelper/seqstream.hxx>
+
+#include <memory.h> // for memcpy
+
+namespace comphelper
+{
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::osl;
+
+//---------------------------------------------------------------------------------------------
+// class SequenceInputStream
+//---------------------------------------------------------------------------------------------
+
+//------------------------------------------------------------------
+SequenceInputStream::SequenceInputStream(const ByteSequence& rData)
+: m_aData(rData)
+, m_nPos(0)
+{
+}
+
+// checks if closed, returns available size, not mutex-protected
+//------------------------------------------------------------------
+inline sal_Int32 SequenceInputStream::avail()
+{
+ if (m_nPos == -1)
+ throw NotConnectedException(::rtl::OUString(), *this);
+
+ return m_aData.getLength() - m_nPos;
+}
+
+// com::sun::star::io::XInputStream
+//------------------------------------------------------------------
+sal_Int32 SAL_CALL SequenceInputStream::readBytes( Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead )
+ throw(NotConnectedException, BufferSizeExceededException,
+ IOException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 nAvail = avail();
+
+ if (nBytesToRead < 0)
+ throw BufferSizeExceededException(::rtl::OUString(),*this);
+
+ if (nAvail < nBytesToRead)
+ nBytesToRead = nAvail;
+
+ aData.realloc(nBytesToRead);
+ memcpy(aData.getArray(), m_aData.getConstArray() + m_nPos, nBytesToRead);
+ m_nPos += nBytesToRead;
+
+ return nBytesToRead;
+}
+
+//------------------------------------------------------------------
+sal_Int32 SAL_CALL SequenceInputStream::readSomeBytes( Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead )
+ throw(NotConnectedException, BufferSizeExceededException,
+ IOException, RuntimeException)
+{
+ // all data is available at once
+ return readBytes(aData, nMaxBytesToRead);
+}
+
+//------------------------------------------------------------------
+void SAL_CALL SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw(NotConnectedException, BufferSizeExceededException,
+ IOException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 nAvail = avail();
+
+ if (nBytesToSkip < 0)
+ throw BufferSizeExceededException(::rtl::OUString(),*this);
+
+ if (nAvail < nBytesToSkip)
+ nBytesToSkip = nAvail;
+
+ m_nPos += nBytesToSkip;
+}
+
+//------------------------------------------------------------------
+sal_Int32 SAL_CALL SequenceInputStream::available( )
+ throw(NotConnectedException, IOException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ return avail();
+}
+
+//------------------------------------------------------------------
+void SAL_CALL SequenceInputStream::closeInput( )
+ throw(NotConnectedException, IOException, RuntimeException)
+{
+ if (m_nPos == -1)
+ throw NotConnectedException(::rtl::OUString(), *this);
+
+ m_nPos = -1;
+}
+
+void SAL_CALL SequenceInputStream::seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException)
+{
+ if ( location > m_aData.getLength() || location < 0 || location > SAL_MAX_INT32 )
+ throw IllegalArgumentException();
+ m_nPos = (sal_Int32) location;
+}
+
+sal_Int64 SAL_CALL SequenceInputStream::getPosition() throw (IOException, RuntimeException)
+{
+ return m_nPos;
+}
+
+sal_Int64 SAL_CALL SequenceInputStream::getLength( ) throw (IOException, RuntimeException)
+{
+ return m_aData.getLength();
+}
+
+//--------------------------------------------------------------------------
+OSequenceOutputStream::OSequenceOutputStream(Sequence< sal_Int8 >& _rSeq, double _nResizeFactor, sal_Int32 _nMinimumResize, sal_Int32 _nMaximumResize)
+ :m_rSequence(_rSeq)
+ ,m_nResizeFactor(_nResizeFactor)
+ ,m_nMinimumResize(_nMinimumResize)
+ ,m_nMaximumResize(_nMaximumResize)
+ ,m_nSize(0) // starting at position 0
+ ,m_bConnected(sal_True)
+{
+ OSL_ENSURE(m_nResizeFactor > 1, "OSequenceOutputStream::OSequenceOutputStream : invalid resize factor !");
+ OSL_ENSURE((m_nMaximumResize < 0) || (m_nMaximumResize > m_nMinimumResize),
+ "OSequenceOutputStream::OSequenceOutputStream : these limits don't make any sense !");
+
+ if (m_nResizeFactor <= 1)
+ m_nResizeFactor = 1.3;
+ if ((m_nMaximumResize >= 0) && (m_nMaximumResize <= m_nMinimumResize))
+ m_nMaximumResize = m_nMinimumResize * 2;
+ // this heuristic is as good as any other ... supply better parameters if you don't like it :)
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rData ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ if (!m_bConnected)
+ throw NotConnectedException();
+
+ // ensure the sequence has enoungh space left
+ if (m_nSize + _rData.getLength() > m_rSequence.getLength())
+ {
+ sal_Int32 nCurrentLength = m_rSequence.getLength();
+ sal_Int32 nNewLength = static_cast< sal_Int32 >(
+ nCurrentLength * m_nResizeFactor);
+
+ if (m_nMinimumResize > nNewLength - nCurrentLength)
+ // we have a minimum so it's not too inefficient for small sequences and small write requests
+ nNewLength = nCurrentLength + m_nMinimumResize;
+
+ if ((m_nMaximumResize > 0) && (nNewLength - nCurrentLength > m_nMaximumResize))
+ // such a large step is not allowed
+ nNewLength = nCurrentLength + m_nMaximumResize;
+
+ if (nNewLength < m_nSize + _rData.getLength())
+ { // it's not enough .... the data would not fit
+
+ // let's take the double amount of the length of the data to be written, as the next write
+ // request could be as large as this one
+ sal_Int32 nNewGrowth = _rData.getLength() * 2;
+ if ((m_nMaximumResize > 0) && (nNewGrowth > m_nMaximumResize))
+ { // we came to the limit, again ...
+ nNewGrowth = m_nMaximumResize;
+ if (nNewGrowth + nCurrentLength < m_nSize + _rData.getLength())
+ // but it would not fit if we respect the limit
+ nNewGrowth = m_nSize + _rData.getLength() - nCurrentLength;
+ }
+ nNewLength = nCurrentLength + nNewGrowth;
+ }
+
+ // round it off to the next multiple of 4 ...
+ nNewLength = (nNewLength + 3) / 4 * 4;
+
+ m_rSequence.realloc(nNewLength);
+ }
+
+ OSL_ENSURE(m_rSequence.getLength() >= m_nSize + _rData.getLength(),
+ "ooops ... the realloc algorithm seems to be wrong :( !");
+
+ memcpy(m_rSequence.getArray() + m_nSize, _rData.getConstArray(), _rData.getLength());
+ m_nSize += _rData.getLength();
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OSequenceOutputStream::flush( ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ if (!m_bConnected)
+ throw NotConnectedException();
+
+ // cut the sequence to the real size
+ m_rSequence.realloc(m_nSize);
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OSequenceOutputStream::closeOutput( ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ if (!m_bConnected)
+ throw NotConnectedException();
+
+ // cut the sequence to the real size
+ m_rSequence.realloc(m_nSize);
+ // and don't allow any further accesses
+ m_bConnected = sal_False;
+}
+
+} // namespace comphelper
diff --git a/comphelper/source/streaming/streamsection.cxx b/comphelper/source/streaming/streamsection.cxx
new file mode 100644
index 000000000000..324299813986
--- /dev/null
+++ b/comphelper/source/streaming/streamsection.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <comphelper/streamsection.hxx>
+#include <osl/diagnose.h>
+
+namespace comphelper
+{
+
+//-------------------------------------------------------------------------
+OStreamSection::OStreamSection(const staruno::Reference< stario::XDataInputStream >& _rxInput)
+ :m_xMarkStream(_rxInput, ::com::sun::star::uno::UNO_QUERY)
+ ,m_xInStream(_rxInput)
+ ,m_nBlockStart(-1)
+ ,m_nBlockLen(-1)
+{
+ OSL_ENSURE(m_xInStream.is() && m_xMarkStream.is(), "OStreamSection::OStreamSection : invalid argument !");
+ if (m_xInStream.is() && m_xMarkStream.is())
+ {
+ m_nBlockLen = _rxInput->readLong();
+ m_nBlockStart = m_xMarkStream->createMark();
+ }
+}
+
+//-------------------------------------------------------------------------
+OStreamSection::OStreamSection(const staruno::Reference< stario::XDataOutputStream >& _rxOutput, sal_Int32 _nPresumedLength)
+ :m_xMarkStream(_rxOutput, ::com::sun::star::uno::UNO_QUERY)
+ ,m_xOutStream(_rxOutput)
+ ,m_nBlockStart(-1)
+ ,m_nBlockLen(-1)
+{
+ OSL_ENSURE(m_xOutStream.is() && m_xMarkStream.is(), "OStreamSection::OStreamSection : invalid argument !");
+ if (m_xOutStream.is() && m_xMarkStream.is())
+ {
+ m_nBlockStart = m_xMarkStream->createMark();
+ // a placeholder where we will write the overall length (within the destructor)
+ if (_nPresumedLength > 0)
+ m_nBlockLen = _nPresumedLength + sizeof(m_nBlockLen);
+ // as the caller did not consider - of course - the placeholder we are going to write
+ else
+ m_nBlockLen = 0;
+ m_xOutStream->writeLong(m_nBlockLen);
+ }
+}
+
+//-------------------------------------------------------------------------
+OStreamSection::~OStreamSection()
+{
+ try
+ { // don't allow any exceptions to leave this block, this may be called during the stack unwinding of an exception
+ // handling routing
+ if (m_xInStream.is() && m_xMarkStream.is())
+ { // we're working on an input stream
+ m_xMarkStream->jumpToMark(m_nBlockStart);
+ m_xInStream->skipBytes(m_nBlockLen);
+ m_xMarkStream->deleteMark(m_nBlockStart);
+ }
+ else if (m_xOutStream.is() && m_xMarkStream.is())
+ {
+ sal_Int32 nRealBlockLength = m_xMarkStream->offsetToMark(m_nBlockStart) - sizeof(m_nBlockLen);
+ if (m_nBlockLen && (m_nBlockLen == nRealBlockLength))
+ // nothing to do : the estimation the caller gave us (in the ctor) was correct
+ m_xMarkStream->deleteMark(m_nBlockStart);
+ else
+ { // the estimation was wrong (or we didn't get one)
+ m_nBlockLen = nRealBlockLength;
+ m_xMarkStream->jumpToMark(m_nBlockStart);
+ m_xOutStream->writeLong(m_nBlockLen);
+ m_xMarkStream->jumpToFurthest();
+ m_xMarkStream->deleteMark(m_nBlockStart);
+ }
+ }
+ }
+ catch(const staruno::Exception&)
+ {
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Int32 OStreamSection::available()
+{
+ sal_Int32 nBytes = 0;
+ try
+ { // don't allow any exceptions to leave this block, this may be called during the stack unwinding of an exception
+ if (m_xInStream.is() && m_xMarkStream.is())
+ nBytes = m_xMarkStream->offsetToMark(m_nBlockStart) - sizeof(m_nBlockLen);
+ }
+ catch(const staruno::Exception&)
+ {
+ }
+ return nBytes;
+}
+// -----------------------------------------------------------------------------
+
+} // namespace comphelper
+
+