diff options
Diffstat (limited to 'patches/dev300/cws-webdavandgvfslocking1-ucb.diff')
-rw-r--r-- | patches/dev300/cws-webdavandgvfslocking1-ucb.diff | 2399 |
1 files changed, 0 insertions, 2399 deletions
diff --git a/patches/dev300/cws-webdavandgvfslocking1-ucb.diff b/patches/dev300/cws-webdavandgvfslocking1-ucb.diff deleted file mode 100644 index 5877cd9f1..000000000 --- a/patches/dev300/cws-webdavandgvfslocking1-ucb.diff +++ /dev/null @@ -1,2399 +0,0 @@ -Index: ucb/source/ucp/file/filglob.cxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/file/filglob.cxx,v -retrieving revision 1.26 -retrieving revision 1.24.64.3 -diff -u -p -u -p -B -r1.26 -r1.24.64.3 ---- ucb/source/ucp/file/filglob.cxx 11 Jul 2008 18:40:28 -0000 1.26 -+++ ucb/source/ucp/file/filglob.cxx 14 Aug 2008 15:36:33 -0000 1.24.64.3 -@@ -435,17 +435,13 @@ namespace fileaccess { - // not enough memory for allocating structures - ioErrorCode = IOErrorCode_OUT_OF_MEMORY; - break; -- case FileBase::E_BUSY: -- // Text file busy -- ioErrorCode = IOErrorCode_LOCKING_VIOLATION; -- break; -- case FileBase::E_AGAIN: -- // Operation would block -+ -+ case FileBase::E_BUSY: // Text file busy -+ case FileBase::E_AGAIN: // Operation would block -+ case FileBase::E_NOLCK: // No record locks available -+ case FileBase::E_TXTBSY:// Text file busy - ioErrorCode = IOErrorCode_LOCKING_VIOLATION; - break; -- case FileBase::E_NOLCK: // No record locks available -- ioErrorCode = IOErrorCode_LOCKING_VIOLATION; -- break; - - case FileBase::E_FAULT: // Bad address - case FileBase::E_LOOP: // Too many symbolic links encountered -Index: ucb/source/ucp/webdav/DAVRequestEnvironment.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/DAVRequestEnvironment.hxx,v -retrieving revision 1.9 -retrieving revision 1.8.40.3 -diff -u -p -u -p -B -r1.9 -r1.8.40.3 ---- ucb/source/ucp/webdav/DAVRequestEnvironment.hxx 10 Apr 2008 15:35:11 -0000 1.9 -+++ ucb/source/ucp/webdav/DAVRequestEnvironment.hxx 4 Jun 2008 13:06:23 -0000 1.8.40.3 -@@ -34,6 +34,8 @@ - #include <rtl/ref.hxx> - #include "DAVAuthListener.hxx" - -+#include <com/sun/star/ucb/XCommandEnvironment.hpp> -+ - namespace webdav_ucp - { - typedef std::pair< rtl::OUString, rtl::OUString > DAVRequestHeader; -@@ -46,12 +48,12 @@ struct DAVRequestEnvironment - // rtl::Reference< DAVStatusListener > m_xStatusListener; - // rtl::Reference< DAVProgressListener > m_xStatusListener; - DAVRequestHeaders m_aRequestHeaders; -- uno::Reference< ucb::XCommandEnvironment > m_xEnv; -+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xEnv; - --DAVRequestEnvironment( const rtl::OUString & rRequestURI, -+ DAVRequestEnvironment( const rtl::OUString & rRequestURI, - const rtl::Reference< DAVAuthListener > & xListener, - const DAVRequestHeaders & rRequestHeaders, -- const uno::Reference< ucb::XCommandEnvironment > & xEnv) -+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv) - : m_aRequestURI( rRequestURI ), - m_xAuthListener( xListener ), - m_aRequestHeaders( rRequestHeaders ), -Index: ucb/source/ucp/webdav/DAVResourceAccess.cxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/DAVResourceAccess.cxx,v -retrieving revision 1.29 -retrieving revision 1.27.20.8 -diff -u -p -u -p -B -r1.29 -r1.27.20.8 ---- ucb/source/ucp/webdav/DAVResourceAccess.cxx 11 Jul 2008 07:41:28 -0000 1.29 -+++ ucb/source/ucp/webdav/DAVResourceAccess.cxx 15 Aug 2008 07:17:29 -0000 1.27.20.8 -@@ -42,6 +42,9 @@ - #include "DAVAuthListenerImpl.hxx" - #include "DAVResourceAccess.hxx" - -+#include <comphelper/processfactory.hxx> -+#include <ucbhelper/commandenvironment.hxx> -+ - using namespace webdav_ucp; - using namespace com::sun::star; - -@@ -61,56 +64,53 @@ int DAVAuthListener_Impl::authenticate( - ::rtl::OUString & inoutUserName, - ::rtl::OUString & outPassWord ) - { -+ uno::Reference< task::XInteractionHandler > xIH; -+ - if ( m_xEnv.is() ) -- { -- uno::Reference< task::XInteractionHandler > xIH -- = m_xEnv->getInteractionHandler(); -- if ( xIH.is() ) -- { -- // #102871# - Supply username and password from previous try. -- // Password container service depends on this! -- if ( inoutUserName.getLength() == 0 ) -- inoutUserName = m_aPrevUsername; -- -- if ( outPassWord.getLength() == 0 ) -- outPassWord = m_aPrevPassword; -- -- rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest -- = new ucbhelper::SimpleAuthenticationRequest( inHostName, -- inRealm, -- inoutUserName, -- outPassWord ); -- xIH->handle( xRequest.get() ); -+ xIH = m_xEnv->getInteractionHandler(); - -- rtl::Reference< ucbhelper::InteractionContinuation > xSelection -- = xRequest->getSelection(); -- -- if ( xSelection.is() ) -- { -- // Handler handled the request. -- uno::Reference< task::XInteractionAbort > xAbort( -- xSelection.get(), uno::UNO_QUERY ); -- if ( !xAbort.is() ) -- { -- const rtl::Reference< -- ucbhelper::InteractionSupplyAuthentication > & xSupp -- = xRequest->getAuthenticationSupplier(); -- -- inoutUserName = xSupp->getUserName(); -- outPassWord = xSupp->getPassword(); -- -- // #102871# - Remember username and password. -- m_aPrevUsername = inoutUserName; -- m_aPrevPassword = outPassWord; -+ if ( !xIH.is() ) -+ return -1; - -- // go on. -- return 0; -- } -- } -- } -- } -- // Abort. -- return -1; -+ // #102871# - Supply username and password from previous try. -+ // Password container service depends on this! -+ if ( inoutUserName.getLength() == 0 ) -+ inoutUserName = m_aPrevUsername; -+ -+ if ( outPassWord.getLength() == 0 ) -+ outPassWord = m_aPrevPassword; -+ -+ rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest -+ = new ucbhelper::SimpleAuthenticationRequest( inHostName, -+ inRealm, -+ inoutUserName, -+ outPassWord ); -+ xIH->handle( xRequest.get() ); -+ -+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection -+ = xRequest->getSelection(); -+ -+ if ( !xSelection.is() ) -+ return -1; -+ -+ // Handler handled the request. -+ uno::Reference< task::XInteractionAbort > xAbort( -+ xSelection.get(), uno::UNO_QUERY ); -+ if ( xAbort.is() ) -+ return -1; -+ -+ const rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp -+ = xRequest->getAuthenticationSupplier(); -+ -+ inoutUserName = xSupp->getUserName(); -+ outPassWord = xSupp->getPassword(); -+ -+ // #102871# - Remember username and password. -+ m_aPrevUsername = inoutUserName; -+ m_aPrevPassword = outPassWord; -+ -+ // go on. -+ return 0; - } - - //========================================================================= -@@ -444,15 +444,18 @@ void DAVResourceAccess::GET( - } - - //========================================================================= --uno::Reference< io::XInputStream > DAVResourceAccess::GET( -+uno::Reference< io::XStream > DAVResourceAccess::GET( - const std::vector< rtl::OUString > & rHeaderNames, - DAVResource & rResource, -- const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -+ const uno::Reference< ucb::XCommandEnvironment > & xEnv, -+ sal_Bool bAllowEmpty, -+ const ucb::Lock *pLock, -+ const rtl::OUString &rFullURL ) - throw( DAVException ) - { - initialize(); - -- uno::Reference< io::XInputStream > xStream; -+ uno::Reference< io::XStream > xStream; - int errorCount = 0; - bool bRetry; - do -@@ -472,7 +475,10 @@ uno::Reference< io::XInputStream > DAVRe - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv ), -- aHeaders, xEnv ) ); -+ aHeaders, xEnv ), -+ bAllowEmpty, -+ pLock, -+ rFullURL ); - } - catch ( DAVException & e ) - { -@@ -606,6 +612,45 @@ void DAVResourceAccess::PUT( - } - - //========================================================================= -+void DAVResourceAccess::PUT( -+ const char * buffer, size_t size, -+ const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -+throw( DAVException ) -+{ -+ initialize(); -+ -+ int errorCount = 0; -+ bool bRetry = false; -+ do -+ { -+ bRetry = false; -+ try -+ { -+ DAVRequestHeaders aHeaders; -+ getUserRequestHeaders( xEnv, -+ getRequestURI(), -+ rtl::OUString::createFromAscii( "PUT" ), -+ aHeaders ); -+ -+ m_xSession->PUT( getRequestURI(), -+ buffer, size, -+ DAVRequestEnvironment( -+ getRequestURI(), -+ new DAVAuthListener_Impl( xEnv ), -+ aHeaders, xEnv ) ); -+ } -+ catch ( DAVException & e ) -+ { -+ errorCount++; -+ bRetry = handleException( e, errorCount ); -+ if ( !bRetry ) -+ throw; -+ } -+ } -+ while ( bRetry ); -+} -+ -+//========================================================================= - uno::Reference< io::XInputStream > DAVResourceAccess::POST( - const rtl::OUString & rContentType, - const rtl::OUString & rReferer, -@@ -888,22 +933,44 @@ void DAVResourceAccess::DESTROY( - - //========================================================================= - void DAVResourceAccess::LOCK ( -- const ucb::Lock & /*rLock*/, -- const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ ) -+ ucb::Lock & rLock, -+ const uno::Reference< ucb::XCommandEnvironment > & xEnv ) - throw( DAVException ) - { --// initialize(); -- OSL_ENSURE( sal_False, "DAVResourceAccess::LOCK - NYI" ); -+ initialize(); -+ -+ DAVRequestHeaders aHeaders; -+ getUserRequestHeaders( xEnv, -+ getRequestURI(), -+ rtl::OUString::createFromAscii( "LOCK" ), -+ aHeaders ); -+ -+ m_xSession->LOCK( rLock, -+ DAVRequestEnvironment( -+ getRequestURI(), -+ new DAVAuthListener_Impl( xEnv ), -+ aHeaders, xEnv ) ); - } - - //========================================================================= - void DAVResourceAccess::UNLOCK ( -- const ucb::Lock & /*rLock*/, -- const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ ) -+ ucb::Lock & rLock, -+ const uno::Reference< ucb::XCommandEnvironment > & xEnv ) - throw( DAVException ) - { --// initialize(); -- OSL_ENSURE( sal_False, "DAVResourceAccess::UNLOCK - NYI" ); -+ initialize(); -+ -+ DAVRequestHeaders aHeaders; -+ getUserRequestHeaders( xEnv, -+ getRequestURI(), -+ rtl::OUString::createFromAscii( "UNLOCK" ), -+ aHeaders ); -+ -+ m_xSession->UNLOCK( rLock, -+ DAVRequestEnvironment( -+ getRequestURI(), -+ new DAVAuthListener_Impl( xEnv ), -+ aHeaders, xEnv ) ); - } - - //========================================================================= -Index: ucb/source/ucp/webdav/DAVResourceAccess.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/DAVResourceAccess.hxx,v -retrieving revision 1.19 -retrieving revision 1.17.60.5 -diff -u -p -u -p -B -r1.19 -r1.17.60.5 ---- ucb/source/ucp/webdav/DAVResourceAccess.hxx 11 Jul 2008 07:41:56 -0000 1.19 -+++ ucb/source/ucp/webdav/DAVResourceAccess.hxx 14 Aug 2008 15:36:40 -0000 1.17.60.5 -@@ -134,11 +134,14 @@ public: - com::sun::star::ucb::XCommandEnvironment > & xEnv ) - throw( DAVException ); - -- com::sun::star::uno::Reference< com::sun::star::io::XInputStream > -+ com::sun::star::uno::Reference< com::sun::star::io::XStream > - GET( const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all' - DAVResource & rResource, - const com::sun::star::uno::Reference< -- com::sun::star::ucb::XCommandEnvironment > & xEnv ) -+ com::sun::star::ucb::XCommandEnvironment > & xEnv, -+ sal_Bool bAllowEmpty = sal_False, -+ const com::sun::star::ucb::Lock *pLock = NULL, -+ const rtl::OUString &rFullURL = rtl::OUString() ) - throw( DAVException ); - - void -@@ -157,6 +160,11 @@ public: - com::sun::star::ucb::XCommandEnvironment > & xEnv ) - throw( DAVException ); - -+ void -+ PUT( const char * buffer, size_t size, -+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv ) -+ throw( DAVException ); -+ - com::sun::star::uno::Reference< com::sun::star::io::XInputStream > - POST( const rtl::OUString & rContentType, - const rtl::OUString & rReferer, -@@ -204,13 +212,13 @@ public: - throw( DAVException ); - - void -- LOCK( const com::sun::star::ucb::Lock & rLock, -+ LOCK( com::sun::star::ucb::Lock & rLock, - const com::sun::star::uno::Reference< - com::sun::star::ucb::XCommandEnvironment > & xEnv ) - throw( DAVException ); - - void -- UNLOCK( const com::sun::star::ucb::Lock & rLock, -+ UNLOCK( com::sun::star::ucb::Lock & rLock, - const com::sun::star::uno::Reference< - com::sun::star::ucb::XCommandEnvironment > & xEnv ) - throw( DAVException ); -Index: ucb/source/ucp/webdav/DAVSession.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/DAVSession.hxx,v -retrieving revision 1.20 -retrieving revision 1.19.70.3 -diff -u -p -u -p -B -r1.20 -r1.19.70.3 ---- ucb/source/ucp/webdav/DAVSession.hxx 10 Apr 2008 15:36:30 -0000 1.20 -+++ ucb/source/ucp/webdav/DAVSession.hxx 2 Jun 2008 13:29:03 -0000 1.19.70.3 -@@ -33,8 +33,12 @@ - - #include <memory> - #include <rtl/ustring.hxx> -+ -+#include <com/sun/star/io/XStream.hpp> - #include <com/sun/star/io/XInputStream.hpp> - #include <com/sun/star/io/XOutputStream.hpp> -+#include <com/sun/star/ucb/Lock.hpp> -+ - #include "DAVException.hxx" - #include "DAVProperties.hxx" - #include "DAVResource.hxx" -@@ -114,11 +117,14 @@ public: - const DAVRequestEnvironment & rEnv ) - throw( DAVException ) = 0; - -- virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > -+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > - GET( const ::rtl::OUString & inPath, - const std::vector< ::rtl::OUString > & inHeaderNames, - DAVResource & ioResource, -- const DAVRequestEnvironment & rEnv ) -+ const DAVRequestEnvironment & rEnv, -+ sal_Bool bAllowEmpty, -+ const com::sun::star::ucb::Lock *pLock, -+ const rtl::OUString &rFullURL = rtl::OUString() ) - throw( DAVException ) = 0; - - virtual void GET( const ::rtl::OUString & inPath, -@@ -134,6 +140,12 @@ public: - const DAVRequestEnvironment & rEnv ) - throw( DAVException ) = 0; - -+ virtual void PUT( const ::rtl::OUString & inPath, -+ const char * buffer, -+ size_t size, -+ const DAVRequestEnvironment & rEnv ) -+ throw ( DAVException ) = 0; -+ - virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > - POST( const rtl::OUString & inPath, - const rtl::OUString & rContentType, -@@ -173,16 +185,14 @@ public: - const DAVRequestEnvironment & rEnv ) - throw( DAVException ) = 0; - -- // Note: Uncomment the following if locking support is required -- /* -- virtual void LOCK ( const Lock & inLock, -+ virtual void LOCK ( com::sun::star::ucb::Lock & rLock, - const DAVRequestEnvironment & rEnv ) - throw( DAVException ) = 0; - -- virtual void UNLOCK ( const Lock & inLock, -+ virtual void UNLOCK ( com::sun::star::ucb::Lock & rLock, - const DAVRequestEnvironment & rEnv ) - throw( DAVException ) = 0; -- */ -+ - protected: - rtl::Reference< DAVSessionFactory > m_xFactory; - -Index: ucb/source/ucp/webdav/NeonInputStream.cxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/NeonInputStream.cxx,v -retrieving revision 1.11 -retrieving revision 1.10.116.5 -diff -u -p -u -p -B -r1.11 -r1.10.116.5 ---- ucb/source/ucp/webdav/NeonInputStream.cxx 10 Apr 2008 15:40:23 -0000 1.11 -+++ ucb/source/ucp/webdav/NeonInputStream.cxx 28 Jun 2008 01:20:47 -0000 1.10.116.5 -@@ -31,22 +31,149 @@ - // MARKER(update_precomp.py): autogen include statement, do not remove - #include "precompiled_ucb.hxx" - #include "NeonInputStream.hxx" -+#include "DAVResourceAccess.hxx" -+ -+#include <osl/thread.hxx> - #include <rtl/memory.h> - -+#include <com/sun/star/ucb/CommandFailedException.hpp> -+#include <comphelper/processfactory.hxx> -+#include <com/sun/star/lang/XMultiServiceFactory.hpp> -+ -+#include <cstdio> -+ - using namespace cppu; --using namespace rtl; - using namespace com::sun::star::io; --using namespace com::sun::star::uno; -+using namespace com::sun::star; - using namespace webdav_ucp; - -+// Our signal - 246 is just a random number ;-) -+const sal_Int32 TICKER_THREAD_USER_SIGNAL = OSL_SIGNAL_USER_RESERVED + 246; -+ -+// ------------------------------------------------------------------- -+// A thread that 'ticks' - emits the user signal every second -+// ------------------------------------------------------------------- -+class TickerThread : public osl::Thread -+{ -+ bool m_bFinish; -+ -+public: -+ -+ TickerThread() : osl::Thread(), m_bFinish( false ) {} -+ -+ void finish() { m_bFinish = true; } -+ -+protected: -+ -+ virtual void SAL_CALL run(); -+}; -+ -+void TickerThread::run() -+{ -+ // we have to go through the loop more often to be able to finish ~quickly -+ const int nNth = 25; -+ -+ int nCount = nNth; -+ while ( !m_bFinish ) -+ { -+ if ( nCount-- <= 0 ) -+ { -+ osl_raiseSignal( TICKER_THREAD_USER_SIGNAL, NULL ); -+ nCount = nNth; -+ } -+ -+ TimeValue aTV; -+ aTV.Seconds = 0; -+ aTV.Nanosec = 1000000000/nNth; -+ wait( aTV ); -+ } -+} -+ -+// ------------------------------------------------------------------- -+// A class that takes care of creating and destroying the ticker thread -+// ------------------------------------------------------------------- -+class TickerThreadController -+{ -+ osl::Mutex m_aMutex; -+ int m_nCount; -+ TickerThread *m_pTickerThread; -+ -+public: -+ -+ TickerThreadController() : m_nCount( 0 ), m_pTickerThread( NULL ) {} -+ -+ void start(); -+ void stop(); -+}; -+ -+void TickerThreadController::start() -+{ -+ osl::MutexGuard aGuard( m_aMutex ); -+ -+ if ( ( m_nCount++ == 0 ) && !m_pTickerThread ) -+ { -+ m_pTickerThread = new TickerThread(); -+ m_pTickerThread->create(); -+ } -+} -+ -+void TickerThreadController::stop() -+{ -+ osl::MutexGuard aGuard( m_aMutex ); -+ -+ if ( ( --m_nCount == 0 ) && m_pTickerThread ) -+ { -+ m_pTickerThread->finish(); -+ m_pTickerThread->join(); -+ -+ delete m_pTickerThread; -+ m_pTickerThread = NULL; -+ } -+} -+ -+// ------------------------------------------------------------------- -+// Signal handler -+// ------------------------------------------------------------------- -+oslSignalAction NeonInputStream::HandleLockingSignal( void* pData, oslSignalInfo* pSignalInfo ) -+{ -+ NeonInputStream *pStream = static_cast< NeonInputStream *>( pData ); -+ -+ if ( !pStream ) -+ return osl_Signal_ActCallNextHdl; -+ -+ if ( pSignalInfo && -+ pSignalInfo->Signal == osl_Signal_User && -+ pSignalInfo->UserSignal == TICKER_THREAD_USER_SIGNAL ) -+ { -+ pStream->RefreshLock(); -+ } -+ else if ( !pSignalInfo || ( pSignalInfo->Signal != osl_Signal_User ) ) -+ { -+ // terminating or something, let's unlock the stream -+ pStream->Unlock(); -+ } -+ -+ return osl_Signal_ActCallNextHdl; -+} -+ -+static TickerThreadController sTickerThreadController; - - // ------------------------------------------------------------------- - // Constructor - // ------------------------------------------------------------------- --NeonInputStream::NeonInputStream( void ) --: mLen( 0 ), -- mPos( 0 ) -+NeonInputStream::NeonInputStream( const uno::Reference< lang::XMultiServiceFactory > &m_rMSF, -+ const uno::Reference< ucb::XCommandEnvironment > &m_rEnv ) -+: m_nLen( 0 ), -+ m_nPos( 0 ), -+ m_bDirty( sal_False ), -+ m_pLock( NULL ), -+ m_nToExpire( -1 ), -+ m_xMSF( m_rMSF ), -+ m_xEnv( m_rEnv ) - { -+ m_pSignalHandler = osl_addSignalHandler( NeonInputStream::HandleLockingSignal, this ); -+ -+ sTickerThreadController.start(); - } - - // ------------------------------------------------------------------- -@@ -54,6 +181,11 @@ NeonInputStream::NeonInputStream( void ) - // ------------------------------------------------------------------- - NeonInputStream::~NeonInputStream( void ) - { -+ sTickerThreadController.stop(); -+ -+ Unlock(); -+ -+ osl_removeSignalHandler( m_pSignalHandler ); - } - - // ------------------------------------------------------------------- -@@ -62,24 +194,68 @@ NeonInputStream::~NeonInputStream( void - // ------------------------------------------------------------------- - void NeonInputStream::AddToStream( const char * inBuf, sal_Int32 inLen ) - { -- mInputBuffer.realloc( sal::static_int_cast<sal_Int32>(mLen) + inLen ); -- rtl_copyMemory( mInputBuffer.getArray() + mLen, inBuf, inLen ); -- mLen += inLen; -+ OSL_ENSURE( !m_bDirty, "Cannot AddToStream() when it was already written to it." ); -+ -+ m_aInputBuffer.realloc( sal::static_int_cast<sal_Int32>(m_nLen) + inLen ); -+ rtl_copyMemory( m_aInputBuffer.getArray() + m_nLen, inBuf, inLen ); -+ m_nLen += inLen; -+} -+ -+// ------------------------------------------------------------------- -+// Associate a lock with this stream -+// ------------------------------------------------------------------- -+void NeonInputStream::SetLock( const com::sun::star::ucb::Lock &rLock, -+ const rtl::OUString &rURL ) -+{ -+ osl::MutexGuard aGuard( m_aLock ); -+ -+ m_aURL = rURL; -+ -+ if ( !m_pLock ) -+ m_pLock = new ucb::Lock( rLock ); -+ else -+ *m_pLock = rLock; -+ -+ if ( m_pLock ) -+ m_nToExpire = m_pLock->Timeout; - } - - // ------------------------------------------------------------------- - // queryInterface - // ------------------------------------------------------------------- --Any NeonInputStream::queryInterface( const Type &type ) -- throw( RuntimeException ) -+uno::Any NeonInputStream::queryInterface( const uno::Type &type ) -+ throw( uno::RuntimeException ) - { -- Any aRet = ::cppu::queryInterface( type, -- static_cast< XInputStream * >( this ), -- static_cast< XSeekable * >( this ) ); -+ uno::Any aRet = ::cppu::queryInterface( type, -+ static_cast< XStream * >( this ), -+ static_cast< XInputStream * >( this ), -+ static_cast< XOutputStream * >( this ), -+ static_cast< XSeekable * >( this ), -+ static_cast< XTruncate * >( this ) ); - return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type ); - } - - // ------------------------------------------------------------------- -+// getInputStream -+// ------------------------------------------------------------------- -+com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL -+NeonInputStream::getInputStream( void ) -+ throw( com::sun::star::uno::RuntimeException ) -+{ -+ return uno::Reference< XInputStream >( this ); -+} -+ -+// ------------------------------------------------------------------- -+// getOutputStream -+// ------------------------------------------------------------------- -+com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL -+NeonInputStream::getOutputStream( void ) -+ throw( com::sun::star::uno::RuntimeException ) -+{ -+ return uno::Reference< XOutputStream >( this ); -+} -+ -+// ------------------------------------------------------------------- - // readBytes - // "Reads" the specified number of bytes from the stream - // ------------------------------------------------------------------- -@@ -92,7 +268,7 @@ sal_Int32 SAL_CALL NeonInputStream::read - { - // Work out how much we're actually going to write - sal_Int32 theBytes2Read = nBytesToRead; -- sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(mLen - mPos); -+ sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(m_nLen - m_nPos); - if ( theBytes2Read > theBytesLeft ) - theBytes2Read = theBytesLeft; - -@@ -101,10 +277,10 @@ sal_Int32 SAL_CALL NeonInputStream::read - - // Write the data - rtl_copyMemory( -- aData.getArray(), mInputBuffer.getConstArray() + mPos, theBytes2Read ); -+ aData.getArray(), m_aInputBuffer.getConstArray() + m_nPos, theBytes2Read ); - - // Update our stream position for next time -- mPos += theBytes2Read; -+ m_nPos += theBytes2Read; - - return theBytes2Read; - } -@@ -133,9 +309,9 @@ void SAL_CALL NeonInputStream::skipBytes - ::com::sun::star::io::IOException, - ::com::sun::star::uno::RuntimeException ) - { -- mPos += nBytesToSkip; -- if ( mPos >= mLen ) -- mPos = mLen; -+ m_nPos += nBytesToSkip; -+ if ( m_nPos >= m_nLen ) -+ m_nPos = m_nLen; - } - - // ------------------------------------------------------------------- -@@ -147,7 +323,7 @@ sal_Int32 SAL_CALL NeonInputStream::avai - ::com::sun::star::io::IOException, - ::com::sun::star::uno::RuntimeException ) - { -- return sal::static_int_cast<sal_Int32>(mLen - mPos); -+ return sal::static_int_cast<sal_Int32>(m_nLen - m_nPos); - } - - // ------------------------------------------------------------------- -@@ -168,12 +344,12 @@ void SAL_CALL NeonInputStream::seek( sal - ::com::sun::star::io::IOException, - ::com::sun::star::uno::RuntimeException ) - { -- if ( location < 0 ) -- throw ::com::sun::star::lang::IllegalArgumentException(); -+ if ( location < 0 ) -+ throw ::com::sun::star::lang::IllegalArgumentException(); - -- if ( location <= mLen ) -- mPos = location; -- else -+ if ( location <= m_nLen ) -+ m_nPos = location; -+ else - throw ::com::sun::star::lang::IllegalArgumentException(); - } - -@@ -184,7 +360,7 @@ sal_Int64 SAL_CALL NeonInputStream::getP - throw( ::com::sun::star::io::IOException, - ::com::sun::star::uno::RuntimeException ) - { -- return mPos; -+ return m_nPos; - } - - // ------------------------------------------------------------------- -@@ -194,5 +370,164 @@ sal_Int64 SAL_CALL NeonInputStream::getL - throw( ::com::sun::star::io::IOException, - ::com::sun::star::uno::RuntimeException ) - { -- return mLen; -+ return m_nLen; -+} -+ -+// ------------------------------------------------------------------- -+// writeBytes -+// ------------------------------------------------------------------- -+void SAL_CALL NeonInputStream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData ) -+ throw( com::sun::star::io::NotConnectedException, -+ com::sun::star::io::BufferSizeExceededException, -+ com::sun::star::io::IOException, -+ com::sun::star::uno::RuntimeException) -+{ -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: writeBytes()\n" ); -+#endif -+ -+ sal_Int32 nDataLen = aData.getLength(); -+ OSL_ASSERT( nDataLen >= 0 ); -+ -+ // Anything to do? -+ if ( nDataLen == 0 ) -+ return; -+ -+ // Update the length of the stream & size of the buffer -+ if ( m_nLen < m_nPos + nDataLen ) -+ { -+ m_nLen = m_nPos + nDataLen; -+ if ( m_aInputBuffer.getLength() < m_nLen ) -+ m_aInputBuffer.realloc( sal::static_int_cast<sal_Int32>( m_nLen ) ); -+ } -+ -+ rtl_copyMemory( m_aInputBuffer.getArray() + m_nPos, aData.getConstArray(), nDataLen ); -+ m_nPos += nDataLen; -+ -+ m_bDirty = sal_True; -+} -+ -+// ------------------------------------------------------------------- -+// flush -+// ------------------------------------------------------------------- -+void SAL_CALL NeonInputStream::flush( void ) -+ throw( NotConnectedException, BufferSizeExceededException, -+ IOException, uno::RuntimeException ) -+{ -+ if ( m_bDirty ) -+ { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: flush(), saving the changed file.\n" ); -+#endif -+ // FIXME It's really hacky to create the new session -+ // But so far it seems I have no other chance... -+ // see also NeonInputStream::Unlock() -+ rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() ); -+ -+ DAVResourceAccess aResourceAccess( m_xMSF, rDAVFactory, m_aURL ); -+ -+ try { -+ aResourceAccess.PUT( reinterpret_cast<const char*>( m_aInputBuffer.getConstArray() ), m_nLen, m_xEnv ); -+ } -+ catch ( DAVException & e ) -+ { -+ throw ucb::CommandFailedException( -+ e.getData(), -+ uno::Reference< uno::XInterface >(), -+ uno::makeAny( e.getData() ) ); -+ } -+ -+ m_bDirty = sal_False; -+ } -+} -+ -+// ------------------------------------------------------------------- -+// closeOutput -+// ------------------------------------------------------------------- -+void SAL_CALL NeonInputStream::closeOutput( void ) -+ throw( com::sun::star::io::NotConnectedException, -+ com::sun::star::io::IOException, -+ com::sun::star::uno::RuntimeException ) -+{ -+ if ( m_bDirty ) -+ { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: TODO write on closeOutput(), the stream is dirty!\n" ); -+#endif -+ } -+} -+ -+// ------------------------------------------------------------------- -+// truncate -+// ------------------------------------------------------------------- -+void SAL_CALL NeonInputStream::truncate( void ) -+ throw( com::sun::star::io::IOException, -+ com::sun::star::uno::RuntimeException ) -+{ -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: truncate()\n" ); -+#endif -+ -+ if ( m_nLen > 0 ) -+ { -+ m_nLen = m_nPos = 0; -+ m_bDirty = sal_True; -+ } -+} -+ -+// ------------------------------------------------------------------- -+// Lock the stream again -+// ------------------------------------------------------------------- -+void NeonInputStream::RefreshLock( void ) -+{ -+ osl::MutexGuard aGuard( m_aLock ); -+ -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: RefreshLock() - will refresh in %d sec\n", m_nToExpire - 30 ); -+#endif -+ -+ if ( m_nToExpire > 0 ) -+ --m_nToExpire; -+ -+ // Refresh the lock if it expires in less than 30 sec -+ if ( m_pLock && m_nToExpire >= 0 && m_nToExpire < 30 ) -+ { -+ // FIXME It's really hacky to create the new session -+ // But so far it seems I have no other chance... -+ rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() ); -+ -+ DAVResourceAccess aResourceAccess( m_xMSF, rDAVFactory, m_aURL ); -+ -+ aResourceAccess.LOCK( *m_pLock, m_xEnv ); -+ -+ m_nToExpire = m_pLock->Timeout; -+ } -+} -+ -+// ------------------------------------------------------------------- -+// Unlock the stream & destroy the lock -+// ------------------------------------------------------------------- -+void NeonInputStream::Unlock( void ) -+{ -+ osl::MutexGuard aGuard( m_aLock ); -+ -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: unlock()\n" ); -+#endif -+ -+ if ( m_pLock ) -+ { -+ // FIXME It's really hacky to create the new session -+ // But so far it seems I have no other chance... -+ rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() ); -+ -+ DAVResourceAccess aResourceAccess( m_xMSF, rDAVFactory, m_aURL ); -+ -+ aResourceAccess.UNLOCK( *m_pLock, m_xEnv ); -+ -+ delete m_pLock; -+ m_pLock = NULL; -+ -+ m_nToExpire = -1; -+ } - } -Index: ucb/source/ucp/webdav/NeonInputStream.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/NeonInputStream.hxx,v -retrieving revision 1.8 -retrieving revision 1.7.136.4 -diff -u -p -u -p -B -r1.8 -r1.7.136.4 ---- ucb/source/ucp/webdav/NeonInputStream.hxx 10 Apr 2008 15:40:39 -0000 1.8 -+++ ucb/source/ucp/webdav/NeonInputStream.hxx 27 Jun 2008 12:59:58 -0000 1.7.136.4 -@@ -31,11 +31,23 @@ - #define _NEONINPUTSTREAM_HXX_ - - #include <sal/types.h> -+#include <osl/mutex.hxx> -+#include <osl/signal.h> - #include <rtl/ustring.hxx> - #include <cppuhelper/weak.hxx> -+ -+#include <com/sun/star/io/XStream.hpp> - #include <com/sun/star/io/XInputStream.hpp> -+#include <com/sun/star/io/XOutputStream.hpp> - #include <com/sun/star/io/XSeekable.hpp> -+#include <com/sun/star/io/XTruncate.hpp> -+#include <com/sun/star/ucb/Lock.hpp> -+ -+#include "DAVRequestEnvironment.hxx" - -+namespace com { namespace sun { namespace star { namespace lang { -+ class XMultiServiceFactory; -+} } } } - - namespace webdav_ucp - { -@@ -45,21 +57,42 @@ namespace webdav_ucp - // A simple XInputStream implementation provided specifically for use - // by the DAVSession::GET method. - // ------------------------------------------------------------------- --class NeonInputStream : public ::com::sun::star::io::XInputStream, -+class NeonInputStream : public ::com::sun::star::io::XStream, -+ public ::com::sun::star::io::XInputStream, -+ public ::com::sun::star::io::XOutputStream, - public ::com::sun::star::io::XSeekable, -+ public ::com::sun::star::io::XTruncate, - public ::cppu::OWeakObject - { -- private: -- com::sun::star::uno::Sequence< sal_Int8 > mInputBuffer; -- sal_Int64 mLen; -- sal_Int64 mPos; -- -- public: -- NeonInputStream( void ); -- virtual ~NeonInputStream(); -+private: -+ com::sun::star::uno::Sequence< sal_Int8 > m_aInputBuffer; -+ sal_Int64 m_nLen; // cannot be just m_aInputBuffer.getLength() - the buffer can be bigger -+ sal_Int64 m_nPos; -+ -+ sal_Bool m_bDirty; -+ -+ com::sun::star::ucb::Lock *m_pLock; -+ int m_nToExpire; -+ rtl::OUString m_aURL; -+ -+ oslSignalHandler m_pSignalHandler; -+ -+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMSF; -+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xEnv; - -- // Add some data to the end of the stream -- void AddToStream( const char * inBuf, sal_Int32 inLen ); -+ osl::Mutex m_aLock; -+ -+public: -+ NeonInputStream( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &m_rMSF, -+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > &m_rEnv ); -+ virtual ~NeonInputStream(); -+ -+ // Add some data to the end of the stream -+ void AddToStream( const char * inBuf, sal_Int32 inLen ); -+ -+ // Associate a lock with this stream -+ void SetLock( const com::sun::star::ucb::Lock &rLock, -+ const rtl::OUString &rURL ); - - // XInterface - virtual com::sun::star::uno::Any SAL_CALL queryInterface( -@@ -74,6 +107,12 @@ class NeonInputStream : public ::com::su - throw() - { OWeakObject::release(); } - -+ // XStream -+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL getInputStream( void ) -+ throw( com::sun::star::uno::RuntimeException ); -+ -+ virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( void ) -+ throw( com::sun::star::uno::RuntimeException ); - - // XInputStream - virtual sal_Int32 SAL_CALL readBytes( -@@ -121,6 +160,42 @@ class NeonInputStream : public ::com::su - virtual sal_Int64 SAL_CALL getLength() - throw( ::com::sun::star::io::IOException, - ::com::sun::star::uno::RuntimeException ); -+ -+ // XOutputStream -+ virtual void SAL_CALL writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData ) -+ throw( com::sun::star::io::NotConnectedException, -+ com::sun::star::io::BufferSizeExceededException, -+ com::sun::star::io::IOException, -+ com::sun::star::uno::RuntimeException); -+ -+ virtual void SAL_CALL flush( void ) -+ throw( com::sun::star::io::NotConnectedException, -+ com::sun::star::io::BufferSizeExceededException, -+ com::sun::star::io::IOException, -+ com::sun::star::uno::RuntimeException); -+ -+ -+ virtual void SAL_CALL closeOutput( void ) -+ throw( com::sun::star::io::NotConnectedException, -+ com::sun::star::io::IOException, -+ com::sun::star::uno::RuntimeException ); -+ -+ // XTruncate -+ virtual void SAL_CALL truncate( void ) -+ throw( com::sun::star::io::IOException, -+ com::sun::star::uno::RuntimeException ); -+ -+protected: -+ -+ // Refresh the lock on the stream -+ void RefreshLock( void ); -+ -+ // Unlock the stream & destroy the lock -+ void Unlock( void ); -+ -+ // Refresh the lock if necessary, or unlock the stream when -+ // OOo crashes/is terminated/... -+ static oslSignalAction HandleLockingSignal( void* pData, oslSignalInfo* pInfo ); - }; - - } // namespace webdav_ucp -Index: ucb/source/ucp/webdav/NeonSession.cxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/NeonSession.cxx,v -retrieving revision 1.55 -retrieving revision 1.53.12.9 -diff -u -p -u -p -B -r1.55 -r1.53.12.9 ---- ucb/source/ucp/webdav/NeonSession.cxx 4 Jun 2008 09:44:08 -0000 1.55 -+++ ucb/source/ucp/webdav/NeonSession.cxx 4 Jul 2008 11:33:47 -0000 1.53.12.9 -@@ -34,11 +34,13 @@ - #include <hash_map> - #include <string.h> - #include <rtl/string.h> -+ -+#include "NeonTypes.hxx" - #include <ne_socket.h> - #include <ne_auth.h> - #include <ne_redirect.h> --#include <ne_locks.h> - #include <ne_ssl.h> -+ - #include "libxml/parser.h" - #include <rtl/ustrbuf.hxx> - #include "DAVAuthListener.hxx" -@@ -42,15 +44,12 @@ - #include "libxml/parser.h" - #include <rtl/ustrbuf.hxx> - #include "DAVAuthListener.hxx" --#include "NeonTypes.hxx" - #include "NeonSession.hxx" - #include "NeonInputStream.hxx" - #include "NeonPropFindRequest.hxx" - #include "NeonHeadRequest.hxx" - #include "NeonUri.hxx" --#ifndef _LINKSEQUENCE_HXX_ - #include "LinkSequence.hxx" --#endif - - #include <com/sun/star/xml/crypto/XSEInitializer.hpp> - #include "UCBDeadPropertyValue.hxx" -@@ -61,10 +60,8 @@ - #include <com/sun/star/security/CertificateContainer.hpp> - #include <com/sun/star/security/XCertificateContainer.hpp> - -- --#ifndef _SIMPLECERTIFICATIONVALIDATIONREQUEST_HXX_ - #include "ucbhelper/simplecertificatevalidationrequest.hxx" --#endif -+#include <ucbhelper/cancelcommandexecution.hxx> - - #include <cppuhelper/bootstrap.hxx> - -@@ -153,6 +150,12 @@ static sal_uInt16 makeStatusCode( const - return sal_uInt16( rStatusText.copy( 0, nPos ).toInt32() ); - } - -+static sal_uInt16 getStatusCode( HttpSession *pSession ) -+{ -+ rtl::OUString aText = rtl::OUString::createFromAscii( ne_get_error( pSession ) ); -+ return makeStatusCode( aText ); -+} -+ - // ------------------------------------------------------------------- - struct NeonRequestContext - { -@@ -196,12 +199,13 @@ struct NeonRequestContext - // ------------------------------------------------------------------- - - #if NEON_VERSION >= 0x0250 --extern "C" int NeonSession_ResponseBlockReader(void * inUserData, -+extern "C" int - #else --extern "C" void NeonSession_ResponseBlockReader(void * inUserData, -+extern "C" void - #endif -- const char * inBuf, -- size_t inLen ) -+NeonSession_ResponseBlockReader(void * inUserData, -+ const char * inBuf, -+ size_t inLen ) - { - // neon calls this function with (inLen == 0)... - if ( inLen > 0 ) -@@ -226,12 +230,13 @@ extern "C" void NeonSession_ResponseBloc - // ------------------------------------------------------------------- - - #if NEON_VERSION >= 0x0250 --extern "C" int NeonSession_ResponseBlockWriter( void * inUserData, -+extern "C" int - #else --extern "C" void NeonSession_ResponseBlockWriter( void * inUserData, -+extern "C" void - #endif -- const char * inBuf, -- size_t inLen ) -+NeonSession_ResponseBlockWriter( void * inUserData, -+ const char * inBuf, -+ size_t inLen ) - { - // neon calls this function with (inLen == 0)... - if ( inLen > 0 ) -@@ -297,11 +302,10 @@ extern "C" int NeonSession_NeonAuth( voi - - try - { -- NeonUri uri( theSession->getRequestEnvironment().m_aRequestURI ); -- rtl::OUString aUserInfo( uri.GetUserInfo() ); -+ rtl::OUString aUserInfo( theSession->getUserInfo() ); - if ( aUserInfo.getLength() ) - { -- sal_Int32 nPos = aUserInfo.indexOf( '@' ); -+ sal_Int32 nPos = aUserInfo.indexOf( ':' ); - if ( nPos == -1 ) - { - theUserName = aUserInfo; -@@ -561,6 +565,8 @@ extern "C" void NeonSession_PreSendReque - } - } - -+NeonLockStore * NeonSession::s_aNeonLockStore = NULL; -+ - // ------------------------------------------------------------------- - // Constructor - // ------------------------------------------------------------------- -@@ -578,6 +584,7 @@ NeonSession::NeonSession( - m_aScheme = theUri.GetScheme(); - m_aHostName = theUri.GetHost(); - m_nPort = theUri.GetPort(); -+ m_aUserInfo = theUri.GetUserInfo(); - - // Init(); - } -@@ -591,14 +598,6 @@ NeonSession::~NeonSession( ) - { - ne_session_destroy( m_pHttpSession ); - m_pHttpSession = 0; -- // Note: Uncomment the following if locking support is required -- /* -- if ( mNeonLockSession != NULL ) -- { -- ne_lock_unregister( mNeonLockSession ); -- mNeonLockSession = NULL; -- } -- */ - } - - delete static_cast<RequestDataMap*>(m_pRequestData); -@@ -614,7 +613,7 @@ void NeonSession::Init() - - if ( m_pHttpSession == 0 ) - { -- // Ensure that Neon sockets are initialize -+ // Ensure that Neon sockets are initialized - - // --> tkr #151111# crashed if copy and pasted pictures from the internet - // ne_sock_init() was executed by two threads at the same time. -@@ -743,14 +742,15 @@ void NeonSession::Init() - m_nProxyPort ); - } - -- // Note: Uncomment the following if locking support is required -- /* -- mNeonLockSession = ne_lock_register( m_pHttpSession ); -+ if ( !s_aNeonLockStore ) -+ s_aNeonLockStore = ne_lockstore_create(); - -- if ( mNeonLockSession == NULL ) -+ if ( s_aNeonLockStore == NULL ) - throw DAVException( DAVException::DAV_SESSION_CREATE, -- theUri::makeConnectionEndPointString() ); -- */ -+ NeonUri::makeConnectionEndPointString( m_aHostName, m_nPort ) ); -+ -+ // Register the lock store -+ ne_lockstore_register( s_aNeonLockStore, m_pHttpSession ); - - // Register for redirects. - ne_redirect_register( m_pHttpSession ); -@@ -1043,7 +1043,7 @@ NeonSession::GET( const rtl::OUString & - - m_aEnv = rEnv; - -- rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream ); -+ rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream( getMSF(), getRequestEnvironment().m_xEnv.get() ) ); - NeonRequestContext aCtx( xInputStream ); - int theRetVal = GET( m_pHttpSession, - rtl::OUStringToOString( -@@ -1082,11 +1082,14 @@ void NeonSession::GET( const rtl::OUStri - // ------------------------------------------------------------------- - // GET - // ------------------------------------------------------------------- --uno::Reference< io::XInputStream > -+uno::Reference< io::XStream > - NeonSession::GET( const rtl::OUString & inPath, - const std::vector< ::rtl::OUString > & inHeaderNames, - DAVResource & ioResource, -- const DAVRequestEnvironment & rEnv ) -+ const DAVRequestEnvironment & rEnv, -+ sal_Bool bAllowEmpty, -+ const com::sun::star::ucb::Lock *pLock, -+ const rtl::OUString &rFullURL ) - throw ( DAVException ) - { - osl::Guard< osl::Mutex > theGuard( m_aMutex ); -@@ -1098,16 +1101,27 @@ NeonSession::GET( const rtl::OUString & - ioResource.uri = inPath; - ioResource.properties.clear(); - -- rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream ); -- NeonRequestContext aCtx( xInputStream, inHeaderNames, ioResource ); -+ rtl::Reference< NeonInputStream > xStream( new NeonInputStream( getMSF(), getRequestEnvironment().m_xEnv.get() ) ); -+ NeonRequestContext aCtx( xStream, inHeaderNames, ioResource ); - int theRetVal = GET( m_pHttpSession, - rtl::OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ), - NeonSession_ResponseBlockReader, - true, - &aCtx ); -- HandleError( theRetVal ); -- return uno::Reference< io::XInputStream >( xInputStream.get() ); -+ try { -+ HandleError( theRetVal ); -+ } -+ catch ( DAVException const & e ) -+ { -+ if ( !bAllowEmpty || ( e.getStatus() != SC_NOT_FOUND ) ) -+ throw; -+ } -+ -+ if ( pLock ) -+ xStream->SetLock( *pLock, rFullURL ); -+ -+ return uno::Reference< io::XStream >( xStream.get() ); - } - - // ------------------------------------------------------------------- -@@ -1147,22 +1161,38 @@ void NeonSession::PUT( const rtl::OUStri - const DAVRequestEnvironment & rEnv ) - throw ( DAVException ) - { -+ // initialization etc. is performed in the other PUT -+ -+ uno::Sequence< sal_Int8 > aDataToSend; -+ if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) -+ throw DAVException( DAVException::DAV_INVALID_ARG ); -+ -+ PUT( inPath, -+ reinterpret_cast< const char * >( aDataToSend.getConstArray() ), -+ aDataToSend.getLength(), -+ rEnv ); -+} -+ -+// ------------------------------------------------------------------- -+// PUT -+// ------------------------------------------------------------------- -+void NeonSession::PUT( const rtl::OUString &inPath, -+ const char * buffer, -+ size_t size, -+ const DAVRequestEnvironment & rEnv ) -+ throw ( DAVException ) -+{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - - Init(); - - m_aEnv = rEnv; - -- uno::Sequence< sal_Int8 > aDataToSend; -- if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) -- throw DAVException( DAVException::DAV_INVALID_ARG ); -- - int theRetVal = PUT( m_pHttpSession, - rtl::OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ), -- reinterpret_cast< const char * >( -- aDataToSend.getConstArray() ), -- aDataToSend.getLength() ); -+ buffer, -+ size ); - - HandleError( theRetVal ); - } -@@ -1188,7 +1218,7 @@ NeonSession::POST( const rtl::OUString & - - m_aEnv = rEnv; - -- rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream ); -+ rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream( getMSF(), getRequestEnvironment().m_xEnv.get() ) ); - NeonRequestContext aCtx( xInputStream ); - int theRetVal = POST( m_pHttpSession, - rtl::OUStringToOString( -@@ -1338,9 +1368,7 @@ void NeonSession::DESTROY( const rtl::OU - // ------------------------------------------------------------------- - // LOCK - // ------------------------------------------------------------------- --// Note: Uncomment the following if locking support is required --/* --void NeonSession::LOCK( const Lock & inLock, -+void NeonSession::LOCK( ucb::Lock & rLock, - const DAVRequestEnvironment & rEnv ) - throw ( DAVException ) - { -@@ -1350,16 +1378,13 @@ void NeonSession::LOCK( const Lock & inL - - m_aEnv = rEnv; - -- Lockit( inLock, true ); -+ Lockit( rLock, true ); - } --*/ - - // ------------------------------------------------------------------- - // UNLOCK - // ------------------------------------------------------------------- --// Note: Uncomment the following if locking support is required --/* --void NeonSession::UNLOCK( const Lock & inLock, -+void NeonSession::UNLOCK( ucb::Lock & rLock, - const DAVRequestEnvironment & rEnv ) - throw ( DAVException ) - { -@@ -1369,9 +1394,8 @@ void NeonSession::UNLOCK( const Lock & i - - m_aEnv = rEnv; - -- Lockit( inLock, false ); -+ Lockit( rLock, false ); - } --*/ - - // ------------------------------------------------------------------- - const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const -@@ -1410,7 +1434,10 @@ void NeonSession::HandleError( int nErro - case NE_ERROR: // Generic error - { - rtl::OUString aText = rtl::OUString::createFromAscii( -- ne_get_error( m_pHttpSession ) ); -+ ne_get_error( m_pHttpSession ) ); -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: got error '%s'\n", rtl::OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ).getStr() ); -+#endif - throw DAVException( DAVException::DAV_HTTP_ERROR, - aText, - makeStatusCode( aText ) ); -@@ -1467,77 +1494,151 @@ void NeonSession::HandleError( int nErro - } - } - --// Note: Uncomment the following if locking support is required --/* --void NeonSession::Lockit( const Lock & inLock, bool inLockit ) -+void NeonSession::Lockit( ucb::Lock & rLock, bool bLockit ) - throw ( DAVException ) - { - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - -- // Create the neon lock -- NeonLock * theLock = new NeonLock; -- int theRetVal; -- -- // Set the lock uri -- NeonUri theUri( inLock.uri ); -- theLock->uri = const_cast< char * > -- ( rtl::OUStringToOString( -- theUri.GetPath(), RTL_TEXTENCODING_UTF8 ).getStr() ); -+ if ( !s_aNeonLockStore ) -+ throw DAVException( DAVException::DAV_INVALID_ARG ); - -- if ( inLockit ) -- { -- // Set the lock depth -- switch( inLock.depth ) -- { -- case DAVZERO: -- case DAVINFINITY: -- theLock->depth = int ( inLock.depth ); -- break; -- default: -- throw DAVException( DAVException::DAV_INVALID_ARG ); -- break; -- } -+ ne_uri aUri; -+ ne_uri_parse( rtl::OUStringToOString( m_aEnv.m_aRequestURI, RTL_TEXTENCODING_UTF8 ).getStr(), -+ &aUri ); -+ -+#if NEON_VERSION < 0x0260 -+#define FILLIN( field, val ) aUri.field = aUri.field? aUri.field: strdup( rtl::OUStringToOString( val, RTL_TEXTENCODING_UTF8 ).getStr() ) -+ FILLIN( scheme, m_aScheme ); -+ FILLIN( host, m_aHostName ); -+ aUri.port = aUri.port? aUri.port: m_nPort; -+#undef FILLIN -+#endif - -- // Set the lock scope -- switch ( inLock.scope ) -- { -- case EXCLUSIVE: -- theLock->scope = ne_lockscope_exclusive; -- break; -- case SHARED: -- theLock->scope = ne_lockscope_shared; -- break; -- default: -- throw DAVException( DAVException::DAV_INVALID_ARG ); -- break; -- } -+ // Create the neon lock -+ NeonLock * theLock = ne_lockstore_findbyuri( s_aNeonLockStore, &aUri ); -+ bool bAlreadyExists = false; -+ if ( theLock ) -+ bAlreadyExists = true; -+ else -+ { -+ theLock = ne_lock_create(); - -- // Set the lock owner -- const char * theOwner = rtl::OUStringToOString( inLock.owner, -- RTL_TEXTENCODING_UTF8 ); -- theLock->owner = const_cast< char * > ( theOwner ); -- -- // Set the lock timeout -- // Note: Neon ignores the timeout -- //theLock->timeout = inLock.timeout; -+ // Set the lock uri -+ theLock->uri = aUri; - -- theRetVal = ne_lock( m_pHttpSession, theLock ); -- } -- else -- { -+ // Set the lock depth -+ switch( rLock.Depth ) -+ { -+ case ucb::LockDepth_ZERO: theLock->depth = NE_DEPTH_ZERO; break; -+ case ucb::LockDepth_ONE: theLock->depth = NE_DEPTH_ONE; break; -+ case ucb::LockDepth_INFINITY: theLock->depth = NE_DEPTH_INFINITE; break; -+ default: -+ throw DAVException( DAVException::DAV_INVALID_ARG ); -+ } - -- // Set the lock token -- rtl::OUString theToken = inLock.locktoken.getConstArray()[ 0 ]; -- theLock->token = const_cast< char * > -- ( rtl::OUStringToOString( -- theToken, RTL_TEXTENCODING_UTF8 ).getStr() ); -+ // Set the lock scope -+ switch ( rLock.Scope ) -+ { -+ case ucb::LockScope_EXCLUSIVE: theLock->scope = ne_lockscope_exclusive; break; -+ case ucb::LockScope_SHARED: theLock->scope = ne_lockscope_shared; break; -+ default: -+ throw DAVException( DAVException::DAV_INVALID_ARG ); -+ break; -+ } - -- theRetVal = ne_unlock( m_pHttpSession, theLock ); -- } -+ // Set the lock owner -+ rtl::OUString aValue; -+ rLock.Owner >>= aValue; - -- HandleError( theRetVal ); -+ theLock->owner = strdup( rtl::OUStringToOString( aValue, RTL_TEXTENCODING_UTF8 ).getStr() ); -+ -+ // Set the lock timeout -+ // We re-new the lock while the stream is open -+ theLock->timeout = rLock.Timeout; -+ } -+ -+ if ( bLockit ) -+ { -+ int nRet; -+ if ( !bAlreadyExists ) -+ { -+ nRet = ne_lock( m_pHttpSession, theLock ); -+ -+ if ( nRet == NE_OK ) -+ { -+ ne_lockstore_add( s_aNeonLockStore, theLock ); -+ -+ uno::Sequence< rtl::OUString > aTokens( 1 ); -+ aTokens[0] = rtl::OUString::createFromAscii( theLock->token ); -+ rLock.LockTokens = aTokens; -+ -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: locked the URL, the token is: %s\n", theLock->token ); -+#endif -+ } -+ } -+ else -+ { -+#if NEON_VERSION >= 0x0260 -+ nRet = ne_lock_refresh( m_pHttpSession, theLock ); -+#else -+ // workaround for a bug in neon 0.24 -+ // we have to call with a bigger structure that is used internally -+ // and initialize parts of it -+ -+ struct lock_ctx -+ { -+ struct ne_lock active; /* activelock */ -+ char *token; /* the token we're after. */ -+ int found; -+ ne_buffer *cdata; -+ }; -+ -+ struct lock_ctx ctx; -+ -+ memset( &ctx, 0, sizeof ctx ); -+ ctx.cdata = ne_buffer_create(); -+ -+ memcpy( &ctx, theLock, sizeof( *theLock ) ); -+ nRet = ne_lock_refresh( m_pHttpSession, reinterpret_cast<NeonLock*>( &ctx ) ); -+ -+ ne_buffer_destroy( ctx.cdata ); -+#endif -+ } -+ -+ if ( ( nRet == NE_ERROR ) && ( getStatusCode( m_pHttpSession ) == SC_LOCKED ) ) -+ { -+ ucbhelper::cancelCommandExecution( ucb::IOErrorCode_LOCKING_VIOLATION, -+ uno::Sequence< uno::Any >( 0 ), // FIXME more info about the file? -+ m_aEnv.m_xEnv, -+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "a locking error occured" ) ), -+ uno::Reference< ucb::XCommandProcessor >() ); -+ } -+#if OSL_DEBUG_LEVEL > 0 -+ else if ( nRet == NE_OK ) -+ fprintf( stderr, "WebDAV: locked/refreshed lock OK\n" ); -+ else -+ fprintf( stderr, "WebDAV: failed to lock the file, status code is: %d\n", getStatusCode( m_pHttpSession ) ); -+#endif -+ } -+ else -+ { -+ // Set the lock token -+ if ( rLock.LockTokens.getLength() > 0 ) -+ { -+ rtl::OUString theToken = rLock.LockTokens.getConstArray()[ 0 ]; -+ theLock->token = strdup( rtl::OUStringToOString( theToken, RTL_TEXTENCODING_UTF8 ).getStr() ); -+ -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: going to unlock the URL, the token is: %s\n", theLock->token ); -+#endif -+ -+ ne_unlock( m_pHttpSession, theLock ); -+ ne_lockstore_remove( s_aNeonLockStore, theLock ); -+ // FIXME even ne_lock_destroy( theLock )? -+ } -+ } - } --*/ - - // ------------------------------------------------------------------- - namespace { -Index: ucb/source/ucp/webdav/NeonSession.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/NeonSession.hxx,v -retrieving revision 1.31 -retrieving revision 1.29.40.4 -diff -u -p -u -p -B -r1.31 -r1.29.40.4 ---- ucb/source/ucp/webdav/NeonSession.hxx 4 Jun 2008 09:44:25 -0000 1.31 -+++ ucb/source/ucp/webdav/NeonSession.hxx 30 Jun 2008 09:01:27 -0000 1.29.40.4 -@@ -57,6 +57,7 @@ class NeonSession : public DAVSession - rtl::OUString m_aScheme; - rtl::OUString m_aHostName; - rtl::OUString m_aProxyName; -+ rtl::OUString m_aUserInfo; - sal_Int32 m_nPort; - sal_Int32 m_nProxyPort; - HttpSession * m_pHttpSession; -@@ -70,8 +71,7 @@ class NeonSession : public DAVSession - // moment. - DAVRequestEnvironment m_aEnv; - -- // Note: Uncomment the following if locking support is required -- // NeonLockSession * mNeonLockSession; -+ static NeonLockStore *s_aNeonLockStore; - - static bool m_bGlobalsInited; - -@@ -92,6 +92,8 @@ class NeonSession : public DAVSession - const DAVRequestEnvironment & getRequestEnvironment() const - { return m_aEnv; } - -+ const rtl::OUString & getUserInfo() const { return m_aUserInfo; } -+ - virtual void - OPTIONS( const ::rtl::OUString & inPath, - DAVCapabilities & outCapabilities, -@@ -142,11 +144,14 @@ class NeonSession : public DAVSession - throw ( DAVException ); - - virtual com::sun::star::uno::Reference< -- com::sun::star::io::XInputStream > -+ com::sun::star::io::XStream > - GET( const ::rtl::OUString & inPath, - const std::vector< ::rtl::OUString > & inHeaderNames, - DAVResource & ioResource, -- const DAVRequestEnvironment & rEnv ) -+ const DAVRequestEnvironment & rEnv, -+ sal_Bool bAllowEmpty = sal_False, -+ const com::sun::star::ucb::Lock *pLock = NULL, -+ const rtl::OUString &rFullURL = rtl::OUString() ) - throw ( DAVException ); - - virtual void -@@ -165,6 +170,13 @@ class NeonSession : public DAVSession - const DAVRequestEnvironment & rEnv ) - throw ( DAVException ); - -+ virtual void -+ PUT( const ::rtl::OUString & inPath, -+ const char * buffer, -+ size_t size, -+ const DAVRequestEnvironment & rEnv ) -+ throw ( DAVException ); -+ - virtual com::sun::star::uno::Reference< - com::sun::star::io::XInputStream > - POST( const rtl::OUString & inPath, -@@ -209,16 +221,13 @@ class NeonSession : public DAVSession - const DAVRequestEnvironment & rEnv ) - throw ( DAVException ); - -- // Note: Uncomment the following if locking support is required -- /* -- virtual void LOCK (const Lock & inLock, -- const DAVRequestEnvironment & rEnv ) -+ virtual void LOCK ( com::sun::star::ucb::Lock & rLock, -+ const DAVRequestEnvironment & rEnv ) - throw ( DAVException ); - -- virtual void UNLOCK (const Lock & inLock, -- const DAVRequestEnvironment & rEnv ) -+ virtual void UNLOCK ( com::sun::star::ucb::Lock & rLock, -+ const DAVRequestEnvironment & rEnv ) - throw ( DAVException ); -- */ - - // helpers - const rtl::OUString & getHostName() const { return m_aHostName; } -@@ -243,9 +252,8 @@ class NeonSession : public DAVSession - - const ucbhelper::InternetProxyServer & getProxySettings() const; - -- // Note: Uncomment the following if locking support is required -- // void Lockit( const Lock & inLock, bool inLockit ) -- // throw ( DAVException ); -+ void Lockit( com::sun::star::ucb::Lock & rLock, bool bLockit ) -+ throw ( DAVException ); - - // low level GET implementation, used by public GET implementations - static int GET( ne_session * sess, -Index: ucb/source/ucp/webdav/NeonTypes.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/NeonTypes.hxx,v -retrieving revision 1.13 -retrieving revision 1.12.150.3 -diff -u -p -u -p -B -r1.13 -r1.12.150.3 ---- ucb/source/ucp/webdav/NeonTypes.hxx 10 Apr 2008 15:42:08 -0000 1.13 -+++ ucb/source/ucp/webdav/NeonTypes.hxx 17 Jun 2008 12:58:27 -0000 1.12.150.3 -@@ -36,6 +36,24 @@ - #include <ne_basic.h> - #include <ne_props.h> - -+// ne_locks.h throws this warning during compilation: -+// /usr/include/neon/ne_locks.h:125: warning: 'int ne_lock(ne_session*, ne_lock*)' hides constructor for 'struct ne_lock' -+// Let's disable the warnings for that file -+#if defined __GNUC__ -+#pragma GCC system_header -+#elif defined __SUNPRO_CC -+#pragma disable_warn -+#elif defined _MSC_VER -+#pragma warning(push, 1) -+#endif -+#include <ne_locks.h> -+#if defined __SUNPRO_CC -+#pragma enable_warn -+#elif defined _MSC_VER -+#pragma warning(pop) -+#endif -+// end of ne_locks.h inclusion -+ - typedef ne_session HttpSession; - typedef ne_status HttpStatus; - typedef ne_server_capabilities HttpServerCapabilities; -@@ -43,4 +61,7 @@ typedef ne_server_capabilities Http - typedef ne_propname NeonPropName; - typedef ne_prop_result_set NeonPropFindResultSet; - -+typedef ne_lock_store NeonLockStore; -+typedef struct ne_lock NeonLock; -+ - #endif // _NEONTYPES_HXX_ -Index: ucb/source/ucp/webdav/webdavcontent.cxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/webdavcontent.cxx,v -retrieving revision 1.65 -retrieving revision 1.59.16.8 -diff -u -p -u -p -B -r1.65 -r1.59.16.8 ---- ucb/source/ucp/webdav/webdavcontent.cxx 25 Jul 2008 06:34:03 -0000 1.65 -+++ ucb/source/ucp/webdav/webdavcontent.cxx 15 Aug 2008 07:17:29 -0000 1.59.16.8 -@@ -48,20 +48,17 @@ - #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp> - #include <com/sun/star/beans/PropertyValue.hpp> - #include <com/sun/star/io/XActiveDataSink.hpp> -+#include <com/sun/star/io/XActiveDataStreamer.hpp> - #include <com/sun/star/io/XOutputStream.hpp> - #include <com/sun/star/lang/IllegalAccessException.hpp> - #include "com/sun/star/ucb/AuthenticationRequest.hpp" - #include <com/sun/star/ucb/CommandFailedException.hpp> - #include <com/sun/star/ucb/ContentInfoAttribute.hpp> - #include <com/sun/star/ucb/InsertCommandArgument.hpp> --#ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_ - #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> --#endif - #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> - #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp> --#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKGENBERALEXCEPTION_HPP_ - #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp> --#endif - #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp> - #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp> - #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp> -@@ -90,6 +87,8 @@ - #include "NeonUri.hxx" - #include "UCBDeadPropertyValue.hxx" - -+#include "NeonInputStream.hxx" -+ - using namespace com::sun::star; - using namespace webdav_ucp; - -@@ -353,7 +352,8 @@ Content::Content( - m_eResourceType( UNKNOWN ), - m_pProvider( pProvider ), - m_bTransient( sal_False ), -- m_bCollection( sal_False ) -+ m_bCollection( sal_False ), -+ m_bForceReadOnly( sal_False ) - { - try - { -@@ -624,6 +624,11 @@ uno::Any SAL_CALL Content::execute( - ucb::CommandAbortedException, - uno::RuntimeException ) - { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: Execute command '%s'\n", -+ rtl::OUStringToOString( aCommand.Name, RTL_TEXTENCODING_UTF8 ).getStr() ); -+#endif -+ - uno::Any aRet; - - if ( aCommand.Name.equalsAsciiL( -@@ -1343,6 +1348,14 @@ uno::Reference< sdbc::XRow > Content::ge - uno::Reference< ucb::XContentIdentifier > xIdentifier; - rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider; - -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: getPropertyValues: answering the following properties: " ); -+ for ( int i = 0; i < rProperties.getLength(); ++i ) -+ fprintf( stderr, " %s,", -+ rtl::OUStringToOString( rProperties[i].Name, RTL_TEXTENCODING_UTF8 ).getStr() ); -+ fprintf( stderr, "\n" ); -+#endif -+ - const ResourceType & rType = getResourceType( xEnv ); - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); -@@ -1463,8 +1476,13 @@ uno::Reference< sdbc::XRow > Content::ge - - if ( !bNetworkAccessAllowed ) - { -- cancelCommandExecution( e, xEnv ); -- // unreachable -+ if ( e.getStatus() == SC_NOT_FOUND ) -+ xProps.reset(); -+ else -+ { -+ cancelCommandExecution( e, xEnv ); -+ // unreachable -+ } - } - } - } -@@ -1526,6 +1544,15 @@ uno::Reference< sdbc::XRow > Content::ge - m_bCollection ) ); - } - -+ // WebDAV supports XActiveDataStreamer -+ xProps->addProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SupportsActiveStreaming" ) ), -+ uno::makeAny( sal_True ), true ); -+ -+ // If we are locked, let's show it to the user -+ if ( m_bForceReadOnly ) -+ xProps->addProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), -+ uno::makeAny( sal_True ), true ); -+ - // Add BaseURI property, if requested. - if ( !xProps->contains( - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ) ) ) -@@ -2023,30 +2051,90 @@ uno::Any Content::open( - } - } - -- if ( rArg.Sink.is() ) -- { -- // Open document. -+ if ( !rArg.Sink.is() ) -+ return aRet; - -- if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || -- ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) -- { -- // Currently(?) unsupported. -- ucbhelper::cancelCommandExecution( -+ // Open document. -+ -+ if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || -+ ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) -+ { -+ // Currently(?) unsupported. -+ ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::UnsupportedOpenModeException( -- rtl::OUString(), -- static_cast< cppu::OWeakObject * >( this ), -- sal_Int16( rArg.Mode ) ) ), -+ rtl::OUString(), -+ static_cast< cppu::OWeakObject * >( this ), -+ sal_Int16( rArg.Mode ) ) ), - xEnv ); -+ // Unreachable -+ } -+ -+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); -+ uno::Reference< io::XOutputStream > xOut -+ = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY ); -+ if ( xOut.is() ) -+ { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: rArg.Sink is XOutputStream\n" ); -+#endif -+ // PUSH: write data -+ try -+ { -+ std::auto_ptr< DAVResourceAccess > xResAccess; -+ -+ { -+ osl::MutexGuard aGuard( m_aMutex ); -+ -+ // throw away previously cached headers. -+// m_xCachedProps.reset(); -+ -+ xResAccess.reset( -+ new DAVResourceAccess( *m_xResAccess.get() ) ); -+ } -+ -+ DAVResource aResource; -+ std::vector< rtl::OUString > aHeaders; -+ // // Obtain list containing all HTTP headers that can -+ // // be mapped to UCB properties. -+ // ContentProperties::getMappableHTTPHeaders( aHeaders ); -+ -+ xResAccess->GET( xOut, aHeaders, aResource, xEnv ); -+ -+ { -+ osl::MutexGuard aGuard( m_aMutex ); -+ -+ // cache headers. -+// m_xCachedProps.reset( new ContentProperties( aResource ) ); -+ std::vector< DAVPropertyValue >::const_iterator it = aResource.properties.begin(); -+ std::vector< DAVPropertyValue >::const_iterator end = aResource.properties.end(); -+ while ( it != end ) -+ { -+ DAVPropertyValue aProp = (*it++); -+ m_xCachedProps->addProperty( aProp.Name, aProp.Value, true); -+ } -+ -+ m_xResAccess.reset( -+ new DAVResourceAccess( *xResAccess.get() ) ); -+ } -+ } -+ catch ( DAVException const & e ) -+ { -+ cancelCommandExecution( e, xEnv ); - // Unreachable - } -- -- rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); -- uno::Reference< io::XOutputStream > xOut -- = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY ); -- if ( xOut.is() ) -+ } -+ else -+ { -+ uno::Reference< io::XActiveDataSink > xDataSink -+ = uno::Reference< io::XActiveDataSink >( rArg.Sink, -+ uno::UNO_QUERY ); -+ if ( xDataSink.is() ) - { -- // PUSH: write data -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataSink\n" ); -+#endif -+ // PULL: wait for client read - try - { - std::auto_ptr< DAVResourceAccess > xResAccess; -@@ -2060,29 +2148,20 @@ uno::Any Content::open( - xResAccess.reset( - new DAVResourceAccess( *m_xResAccess.get() ) ); - } -- -+ // fill inputsream sync; return if all data present - DAVResource aResource; - std::vector< rtl::OUString > aHeaders; --// // Obtain list containing all HTTP headers that can --// // be mapped to UCB properties. --// ContentProperties::getMappableHTTPHeaders( aHeaders ); -- -- xResAccess->GET( xOut, aHeaders, aResource, xEnv ); -+ // // Obtain list containing all HTTP headers that can -+ // // be mapped to UCB properties. -+ // ContentProperties::getMappableHTTPHeaders( aHeaders ); -+ uno::Reference< io::XInputStream > xIn -+ = xResAccess->GET( aHeaders, aResource, xEnv )->getInputStream(); - - { - osl::MutexGuard aGuard( m_aMutex ); - - // cache headers. - // m_xCachedProps.reset( new ContentProperties( aResource ) ); -- std::vector< DAVPropertyValue >::const_iterator it = aResource.properties.begin(); -- std::vector< DAVPropertyValue >::const_iterator end = aResource.properties.end(); -- while ( it != end ) -- { -- DAVPropertyValue aProp = (*it++); -- m_xCachedProps->addProperty( aProp.Name, aProp.Value, true); -- } -- -- - - m_xResAccess.reset( - new DAVResourceAccess( *xResAccess.get() ) ); -@@ -2086,7 +2165,10 @@ uno::Any Content::open( - - m_xResAccess.reset( - new DAVResourceAccess( *xResAccess.get() ) ); -+ - } -+ -+ xDataSink->setInputStream( xIn ); - } - catch ( DAVException const & e ) - { -@@ -2096,15 +2178,24 @@ uno::Any Content::open( - } - else - { -- uno::Reference< io::XActiveDataSink > xDataSink -- = uno::Reference< io::XActiveDataSink >( rArg.Sink, -- uno::UNO_QUERY ); -- if ( xDataSink.is() ) -+ uno::Reference< io::XActiveDataStreamer > xDataStreamer -+ = uno::Reference< io::XActiveDataStreamer >( rArg.Sink, -+ uno::UNO_QUERY ); -+ if ( xDataStreamer.is() && !m_bForceReadOnly ) - { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataStreamer\n" ); -+#endif -+ // prepare the lock -+ ucb::Lock aLock; -+ aLock.Depth = ucb::LockDepth_ZERO; -+ aLock.Scope = ucb::LockScope_EXCLUSIVE; -+ aLock.Timeout = 3*60; // 3 minutes -+ - // PULL: wait for client read -+ std::auto_ptr< DAVResourceAccess > xResAccess; - try - { -- std::auto_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - -@@ -2118,43 +2209,66 @@ uno::Any Content::open( - // fill inputsream sync; return if all data present - DAVResource aResource; - std::vector< rtl::OUString > aHeaders; --// // Obtain list containing all HTTP headers that can --// // be mapped to UCB properties. --// ContentProperties::getMappableHTTPHeaders( aHeaders ); -+ // // Obtain list containing all HTTP headers that can -+ // // be mapped to UCB properties. -+ // ContentProperties::getMappableHTTPHeaders( aHeaders ); -+ -+ try { -+ xResAccess->LOCK( aLock, xEnv ); -+ } -+ catch ( ucb::CommandFailedException const &e ) -+ { -+ // stream locked? -+ ucb::InteractiveIOException aIoException; -+ if ( ( e.Reason >>= aIoException ) && ( aIoException.Code == ucb::IOErrorCode_LOCKING_VIOLATION ) ) -+ { -+ // yes => we must be read only at the next try -+ m_bForceReadOnly = sal_True; -+ } -+ -+ throw; -+ } - -- uno::Reference< io::XInputStream > xIn -- = xResAccess->GET( aHeaders, aResource, xEnv ); -+ uno::Reference< io::XStream > xStream -+ = xResAccess->GET( aHeaders, aResource, xEnv, sal_True, &aLock, xResAccess->getURL() ); - - { -+ - osl::MutexGuard aGuard( m_aMutex ); -- // m_xCachedProps.reset( -- // new ContentProperties( aResource ) ); -+// m_xCachedProps.reset( -+// new ContentProperties( aResource ) ); - - m_xResAccess.reset( - new DAVResourceAccess( *xResAccess.get() ) ); - - } - -- xDataSink->setInputStream( xIn ); -+ xDataStreamer->setStream( xStream ); - } - catch ( DAVException const & e ) - { -+ xResAccess->UNLOCK( aLock, xEnv ); -+ m_bForceReadOnly = sal_False; -+ - cancelCommandExecution( e, xEnv ); - // Unreachable - } - } - else - { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: unsupported rArg.Sink\n" ); -+#endif - // Note: aOpenCommand.Sink may contain an XStream - // implementation. Support for this type of - // sink is optional... - ucbhelper::cancelCommandExecution( -- uno::makeAny( -- ucb::UnsupportedDataSinkException( -- rtl::OUString(), -- static_cast< cppu::OWeakObject * >( this ), -- rArg.Sink ) ), -- xEnv ); -+ uno::makeAny( -+ ucb::UnsupportedDataSinkException( -+ rtl::OUString(), -+ static_cast< cppu::OWeakObject * >( this ), -+ rArg.Sink ) ), -+ xEnv ); - // Unreachable - } - } -@@ -2172,6 +2286,9 @@ void Content::post( - uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY ); - if ( xSink.is() ) - { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataSink\n" ); -+#endif - try - { - std::auto_ptr< DAVResourceAccess > xResAccess; -@@ -2206,6 +2323,9 @@ void Content::post( - uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY ); - if ( xResult.is() ) - { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: rArg.Sink is XOutputStream\n" ); -+#endif - try - { - std::auto_ptr< DAVResourceAccess > xResAccess; -@@ -2235,6 +2355,9 @@ void Content::post( - } - else - { -+#if OSL_DEBUG_LEVEL > 0 -+ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataStreamer (or something)\n" ); -+#endif - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::UnsupportedDataSinkException( -@@ -2575,19 +2698,19 @@ void Content::transfer( - // - const rtl::OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase(); - if ( aScheme.equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ) -+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) || -+ aScheme.equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) || -+ aScheme.equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) ) - { - sourceURI.SetScheme( - rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); - } - else if ( aScheme.equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ) -- { -- sourceURI.SetScheme( -- rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); -- } -- else if ( aScheme.equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) ) -+ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) || -+ aScheme.equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) ) - { - sourceURI.SetScheme( - rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) ); -@@ -2611,13 +2734,23 @@ void Content::transfer( - } - - if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ) -+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) || -+ targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) || -+ targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) ) -+ { - targetURI.SetScheme( - rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); -+ } - else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ) -+ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) || -+ targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) ) -+ { - targetURI.SetScheme( -- rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); -+ rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) ); -+ } - - // @@@ This implementation of 'transfer' only works - // if the source and target are located at same host. -Index: ucb/source/ucp/webdav/webdavcontent.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/webdavcontent.hxx,v -retrieving revision 1.23 -retrieving revision 1.22.20.2 -diff -u -p -u -p -B -r1.23 -r1.22.20.2 ---- ucb/source/ucp/webdav/webdavcontent.hxx 10 Apr 2008 15:44:22 -0000 1.23 -+++ ucb/source/ucp/webdav/webdavcontent.hxx 2 Jun 2008 13:29:28 -0000 1.22.20.2 -@@ -90,6 +90,7 @@ class Content : public ::ucbhelper::Cont - ContentProvider* m_pProvider; // No need for a ref, base class holds object - sal_Bool m_bTransient; - sal_Bool m_bCollection; -+ sal_Bool m_bForceReadOnly; - - private: - virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property > -Index: ucb/source/ucp/webdav/webdavcontentcaps.cxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/webdavcontentcaps.cxx,v -retrieving revision 1.21 -retrieving revision 1.20.70.2 -diff -u -p -u -p -B -r1.21 -r1.20.70.2 ---- ucb/source/ucp/webdav/webdavcontentcaps.cxx 10 Apr 2008 15:44:38 -0000 1.21 -+++ ucb/source/ucp/webdav/webdavcontentcaps.cxx 2 Jun 2008 13:29:31 -0000 1.20.70.2 -@@ -263,6 +263,24 @@ bool ContentProvider::getProperty( - -1, - getCppuType( static_cast< const rtl::OUString * >( 0 ) ), - beans::PropertyAttribute::BOUND ) ); -+ -+ m_pProps->insert( -+ beans::Property( -+ rtl::OUString( -+ RTL_CONSTASCII_USTRINGPARAM( "SupportsActiveStreaming" ) ), -+ -1, -+ getCppuBooleanType(), -+ beans::PropertyAttribute::BOUND -+ | beans::PropertyAttribute::READONLY ) ); -+ -+ m_pProps->insert( -+ beans::Property( -+ rtl::OUString( -+ RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), -+ -1, -+ getCppuBooleanType(), -+ beans::PropertyAttribute::BOUND -+ | beans::PropertyAttribute::READONLY ) ); - } - } - -Index: ucb/source/ucp/webdav/webdavprovider.cxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/webdavprovider.cxx,v -retrieving revision 1.21 -retrieving revision 1.18.70.3 -diff -u -p -u -p -B -r1.21 -r1.18.70.3 ---- ucb/source/ucp/webdav/webdavprovider.cxx 4 Jun 2008 09:44:59 -0000 1.21 -+++ ucb/source/ucp/webdav/webdavprovider.cxx 30 Jun 2008 09:01:32 -0000 1.18.70.3 -@@ -36,6 +36,9 @@ - ************************************************************************** - - *************************************************************************/ -+ -+#include <string.h> -+ - #include <ucbhelper/contentidentifier.hxx> - #include "webdavprovider.hxx" - #include "webdavcontent.hxx" -@@ -138,7 +141,11 @@ ContentProvider::queryContent( - RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) && - !aScheme.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) && -- !aScheme.equalsAsciiL( -+ !aScheme.equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) && -+ !aScheme.equalsAsciiL( -+ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) && -+ !aScheme.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) ) ) - throw ucb::IllegalIdentifierException(); - -@@ -157,32 +164,27 @@ ContentProvider::queryContent( - uno::Reference< ucb::XContentIdentifier > xCanonicId; - - bool bNewId = false; -- if ( aScheme.equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ) -+ struct { -+ const char *from; -+ const char *to; -+ } const *pScheme, pReplace[] = { -+ { WEBDAV_URL_SCHEME, HTTP_URL_SCHEME }, -+ { DAV_URL_SCHEME, HTTP_URL_SCHEME }, -+ { DAVS_URL_SCHEME, HTTPS_URL_SCHEME }, -+ { PLAIN_WEBDAV_URL_SCHEME, HTTP_URL_SCHEME }, -+ { PLAIN_WEBDAVS_URL_SCHEME, HTTPS_URL_SCHEME }, -+ { NULL, NULL } -+ }; -+ for ( pScheme = pReplace; pScheme->from ; ++pScheme ) - { -- aURL = aURL.replaceAt( 0, -- WEBDAV_URL_SCHEME_LENGTH, -- rtl::OUString::createFromAscii( -- HTTP_URL_SCHEME ) ); -- bNewId = true; -- } -- else if ( aScheme.equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ) -- { -- aURL = aURL.replaceAt( 0, -- DAV_URL_SCHEME_LENGTH, -- rtl::OUString::createFromAscii( -- HTTP_URL_SCHEME ) ); -- bNewId = true; -- } -- else if ( aScheme.equalsAsciiL( -- RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) ) -- { -- aURL = aURL.replaceAt( 0, -- DAVS_URL_SCHEME_LENGTH, -- rtl::OUString::createFromAscii( -- HTTPS_URL_SCHEME ) ); -- bNewId = true; -+ if ( aScheme.equalsAscii( pScheme->from ) ) -+ { -+ aURL = aURL.replaceAt( 0, -+ strlen( pScheme->from ), -+ rtl::OUString::createFromAscii( pScheme->to ) ); -+ bNewId = true; -+ break; -+ } - } - - sal_Int32 nPos = aURL.lastIndexOf( '/' ); -Index: ucb/source/ucp/webdav/webdavprovider.hxx -=================================================================== -RCS file: /cvs/ucb/ucb/source/ucp/webdav/webdavprovider.hxx,v -retrieving revision 1.11 -retrieving revision 1.9.70.3 -diff -u -p -u -p -B -r1.11 -r1.9.70.3 ---- ucb/source/ucp/webdav/webdavprovider.hxx 4 Jun 2008 09:45:13 -0000 1.11 -+++ ucb/source/ucp/webdav/webdavprovider.hxx 30 Jun 2008 09:01:35 -0000 1.9.70.3 -@@ -50,25 +50,18 @@ namespace webdav_ucp { - // URL scheme. This is the scheme the provider will be able to create - // contents for. The UCB will select the provider ( i.e. in order to create - // contents ) according to this scheme. --#define WEBDAV_URL_SCHEME \ -- "vnd.sun.star.webdav" --#define WEBDAV_URL_SCHEME_LENGTH 19 -+#define WEBDAV_URL_SCHEME "vnd.sun.star.webdav" - --#define HTTP_URL_SCHEME "http" --#define HTTP_URL_SCHEME_LENGTH 4 -+#define HTTP_URL_SCHEME "http" -+#define HTTPS_URL_SCHEME "https" - --#define HTTPS_URL_SCHEME "https" --#define HTTPS_URL_SCHEME_LENGTH 5 -+#define DAV_URL_SCHEME "dav" -+#define DAVS_URL_SCHEME "davs" - --#define DAV_URL_SCHEME "dav" --#define DAV_URL_SCHEME_LENGTH 3 -+#define PLAIN_WEBDAV_URL_SCHEME "webdav" -+#define PLAIN_WEBDAVS_URL_SCHEME "webdavs" - --#define DAVS_URL_SCHEME "davs" --#define DAVS_URL_SCHEME_LENGTH 4 -- -- -- --#define FTP_URL_SCHEME "ftp" -+#define FTP_URL_SCHEME "ftp" - - #define HTTP_CONTENT_TYPE \ - "application/" HTTP_URL_SCHEME "-content" |