LCOV - code coverage report
Current view: top level - unotools/source/ucbhelper - ucblockbytes.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 223 610 36.6 %
Date: 2015-06-13 12:38:46 Functions: 36 84 42.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <ucblockbytes.hxx>
      21             : 
      22             : #include <sal/macros.h>
      23             : #include <comphelper/processfactory.hxx>
      24             : #include <salhelper/condition.hxx>
      25             : #include <osl/thread.hxx>
      26             : #include <osl/diagnose.h>
      27             : #include <tools/urlobj.hxx>
      28             : #include <ucbhelper/interactionrequest.hxx>
      29             : #include <com/sun/star/task/XInteractionAbort.hpp>
      30             : #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
      31             : #include <com/sun/star/ucb/CommandFailedException.hpp>
      32             : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
      33             : #include <com/sun/star/ucb/InteractiveIOException.hpp>
      34             : #include <com/sun/star/io/XActiveDataStreamer.hpp>
      35             : #include <com/sun/star/io/TempFile.hpp>
      36             : #include <com/sun/star/ucb/DocumentHeaderField.hpp>
      37             : #include <com/sun/star/ucb/XCommandInfo.hpp>
      38             : #include <com/sun/star/ucb/XCommandProcessor.hpp>
      39             : #include <com/sun/star/task/XInteractionHandler.hpp>
      40             : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
      41             : #include <com/sun/star/ucb/PostCommandArgument2.hpp>
      42             : #include <com/sun/star/ucb/OpenMode.hpp>
      43             : #include <com/sun/star/beans/Property.hpp>
      44             : #include <com/sun/star/beans/PropertyValue.hpp>
      45             : #include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
      46             : #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
      47             : #include <com/sun/star/sdbc/XRow.hpp>
      48             : #include <com/sun/star/io/XActiveDataSink.hpp>
      49             : #include <com/sun/star/io/XActiveDataControl.hpp>
      50             : #include <com/sun/star/io/XSeekable.hpp>
      51             : #include <cppuhelper/implbase1.hxx>
      52             : #include <cppuhelper/implbase2.hxx>
      53             : #include <tools/inetmsg.hxx>
      54             : #include <com/sun/star/io/XTruncate.hpp>
      55             : #include <com/sun/star/lang/IllegalArgumentException.hpp>
      56             : 
      57             : #include <comphelper/storagehelper.hxx>
      58             : #include <ucbhelper/content.hxx>
      59             : 
      60             : using namespace ::com::sun::star::uno;
      61             : using namespace ::com::sun::star::io;
      62             : using namespace ::com::sun::star::ucb;
      63             : using namespace ::com::sun::star::task;
      64             : using namespace ::com::sun::star::lang;
      65             : using namespace ::com::sun::star::beans;
      66             : 
      67             : namespace utl
      68             : {
      69             : 
      70             : /**
      71             :     Helper class for getting a XInputStream when opening a content
      72             :  */
      73         510 : class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink >
      74             : {
      75             :     UcbLockBytesRef         m_xLockBytes;
      76             : 
      77             : public:
      78         255 :     explicit UcbDataSink_Impl( UcbLockBytes* pLockBytes )
      79         255 :         : m_xLockBytes( pLockBytes )
      80         255 :     {}
      81             : 
      82             :     // XActiveDataControl.
      83           0 :     virtual void SAL_CALL   addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException, std::exception) SAL_OVERRIDE {}
      84           0 :     virtual void SAL_CALL   removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException, std::exception) SAL_OVERRIDE {}
      85           0 :     virtual void SAL_CALL   start() throw(RuntimeException, std::exception) SAL_OVERRIDE {}
      86         255 :     virtual void SAL_CALL   terminate() throw(RuntimeException, std::exception) SAL_OVERRIDE
      87         255 :                             { m_xLockBytes->terminate_Impl(); }
      88             : 
      89             :     // XActiveDataSink.
      90         281 :     virtual void SAL_CALL   setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException, std::exception) SAL_OVERRIDE
      91         281 :                             { m_xLockBytes->setInputStream_Impl (rxInputStream); }
      92           0 :     virtual Reference<XInputStream> SAL_CALL getInputStream() throw(RuntimeException, std::exception) SAL_OVERRIDE
      93           0 :                             { return m_xLockBytes->getInputStream_Impl(); }
      94             : };
      95             : 
      96             : /**
      97             :     Helper class for getting a XStream when opening a content
      98             :  */
      99       38828 : class UcbStreamer_Impl : public ::cppu::WeakImplHelper2< XActiveDataStreamer, XActiveDataControl >
     100             : {
     101             :     Reference < XStream >   m_xStream;
     102             :     UcbLockBytesRef         m_xLockBytes;
     103             : 
     104             : public:
     105       19414 :     explicit UcbStreamer_Impl( UcbLockBytes* pLockBytes )
     106       19414 :         : m_xLockBytes( pLockBytes )
     107       19414 :     {}
     108             : 
     109             :     // XActiveDataControl.
     110           0 :     virtual void SAL_CALL   addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException, std::exception) SAL_OVERRIDE {}
     111           0 :     virtual void SAL_CALL   removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException, std::exception) SAL_OVERRIDE {}
     112           0 :     virtual void SAL_CALL   start() throw(RuntimeException, std::exception) SAL_OVERRIDE {}
     113       19414 :     virtual void SAL_CALL   terminate() throw(RuntimeException, std::exception) SAL_OVERRIDE
     114       19414 :                             { m_xLockBytes->terminate_Impl(); }
     115             : 
     116             :     // XActiveDataStreamer
     117       19424 :     virtual void SAL_CALL   setStream( const Reference< XStream >& aStream ) throw(RuntimeException, std::exception) SAL_OVERRIDE
     118       19424 :                             { m_xStream = aStream; m_xLockBytes->setStream_Impl( aStream ); }
     119           0 :     virtual Reference< XStream > SAL_CALL getStream() throw(RuntimeException, std::exception) SAL_OVERRIDE
     120           0 :                             { return m_xStream; }
     121             : };
     122             : 
     123             : /**
     124             :     Helper class for managing interactions and progress when executing UCB commands
     125             :  */
     126       39338 : class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment >
     127             : {
     128             :     Reference< XInteractionHandler >                m_xInteractionHandler;
     129             :     Reference< XProgressHandler >                   m_xProgressHandler;
     130             : 
     131             : public:
     132       19669 :                             UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler,
     133             :                                                 const Reference< XProgressHandler>& rxProgressHandler )
     134             :                                 : m_xInteractionHandler( rxInteractionHandler )
     135       19669 :                                 , m_xProgressHandler( rxProgressHandler )
     136       19669 :                             {}
     137             : 
     138          85 :     virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException, std::exception) SAL_OVERRIDE
     139          85 :     { return m_xInteractionHandler; }
     140             : 
     141           0 :     virtual Reference<XProgressHandler> SAL_CALL    getProgressHandler() throw (RuntimeException, std::exception) SAL_OVERRIDE
     142           0 :     { return m_xProgressHandler; }
     143             : };
     144             : 
     145             : /**
     146             :     Helper class for property change notifies when executing UCB commands
     147             : */
     148       39338 : class UcbPropertiesChangeListener_Impl : public ::cppu::WeakImplHelper1< XPropertiesChangeListener >
     149             : {
     150             : public:
     151             :     UcbLockBytesRef         m_xLockBytes;
     152             : 
     153       19669 :     explicit UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef )
     154       19669 :         : m_xLockBytes( rRef )
     155       19669 :     {}
     156             : 
     157           0 :     virtual void SAL_CALL   disposing ( const EventObject &/*rEvent*/) throw(RuntimeException, std::exception) SAL_OVERRIDE {}
     158             :     virtual void SAL_CALL   propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException, std::exception) SAL_OVERRIDE;
     159             : };
     160             : 
     161           0 : void SAL_CALL UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException, std::exception)
     162             : {
     163           0 :     sal_Int32 i, n = rEvent.getLength();
     164           0 :     for (i = 0; i < n; i++)
     165             :     {
     166           0 :         PropertyChangeEvent evt (rEvent[i]);
     167           0 :         if (evt.PropertyName == "DocumentHeader")
     168             :         {
     169           0 :             Sequence<DocumentHeaderField> aHead;
     170           0 :             if (evt.NewValue >>= aHead)
     171             :             {
     172           0 :                 sal_Int32 k, m = aHead.getLength();
     173           0 :                 for (k = 0; k < m; k++)
     174             :                 {
     175           0 :                     OUString aName( aHead[k].Name );
     176           0 :                     OUString aValue( aHead[k].Value );
     177             : 
     178           0 :                     if (aName.compareToIgnoreAsciiCaseAscii("Expires") == 0)
     179             :                     {
     180           0 :                         DateTime aExpires (0, 0);
     181           0 :                         if (INetMIMEMessage::ParseDateField (aValue, aExpires))
     182             :                         {
     183           0 :                             aExpires.ConvertToLocalTime();
     184           0 :                             m_xLockBytes->SetExpireDate_Impl( aExpires );
     185             :                         }
     186             :                     }
     187           0 :                 }
     188             :             }
     189             : 
     190           0 :             m_xLockBytes->SetStreamValid_Impl();
     191             :         }
     192           0 :         else if (evt.PropertyName == "PresentationURL")
     193             :         {
     194           0 :             OUString aUrl;
     195           0 :             if (evt.NewValue >>= aUrl)
     196             :             {
     197           0 :                 OUString aBad ("private:");
     198           0 :                 if (!aUrl.startsWith(aBad))
     199             :                 {
     200             :                     // URL changed (Redirection).
     201           0 :                     m_xLockBytes->SetRealURL_Impl( aUrl );
     202           0 :                 }
     203           0 :             }
     204             :         }
     205           0 :         else if (evt.PropertyName == "MediaType")
     206             :         {
     207           0 :             OUString aContentType;
     208           0 :             if (evt.NewValue >>= aContentType)
     209           0 :                 m_xLockBytes->SetContentType_Impl( aContentType );
     210             :         }
     211           0 :     }
     212           0 : }
     213             : 
     214             : class Moderator
     215             :     : public osl::Thread
     216             : {
     217             :     // usage restriction:
     218             :     // It might be possible, that the call to the interactionhandler and/or
     219             :     // progresshandler is done asynchrounsly, while the 'execute' simply
     220             :     // returns. This would imply that these class must be refcounted !!!
     221             : 
     222             : public:
     223             :     Moderator(
     224             :         Reference < XContent >& xContent,
     225             :         Reference < XInteractionHandler >& xInteract,
     226             :         const Command& rArg
     227             :     )
     228             :         throw(
     229             :             ContentCreationException,
     230             :             RuntimeException
     231             :         );
     232             : 
     233             :     virtual ~Moderator();
     234             : 
     235             :     enum ResultType {
     236             :         NORESULT,
     237             : 
     238             :         INTERACTIONREQUEST,    // reply expected
     239             : 
     240             :         PROGRESSPUSH,
     241             :         PROGRESSUPDATE,
     242             :         PROGRESSPOP,
     243             : 
     244             :         INPUTSTREAM,
     245             :         STREAM,
     246             : 
     247             :         RESULT,
     248             :         TIMEDOUT,
     249             :         COMMANDABORTED,
     250             :         COMMANDFAILED,
     251             :         INTERACTIVEIO,
     252             :         UNSUPPORTED,
     253             :         GENERAL
     254             :     };
     255             : 
     256           0 :     class ConditionRes
     257             :         : public salhelper::Condition
     258             :     {
     259             :     public:
     260           0 :         ConditionRes(osl::Mutex& aMutex,Moderator& aModerator)
     261             :             : salhelper::Condition(aMutex),
     262           0 :               m_aModerator(aModerator)
     263             :         {
     264           0 :         }
     265             : 
     266             :     protected:
     267           0 :         bool applies() const SAL_OVERRIDE {
     268           0 :             return m_aModerator.m_aResultType != NORESULT;
     269             :         }
     270             : 
     271             :     private:
     272             :         Moderator& m_aModerator;
     273             :     };
     274             : 
     275           0 :     struct Result {
     276             :         ResultType        type;
     277             :         Any               result;
     278             :         sal_Int32         ioErrorCode;
     279             :     };
     280             : 
     281             :     Result getResult(const sal_uInt32 milliSec);
     282             : 
     283             :     enum ReplyType {
     284             :         NOREPLY,
     285             :         EXIT,
     286             :         RETRY,
     287             :         REQUESTHANDLED
     288             :     };
     289             : 
     290           0 :     class ConditionRep
     291             :         : public salhelper::Condition
     292             :     {
     293             :     public:
     294           0 :         ConditionRep(osl::Mutex& aMutex,Moderator& aModerator)
     295             :             : salhelper::Condition(aMutex),
     296           0 :               m_aModerator(aModerator)
     297             :         {
     298           0 :         }
     299             : 
     300             :     protected:
     301           0 :         bool applies() const SAL_OVERRIDE {
     302           0 :             return m_aModerator.m_aReplyType != NOREPLY;
     303             :         }
     304             : 
     305             :     private:
     306             :         Moderator& m_aModerator;
     307             :     };
     308             : 
     309             :     void setReply(ReplyType);
     310             : 
     311             :     void handle( const Reference<XInteractionRequest >& Request );
     312             : 
     313             :     void setStream(const Reference< XStream >& aStream);
     314             :     void setInputStream(const Reference<XInputStream> &rxInputStream);
     315             : 
     316             : protected:
     317             :     virtual void SAL_CALL run() SAL_OVERRIDE;
     318             :     virtual void SAL_CALL onTerminated() SAL_OVERRIDE;
     319             : 
     320             : private:
     321             :     osl::Mutex        m_aMutex;
     322             : 
     323             :     friend class ConditionRes;
     324             : 
     325             :     ConditionRes      m_aRes;
     326             :     ResultType        m_aResultType;
     327             :     sal_Int32         m_nIOErrorCode;
     328             :     Any               m_aResult;
     329             : 
     330             :     friend class ConditionRep;
     331             : 
     332             :     ConditionRep      m_aRep;
     333             :     ReplyType         m_aReplyType;
     334             : 
     335             :     Command                           m_aArg;
     336             :     ::ucbhelper::Content              m_aContent;
     337             : };
     338             : 
     339             : class ModeratorsActiveDataStreamer
     340             :     : public ::cppu::WeakImplHelper1<XActiveDataStreamer>
     341             : {
     342             : public:
     343             : 
     344             :     explicit ModeratorsActiveDataStreamer(Moderator &theModerator);
     345             : 
     346             :     virtual ~ModeratorsActiveDataStreamer();
     347             : 
     348             :     // XActiveDataStreamer
     349             :     virtual void SAL_CALL
     350             :     setStream(
     351             :         const Reference< XStream >& aStream
     352             :     )
     353             :         throw(
     354             :             RuntimeException, std::exception
     355             :         ) SAL_OVERRIDE;
     356             : 
     357             :     virtual Reference<XStream> SAL_CALL
     358           0 :     getStream (
     359             :         void
     360             :     ) throw(
     361             :         RuntimeException, std::exception
     362             :     ) SAL_OVERRIDE
     363             :     {
     364           0 :         osl::MutexGuard aGuard(m_aMutex);
     365           0 :         return m_xStream;
     366             :     }
     367             : 
     368             : private:
     369             :     Moderator& m_aModerator;
     370             : 
     371             :     osl::Mutex m_aMutex;
     372             :     Reference<XStream> m_xStream;
     373             : };
     374             : 
     375             : class ModeratorsActiveDataSink
     376             :     : public ::cppu::WeakImplHelper1<XActiveDataSink>
     377             : {
     378             : public:
     379             : 
     380             :     explicit ModeratorsActiveDataSink(Moderator &theModerator);
     381             : 
     382             :     virtual ~ModeratorsActiveDataSink();
     383             : 
     384             :     // XActiveDataSink.
     385             :     virtual void SAL_CALL
     386             :     setInputStream (
     387             :         const Reference<XInputStream> &rxInputStream
     388             :     )
     389             :         throw(
     390             :             RuntimeException, std::exception
     391             :         ) SAL_OVERRIDE;
     392             : 
     393             :     virtual Reference<XInputStream> SAL_CALL
     394           0 :     getInputStream (
     395             :         void
     396             :     ) throw(
     397             :         RuntimeException, std::exception
     398             :     ) SAL_OVERRIDE
     399             :     {
     400           0 :         osl::MutexGuard aGuard(m_aMutex);
     401           0 :         return m_xStream;
     402             :     }
     403             : 
     404             : private:
     405             :     Moderator& m_aModerator;
     406             :     osl::Mutex m_aMutex;
     407             :     Reference<XInputStream> m_xStream;
     408             : };
     409             : 
     410           0 : ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator &theModerator)
     411           0 :     : m_aModerator(theModerator)
     412             : {
     413           0 : }
     414             : 
     415           0 : ModeratorsActiveDataSink::~ModeratorsActiveDataSink()
     416             : {
     417           0 : }
     418             : 
     419             : // XActiveDataSink.
     420             : void SAL_CALL
     421           0 : ModeratorsActiveDataSink::setInputStream (
     422             :     const Reference<XInputStream> &rxInputStream
     423             : )
     424             :     throw(
     425             :         RuntimeException, std::exception
     426             :     )
     427             : {
     428           0 :     m_aModerator.setInputStream(rxInputStream);
     429           0 :     osl::MutexGuard aGuard(m_aMutex);
     430           0 :     m_xStream = rxInputStream;
     431           0 : }
     432             : 
     433           0 : ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer(
     434             :     Moderator &theModerator
     435             : )
     436           0 :     : m_aModerator(theModerator)
     437             : {
     438           0 : }
     439             : 
     440           0 : ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer()
     441             : {
     442           0 : }
     443             : 
     444             : // XActiveDataStreamer.
     445             : void SAL_CALL
     446           0 : ModeratorsActiveDataStreamer::setStream (
     447             :     const Reference<XStream> &rxStream
     448             : )
     449             :     throw(
     450             :         RuntimeException, std::exception
     451             :     )
     452             : {
     453           0 :     m_aModerator.setStream(rxStream);
     454           0 :     osl::MutexGuard aGuard(m_aMutex);
     455           0 :     m_xStream = rxStream;
     456           0 : }
     457             : 
     458             : class ModeratorsInteractionHandler
     459             :     : public ::cppu::WeakImplHelper1<XInteractionHandler>
     460             : {
     461             : public:
     462             : 
     463             :     explicit ModeratorsInteractionHandler(Moderator &theModerator);
     464             : 
     465             :     virtual ~ModeratorsInteractionHandler();
     466             : 
     467             :     virtual void SAL_CALL
     468             :     handle( const Reference<XInteractionRequest >& Request )
     469             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     470             : 
     471             : private:
     472             : 
     473             :     Moderator& m_aModerator;
     474             : };
     475             : 
     476           0 : ModeratorsInteractionHandler::ModeratorsInteractionHandler(
     477             :     Moderator &aModerator)
     478           0 :     : m_aModerator(aModerator)
     479             : {
     480           0 : }
     481             : 
     482           0 : ModeratorsInteractionHandler::~ModeratorsInteractionHandler()
     483             : {
     484           0 : }
     485             : 
     486             : void SAL_CALL
     487           0 : ModeratorsInteractionHandler::handle(
     488             :     const Reference<XInteractionRequest >& Request
     489             : )
     490             :     throw (
     491             :         RuntimeException, std::exception
     492             :     )
     493             : {
     494             :     // wakes up the mainthread
     495           0 :     m_aModerator.handle(Request);
     496           0 : }
     497             : 
     498           0 : Moderator::Moderator(
     499             :     Reference < XContent >& xContent,
     500             :     Reference < XInteractionHandler >& xInteract,
     501             :     const Command& rArg
     502             : )
     503             :     throw(
     504             :         ::com::sun::star::ucb::ContentCreationException,
     505             :         ::com::sun::star::uno::RuntimeException
     506             :     )
     507             :     : m_aMutex(),
     508             : 
     509             :       m_aRes(m_aMutex,*this),
     510             :       m_aResultType(NORESULT),
     511             :       m_nIOErrorCode(0),
     512             :       m_aResult(),
     513             : 
     514             :       m_aRep(m_aMutex,*this),
     515             :       m_aReplyType(NOREPLY),
     516             : 
     517             :       m_aArg(rArg),
     518             :       m_aContent(
     519             :           xContent,
     520             :           new UcbTaskEnvironment(
     521           0 :               xInteract.is() ? new ModeratorsInteractionHandler(*this) : 0,
     522           0 :               0),
     523           0 :           comphelper::getProcessComponentContext())
     524             : {
     525             :     // now exchange the whole data sink stuff
     526             :     // with a thread safe version
     527             : 
     528           0 :     Reference<XInterface> *pxSink = NULL;
     529             : 
     530           0 :     PostCommandArgument2 aPostArg;
     531           0 :     OpenCommandArgument2 aOpenArg;
     532             : 
     533           0 :     int dec(2);
     534           0 :     if(m_aArg.Argument >>= aPostArg) {
     535           0 :         pxSink = &aPostArg.Sink;
     536           0 :         dec = 0;
     537             :     }
     538           0 :     else if(m_aArg.Argument >>= aOpenArg) {
     539           0 :         pxSink = &aOpenArg.Sink;
     540           0 :         dec = 1;
     541             :     }
     542             : 
     543           0 :     if(dec ==2)
     544           0 :         throw ContentCreationException();
     545             : 
     546           0 :     Reference < XActiveDataSink > xActiveSink(*pxSink,UNO_QUERY);
     547           0 :     if(xActiveSink.is())
     548           0 :         *pxSink = Reference<XInterface>(
     549           0 :             static_cast<cppu::OWeakObject*>(new ModeratorsActiveDataSink(*this)));
     550             : 
     551           0 :     Reference<XActiveDataStreamer> xStreamer( *pxSink, UNO_QUERY );
     552           0 :     if ( xStreamer.is() )
     553           0 :         *pxSink = Reference<XInterface>(
     554           0 :             static_cast<cppu::OWeakObject*>(new ModeratorsActiveDataStreamer(*this)));
     555             : 
     556           0 :     if(dec == 0)
     557           0 :         m_aArg.Argument <<= aPostArg;
     558           0 :     else if(dec == 1)
     559           0 :         m_aArg.Argument <<= aOpenArg;
     560           0 : }
     561             : 
     562           0 : Moderator::~Moderator()
     563             : {
     564           0 : }
     565             : 
     566           0 : Moderator::Result Moderator::getResult(const sal_uInt32 milliSec)
     567             : {
     568           0 :     Result ret;
     569             :     try {
     570           0 :         salhelper::ConditionWaiter aWaiter(m_aRes,milliSec);
     571           0 :         ret.type = m_aResultType;
     572           0 :         ret.result = m_aResult;
     573           0 :         ret.ioErrorCode = m_nIOErrorCode;
     574             : 
     575             :         // reset
     576           0 :         m_aResultType = NORESULT;
     577             :     }
     578           0 :     catch (const salhelper::ConditionWaiter::timedout&)
     579             :     {
     580           0 :         ret.type = TIMEDOUT;
     581             :     }
     582             : 
     583           0 :     return ret;
     584             : }
     585             : 
     586           0 : void Moderator::setReply(ReplyType aReplyType )
     587             : {
     588           0 :     salhelper::ConditionModifier aMod(m_aRep);
     589           0 :     m_aReplyType = aReplyType;
     590           0 : }
     591             : 
     592           0 : void Moderator::handle( const Reference<XInteractionRequest >& Request )
     593             : {
     594             :     ReplyType aReplyType;
     595             : 
     596           0 :     do {
     597             :         {
     598           0 :             salhelper::ConditionModifier aMod(m_aRes);
     599           0 :             m_aResultType = INTERACTIONREQUEST;
     600           0 :             m_aResult <<= Request;
     601             :         }
     602             : 
     603             :         {
     604           0 :             salhelper::ConditionWaiter aWait(m_aRep);
     605           0 :             aReplyType = m_aReplyType;
     606             : 
     607             :             // reset
     608           0 :             m_aReplyType = NOREPLY;
     609             :         }
     610             : 
     611           0 :         if(aReplyType == EXIT) {
     612             :             Sequence<Reference<XInteractionContinuation> > aSeq(
     613           0 :                 Request->getContinuations());
     614           0 :             for(sal_Int32 i = 0; i < aSeq.getLength(); ++i) {
     615           0 :                 Reference<XInteractionAbort> aRef(aSeq[i],UNO_QUERY);
     616           0 :                 if(aRef.is()) {
     617           0 :                     aRef->select();
     618             :                 }
     619           0 :             }
     620             : 
     621             :             // resignal the exitcondition
     622           0 :             setReply(EXIT);
     623           0 :             break;
     624             :         }
     625             :     } while(aReplyType != REQUESTHANDLED);
     626           0 : }
     627             : 
     628           0 : void Moderator::setStream(const Reference< XStream >& aStream)
     629             : {
     630             :     {
     631           0 :         salhelper::ConditionModifier aMod(m_aRes);
     632           0 :         m_aResultType = STREAM;
     633           0 :         m_aResult <<= aStream;
     634             :     }
     635             :     ReplyType aReplyType;
     636             :     {
     637           0 :         salhelper::ConditionWaiter aWait(m_aRep);
     638           0 :         aReplyType = m_aReplyType;
     639           0 :         m_aReplyType = NOREPLY;
     640             :     }
     641           0 :     if(aReplyType == EXIT)
     642           0 :         setReply(EXIT);
     643           0 : }
     644             : 
     645           0 : void Moderator::setInputStream(const Reference<XInputStream> &rxInputStream)
     646             : {
     647             :     {
     648           0 :         salhelper::ConditionModifier aMod(m_aRes);
     649           0 :         m_aResultType = INPUTSTREAM;
     650           0 :         m_aResult <<= rxInputStream;
     651             :     }
     652             :     ReplyType aReplyType;
     653             :     {
     654           0 :         salhelper::ConditionWaiter aWait(m_aRep);
     655           0 :         aReplyType = m_aReplyType;
     656           0 :         m_aReplyType = NOREPLY;
     657             :     }
     658           0 :     if(aReplyType == EXIT)
     659           0 :         setReply(EXIT);
     660           0 : }
     661             : 
     662           0 : void SAL_CALL Moderator::run()
     663             : {
     664           0 :     osl_setThreadName("utl::Moderator");
     665             : 
     666             :     ResultType aResultType;
     667           0 :     Any        aResult;
     668           0 :     sal_Int32  nIOErrorCode = 0;
     669             : 
     670             :     try
     671             :     {
     672           0 :         aResult = m_aContent.executeCommand(m_aArg.Name,m_aArg.Argument);
     673           0 :         aResultType = RESULT;
     674             :     }
     675           0 :     catch (const CommandAbortedException&)
     676             :     {
     677           0 :         aResultType = COMMANDABORTED;
     678             :     }
     679           0 :     catch (const CommandFailedException&)
     680             :     {
     681           0 :         aResultType = COMMANDFAILED;
     682             :     }
     683           0 :     catch (const InteractiveIOException& r)
     684             :     {
     685           0 :         nIOErrorCode = r.Code;
     686           0 :         aResultType = INTERACTIVEIO;
     687             :     }
     688           0 :     catch (const UnsupportedDataSinkException &)
     689             :     {
     690           0 :         aResultType = UNSUPPORTED;
     691             :     }
     692           0 :     catch (const Exception&)
     693             :     {
     694           0 :         aResultType = GENERAL;
     695             :     }
     696             : 
     697             :     {
     698           0 :         salhelper::ConditionModifier aMod(m_aRes);
     699           0 :         m_aResultType = aResultType;
     700           0 :         m_aResult = aResult;
     701           0 :         m_nIOErrorCode = nIOErrorCode;
     702           0 :     }
     703           0 : }
     704             : 
     705           0 : void SAL_CALL Moderator::onTerminated()
     706             : {
     707             :     {
     708           0 :         salhelper::ConditionWaiter aWaiter(m_aRep);
     709             :     }
     710           0 :      delete this;
     711           0 : }
     712             : 
     713             : /**
     714             :    Function for opening UCB contents synchronously,
     715             :    but with handled timeout;
     716             : */
     717             : static bool _UCBOpenContentSync(
     718             :     UcbLockBytesRef xLockBytes,
     719             :     Reference < XContent > xContent,
     720             :     const Command& rArg,
     721             :     Reference < XInterface > xSink,
     722             :     Reference < XInteractionHandler > xInteract );
     723             : 
     724       19669 : static bool UCBOpenContentSync(
     725             :     UcbLockBytesRef xLockBytes,
     726             :     Reference < XContent > xContent,
     727             :     const Command& rArg,
     728             :     Reference < XInterface > xSink,
     729             :     Reference < XInteractionHandler > xInteract )
     730             : {
     731             :     // http protocol must be handled in a special way:
     732             :     //        during the opening process the input stream may change
     733             :     //        only the last inputstream after notifying the document
     734             :     //        headers is valid
     735             : 
     736             :     Reference<XContentIdentifier> xContId(
     737       19669 :         xContent.is() ? xContent->getIdentifier() : 0 );
     738             : 
     739       39338 :     OUString aScheme;
     740       19669 :     if(xContId.is())
     741       19669 :         aScheme = xContId->getContentProviderScheme();
     742             : 
     743             :     // now determine whether we use a timeout or not;
     744       59007 :     if( ! aScheme.equalsIgnoreAsciiCase("http")                &&
     745       39338 :         ! aScheme.equalsIgnoreAsciiCase("https")               &&
     746       59007 :         ! aScheme.equalsIgnoreAsciiCase("vnd.sun.star.webdav") &&
     747       19669 :         ! aScheme.equalsIgnoreAsciiCase("ftp"))
     748             :         return _UCBOpenContentSync(
     749       19669 :             xLockBytes,xContent,rArg,xSink,xInteract);
     750             : 
     751           0 :     if ( !aScheme.equalsIgnoreAsciiCase( "http" ) &&
     752           0 :          !aScheme.equalsIgnoreAsciiCase( "https" ) )
     753           0 :         xLockBytes->SetStreamValid_Impl();
     754             : 
     755           0 :     Reference< XPropertiesChangeListener > xListener;
     756           0 :     Reference< XPropertiesChangeNotifier > xProps(xContent,UNO_QUERY);
     757           0 :     if(xProps.is()) {
     758           0 :         xListener =
     759           0 :             new UcbPropertiesChangeListener_Impl(xLockBytes);
     760           0 :         xProps->addPropertiesChangeListener(
     761             :             Sequence< OUString >(),
     762           0 :             xListener);
     763             :     }
     764             : 
     765           0 :     Any aResult;
     766           0 :     bool bException(false);
     767           0 :     bool bAborted(false);
     768           0 :     bool bResultAchieved(false);
     769             : 
     770           0 :     Moderator* pMod = 0;
     771             :     try
     772             :     {
     773           0 :         pMod = new Moderator(xContent,xInteract,rArg);
     774           0 :         pMod->create();
     775             :     }
     776           0 :     catch (const ContentCreationException&)
     777             :     {
     778           0 :         bResultAchieved = bException = true;
     779           0 :         xLockBytes->SetError( ERRCODE_IO_GENERAL );
     780             :     }
     781             : 
     782           0 :     sal_uInt32 nTimeout(5000); // initially 5000 milliSec
     783           0 :     while(!bResultAchieved) {
     784             : 
     785           0 :         Moderator::Result res;
     786             :         // try to get the result for with timeout
     787           0 :         res = pMod->getResult(nTimeout);
     788             : 
     789           0 :         switch(res.type) {
     790             :         case Moderator::PROGRESSPUSH:
     791             :             {
     792           0 :                 pMod->setReply(Moderator::REQUESTHANDLED);
     793           0 :                 break;
     794             :             }
     795             :         case Moderator::PROGRESSUPDATE:
     796             :             {
     797           0 :                 pMod->setReply(Moderator::REQUESTHANDLED);
     798           0 :                 break;
     799             :             }
     800             :         case Moderator::PROGRESSPOP:
     801             :             {
     802           0 :                 pMod->setReply(Moderator::REQUESTHANDLED);
     803           0 :                 break;
     804             :             }
     805             :         case Moderator::STREAM:
     806             :             {
     807           0 :                 Reference<XStream> result;
     808           0 :                 if(res.result >>= result) {
     809             :                     Reference < XActiveDataStreamer > xStreamer(
     810             :                         xSink, UNO_QUERY
     811           0 :                     );
     812             : 
     813           0 :                     if(xStreamer.is())
     814           0 :                         xStreamer->setStream(result);
     815             :                 }
     816           0 :                 pMod->setReply(Moderator::REQUESTHANDLED);
     817           0 :                 break;
     818             :             }
     819             :         case Moderator::INPUTSTREAM:
     820             :             {
     821           0 :                 Reference<XInputStream> result;
     822           0 :                 res.result >>= result;
     823             :                 Reference < XActiveDataSink > xActiveSink(
     824             :                     xSink, UNO_QUERY
     825           0 :                 );
     826             : 
     827           0 :                 if(xActiveSink.is())
     828           0 :                     xActiveSink->setInputStream(result);
     829           0 :                 pMod->setReply(Moderator::REQUESTHANDLED);
     830           0 :                 break;
     831             :             }
     832             :         case Moderator::TIMEDOUT:
     833             :             {
     834           0 :                 Reference<XInteractionRetry> xRet;
     835           0 :                 if(xInteract.is()) {
     836           0 :                     InteractiveNetworkConnectException aExcep;
     837             :                     INetURLObject aURL(
     838           0 :                         xContId.is() ?
     839           0 :                         xContId->getContentIdentifier() :
     840           0 :                         OUString() );
     841           0 :                     aExcep.Server = aURL.GetHost();
     842           0 :                     aExcep.Classification = InteractionClassification_ERROR;
     843           0 :                     aExcep.Message = "server not responding after five seconds";
     844           0 :                     Any request;
     845           0 :                     request <<= aExcep;
     846             :                     ucbhelper::InteractionRequest *ir =
     847           0 :                         new ucbhelper::InteractionRequest(request);
     848           0 :                     Reference<XInteractionRequest> xIR(ir);
     849           0 :                     Sequence<Reference<XInteractionContinuation> > aSeq(2);
     850             :                     ucbhelper::InteractionRetry *retryP =
     851           0 :                         new ucbhelper::InteractionRetry(ir);
     852           0 :                     aSeq[0] = retryP;
     853             :                     ucbhelper::InteractionAbort *abortP =
     854           0 :                         new ucbhelper::InteractionAbort(ir);
     855           0 :                     aSeq[1] = abortP;
     856             : 
     857           0 :                     ir->setContinuations(aSeq);
     858           0 :                     xInteract->handle(xIR);
     859             :                     rtl::Reference< ucbhelper::InteractionContinuation > ref
     860           0 :                         = ir->getSelection();
     861           0 :                     if(ref.is()) {
     862           0 :                         Reference<XInterface> xInt(ref.get());
     863           0 :                         xRet = Reference<XInteractionRetry>(xInt,UNO_QUERY);
     864           0 :                     }
     865             :                 }
     866             : 
     867           0 :                 if(!xRet.is()) {
     868           0 :                     bAborted = true;
     869           0 :                     xLockBytes->SetError(ERRCODE_ABORT);
     870             :                 }
     871             : 
     872           0 :                 break;
     873             :             }
     874             :         case Moderator::INTERACTIONREQUEST:
     875             :             {
     876           0 :                 Reference<XInteractionRequest> Request;
     877           0 :                 res.result >>= Request;
     878           0 :                 xInteract->handle(Request);
     879           0 :                 pMod->setReply(Moderator::REQUESTHANDLED);
     880           0 :                 break;
     881             :             }
     882             :         case Moderator::RESULT:
     883             :             {
     884           0 :                 bResultAchieved = true;
     885           0 :                 aResult = res.result;
     886           0 :                 break;
     887             :             }
     888             :         case Moderator::COMMANDABORTED:
     889             :             {
     890           0 :                 bAborted = true;
     891           0 :                 xLockBytes->SetError( ERRCODE_ABORT );
     892           0 :                 break;
     893             :             }
     894             :         case Moderator::COMMANDFAILED:
     895             :             {
     896           0 :                 bAborted = true;
     897           0 :                 xLockBytes->SetError( ERRCODE_ABORT );
     898           0 :                 break;
     899             :             }
     900             :         case Moderator::INTERACTIVEIO:
     901             :             {
     902           0 :                 bException = true;
     903           0 :                 if ( res.ioErrorCode == IOErrorCode_ACCESS_DENIED ||
     904           0 :                      res.ioErrorCode == IOErrorCode_LOCKING_VIOLATION )
     905           0 :                     xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
     906           0 :                 else if ( res.ioErrorCode == IOErrorCode_NOT_EXISTING )
     907           0 :                     xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
     908           0 :                 else if ( res.ioErrorCode == IOErrorCode_CANT_READ )
     909           0 :                     xLockBytes->SetError( ERRCODE_IO_CANTREAD );
     910             :                 else
     911           0 :                     xLockBytes->SetError( ERRCODE_IO_GENERAL );
     912           0 :                 break;
     913             :             }
     914             :         case Moderator::UNSUPPORTED:
     915             :             {
     916           0 :                 bException = true;
     917           0 :                 xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
     918           0 :                 break;
     919             :             }
     920             :         default:
     921             :             {
     922           0 :                 bException = true;
     923           0 :                 xLockBytes->SetError( ERRCODE_IO_GENERAL );
     924           0 :                 break;
     925             :             }
     926             :         }
     927             : 
     928           0 :         bResultAchieved |= bException;
     929           0 :         bResultAchieved |= bAborted;
     930           0 :         if(nTimeout == 5000) nTimeout *= 2;
     931           0 :     }
     932             : 
     933           0 :     if(pMod) pMod->setReply(Moderator::EXIT);
     934             : 
     935           0 :     if ( bAborted || bException )
     936             :     {
     937           0 :         Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
     938           0 :         if ( xActiveSink.is() )
     939           0 :             xActiveSink->setInputStream( Reference < XInputStream >() );
     940             : 
     941           0 :         Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
     942           0 :         if ( xStreamer.is() )
     943           0 :             xStreamer->setStream( Reference < XStream >() );
     944             :     }
     945             : 
     946           0 :     Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
     947           0 :     if ( xControl.is() )
     948           0 :         xControl->terminate();
     949             : 
     950           0 :     if ( xProps.is() )
     951           0 :         xProps->removePropertiesChangeListener(
     952             :             Sequence< OUString >(),
     953           0 :             xListener );
     954             : 
     955       19669 :     return ( bAborted || bException );
     956             : }
     957             : 
     958             : /**
     959             :     Function for opening UCB contents synchronously
     960             :  */
     961       19669 : static bool _UCBOpenContentSync(
     962             :     UcbLockBytesRef xLockBytes,
     963             :     Reference < XContent > xContent,
     964             :     const Command& rArg,
     965             :     Reference < XInterface > xSink,
     966             :     Reference < XInteractionHandler > xInteract )
     967             : {
     968             :     ::ucbhelper::Content aContent(
     969       19669 :         xContent, new UcbTaskEnvironment( xInteract, 0 ),
     970       39338 :         comphelper::getProcessComponentContext() );
     971       39338 :     Reference < XContentIdentifier > xIdent = xContent->getIdentifier();
     972       39338 :     OUString aScheme = xIdent->getContentProviderScheme();
     973             : 
     974             :     // http protocol must be handled in a special way: during the opening process the input stream may change
     975             :     // only the last inputstream after notifying the document headers is valid
     976       19669 :     if ( !aScheme.equalsIgnoreAsciiCase("http") )
     977       19669 :         xLockBytes->SetStreamValid_Impl();
     978             : 
     979       39338 :     Reference< XPropertiesChangeListener > xListener = new UcbPropertiesChangeListener_Impl( xLockBytes );
     980       39338 :     Reference< XPropertiesChangeNotifier > xProps ( xContent, UNO_QUERY );
     981       19669 :     if ( xProps.is() )
     982       19669 :         xProps->addPropertiesChangeListener( Sequence< OUString >(), xListener );
     983             : 
     984       39338 :     Any aResult;
     985       19669 :     bool bException = false;
     986       19669 :     bool bAborted = false;
     987             : 
     988             :     try
     989             :     {
     990       19669 :         aResult = aContent.executeCommand( rArg.Name, rArg.Argument );
     991             :     }
     992           0 :     catch (const CommandAbortedException&)
     993             :     {
     994           0 :         bAborted = true;
     995           0 :         xLockBytes->SetError( ERRCODE_ABORT );
     996             :     }
     997           0 :     catch (const CommandFailedException&)
     998             :     {
     999           0 :         bAborted = true;
    1000           0 :         xLockBytes->SetError( ERRCODE_ABORT );
    1001             :     }
    1002         170 :     catch (const InteractiveIOException& r)
    1003             :     {
    1004          85 :         bException = true;
    1005          85 :         if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
    1006           0 :             xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
    1007          85 :         else if ( r.Code == IOErrorCode_NOT_EXISTING )
    1008          85 :             xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
    1009           0 :         else if ( r.Code == IOErrorCode_CANT_READ )
    1010           0 :             xLockBytes->SetError( ERRCODE_IO_CANTREAD );
    1011             :         else
    1012           0 :             xLockBytes->SetError( ERRCODE_IO_GENERAL );
    1013             :     }
    1014           0 :     catch (const UnsupportedDataSinkException&)
    1015             :     {
    1016           0 :         bException = true;
    1017           0 :         xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
    1018             :     }
    1019           0 :     catch (const Exception&)
    1020             :     {
    1021           0 :         bException = true;
    1022           0 :         xLockBytes->SetError( ERRCODE_IO_GENERAL );
    1023             :     }
    1024             : 
    1025       19669 :     if ( bAborted || bException )
    1026             :     {
    1027          85 :         Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
    1028          85 :         if ( xActiveSink.is() )
    1029          75 :             xActiveSink->setInputStream( Reference < XInputStream >() );
    1030             : 
    1031         170 :         Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
    1032          85 :         if ( xStreamer.is() )
    1033          95 :             xStreamer->setStream( Reference < XStream >() );
    1034             :     }
    1035             : 
    1036       39338 :     Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
    1037       19669 :     if ( xControl.is() )
    1038       19669 :         xControl->terminate();
    1039             : 
    1040       19669 :     if ( xProps.is() )
    1041       19669 :         xProps->removePropertiesChangeListener( Sequence< OUString >(), xListener );
    1042             : 
    1043       39338 :     return ( bAborted || bException );
    1044             : }
    1045             : 
    1046       46772 : UcbLockBytes::UcbLockBytes( UcbLockBytesHandler* pHandler )
    1047             :     : m_aExpireDate( DateTime::EMPTY )
    1048             :     , m_xInputStream (NULL)
    1049             :     , m_pCommandThread( NULL )
    1050             :     , m_xHandler( pHandler )
    1051             :     , m_nError( ERRCODE_NONE )
    1052             :     , m_bTerminated  (false)
    1053             :     , m_bDontClose( false )
    1054       46772 :     , m_bStreamValid  (false)
    1055             : {
    1056       46772 :     SetSynchronMode( true );
    1057       46772 : }
    1058             : 
    1059      186880 : UcbLockBytes::~UcbLockBytes()
    1060             : {
    1061       46720 :     if ( !m_bDontClose )
    1062             :     {
    1063          69 :         if ( m_xInputStream.is() )
    1064             :         {
    1065             :             try
    1066             :             {
    1067           0 :                 m_xInputStream->closeInput();
    1068             :             }
    1069           0 :             catch (const RuntimeException&)
    1070             :             {
    1071             :             }
    1072           0 :             catch (const IOException&)
    1073             :             {
    1074             :             }
    1075             :         }
    1076             :     }
    1077             : 
    1078       46720 :     if ( !m_xInputStream.is() && m_xOutputStream.is() )
    1079             :     {
    1080             :         try
    1081             :         {
    1082           0 :             m_xOutputStream->closeOutput();
    1083             :         }
    1084           0 :         catch (const RuntimeException&)
    1085             :         {
    1086             :         }
    1087           0 :         catch (const IOException&)
    1088             :         {
    1089             :         }
    1090             :     }
    1091      140160 : }
    1092             : 
    1093       19584 : Reference < XInputStream > UcbLockBytes::getInputStream()
    1094             : {
    1095       19584 :     osl::MutexGuard aGuard( m_aMutex );
    1096       19584 :     m_bDontClose = true;
    1097       19584 :     return m_xInputStream;
    1098             : }
    1099             : 
    1100       22915 : bool UcbLockBytes::setStream_Impl( const Reference<XStream>& aStream )
    1101             : {
    1102       22915 :     osl::MutexGuard aGuard( m_aMutex );
    1103       22915 :     if ( aStream.is() )
    1104             :     {
    1105       22895 :         m_xOutputStream = aStream->getOutputStream();
    1106       22895 :         setInputStream_Impl( aStream->getInputStream(), false );
    1107       22895 :         m_xSeekable = Reference < XSeekable > ( aStream, UNO_QUERY );
    1108             :     }
    1109             :     else
    1110             :     {
    1111          20 :         m_xOutputStream.clear();
    1112          20 :         setInputStream_Impl( Reference < XInputStream >() );
    1113             :     }
    1114             : 
    1115       22915 :     return m_xInputStream.is();
    1116             : }
    1117             : 
    1118       46808 : bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream, bool bSetXSeekable )
    1119             : {
    1120       46808 :     bool bRet = false;
    1121             : 
    1122             :     try
    1123             :     {
    1124       46808 :         osl::MutexGuard aGuard( m_aMutex );
    1125             : 
    1126       46808 :         if ( !m_bDontClose && m_xInputStream.is() )
    1127           0 :             m_xInputStream->closeInput();
    1128             : 
    1129       46808 :         m_xInputStream = rxInputStream;
    1130             : 
    1131       46808 :         if( bSetXSeekable )
    1132             :         {
    1133       23913 :             m_xSeekable = Reference < XSeekable > ( rxInputStream, UNO_QUERY );
    1134       23913 :             if( !m_xSeekable.is() && rxInputStream.is() )
    1135             :             {
    1136        1328 :                 Reference < XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    1137        2654 :                 Reference< XOutputStream > rxTempOut = Reference < XOutputStream > ( TempFile::create(xContext), UNO_QUERY_THROW );
    1138             : 
    1139        1326 :                 ::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream, rxTempOut );
    1140        1326 :                 m_xInputStream = Reference< XInputStream >( rxTempOut, UNO_QUERY );
    1141        2654 :                 m_xSeekable = Reference < XSeekable > ( rxTempOut, UNO_QUERY );
    1142             :             }
    1143             :         }
    1144             : 
    1145       46808 :         bRet = m_xInputStream.is();
    1146             :     }
    1147           2 :     catch (const Exception&)
    1148             :     {
    1149             :     }
    1150             : 
    1151       46808 :     if ( m_bStreamValid && m_xInputStream.is() )
    1152       19584 :         m_aInitialized.set();
    1153             : 
    1154       46808 :     return bRet;
    1155             : }
    1156             : 
    1157       19669 : void UcbLockBytes::SetStreamValid_Impl()
    1158             : {
    1159       19669 :     m_bStreamValid = true;
    1160       19669 :     if ( m_xInputStream.is() )
    1161           0 :         m_aInitialized.set();
    1162       19669 : }
    1163             : 
    1164       46772 : void UcbLockBytes::terminate_Impl()
    1165             : {
    1166       46772 :     m_bTerminated = true;
    1167       46772 :     m_aInitialized.set();
    1168       46772 :     m_aTerminated.set();
    1169             : 
    1170       46772 :     if ( GetError() == ERRCODE_NONE && !m_xInputStream.is() )
    1171             :     {
    1172             :         OSL_FAIL("No InputStream, but no error set!" );
    1173           0 :         SetError( ERRCODE_IO_NOTEXISTS );
    1174             :     }
    1175       46772 : }
    1176             : 
    1177       66568 : void UcbLockBytes::SetSynchronMode (bool bSynchron)
    1178             : {
    1179       66568 :     SvLockBytes::SetSynchronMode (bSynchron);
    1180       66568 : }
    1181             : 
    1182      197383 : ErrCode UcbLockBytes::ReadAt(sal_uInt64 const nPos,
    1183             :         void *pBuffer, sal_uLong nCount, sal_uLong *pRead) const
    1184             : {
    1185      197383 :     if ( IsSynchronMode() )
    1186             :     {
    1187      197383 :         UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
    1188      197383 :         pThis->m_aInitialized.wait();
    1189             :     }
    1190             : 
    1191      197383 :     Reference <XInputStream> xStream = getInputStream_Impl();
    1192      197383 :     if ( !xStream.is() )
    1193             :     {
    1194           0 :         if ( m_bTerminated )
    1195           0 :             return ERRCODE_IO_CANTREAD;
    1196             :         else
    1197           0 :             return ERRCODE_IO_PENDING;
    1198             :     }
    1199             : 
    1200      197383 :     if ( pRead )
    1201      197383 :         *pRead = 0;
    1202             : 
    1203      394766 :     Reference <XSeekable> xSeekable = getSeekable_Impl();
    1204      197383 :     if ( !xSeekable.is() )
    1205           0 :         return ERRCODE_IO_CANTREAD;
    1206             : 
    1207             :     try
    1208             :     {
    1209      197383 :         xSeekable->seek( nPos );
    1210             :     }
    1211           0 :     catch (const IOException&)
    1212             :     {
    1213           0 :         return ERRCODE_IO_CANTSEEK;
    1214             :     }
    1215           2 :     catch (const com::sun::star::lang::IllegalArgumentException&)
    1216             :     {
    1217           1 :         return ERRCODE_IO_CANTSEEK;
    1218             :     }
    1219             : 
    1220      394764 :     Sequence<sal_Int8> aData;
    1221             :     sal_Int32          nSize;
    1222             : 
    1223      197382 :     if(nCount > 0x7FFFFFFF)
    1224             :     {
    1225           0 :         nCount = 0x7FFFFFFF;
    1226             :     }
    1227             :     try
    1228             :     {
    1229      197382 :         if ( !m_bTerminated && !IsSynchronMode() )
    1230             :         {
    1231           0 :             sal_uInt64 nLen = xSeekable->getLength();
    1232           0 :             if ( nPos + nCount > nLen )
    1233           0 :                 return ERRCODE_IO_PENDING;
    1234             :         }
    1235             : 
    1236      197382 :         nSize = xStream->readBytes( aData, sal_Int32(nCount) );
    1237             :     }
    1238           0 :     catch (const IOException&)
    1239             :     {
    1240           0 :         return ERRCODE_IO_CANTREAD;
    1241             :     }
    1242             : 
    1243      197382 :     memcpy (pBuffer, aData.getConstArray(), nSize);
    1244      197382 :     if (pRead)
    1245      197382 :         *pRead = sal_uLong(nSize);
    1246             : 
    1247      394765 :     return ERRCODE_NONE;
    1248             : }
    1249             : 
    1250       45021 : ErrCode UcbLockBytes::WriteAt(sal_uInt64 const nPos, const void *pBuffer,
    1251             :         sal_uLong nCount, sal_uLong *pWritten)
    1252             : {
    1253       45021 :     if ( pWritten )
    1254       45021 :         *pWritten = 0;
    1255             : 
    1256             :     DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" );
    1257             :     DBG_ASSERT( m_aInitialized.check(), "Writing bevor stream is ready!" );
    1258             : 
    1259       45021 :     Reference <XSeekable> xSeekable = getSeekable_Impl();
    1260       90042 :     Reference <XOutputStream> xOutputStream = getOutputStream_Impl();
    1261       45021 :     if ( !xOutputStream.is() || !xSeekable.is() )
    1262           8 :         return ERRCODE_IO_CANTWRITE;
    1263             : 
    1264             :     try
    1265             :     {
    1266       45013 :         xSeekable->seek( nPos );
    1267             :     }
    1268           0 :     catch (const IOException&)
    1269             :     {
    1270           0 :         return ERRCODE_IO_CANTSEEK;
    1271             :     }
    1272             : 
    1273       45013 :     sal_Int8 const * pData = static_cast<sal_Int8 const *>(pBuffer);
    1274       90026 :     Sequence<sal_Int8> aData( pData, nCount );
    1275             :     try
    1276             :     {
    1277       45013 :         xOutputStream->writeBytes( aData );
    1278       45013 :         if ( pWritten )
    1279       45013 :             *pWritten = nCount;
    1280             :     }
    1281           0 :     catch (const Exception&)
    1282             :     {
    1283           0 :         return ERRCODE_IO_CANTWRITE;
    1284             :     }
    1285             : 
    1286       90034 :     return ERRCODE_NONE;
    1287             : }
    1288             : 
    1289       50346 : ErrCode UcbLockBytes::Flush() const
    1290             : {
    1291       50346 :     Reference <XOutputStream > xOutputStream = getOutputStream_Impl();
    1292       50346 :     if ( !xOutputStream.is() )
    1293       23788 :         return ERRCODE_IO_CANTWRITE;
    1294             : 
    1295             :     try
    1296             :     {
    1297       26558 :         xOutputStream->flush();
    1298             :     }
    1299           2 :     catch (const Exception&)
    1300             :     {
    1301           1 :         return ERRCODE_IO_CANTWRITE;
    1302             :     }
    1303             : 
    1304       26557 :     return ERRCODE_NONE;
    1305             : }
    1306             : 
    1307        3571 : ErrCode UcbLockBytes::SetSize (sal_uInt64 const nNewSize)
    1308             : {
    1309        3571 :     SvLockBytesStat aStat;
    1310        3571 :     Stat( &aStat, (SvLockBytesStatFlag) 0 );
    1311        3571 :     sal_uLong nSize = aStat.nSize;
    1312             : 
    1313        3571 :     if ( nSize > nNewSize )
    1314             :     {
    1315           0 :         Reference < XTruncate > xTrunc( getOutputStream_Impl(), UNO_QUERY );
    1316           0 :         if ( xTrunc.is() )
    1317             :         {
    1318           0 :             xTrunc->truncate();
    1319           0 :             nSize = 0;
    1320             :         }
    1321             :         else {
    1322             :             DBG_WARNING("Not truncatable!");
    1323           0 :         }
    1324             :     }
    1325             : 
    1326        3571 :     if ( nSize < nNewSize )
    1327             :     {
    1328        3571 :         sal_uLong nDiff = nNewSize-nSize, nCount=0;
    1329        3571 :         sal_uInt8* pBuffer = new sal_uInt8[ nDiff ];
    1330        3571 :         memset(pBuffer, 0, nDiff); // initialize for enhanced security
    1331        3571 :         WriteAt( nSize, pBuffer, nDiff, &nCount );
    1332        3571 :         delete[] pBuffer;
    1333        3571 :         if ( nCount != nDiff )
    1334           0 :             return ERRCODE_IO_CANTWRITE;
    1335             :     }
    1336             : 
    1337        3571 :     return ERRCODE_NONE;
    1338             : }
    1339             : 
    1340       76201 : ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const
    1341             : {
    1342       76201 :     if ( IsSynchronMode() )
    1343             :     {
    1344       76201 :         UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
    1345       76201 :         pThis->m_aInitialized.wait();
    1346             :     }
    1347             : 
    1348       76201 :     if (!pStat)
    1349           0 :         return ERRCODE_IO_INVALIDPARAMETER;
    1350             : 
    1351       76201 :     Reference <XInputStream> xStream = getInputStream_Impl();
    1352      152402 :     Reference <XSeekable> xSeekable = getSeekable_Impl();
    1353             : 
    1354       76201 :     if ( !xStream.is() )
    1355             :     {
    1356           0 :         if ( m_bTerminated )
    1357           0 :             return ERRCODE_IO_INVALIDACCESS;
    1358             :         else
    1359           0 :             return ERRCODE_IO_PENDING;
    1360             :     }
    1361       76201 :     else if( !xSeekable.is() )
    1362           4 :         return ERRCODE_IO_CANTTELL;
    1363             : 
    1364             :     try
    1365             :     {
    1366       76197 :         pStat->nSize = sal_uLong(xSeekable->getLength());
    1367             :     }
    1368           0 :     catch (const IOException&)
    1369             :     {
    1370           0 :         return ERRCODE_IO_CANTTELL;
    1371             :     }
    1372             : 
    1373      152398 :     return ERRCODE_NONE;
    1374             : }
    1375             : 
    1376       23612 : UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( const Reference< XInputStream >& xInputStream )
    1377             : {
    1378       23612 :     if( !xInputStream.is() )
    1379           0 :         return NULL;
    1380             : 
    1381       23612 :     UcbLockBytesRef xLockBytes = new UcbLockBytes(nullptr);
    1382       23612 :     xLockBytes->setDontClose_Impl();
    1383       23612 :     xLockBytes->setInputStream_Impl( xInputStream );
    1384       23612 :     xLockBytes->terminate_Impl();
    1385       23612 :     return xLockBytes;
    1386             : }
    1387             : 
    1388        3491 : UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference< XStream >& xStream )
    1389             : {
    1390        3491 :     if( !xStream.is() )
    1391           0 :         return NULL;
    1392             : 
    1393        3491 :     UcbLockBytesRef xLockBytes = new UcbLockBytes(nullptr);
    1394        3491 :     xLockBytes->setDontClose_Impl();
    1395        3491 :     xLockBytes->setStream_Impl( xStream );
    1396        3491 :     xLockBytes->terminate_Impl();
    1397        3491 :     return xLockBytes;
    1398             : }
    1399             : 
    1400       19669 : UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const Sequence < PropertyValue >& rProps,
    1401             :         StreamMode eOpenMode, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
    1402             : {
    1403       19669 :     if( !xContent.is() )
    1404           0 :         return NULL;
    1405             : 
    1406       19669 :     UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
    1407       19669 :     xLockBytes->SetSynchronMode( !pHandler );
    1408       39338 :     Reference< XActiveDataControl > xSink;
    1409       19669 :     if ( eOpenMode & StreamMode::WRITE )
    1410       19414 :         xSink = static_cast<XActiveDataControl*>(new UcbStreamer_Impl( xLockBytes ));
    1411             :     else
    1412         255 :         xSink = static_cast<XActiveDataControl*>(new UcbDataSink_Impl( xLockBytes ));
    1413             : 
    1414       19669 :     if ( rProps.getLength() )
    1415             :     {
    1416           0 :         Reference < XCommandProcessor > xProcessor( xContent, UNO_QUERY );
    1417           0 :         Command aCommand;
    1418           0 :         aCommand.Name     = "setPropertyValues";
    1419           0 :         aCommand.Handle   = -1; /* unknown */
    1420           0 :         aCommand.Argument <<= rProps;
    1421           0 :         xProcessor->execute( aCommand, 0, Reference < XCommandEnvironment >() );
    1422             :     }
    1423             : 
    1424       39338 :     OpenCommandArgument2 aArgument;
    1425       19669 :     aArgument.Sink = xSink;
    1426       19669 :     aArgument.Mode = OpenMode::DOCUMENT;
    1427             : 
    1428       39338 :     Command aCommand;
    1429       19669 :     aCommand.Name = "open";
    1430       19669 :     aCommand.Argument <<= aArgument;
    1431             : 
    1432             :     bool bError = UCBOpenContentSync( xLockBytes,
    1433             :                                       xContent,
    1434             :                                       aCommand,
    1435             :                                       xSink,
    1436       19669 :                                       xInteractionHandler );
    1437             : 
    1438       19669 :     if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
    1439             :     {
    1440             :         OSL_FAIL("No InputStream, but no error set!" );
    1441           0 :            xLockBytes->SetError( ERRCODE_IO_GENERAL );
    1442             :     }
    1443             : 
    1444       39338 :     return xLockBytes;
    1445             : }
    1446             : 
    1447             : }
    1448             : 
    1449             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11