diff options
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/source/streaming/otransactedfilestream.cxx | 868 |
1 files changed, 868 insertions, 0 deletions
diff --git a/comphelper/source/streaming/otransactedfilestream.cxx b/comphelper/source/streaming/otransactedfilestream.cxx new file mode 100644 index 000000000000..864b38f653f3 --- /dev/null +++ b/comphelper/source/streaming/otransactedfilestream.cxx @@ -0,0 +1,868 @@ +/************************************************************************* + * + * $RCSfile: otransactedfilestream.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: obo $ $Date: 2005-05-03 13:55:26 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#ifndef _COM_SUN_STAR_IO_XASYNCOUTPUTMONITOR_HPP_ +#include <com/sun/star/io/XAsyncOutputMonitor.hpp> +#endif +#ifndef _COM_SUN_STAR_EMBED_USEBACKUPEXCEPTION_HPP_ +#include <com/sun/star/embed/UseBackupException.hpp> +#endif + +#include <comphelper/otransactedfilestream.hxx> +#include <comphelper/storagehelper.hxx> + +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif + +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_xOrigInStream( xOrigInStream ) + , m_xOrigOutStream( xOrigOutStream ) + , m_xOrigTruncate( xOrigTruncate ) + , m_xOrigSeekable( xOrigSeekable ) + , m_xTempStream( xTempStream ) + , m_xTempInStream( xTempInStream ) + , m_xTempOutStream( xTempOutStream ) + , m_xTempTruncate( xTempTruncate ) + , m_xTempSeekable( xTempSeekable ) + , 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& aValue ) + 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& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::addVetoableChangeListener( const ::rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +} // namespace comphelper + |