| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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.isEmpty() ) |
| { |
| // 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 |
| |