diff options
author | Mathias Bauer <mba@openoffice.org> | 2000-09-27 11:27:08 +0000 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2000-09-27 11:27:08 +0000 |
commit | a5466b60814d933098accd2221dc1240b7458a96 (patch) | |
tree | 4d6ada01bdf53c3800f756b3caed7c0a1376e716 /unotools | |
parent | 1bb0e3c36397a092dd9ed5b8b52f19a1325546df (diff) |
new class for stream access using ucb
Diffstat (limited to 'unotools')
-rw-r--r-- | unotools/inc/unotools/ucblockbytes.hxx | 128 | ||||
-rw-r--r-- | unotools/source/ucbhelper/ucblockbytes.cxx | 516 |
2 files changed, 644 insertions, 0 deletions
diff --git a/unotools/inc/unotools/ucblockbytes.hxx b/unotools/inc/unotools/ucblockbytes.hxx new file mode 100644 index 000000000000..60b28cc8ff30 --- /dev/null +++ b/unotools/inc/unotools/ucblockbytes.hxx @@ -0,0 +1,128 @@ +#ifndef _UNTOOLS_UCBLOCKBYTES_HXX +#define _UNTOOLS_UCBLOCKBYTES_HXX + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif +#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_ +#include <com/sun/star/io/XInputStream.hpp> +#endif +#ifndef _COM_SUN_STAR_UCB_XCONTENT_HPP_ +#include <com/sun/star/ucb/XContent.hpp> +#endif + +#include <vos/thread.hxx> +#include <vos/conditn.hxx> +#include <vos/mutex.hxx> +#include <tools/stream.hxx> +#include <tools/link.hxx> + +class UCB_Link_Helper : public SvRefBase +{ + ::vos::OMutex maMutex; + + Link maDoneLink; + Link maDataAvailLink; + Link maCancelLink; + + BOOL mbSet; + + ~UCB_Link_Helper(){;} +public: + UCB_Link_Helper() + { mbSet = FALSE;} + + void SetDoneLink( const Link& rLink ); + void SetDataAvailLink( const Link& rLink ); + void SetCancelLink( const Link& rLink ); + + void Done(); + void DataAvail(); + void Cancel(); + + void Clear(); +}; + +SV_DECL_IMPL_REF( UCB_Link_Helper ) + +#define NS_UNO ::com::sun::star::uno +#define NS_IO ::com::sun::star::io +#define NS_UCB ::com::sun::star::ucb + +SV_DECL_REF( UcbLockBytes ); + + +class CommandThread_Impl; +class UcbLockBytes : public virtual SvLockBytes +{ + vos::OCondition m_aInitialized; + vos::OCondition m_aTerminated; + vos::OMutex m_aMutex; + NS_UNO::Reference < NS_IO::XInputStream > m_xInputStream; + CommandThread_Impl* m_pCommandThread; + + sal_Bool m_bTerminated; + sal_Bool m_bDontClose; + + sal_uInt32 m_nRead; + sal_uInt32 m_nSize; + + UCB_Link_HelperRef m_aLinkList; + + DECL_LINK( DataAvailHdl, void * ); + +protected: + virtual ~UcbLockBytes (void); + +public: + + static UcbLockBytesRef CreateInputLockBytes( NS_UNO::Reference < NS_UCB::XContent > xContent, UCB_Link_HelperRef xLinkList ); + + UcbLockBytes( UCB_Link_HelperRef xLink ) + : m_xInputStream (NULL) + , m_pCommandThread( NULL ) + , m_bTerminated (sal_False) + , m_bDontClose( sal_False ) + , m_nRead (0) + , m_nSize (0) + , m_aLinkList( xLink ) + {} + + // SvLockBytes + virtual void SetSynchronMode (BOOL bSynchron); + virtual ErrCode ReadAt ( ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const; + virtual ErrCode WriteAt ( ULONG, const void*, ULONG, ULONG *pWritten); + virtual ErrCode Flush (void) const; + virtual ErrCode SetSize (ULONG); + virtual ErrCode Stat ( SvLockBytesStat *pStat, SvLockBytesStatFlag) const; + + void Cancel(); + +#if __PRIVATE + sal_Bool setInputStream_Impl( const NS_UNO::Reference < NS_IO::XInputStream > &rxInputStream ); + void terminate_Impl (void); + + NS_UNO::Reference < NS_IO::XInputStream > getInputStream_Impl() const + { + vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex ); + return m_xInputStream; + } + + sal_Bool hasInputStream_Impl() const + { + vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex ); + return m_xInputStream.is(); + } + + void setCommandThread_Impl( CommandThread_Impl* pThread ) + { m_pCommandThread = pThread; } + + void setDontClose_Impl() + { m_bDontClose = sal_True; } +#endif +}; + +//---------------------------------------------------------------------------- +SV_IMPL_REF( UcbLockBytes ); + +#endif diff --git a/unotools/source/ucbhelper/ucblockbytes.cxx b/unotools/source/ucbhelper/ucblockbytes.cxx new file mode 100644 index 000000000000..ccd2d369c4fc --- /dev/null +++ b/unotools/source/ucbhelper/ucblockbytes.cxx @@ -0,0 +1,516 @@ +#include "unotools/ucblockbytes.hxx" + +#ifndef _COM_SUN_STAR_UCB_XCOMMANDINFO_HPP_ +#include <com/sun/star/ucb/XCommandInfo.hpp> +#endif +#ifndef _COM_SUN_STAR_UCB_XCOMMANDPROCESSOR_HPP_ +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#endif +#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_ +#include <com/sun/star/task/XInteractionHandler.hpp> +#endif +#ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_ +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#endif +#ifndef _COM_SUN_STAR_CHAOS_OPENMODE_HPP_ +#include <com/sun/star/chaos/OpenMode.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_PROPERTY_HPP_ +#include <com/sun/star/beans/Property.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_ +#include <com/sun/star/beans/PropertyValue.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTIESCHANGENOTIFIER_HPP_ +#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp> +#endif +#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_ +#include <com/sun/star/sdbc/XRow.hpp> +#endif +#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_ +#include <com/sun/star/io/XActiveDataSink.hpp> +#endif +#ifndef _COM_SUN_STAR_IO_XACTIVEDATACONTROL_HPP_ +#include <com/sun/star/io/XActiveDataControl.hpp> +#endif +#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_ +#include <com/sun/star/io/XSeekable.hpp> +#endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE2_HXX_ +#include <cppuhelper/implbase2.hxx> +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif + +#include <ucbhelper/content.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::chaos; +using namespace ::com::sun::star::lang; + +class ProgressHandler_Impl: public cppu::OWeakObject, public XProgressHandler +{ + Link m_aProgress; + +public: + ProgressHandler_Impl() {} + + void SetProgressLink( const Link& rLink ) + { m_aProgress = rLink; } + + virtual Any SAL_CALL queryInterface( const Type & rType ) + throw (RuntimeException); + + virtual void SAL_CALL acquire() throw (RuntimeException) + { OWeakObject::acquire(); } + + virtual void SAL_CALL release() throw (RuntimeException) + { OWeakObject::release(); } + + virtual void SAL_CALL push(const Any & rStatus) throw (RuntimeException); + + virtual void SAL_CALL update(const Any & rStatus) + throw (RuntimeException); + + virtual void SAL_CALL pop() throw (RuntimeException); +}; + +//---------------------------------------------------------------------------- +Any SAL_CALL ProgressHandler_Impl::queryInterface( const Type & rType ) throw (RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, + static_cast< XProgressHandler* >( this ))); + + if ( aRet.hasValue() ) + return aRet ; + else + return OWeakObject::queryInterface( rType ); +} + +//---------------------------------------------------------------------------- +void SAL_CALL ProgressHandler_Impl::push( const Any & rStatus ) throw (RuntimeException) +{ +} + +//---------------------------------------------------------------------------- +void SAL_CALL ProgressHandler_Impl::update( const Any & rStatus ) throw (RuntimeException) +{ + if ( m_aProgress.IsSet() ) + m_aProgress.Call( 0 ); +} + +//---------------------------------------------------------------------------- +void SAL_CALL ProgressHandler_Impl::pop() throw (RuntimeException) +{ +} + +class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment > +{ + Reference< XInteractionHandler > m_xInteractionHandler; + Reference< XProgressHandler > m_xProgressHandler; + +public: + UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler, + const Reference< XProgressHandler>& rxProgressHandler ); + + virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException) + { return m_xInteractionHandler; } + + virtual Reference<XProgressHandler> SAL_CALL getProgressHandler() throw (RuntimeException) + { return m_xProgressHandler; } +}; + +class CommandThread_Impl : public ::vos::OThread +{ + Reference< XInteractionHandler > m_xInteract; + Reference< XProgressHandler > m_xProgress; + ::ucb::Content m_aContent; + + OpenCommandArgument2 m_aArgument; + UcbLockBytesRef m_xLockBytes; + UCB_Link_HelperRef m_xLink; + sal_Bool m_bCanceled : 1; + sal_Bool m_bRunning : 1; + sal_Bool m_bSimple : 1; + +public: + CommandThread_Impl( Reference < XContent > xContent, + const OpenCommandArgument2& rArg, + Reference < XInteractionHandler > xInteract, + Reference < XProgressHandler > xProgress, + UCB_Link_HelperRef xLink ) + : m_xInteract( xInteract ) + , m_xProgress( xProgress ) + , m_aContent( xContent, new UcbTaskEnvironment( m_xInteract, m_xProgress ) ) + , m_aArgument( rArg ) + , m_xLink( xLink ) + , m_bCanceled( sal_False ) + , m_bRunning( sal_False ) + , m_bSimple( sal_False ) + {} + + virtual void SAL_CALL onTerminated(); + virtual void SAL_CALL run(); + void Cancel(); +}; + +//---------------------------------------------------------------------------- +void CommandThread_Impl::run() +{ + if ( m_bSimple ) + { + m_bRunning = sal_True; + m_xLockBytes->terminate_Impl(); + m_bRunning = sal_False; + return; + } + + m_bRunning = sal_True; + + if( !m_bCanceled && schedule() ) + { + Any aParam; + aParam <<= m_aArgument; + Any aResult; + bool bException = false; + bool bAborted = false; + + try + { + aResult = m_aContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("open") ), aParam ); + } + catch ( CommandAbortedException ) + { + bAborted = true; + } + catch ( Exception ) + { + bException = true; + } + + if ( bAborted || bException ) + { + if( m_xLink.Is() ) + m_xLink->Cancel(); + + Reference < XInputStream > aDummy; + Reference < XActiveDataSink > ::query(m_aArgument.Sink)->setInputStream( aDummy ); + } + + Reference < XActiveDataControl > ::query(m_aArgument.Sink)->terminate(); + } + + m_bRunning = sal_False; +} + +//---------------------------------------------------------------------------- +void CommandThread_Impl::onTerminated() +{ + delete this; +} + +//---------------------------------------------------------------------------- +void CommandThread_Impl::Cancel() +{ + if ( m_bCanceled ) + return; + + m_bCanceled = sal_True; + + if ( m_bRunning && !m_bSimple ) + { + m_aContent.abortCommand(); + m_bRunning = sal_False; + } +} + +//---------------------------------------------------------------------------- +UcbLockBytes::~UcbLockBytes() +{ + if ( !m_bDontClose && m_xInputStream.is() ) + m_xInputStream->closeInput(); +} + +//---------------------------------------------------------------------------- +sal_Bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream ) +{ + BOOL bRet; + + vos::OClearableGuard aGuard( m_aMutex ); + + if ( !m_bDontClose && m_xInputStream.is() ) + m_xInputStream->closeInput(); + + m_xInputStream = rxInputStream; + bRet = m_xInputStream.is(); + aGuard.clear(); + + m_aInitialized.set(); + + return bRet; +} + +//---------------------------------------------------------------------------- +void UcbLockBytes::terminate_Impl() +{ + m_pCommandThread = NULL; + + Reference<XInputStream> xStream = getInputStream_Impl(); + Reference<XSeekable> xSeekable (xStream, UNO_QUERY); + + if ( xSeekable.is() ) + m_nSize = sal_uInt32(xSeekable->getLength()); + + m_bTerminated = sal_True; + + m_aInitialized.set(); + m_aTerminated.set(); + + m_aLinkList->Done(); +} + +//---------------------------------------------------------------------------- +void UcbLockBytes::SetSynchronMode (BOOL bSynchron) +{ + SvLockBytes::SetSynchronMode (bSynchron); +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::ReadAt ( ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const +{ + Reference<XInputStream> xStream = getInputStream_Impl(); + + if ( !xStream.is() ) + { + if ( m_bTerminated ) + return ERRCODE_IO_CANTREAD; + else + return ERRCODE_IO_PENDING; + } + + if ( pRead ) + *pRead = 0; + + Reference < XSeekable > xSeekable( xStream, UNO_QUERY ); + if ( !xSeekable.is() ) + return ERRCODE_IO_CANTREAD; + + try + { + xSeekable->seek( nPos ); + } + catch ( IOException ) + { + return ERRCODE_IO_CANTSEEK; + } + + Sequence<sal_Int8> aData; + sal_Int32 nSize; + + nCount = VOS_MIN(nCount, 0x7FFFFFFF); + try + { + if ( !m_bTerminated && !IsSynchronMode() ) + { + sal_Int64 nLen = xSeekable->getLength(); + if ( nPos + nCount > nLen ) + return ERRCODE_IO_PENDING; + } + + nSize = xStream->readBytes( aData, sal_Int32(nCount) ); + } + catch (IOException) + { + return ERRCODE_IO_CANTREAD; + } + + rtl_copyMemory (pBuffer, aData.getConstArray(), nSize); + if (pRead) + *pRead = ULONG(nSize); + + sal_uInt32 nRead = VOS_MAX(m_nRead, nPos + nSize); + SAL_CONST_CAST(UcbLockBytes*, this)->m_nRead = nRead; + + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::WriteAt ( ULONG, const void*, ULONG, ULONG *pWritten) +{ + if ( pWritten ) + *pWritten = 0; + return ERRCODE_IO_CANTWRITE; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::Flush (void) const +{ + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::SetSize (ULONG) +{ + return ERRCODE_IO_NOTSUPPORTED; +} + +//---------------------------------------------------------------------------- +ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const +{ + if (!pStat) + return ERRCODE_IO_INVALIDPARAMETER; + + Reference<XInputStream> xStream = getInputStream_Impl(); + + if (!xStream.is()) + return ERRCODE_IO_INVALIDACCESS; + + Reference<XSeekable> xSeekable (xStream, UNO_QUERY); + if (!xSeekable.is()) + return ERRCODE_IO_INVALIDACCESS; + + try + { + pStat->nSize = ULONG(xSeekable->getLength()); + } + catch (IOException) + { + return ERRCODE_IO_CANTTELL; + } + + if (!m_bTerminated) + return ERRCODE_IO_PENDING; + else + return ERRCODE_NONE; +} + +//---------------------------------------------------------------------------- +void UcbLockBytes::Cancel() +{ + if ( m_bTerminated ) + return; + + if ( m_pCommandThread ) + { + m_pCommandThread->Cancel(); + m_pCommandThread = NULL; + } +} + +//---------------------------------------------------------------------------- +IMPL_LINK( UcbLockBytes, DataAvailHdl, void*, EMPTYARG ) +{ + if ( hasInputStream_Impl() ) + m_aLinkList->DataAvail(); + + return 0; +} + +//---------------------------------------------------------------------------- +// class UcbDataSink_Impl +//---------------------------------------------------------------------------- +class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink > +{ + UcbLockBytesRef m_xLockBytes; + +public: + UcbDataSink_Impl( UcbLockBytes* pLockBytes ) + : m_xLockBytes( pLockBytes ) + {} + + SvLockBytes* getLockBytes (void) + { return m_xLockBytes; } + + // XActiveDataControl. + virtual void SAL_CALL addListener ( const Reference<XStreamListener> &rxListener) throw(RuntimeException); + virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &rxListener) throw(RuntimeException); + virtual void SAL_CALL start (void) throw(RuntimeException); + virtual void SAL_CALL terminate (void) throw(RuntimeException); + + // XActiveDataSink. + virtual void SAL_CALL setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException); + virtual Reference<XInputStream> SAL_CALL getInputStream (void) throw(RuntimeException); +}; + +void SAL_CALL UcbDataSink_Impl::addListener ( const Reference<XStreamListener> &rxListener) throw(RuntimeException) +{ + // not supported +} + +void SAL_CALL UcbDataSink_Impl::removeListener ( const Reference<XStreamListener> &rxListener) throw(RuntimeException) +{ + // not supported +} + +void SAL_CALL UcbDataSink_Impl::start (void) throw(RuntimeException) +{ +} + +void SAL_CALL UcbDataSink_Impl::terminate (void) throw(RuntimeException) +{ + m_xLockBytes->terminate_Impl(); +} + +void SAL_CALL UcbDataSink_Impl::setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException) +{ + m_xLockBytes->setInputStream_Impl (rxInputStream); +} + +Reference<XInputStream> SAL_CALL UcbDataSink_Impl::getInputStream (void) throw(RuntimeException) +{ + return m_xLockBytes->getInputStream_Impl(); +} + +//------------------------------------------------------------------------- +UcbTaskEnvironment::UcbTaskEnvironment( const Reference< XInteractionHandler >& rxInteractionHandler, + const Reference< XProgressHandler >& rxProgressHandler ) + : m_xInteractionHandler( rxInteractionHandler ) + , m_xProgressHandler( rxProgressHandler ) +{ +} + +UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( Reference < XContent > xContent, UCB_Link_HelperRef xLink ) +{ + if( !xContent.is() ) + return NULL;; +/* + Reference<XPropertiesChangeNotifier> xProps ( xContent, UNO_QUERY ); + if ( xProps.is() ) + { + m_aContentType = getContentType_Impl (xProps); + if( !m_aContentType.Len() ) + m_aContentType = CONTENT_TYPE_STR_APP_OCTSTREAM; + m_bMimeAvail = sal_True; + xProps->addPropertiesChangeListener ( Sequence< OUString >(), this ); + } +*/ + Reference< XMultiServiceFactory > xFactory = ::utl::getProcessServiceFactory(); + Reference< XInteractionHandler > xInteractionHandler = Reference< XInteractionHandler > ( + xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY ); + + OpenCommandArgument2 aArgument; + String aCmd( RTL_CONSTASCII_USTRINGPARAM( "Open" ) ); + UcbLockBytesRef xLockBytes = new UcbLockBytes( xLink ); + Reference < XActiveDataSink > xSink = new UcbDataSink_Impl( xLockBytes ); + aArgument.Sink = xSink; + aArgument.Mode = OpenMode::DOCUMENT; + + ProgressHandler_Impl *pProgressHdl = new ProgressHandler_Impl(); + Reference< XProgressHandler > xProgressHdl = pProgressHdl; + pProgressHdl->SetProgressLink( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) ); + + ::vos::OThread *pThread = new CommandThread_Impl( xContent, aArgument, xInteractionHandler, xProgressHdl, xLink ); + xLockBytes->setCommandThread_Impl( (CommandThread_Impl*) pThread ); + pThread->create(); + + return UcbLockBytesRef( xLockBytes ); +} + |