diff options
Diffstat (limited to 'ucb/source/ucp/tdoc/tdoc_stgelems.cxx')
-rw-r--r-- | ucb/source/ucp/tdoc/tdoc_stgelems.cxx | 1108 |
1 files changed, 1108 insertions, 0 deletions
diff --git a/ucb/source/ucp/tdoc/tdoc_stgelems.cxx b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx new file mode 100644 index 000000000000..0bd25f94d096 --- /dev/null +++ b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx @@ -0,0 +1,1108 @@ +/************************************************************************* + * + * 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_ucb.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + - remove root storage access workaround + + *************************************************************************/ + +#include "com/sun/star/lang/DisposedException.hpp" +#include "com/sun/star/reflection/XProxyFactory.hpp" + +#include "tdoc_uri.hxx" + +#include "tdoc_stgelems.hxx" + +using namespace com::sun::star; +using namespace tdoc_ucp; + +//========================================================================= +//========================================================================= +// +// ParentStorageHolder Implementation. +// +//========================================================================= +//========================================================================= + +ParentStorageHolder::ParentStorageHolder( + const uno::Reference< embed::XStorage > & xParentStorage, + const rtl::OUString & rUri ) +: m_xParentStorage( xParentStorage ), + m_bParentIsRootStorage( false ) +{ + Uri aUri( rUri ); + if ( aUri.isDocument() ) + m_bParentIsRootStorage = true; +} + +//========================================================================= +//========================================================================= +// +// Storage Implementation. +// +//========================================================================= +//========================================================================= + +Storage::Storage( const uno::Reference< lang::XMultiServiceFactory > & xSMgr, + const rtl::Reference< StorageElementFactory > & xFactory, + const rtl::OUString & rUri, + const uno::Reference< embed::XStorage > & xParentStorage, + const uno::Reference< embed::XStorage > & xStorageToWrap ) +: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ), + m_xFactory( xFactory ), + m_xWrappedStorage( xStorageToWrap ), + m_xWrappedTransObj( xStorageToWrap, uno::UNO_QUERY ), // optional interface + m_xWrappedComponent( xStorageToWrap, uno::UNO_QUERY ), + m_xWrappedTypeProv( xStorageToWrap, uno::UNO_QUERY ), + m_bIsDocumentStorage( Uri( rUri ).isDocument() ) +{ + OSL_ENSURE( m_xWrappedStorage.is(), + "Storage::Storage: No storage to wrap!" ); + + OSL_ENSURE( m_xWrappedComponent.is(), + "Storage::Storage: No component to wrap!" ); + + OSL_ENSURE( m_xWrappedTypeProv.is(), + "Storage::Storage: No Type Provider!" ); + + // Use proxy factory service to create aggregatable proxy. + try + { + uno::Reference< reflection::XProxyFactory > xProxyFac( + xSMgr->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.reflection.ProxyFactory" ) ) ), + uno::UNO_QUERY ); + if ( xProxyFac.is() ) + { + m_xAggProxy = xProxyFac->createProxy( m_xWrappedStorage ); + } + } + catch ( uno::Exception const & ) + { + OSL_ENSURE( false, "Storage::Storage: Caught exception!" ); + } + + OSL_ENSURE( m_xAggProxy.is(), + "Storage::Storage: Wrapped storage cannot be aggregated!" ); + + if ( m_xAggProxy.is() ) + { + osl_incrementInterlockedCount( &m_refCount ); + { + // Solaris compiler problem: + // Extra block to enforce destruction of temporary object created + // in next statement _before_ osl_decrementInterlockedCount is + // called. Otherwise 'this' will destroy itself even before ctor + // is completed (See impl. of XInterface::release())! + + m_xAggProxy->setDelegator( + static_cast< cppu::OWeakObject * >( this ) ); + } + osl_decrementInterlockedCount( &m_refCount ); + } +} + +//========================================================================= +// virtual +Storage::~Storage() +{ + if ( m_xAggProxy.is() ) + m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() ); + + // Never dispose a document storage. Not owner! + if ( !isDocumentStorage() ) + { + if ( m_xWrappedComponent.is() ) + { + // "Auto-dispose"... + try + { + m_xWrappedComponent->dispose(); + } + catch ( lang::DisposedException const & ) + { + // might happen. + } + catch ( ... ) + { + OSL_ENSURE( false, "Storage::~Storage - Caught exception!" ); + } + } + } +} + +//========================================================================= +// +// uno::XInterface +// +//========================================================================= + +// virtual +uno::Any SAL_CALL Storage::queryInterface( const uno::Type& aType ) + throw ( uno::RuntimeException ) +{ + // First, try to use interfaces implemented by myself and base class(es) + uno::Any aRet = StorageUNOBase::queryInterface( aType ); + + if ( aRet.hasValue() ) + return aRet; + + // Try to use requested interface from aggregated storage + return m_xAggProxy->queryAggregation( aType ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::acquire() + throw () +{ + osl_incrementInterlockedCount( &m_refCount ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::release() + throw () +{ + if ( osl_decrementInterlockedCount( &m_refCount ) == 0 ) + { + m_xFactory->releaseElement( this ); + delete this; + } +} + +//========================================================================= +// +// lang::XTypeProvider +// +//========================================================================= + +// virtual +uno::Sequence< uno::Type > SAL_CALL Storage::getTypes() + throw ( uno::RuntimeException ) +{ + return m_xWrappedTypeProv->getTypes(); +} + +//========================================================================= +// virtual +uno::Sequence< sal_Int8 > SAL_CALL Storage::getImplementationId() + throw ( uno::RuntimeException ) +{ + return m_xWrappedTypeProv->getImplementationId(); +} + +//========================================================================= +// +// lang::XComponent (base of embed::XStorage) +// +//========================================================================= +// virtual +void SAL_CALL Storage::dispose() + throw ( uno::RuntimeException ) +{ + m_xWrappedStorage->dispose(); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::addEventListener( + const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + m_xWrappedStorage->addEventListener( xListener ); +} +//========================================================================= +// virtual +void SAL_CALL Storage::removeEventListener( + const uno::Reference< lang::XEventListener >& aListener ) + throw (uno::RuntimeException) +{ + m_xWrappedStorage->removeEventListener( aListener ); +} + +//========================================================================= +// +// container::XElementAccess (base of container::XNameAccess) +// +//========================================================================= + +// virtual +uno::Type SAL_CALL Storage::getElementType() + throw ( uno::RuntimeException ) +{ + return m_xWrappedStorage->getElementType(); +} + +//========================================================================= +// virtual +::sal_Bool SAL_CALL Storage::hasElements() + throw ( uno::RuntimeException ) +{ + return m_xWrappedStorage->hasElements(); +} + +//========================================================================= +// +// container::XNameAccess (base of embed::XStorage) +// +//========================================================================= + +// virtual +uno::Any SAL_CALL Storage::getByName( const ::rtl::OUString& aName ) + throw ( container::NoSuchElementException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->getByName( aName ); +} + +//========================================================================= +// virtual +uno::Sequence< ::rtl::OUString > SAL_CALL Storage::getElementNames() + throw ( uno::RuntimeException ) +{ + return m_xWrappedStorage->getElementNames(); +} + +//========================================================================= +// virtual +::sal_Bool SAL_CALL Storage::hasByName( const ::rtl::OUString& aName ) + throw ( uno::RuntimeException ) +{ + return m_xWrappedStorage->hasByName( aName ); +} + +//========================================================================= +// +// embed::XStorage +// +//========================================================================= + +// virtual +void SAL_CALL Storage::copyToStorage( + const uno::Reference< embed::XStorage >& xDest ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + m_xWrappedStorage->copyToStorage( xDest ); +} + +//========================================================================= +// virtual +uno::Reference< io::XStream > SAL_CALL Storage::openStreamElement( + const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->openStreamElement( aStreamName, nOpenMode ); +} + +//========================================================================= +// virtual +uno::Reference< io::XStream > SAL_CALL Storage::openEncryptedStreamElement( + const ::rtl::OUString& aStreamName, + sal_Int32 nOpenMode, + const ::rtl::OUString& aPassword ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->openEncryptedStreamElement( + aStreamName, nOpenMode, aPassword ); +} + +//========================================================================= +// virtual +uno::Reference< embed::XStorage > SAL_CALL Storage::openStorageElement( + const ::rtl::OUString& aStorName, sal_Int32 nOpenMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->openStorageElement( aStorName, nOpenMode ); +} + +//========================================================================= +// virtual +uno::Reference< io::XStream > SAL_CALL Storage::cloneStreamElement( + const ::rtl::OUString& aStreamName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->cloneStreamElement( aStreamName ); +} + +//========================================================================= +// virtual +uno::Reference< io::XStream > SAL_CALL Storage::cloneEncryptedStreamElement( + const ::rtl::OUString& aStreamName, + const ::rtl::OUString& aPassword ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->cloneEncryptedStreamElement( aStreamName, + aPassword ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::copyLastCommitTo( + const uno::Reference< embed::XStorage >& xTargetStorage ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException) +{ + m_xWrappedStorage->copyLastCommitTo( xTargetStorage ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::copyStorageElementLastCommitTo( + const ::rtl::OUString& aStorName, + const uno::Reference< embed::XStorage >& xTargetStorage ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException) +{ + m_xWrappedStorage->copyStorageElementLastCommitTo( aStorName, xTargetStorage ); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL Storage::isStreamElement( + const ::rtl::OUString& aElementName ) + throw ( container::NoSuchElementException, + lang::IllegalArgumentException, + embed::InvalidStorageException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->isStreamElement( aElementName ); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL Storage::isStorageElement( + const ::rtl::OUString& aElementName ) + throw ( container::NoSuchElementException, + lang::IllegalArgumentException, + embed::InvalidStorageException, + uno::RuntimeException ) +{ + return m_xWrappedStorage->isStorageElement( aElementName ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::removeElement( const ::rtl::OUString& aElementName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + m_xWrappedStorage->removeElement( aElementName ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::renameElement( const ::rtl::OUString& aEleName, + const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + m_xWrappedStorage->renameElement( aEleName, aNewName ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::copyElementTo( + const ::rtl::OUString& aElementName, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + m_xWrappedStorage->copyElementTo( aElementName, xDest, aNewName ); +} + +//========================================================================= +// virtual +void SAL_CALL Storage::moveElementTo( + const ::rtl::OUString& aElementName, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& rNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + m_xWrappedStorage->moveElementTo( aElementName, xDest, rNewName ); +} + +//========================================================================= +// +// embed::XTransactedObject +// +//========================================================================= + +// virtual +void SAL_CALL Storage::commit() + throw ( io::IOException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + // Never commit a root storage (-> has no parent)! + // Would lead in writing the whole document to disk. + + uno::Reference< embed::XStorage > xParentStorage = getParentStorage(); + if ( xParentStorage.is() ) + { + OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" ); + + if ( m_xWrappedTransObj.is() ) + { + m_xWrappedTransObj->commit(); + + if ( !isParentARootStorage() ) + { + uno::Reference< embed::XTransactedObject > xParentTA( + xParentStorage, uno::UNO_QUERY ); + OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" ); + + if ( xParentTA.is() ) + xParentTA->commit(); + } + } + } +} + +//========================================================================= +// virtual +void SAL_CALL Storage::revert() + throw ( io::IOException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + uno::Reference< embed::XStorage > xParentStorage = getParentStorage(); + if ( xParentStorage.is() ) + { + OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" ); + + if ( m_xWrappedTransObj.is() ) + { + m_xWrappedTransObj->revert(); + + if ( !isParentARootStorage() ) + { + uno::Reference< embed::XTransactedObject > xParentTA( + xParentStorage, uno::UNO_QUERY ); + OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" ); + + if ( xParentTA.is() ) + xParentTA->revert(); + } + } + } +} + +//========================================================================= +//========================================================================= +// +// OutputStream Implementation. +// +//========================================================================= +//========================================================================= + +OutputStream::OutputStream( + const uno::Reference< lang::XMultiServiceFactory > & xSMgr, + const rtl::OUString & rUri, + const uno::Reference< embed::XStorage > & xParentStorage, + const uno::Reference< io::XOutputStream > & xStreamToWrap ) +: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ), + m_xWrappedStream( xStreamToWrap ), + m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ), + m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY ) +{ + OSL_ENSURE( m_xWrappedStream.is(), + "OutputStream::OutputStream: No stream to wrap!" ); + + OSL_ENSURE( m_xWrappedComponent.is(), + "OutputStream::OutputStream: No component to wrap!" ); + + OSL_ENSURE( m_xWrappedTypeProv.is(), + "OutputStream::OutputStream: No Type Provider!" ); + + // Use proxy factory service to create aggregatable proxy. + try + { + uno::Reference< reflection::XProxyFactory > xProxyFac( + xSMgr->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.reflection.ProxyFactory" ) ) ), + uno::UNO_QUERY ); + if ( xProxyFac.is() ) + { + m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream ); + } + } + catch ( uno::Exception const & ) + { + OSL_ENSURE( false, "OutputStream::OutputStream: Caught exception!" ); + } + + OSL_ENSURE( m_xAggProxy.is(), + "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" ); + + if ( m_xAggProxy.is() ) + { + osl_incrementInterlockedCount( &m_refCount ); + { + // Solaris compiler problem: + // Extra block to enforce destruction of temporary object created + // in next statement _before_ osl_decrementInterlockedCount is + // called. Otherwise 'this' will destroy itself even before ctor + // is completed (See impl. of XInterface::release())! + + m_xAggProxy->setDelegator( + static_cast< cppu::OWeakObject * >( this ) ); + } + osl_decrementInterlockedCount( &m_refCount ); + } +} + +//========================================================================= +// virtual +OutputStream::~OutputStream() +{ + if ( m_xAggProxy.is() ) + m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() ); +} + +//========================================================================= +// +// uno::XInterface +// +//========================================================================= + +// virtual +uno::Any SAL_CALL OutputStream::queryInterface( const uno::Type& aType ) + throw ( uno::RuntimeException ) +{ + uno::Any aRet = OutputStreamUNOBase::queryInterface( aType ); + + if ( aRet.hasValue() ) + return aRet; + + if ( m_xAggProxy.is() ) + return m_xAggProxy->queryAggregation( aType ); + else + return uno::Any(); +} + +//========================================================================= +// +// lang::XTypeProvider +// +//========================================================================= + +// virtual +uno::Sequence< uno::Type > SAL_CALL OutputStream::getTypes() + throw ( uno::RuntimeException ) +{ + return m_xWrappedTypeProv->getTypes(); +} + +//========================================================================= +// virtual +uno::Sequence< sal_Int8 > SAL_CALL OutputStream::getImplementationId() + throw ( uno::RuntimeException ) +{ + return m_xWrappedTypeProv->getImplementationId(); +} + +//========================================================================= +// +// io::XOutputStream +// +//========================================================================= + +// virtual +void SAL_CALL +OutputStream::writeBytes( const uno::Sequence< sal_Int8 >& aData ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + m_xWrappedStream->writeBytes( aData ); +} + +//========================================================================= +// virtual +void SAL_CALL +OutputStream::flush() + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + m_xWrappedStream->flush(); +} + +//========================================================================= +// virtual +void SAL_CALL +OutputStream::closeOutput( ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + m_xWrappedStream->closeOutput(); + + // Release parent storage. + // Now, that the stream is closed/disposed it is not needed any longer. + setParentStorage( uno::Reference< embed::XStorage >() ); +} + +//========================================================================= +// +// lang::XComponent +// +//========================================================================= + +// virtual +void SAL_CALL +OutputStream::dispose() + throw ( uno::RuntimeException ) +{ + m_xWrappedComponent->dispose(); + + // Release parent storage. + // Now, that the stream is closed/disposed it is not needed any longer. + setParentStorage( uno::Reference< embed::XStorage >() ); +} + +//========================================================================= +// virtual +void SAL_CALL +OutputStream::addEventListener( + const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + m_xWrappedComponent->addEventListener( xListener ); +} + +//========================================================================= +// virtual +void SAL_CALL +OutputStream::removeEventListener( + const uno::Reference< lang::XEventListener >& aListener ) + throw ( uno::RuntimeException ) +{ + m_xWrappedComponent->removeEventListener( aListener ); +} + +//========================================================================= +//========================================================================= +// +// Stream Implementation. +// +//========================================================================= +//========================================================================= + +Stream::Stream( + const uno::Reference< lang::XMultiServiceFactory > & xSMgr, + const rtl::OUString & rUri, + const uno::Reference< embed::XStorage > & xParentStorage, + const uno::Reference< io::XStream > & xStreamToWrap ) +: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ), + m_xWrappedStream( xStreamToWrap ), + m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty + m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be empty + m_xWrappedInputStream( xStreamToWrap->getInputStream(), uno::UNO_QUERY ), + m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ), + m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY ) +{ + OSL_ENSURE( m_xWrappedStream.is(), + "OutputStream::OutputStream: No stream to wrap!" ); + + OSL_ENSURE( m_xWrappedComponent.is(), + "OutputStream::OutputStream: No component to wrap!" ); + + OSL_ENSURE( m_xWrappedTypeProv.is(), + "OutputStream::OutputStream: No Type Provider!" ); + + // Use proxy factory service to create aggregatable proxy. + try + { + uno::Reference< reflection::XProxyFactory > xProxyFac( + xSMgr->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.reflection.ProxyFactory" ) ) ), + uno::UNO_QUERY ); + if ( xProxyFac.is() ) + { + m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream ); + } + } + catch ( uno::Exception const & ) + { + OSL_ENSURE( false, "OutputStream::OutputStream: Caught exception!" ); + } + + OSL_ENSURE( m_xAggProxy.is(), + "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" ); + + if ( m_xAggProxy.is() ) + { + osl_incrementInterlockedCount( &m_refCount ); + { + // Solaris compiler problem: + // Extra block to enforce destruction of temporary object created + // in next statement _before_ osl_decrementInterlockedCount is + // called. Otherwise 'this' will destroy itself even before ctor + // is completed (See impl. of XInterface::release())! + + m_xAggProxy->setDelegator( + static_cast< cppu::OWeakObject * >( this ) ); + } + osl_decrementInterlockedCount( &m_refCount ); + } +} + +//========================================================================= +// virtual +Stream::~Stream() +{ + if ( m_xAggProxy.is() ) + m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() ); +} + +//========================================================================= +// +// uno::XInterface +// +//========================================================================= + +// virtual +uno::Any SAL_CALL Stream::queryInterface( const uno::Type& aType ) + throw ( uno::RuntimeException ) +{ + uno::Any aRet = StreamUNOBase::queryInterface( aType ); + + if ( aRet.hasValue() ) + return aRet; + + if ( m_xAggProxy.is() ) + return m_xAggProxy->queryAggregation( aType ); + else + return uno::Any(); +} + +//========================================================================= +// +// lang::XTypeProvider +// +//========================================================================= + +// virtual +uno::Sequence< uno::Type > SAL_CALL Stream::getTypes() + throw ( uno::RuntimeException ) +{ + return m_xWrappedTypeProv->getTypes(); +} + +//========================================================================= +// virtual +uno::Sequence< sal_Int8 > SAL_CALL Stream::getImplementationId() + throw ( uno::RuntimeException ) +{ + return m_xWrappedTypeProv->getImplementationId(); +} + +//========================================================================= +// +// io::XStream. +// +//========================================================================= + +// virtual +uno::Reference< io::XInputStream > SAL_CALL Stream::getInputStream() + throw( uno::RuntimeException ) +{ + return uno::Reference< io::XInputStream >( this ); +} + +//========================================================================= +// virtual +uno::Reference< io::XOutputStream > SAL_CALL Stream::getOutputStream() + throw( uno::RuntimeException ) +{ + return uno::Reference< io::XOutputStream >( this ); +} + +//========================================================================= +// +// io::XOutputStream. +// +//========================================================================= + +// virtual +void SAL_CALL Stream::writeBytes( const uno::Sequence< sal_Int8 >& aData ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + if ( m_xWrappedOutputStream.is() ) + { + m_xWrappedOutputStream->writeBytes( aData ); + commitChanges(); + } +} + +//========================================================================= +// virtual +void SAL_CALL Stream::flush() + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + if ( m_xWrappedOutputStream.is() ) + { + m_xWrappedOutputStream->flush(); + commitChanges(); + } +} + +//========================================================================= +// virtual +void SAL_CALL Stream::closeOutput() + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + if ( m_xWrappedOutputStream.is() ) + { + m_xWrappedOutputStream->closeOutput(); + commitChanges(); + } + + // Release parent storage. + // Now, that the stream is closed/disposed it is not needed any longer. + setParentStorage( uno::Reference< embed::XStorage >() ); +} + +//========================================================================= +// +// io::XTruncate. +// +//========================================================================= + +// virtual +void SAL_CALL Stream::truncate() + throw( io::IOException, + uno::RuntimeException ) +{ + if ( m_xWrappedTruncate.is() ) + { + m_xWrappedTruncate->truncate(); + commitChanges(); + } +} + +//========================================================================= +// +// io::XInputStream. +// +//========================================================================= + +// virtual +sal_Int32 SAL_CALL Stream::readBytes( uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + return m_xWrappedInputStream->readBytes( aData, nBytesToRead ); +} + +//========================================================================= +// virtual +sal_Int32 SAL_CALL Stream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + return m_xWrappedInputStream->readSomeBytes( aData, nMaxBytesToRead ); +} + +//========================================================================= +// virtual +void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + m_xWrappedInputStream->skipBytes( nBytesToSkip ); +} + +//========================================================================= +// virtual +sal_Int32 SAL_CALL Stream::available() + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + return m_xWrappedInputStream->available(); +} + +//========================================================================= +// virtual +void SAL_CALL Stream::closeInput() + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + m_xWrappedInputStream->closeInput(); +} + +//========================================================================= +// +// lang::XComponent +// +//========================================================================= + +// virtual +void SAL_CALL Stream::dispose() + throw ( uno::RuntimeException ) +{ + m_xWrappedComponent->dispose(); + + // Release parent storage. + // Now, that the stream is closed/disposed it is not needed any longer. + setParentStorage( uno::Reference< embed::XStorage >() ); +} + +//========================================================================= +// virtual +void SAL_CALL Stream::addEventListener( + const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + m_xWrappedComponent->addEventListener( xListener ); +} + +//========================================================================= +// virtual +void SAL_CALL Stream::removeEventListener( + const uno::Reference< lang::XEventListener >& aListener ) + throw ( uno::RuntimeException ) +{ + m_xWrappedComponent->removeEventListener( aListener ); +} + +//========================================================================= +// +// Non-UNO +// +//========================================================================= + +void Stream::commitChanges() + throw( io::IOException ) +{ + uno::Reference< embed::XTransactedObject > + xParentTA( getParentStorage(), uno::UNO_QUERY ); + OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" ); + + if ( xParentTA.is() ) + { + try + { + xParentTA->commit(); + } + catch ( lang::WrappedTargetException const & ) + { + throw io::IOException(); // @@@ + } + } +} + |