Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / unotools / source / ucbhelper / ucblockbytes.cxx
blobee5e861223803fc132565b17b6af5a21b9131060
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <sal/macros.h>
22 #include <unotools/ucblockbytes.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include <salhelper/condition.hxx>
25 #include <osl/thread.hxx>
26 #include <tools/urlobj.hxx>
27 #include <ucbhelper/interactionrequest.hxx>
28 #include <com/sun/star/task/XInteractionAbort.hpp>
29 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
30 #include <com/sun/star/ucb/CommandFailedException.hpp>
31 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
32 #include <com/sun/star/ucb/InteractiveIOException.hpp>
33 #include <com/sun/star/io/XActiveDataStreamer.hpp>
34 #include <com/sun/star/io/TempFile.hpp>
35 #include <com/sun/star/ucb/DocumentHeaderField.hpp>
36 #include <com/sun/star/ucb/XCommandInfo.hpp>
37 #include <com/sun/star/ucb/XCommandProcessor.hpp>
38 #include <com/sun/star/task/XInteractionHandler.hpp>
39 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
40 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
41 #include <com/sun/star/ucb/OpenMode.hpp>
42 #include <com/sun/star/beans/Property.hpp>
43 #include <com/sun/star/beans/PropertyValue.hpp>
44 #include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
45 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
46 #include <com/sun/star/sdbc/XRow.hpp>
47 #include <com/sun/star/io/XActiveDataSink.hpp>
48 #include <com/sun/star/io/XActiveDataControl.hpp>
49 #include <com/sun/star/io/XSeekable.hpp>
50 #include <cppuhelper/implbase1.hxx>
51 #include <cppuhelper/implbase2.hxx>
52 #include <tools/inetmsg.hxx>
53 #include <com/sun/star/io/XTruncate.hpp>
54 #include <com/sun/star/lang/IllegalArgumentException.hpp>
56 #include <comphelper/storagehelper.hxx>
57 #include <ucbhelper/content.hxx>
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::io;
61 using namespace ::com::sun::star::uno;
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;
68 namespace utl
71 /**
72 Helper class for getting a XInputStream when opening a content
74 class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink >
76 UcbLockBytesRef m_xLockBytes;
78 public:
79 UcbDataSink_Impl( UcbLockBytes* pLockBytes )
80 : m_xLockBytes( pLockBytes )
83 SvLockBytes* getLockBytes (void)
84 { return m_xLockBytes; }
86 // XActiveDataControl.
87 virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
88 virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
89 virtual void SAL_CALL start (void) throw(RuntimeException) {}
90 virtual void SAL_CALL terminate (void) throw(RuntimeException)
91 { m_xLockBytes->terminate_Impl(); }
93 // XActiveDataSink.
94 virtual void SAL_CALL setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException)
95 { m_xLockBytes->setInputStream_Impl (rxInputStream); }
96 virtual Reference<XInputStream> SAL_CALL getInputStream (void) throw(RuntimeException)
97 { return m_xLockBytes->getInputStream_Impl(); }
101 Helper class for getting a XStream when opening a content
103 class UcbStreamer_Impl : public ::cppu::WeakImplHelper2< XActiveDataStreamer, XActiveDataControl >
105 Reference < XStream > m_xStream;
106 UcbLockBytesRef m_xLockBytes;
108 public:
109 UcbStreamer_Impl( UcbLockBytes* pLockBytes )
110 : m_xLockBytes( pLockBytes )
113 // XActiveDataControl.
114 virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
115 virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
116 virtual void SAL_CALL start (void) throw(RuntimeException) {}
117 virtual void SAL_CALL terminate (void) throw(RuntimeException)
118 { m_xLockBytes->terminate_Impl(); }
120 // XActiveDataStreamer
121 virtual void SAL_CALL setStream( const Reference< XStream >& aStream ) throw(RuntimeException)
122 { m_xStream = aStream; m_xLockBytes->setStream_Impl( aStream ); }
123 virtual Reference< XStream > SAL_CALL getStream() throw(RuntimeException)
124 { return m_xStream; }
128 Helper class for progress handling while executing UCB commands
130 class ProgressHandler_Impl: public ::cppu::WeakImplHelper1< XProgressHandler >
132 Link m_aProgress;
134 public:
135 ProgressHandler_Impl( const Link& rLink )
136 : m_aProgress( rLink )
138 // XProgressHandler
139 virtual void SAL_CALL push(const Any & /*rStatus*/) throw (RuntimeException) {}
140 virtual void SAL_CALL pop() throw (RuntimeException) {}
141 virtual void SAL_CALL update(const Any & /*rStatus*/) throw (RuntimeException)
142 { if ( m_aProgress.IsSet() ) m_aProgress.Call( 0 ); }
146 Helper class for managing interactions and progress when executing UCB commands
148 class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment >
150 Reference< XInteractionHandler > m_xInteractionHandler;
151 Reference< XProgressHandler > m_xProgressHandler;
153 public:
154 UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler,
155 const Reference< XProgressHandler>& rxProgressHandler )
156 : m_xInteractionHandler( rxInteractionHandler )
157 , m_xProgressHandler( rxProgressHandler )
160 virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException)
161 { return m_xInteractionHandler; }
163 virtual Reference<XProgressHandler> SAL_CALL getProgressHandler() throw (RuntimeException)
164 { return m_xProgressHandler; }
169 Helper class for property change notifies when executing UCB commands
171 class UcbPropertiesChangeListener_Impl : public ::cppu::WeakImplHelper1< XPropertiesChangeListener >
173 public:
174 UcbLockBytesRef m_xLockBytes;
176 UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef )
177 : m_xLockBytes( rRef )
180 virtual void SAL_CALL disposing ( const EventObject &/*rEvent*/) throw(RuntimeException) {}
181 virtual void SAL_CALL propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException);
184 void SAL_CALL UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException)
186 sal_Int32 i, n = rEvent.getLength();
187 for (i = 0; i < n; i++)
189 PropertyChangeEvent evt (rEvent[i]);
190 if (evt.PropertyName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("DocumentHeader")))
192 Sequence<DocumentHeaderField> aHead;
193 if (evt.NewValue >>= aHead)
195 sal_Int32 k, m = aHead.getLength();
196 for (k = 0; k < m; k++)
198 String aName( aHead[k].Name );
199 String aValue( aHead[k].Value );
201 if (aName.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL)
203 DateTime aExpires (0, 0);
204 if (INetRFC822Message::ParseDateField (aValue, aExpires))
206 aExpires.ConvertToLocalTime();
207 m_xLockBytes->SetExpireDate_Impl( aExpires );
213 m_xLockBytes->SetStreamValid_Impl();
215 else if (evt.PropertyName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("PresentationURL")))
217 ::rtl::OUString aUrl;
218 if (evt.NewValue >>= aUrl)
220 ::rtl::OUString aBad (RTL_CONSTASCII_USTRINGPARAM ("private:"));
221 if (!(aUrl.compareTo (aBad, aBad.getLength()) == 0))
223 // URL changed (Redirection).
224 m_xLockBytes->SetRealURL_Impl( aUrl );
228 else if (evt.PropertyName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("MediaType")))
230 ::rtl::OUString aContentType;
231 if (evt.NewValue >>= aContentType)
232 m_xLockBytes->SetContentType_Impl( aContentType );
239 class Moderator
240 : public osl::Thread
242 // usage restriction:
243 // It might be possible, that the call to the interactionhandler and/or
244 // progresshandler is done asynchrounsly, while the 'execute' simply
245 // returns. This would imply that these class must be refcounted !!!
247 public:
248 Moderator(
249 Reference < XContent >& xContent,
250 Reference < XInteractionHandler >& xInteract,
251 Reference < XProgressHandler >& xProgress,
252 const Command& rArg
254 throw(
255 ContentCreationException,
256 RuntimeException
259 ~Moderator();
262 enum ResultType {
263 NORESULT,
265 INTERACTIONREQUEST, // reply expected
267 PROGRESSPUSH,
268 PROGRESSUPDATE,
269 PROGRESSPOP,
271 INPUTSTREAM,
272 STREAM,
274 RESULT,
275 TIMEDOUT,
276 COMMANDABORTED,
277 COMMANDFAILED,
278 INTERACTIVEIO,
279 UNSUPPORTED,
280 GENERAL
284 class ConditionRes
285 : public salhelper::Condition
287 public:
288 ConditionRes(osl::Mutex& aMutex,Moderator& aModerator)
289 : salhelper::Condition(aMutex),
290 m_aModerator(aModerator)
294 protected:
295 bool applies() const {
296 return m_aModerator.m_aResultType != NORESULT;
299 private:
300 Moderator& m_aModerator;
304 struct Result {
305 ResultType type;
306 Any result;
307 sal_Int32 ioErrorCode;
310 Result getResult(const sal_uInt32 milliSec);
312 enum ReplyType {
313 NOREPLY,
314 EXIT,
315 RETRY,
316 REQUESTHANDLED
319 class ConditionRep
320 : public salhelper::Condition
322 public:
323 ConditionRep(osl::Mutex& aMutex,Moderator& aModerator)
324 : salhelper::Condition(aMutex),
325 m_aModerator(aModerator)
329 protected:
330 bool applies() const {
331 return m_aModerator.m_aReplyType != NOREPLY;
334 private:
335 Moderator& m_aModerator;
338 void setReply(ReplyType);
340 void handle( const Reference<XInteractionRequest >& Request );
341 void push( const Any& Status );
342 void update( const Any& Status );
343 void pop( );
345 void setStream(const Reference< XStream >& aStream);
346 void setInputStream(const Reference<XInputStream> &rxInputStream);
349 protected:
350 virtual void SAL_CALL run();
351 virtual void SAL_CALL onTerminated();
353 private:
354 osl::Mutex m_aMutex;
356 friend class ConditionRes;
358 ConditionRes m_aRes;
359 ResultType m_aResultType;
360 sal_Int32 m_nIOErrorCode;
361 Any m_aResult;
363 friend class ConditionRep;
365 ConditionRep m_aRep;
366 ReplyType m_aReplyType;
368 Command m_aArg;
369 ::ucbhelper::Content m_aContent;
373 class ModeratorsActiveDataStreamer
374 : public ::cppu::WeakImplHelper1<XActiveDataStreamer>
376 public:
378 ModeratorsActiveDataStreamer(Moderator &theModerator);
380 ~ModeratorsActiveDataStreamer();
382 // XActiveDataStreamer
383 virtual void SAL_CALL
384 setStream(
385 const Reference< XStream >& aStream
387 throw(
388 RuntimeException
391 virtual Reference<XStream> SAL_CALL
392 getStream (
393 void
394 ) throw(
395 RuntimeException
398 osl::MutexGuard aGuard(m_aMutex);
399 return m_xStream;
403 private:
404 Moderator& m_aModerator;
406 osl::Mutex m_aMutex;
407 Reference<XStream> m_xStream;
411 class ModeratorsActiveDataSink
412 : public ::cppu::WeakImplHelper1<XActiveDataSink>
414 public:
416 ModeratorsActiveDataSink(Moderator &theModerator);
418 ~ModeratorsActiveDataSink();
420 // XActiveDataSink.
421 virtual void SAL_CALL
422 setInputStream (
423 const Reference<XInputStream> &rxInputStream
425 throw(
426 RuntimeException
429 virtual Reference<XInputStream> SAL_CALL
430 getInputStream (
431 void
432 ) throw(
433 RuntimeException
436 osl::MutexGuard aGuard(m_aMutex);
437 return m_xStream;
441 private:
442 Moderator& m_aModerator;
443 osl::Mutex m_aMutex;
444 Reference<XInputStream> m_xStream;
449 ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator &theModerator)
450 : m_aModerator(theModerator)
455 ModeratorsActiveDataSink::~ModeratorsActiveDataSink()
459 // XActiveDataSink.
460 void SAL_CALL
461 ModeratorsActiveDataSink::setInputStream (
462 const Reference<XInputStream> &rxInputStream
464 throw(
465 RuntimeException
468 m_aModerator.setInputStream(rxInputStream);
469 osl::MutexGuard aGuard(m_aMutex);
470 m_xStream = rxInputStream;
474 ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer(
475 Moderator &theModerator
477 : m_aModerator(theModerator)
482 ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer()
486 // XActiveDataStreamer.
487 void SAL_CALL
488 ModeratorsActiveDataStreamer::setStream (
489 const Reference<XStream> &rxStream
491 throw(
492 RuntimeException
495 m_aModerator.setStream(rxStream);
496 osl::MutexGuard aGuard(m_aMutex);
497 m_xStream = rxStream;
502 class ModeratorsInteractionHandler
503 : public ::cppu::WeakImplHelper1<XInteractionHandler>
505 public:
507 ModeratorsInteractionHandler(Moderator &theModerator);
509 ~ModeratorsInteractionHandler();
511 virtual void SAL_CALL
512 handle( const Reference<XInteractionRequest >& Request )
513 throw (RuntimeException);
515 private:
517 Moderator& m_aModerator;
521 class ModeratorsProgressHandler
522 : public ::cppu::WeakImplHelper1<XProgressHandler>
524 public:
525 ModeratorsProgressHandler(Moderator &theModerator);
527 ~ModeratorsProgressHandler();
529 virtual void SAL_CALL push( const Any& Status )
530 throw (
531 RuntimeException);
533 virtual void SAL_CALL update( const Any& Status )
534 throw (RuntimeException);
536 virtual void SAL_CALL pop( )
537 throw (RuntimeException);
540 private:
541 Moderator& m_aModerator;
545 ModeratorsProgressHandler::ModeratorsProgressHandler(Moderator &theModerator)
546 : m_aModerator(theModerator)
550 ModeratorsProgressHandler::~ModeratorsProgressHandler()
555 void SAL_CALL ModeratorsProgressHandler::push( const Any& Status )
556 throw (
557 RuntimeException)
559 m_aModerator.push(Status);
563 void SAL_CALL ModeratorsProgressHandler::update( const Any& Status )
564 throw (RuntimeException)
566 m_aModerator.update(Status);
570 void SAL_CALL ModeratorsProgressHandler::pop( )
571 throw (RuntimeException)
573 m_aModerator.pop();
577 ModeratorsInteractionHandler::ModeratorsInteractionHandler(
578 Moderator &aModerator)
579 : m_aModerator(aModerator)
584 ModeratorsInteractionHandler::~ModeratorsInteractionHandler()
589 void SAL_CALL
590 ModeratorsInteractionHandler::handle(
591 const Reference<XInteractionRequest >& Request
593 throw (
594 RuntimeException
597 // wakes up the mainthread
598 m_aModerator.handle(Request);
604 Moderator::Moderator(
605 Reference < XContent >& xContent,
606 Reference < XInteractionHandler >& xInteract,
607 Reference < XProgressHandler >& xProgress,
608 const Command& rArg
610 throw(
611 ::com::sun::star::ucb::ContentCreationException,
612 ::com::sun::star::uno::RuntimeException
614 : m_aMutex(),
616 m_aRes(m_aMutex,*this),
617 m_aResultType(NORESULT),
618 m_nIOErrorCode(0),
619 m_aResult(),
621 m_aRep(m_aMutex,*this),
622 m_aReplyType(NOREPLY),
624 m_aArg(rArg),
625 m_aContent(
626 xContent,
627 new UcbTaskEnvironment(
628 xInteract.is() ? new ModeratorsInteractionHandler(*this) : 0,
629 xProgress.is() ? new ModeratorsProgressHandler(*this) : 0),
630 comphelper::getProcessComponentContext())
632 // now exchange the whole data sink stuff
633 // with a thread safe version
635 Reference<XInterface> *pxSink = NULL;
637 PostCommandArgument2 aPostArg;
638 OpenCommandArgument2 aOpenArg;
640 int dec(2);
641 if(m_aArg.Argument >>= aPostArg) {
642 pxSink = &aPostArg.Sink;
643 dec = 0;
645 else if(m_aArg.Argument >>= aOpenArg) {
646 pxSink = &aOpenArg.Sink;
647 dec = 1;
650 if(dec ==2)
651 throw ContentCreationException();
653 Reference < XActiveDataSink > xActiveSink(*pxSink,UNO_QUERY);
654 if(xActiveSink.is())
655 *pxSink = Reference<XInterface>(
656 (cppu::OWeakObject*)new ModeratorsActiveDataSink(*this));
658 Reference<XActiveDataStreamer> xStreamer( *pxSink, UNO_QUERY );
659 if ( xStreamer.is() )
660 *pxSink = Reference<XInterface>(
661 (cppu::OWeakObject*)new ModeratorsActiveDataStreamer(*this));
663 if(dec == 0)
664 m_aArg.Argument <<= aPostArg;
665 else if(dec == 1)
666 m_aArg.Argument <<= aOpenArg;
670 Moderator::~Moderator()
675 Moderator::Result Moderator::getResult(const sal_uInt32 milliSec)
677 Result ret;
678 try {
679 salhelper::ConditionWaiter aWaiter(m_aRes,milliSec);
680 ret.type = m_aResultType;
681 ret.result = m_aResult;
682 ret.ioErrorCode = m_nIOErrorCode;
684 // reset
685 m_aResultType = NORESULT;
687 catch (const salhelper::ConditionWaiter::timedout&)
689 ret.type = TIMEDOUT;
692 return ret;
696 void Moderator::setReply(ReplyType aReplyType )
698 salhelper::ConditionModifier aMod(m_aRep);
699 m_aReplyType = aReplyType;
703 void Moderator::handle( const Reference<XInteractionRequest >& Request )
705 ReplyType aReplyType;
707 do {
709 salhelper::ConditionModifier aMod(m_aRes);
710 m_aResultType = INTERACTIONREQUEST;
711 m_aResult <<= Request;
715 salhelper::ConditionWaiter aWait(m_aRep);
716 aReplyType = m_aReplyType;
718 // reset
719 m_aReplyType = NOREPLY;
722 if(aReplyType == EXIT) {
723 Sequence<Reference<XInteractionContinuation> > aSeq(
724 Request->getContinuations());
725 for(sal_Int32 i = 0; i < aSeq.getLength(); ++i) {
726 Reference<XInteractionAbort> aRef(aSeq[i],UNO_QUERY);
727 if(aRef.is()) {
728 aRef->select();
732 // resignal the exitcondition
733 setReply(EXIT);
734 break;
736 } while(aReplyType != REQUESTHANDLED);
740 void Moderator::push( const Any& Status )
743 salhelper::ConditionModifier aMod(m_aRes);
744 m_aResultType = PROGRESSPUSH;
745 m_aResult = Status;
747 ReplyType aReplyType;
749 salhelper::ConditionWaiter aWait(m_aRep);
750 aReplyType = m_aReplyType;
751 m_aReplyType = NOREPLY;
753 if(aReplyType == EXIT)
754 setReply(EXIT);
758 void Moderator::update( const Any& Status )
761 salhelper::ConditionModifier aMod(m_aRes);
762 m_aResultType = PROGRESSUPDATE;
763 m_aResult = Status;
765 ReplyType aReplyType;
767 salhelper::ConditionWaiter aWait(m_aRep);
768 aReplyType = m_aReplyType;
769 m_aReplyType = NOREPLY;
771 if(aReplyType == EXIT)
772 setReply(EXIT);
776 void Moderator::pop( )
779 salhelper::ConditionModifier aMod(m_aRes);
780 m_aResultType = PROGRESSPOP;
782 ReplyType aReplyType;
784 salhelper::ConditionWaiter aWait(m_aRep);
785 aReplyType = m_aReplyType;
786 m_aReplyType = NOREPLY;
788 if(aReplyType == EXIT)
789 setReply(EXIT);
793 void Moderator::setStream(const Reference< XStream >& aStream)
796 salhelper::ConditionModifier aMod(m_aRes);
797 m_aResultType = STREAM;
798 m_aResult <<= aStream;
800 ReplyType aReplyType;
802 salhelper::ConditionWaiter aWait(m_aRep);
803 aReplyType = m_aReplyType;
804 m_aReplyType = NOREPLY;
806 if(aReplyType == EXIT)
807 setReply(EXIT);
811 void Moderator::setInputStream(const Reference<XInputStream> &rxInputStream)
814 salhelper::ConditionModifier aMod(m_aRes);
815 m_aResultType = INPUTSTREAM;
816 m_aResult <<= rxInputStream;
818 ReplyType aReplyType;
820 salhelper::ConditionWaiter aWait(m_aRep);
821 aReplyType = m_aReplyType;
822 m_aReplyType = NOREPLY;
824 if(aReplyType == EXIT)
825 setReply(EXIT);
829 void SAL_CALL Moderator::run()
831 ResultType aResultType;
832 Any aResult;
833 sal_Int32 nIOErrorCode = 0;
837 aResult = m_aContent.executeCommand(m_aArg.Name,m_aArg.Argument);
838 aResultType = RESULT;
840 catch (const CommandAbortedException&)
842 aResultType = COMMANDABORTED;
844 catch (const CommandFailedException&)
846 aResultType = COMMANDFAILED;
848 catch (const InteractiveIOException& r)
850 nIOErrorCode = r.Code;
851 aResultType = INTERACTIVEIO;
853 catch (const UnsupportedDataSinkException &)
855 aResultType = UNSUPPORTED;
857 catch (const Exception&)
859 aResultType = GENERAL;
863 salhelper::ConditionModifier aMod(m_aRes);
864 m_aResultType = aResultType;
865 m_aResult = aResult;
866 m_nIOErrorCode = nIOErrorCode;
870 void SAL_CALL Moderator::onTerminated()
873 salhelper::ConditionWaiter aWaiter(m_aRep);
875 delete this;
879 Function for opening UCB contents synchronously,
880 but with handled timeout;
882 static sal_Bool _UCBOpenContentSync(
883 UcbLockBytesRef xLockBytes,
884 Reference < XContent > xContent,
885 const Command& rArg,
886 Reference < XInterface > xSink,
887 Reference < XInteractionHandler > xInteract,
888 Reference < XProgressHandler > xProgress,
889 UcbLockBytesHandlerRef xHandler );
892 static sal_Bool UCBOpenContentSync(
893 UcbLockBytesRef xLockBytes,
894 Reference < XContent > xContent,
895 const Command& rArg,
896 Reference < XInterface > xSink,
897 Reference < XInteractionHandler > xInteract,
898 Reference < XProgressHandler > xProgress,
899 UcbLockBytesHandlerRef xHandler )
901 // http protocol must be handled in a special way:
902 // during the opening process the input stream may change
903 // only the last inputstream after notifying the document
904 // headers is valid
906 Reference<XContentIdentifier> xContId(
907 xContent.is() ? xContent->getIdentifier() : 0 );
909 rtl::OUString aScheme;
910 if(xContId.is())
911 aScheme = xContId->getContentProviderScheme();
913 // now determine whether we use a timeout or not;
914 if( ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("http")) &&
915 ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("https")) &&
916 ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.webdav")) &&
917 ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("ftp")))
918 return _UCBOpenContentSync(
919 xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler);
921 if ( (aScheme.compareToAscii( "http" ) != COMPARE_EQUAL) ||
922 (aScheme.compareToAscii( "https" ) != COMPARE_EQUAL) )
923 xLockBytes->SetStreamValid_Impl();
925 Reference< XPropertiesChangeListener > xListener;
926 Reference< XPropertiesChangeNotifier > xProps(xContent,UNO_QUERY);
927 if(xProps.is()) {
928 xListener =
929 new UcbPropertiesChangeListener_Impl(xLockBytes);
930 xProps->addPropertiesChangeListener(
931 Sequence< ::rtl::OUString >(),
932 xListener);
935 Any aResult;
936 bool bException(false);
937 bool bAborted(false);
938 bool bResultAchieved(false);
940 Moderator* pMod = 0;
943 pMod = new Moderator(xContent,xInteract,xProgress,rArg);
944 pMod->create();
946 catch (const ContentCreationException&)
948 bResultAchieved = bException = true;
949 xLockBytes->SetError( ERRCODE_IO_GENERAL );
952 sal_uInt32 nTimeout(5000); // initially 5000 milliSec
953 while(!bResultAchieved) {
955 Moderator::Result res;
956 // try to get the result for with timeout
957 res = pMod->getResult(nTimeout);
959 switch(res.type) {
960 case Moderator::PROGRESSPUSH:
962 if(xProgress.is())
963 xProgress->push(res.result);
964 pMod->setReply(Moderator::REQUESTHANDLED);
965 break;
967 case Moderator::PROGRESSUPDATE:
969 if(xProgress.is())
970 xProgress->update(res.result);
971 pMod->setReply(Moderator::REQUESTHANDLED);
972 break;
974 case Moderator::PROGRESSPOP:
976 if(xProgress.is())
977 xProgress->pop();
978 pMod->setReply(Moderator::REQUESTHANDLED);
979 break;
981 case Moderator::STREAM:
983 Reference<XStream> result;
984 if(res.result >>= result) {
985 Reference < XActiveDataStreamer > xStreamer(
986 xSink, UNO_QUERY
989 if(xStreamer.is())
990 xStreamer->setStream(result);
992 pMod->setReply(Moderator::REQUESTHANDLED);
993 break;
995 case Moderator::INPUTSTREAM:
997 Reference<XInputStream> result;
998 res.result >>= result;
999 Reference < XActiveDataSink > xActiveSink(
1000 xSink, UNO_QUERY
1003 if(xActiveSink.is())
1004 xActiveSink->setInputStream(result);
1005 pMod->setReply(Moderator::REQUESTHANDLED);
1006 break;
1008 case Moderator::TIMEDOUT:
1010 Reference<XInteractionRetry> xRet;
1011 if(xInteract.is()) {
1012 InteractiveNetworkConnectException aExcep;
1013 INetURLObject aURL(
1014 xContId.is() ?
1015 xContId->getContentIdentifier() :
1016 rtl::OUString() );
1017 aExcep.Server = aURL.GetHost();
1018 aExcep.Classification = InteractionClassification_ERROR;
1019 aExcep.Message =
1020 rtl::OUString( "server not responding after five seconds");
1021 Any request;
1022 request <<= aExcep;
1023 ucbhelper::InteractionRequest *ir =
1024 new ucbhelper::InteractionRequest(request);
1025 Reference<XInteractionRequest> xIR(ir);
1026 Sequence<Reference<XInteractionContinuation> > aSeq(2);
1027 ucbhelper::InteractionRetry *retryP =
1028 new ucbhelper::InteractionRetry(ir);
1029 aSeq[0] = retryP;
1030 ucbhelper::InteractionAbort *abortP =
1031 new ucbhelper::InteractionAbort(ir);
1032 aSeq[1] = abortP;
1034 ir->setContinuations(aSeq);
1035 xInteract->handle(xIR);
1036 rtl::Reference< ucbhelper::InteractionContinuation > ref
1037 = ir->getSelection();
1038 if(ref.is()) {
1039 Reference<XInterface> xInt(ref.get());
1040 xRet = Reference<XInteractionRetry>(xInt,UNO_QUERY);
1044 if(!xRet.is()) {
1045 bAborted = true;
1046 xLockBytes->SetError(ERRCODE_ABORT);
1049 break;
1051 case Moderator::INTERACTIONREQUEST:
1053 Reference<XInteractionRequest> Request;
1054 res.result >>= Request;
1055 xInteract->handle(Request);
1056 pMod->setReply(Moderator::REQUESTHANDLED);
1057 break;
1059 case Moderator::RESULT:
1061 bResultAchieved = true;
1062 aResult = res.result;
1063 break;
1065 case Moderator::COMMANDABORTED:
1067 bAborted = true;
1068 xLockBytes->SetError( ERRCODE_ABORT );
1069 break;
1071 case Moderator::COMMANDFAILED:
1073 bAborted = true;
1074 xLockBytes->SetError( ERRCODE_ABORT );
1075 break;
1077 case Moderator::INTERACTIVEIO:
1079 bException = true;
1080 if ( res.ioErrorCode == IOErrorCode_ACCESS_DENIED ||
1081 res.ioErrorCode == IOErrorCode_LOCKING_VIOLATION )
1082 xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
1083 else if ( res.ioErrorCode == IOErrorCode_NOT_EXISTING )
1084 xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
1085 else if ( res.ioErrorCode == IOErrorCode_CANT_READ )
1086 xLockBytes->SetError( ERRCODE_IO_CANTREAD );
1087 else
1088 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1089 break;
1091 case Moderator::UNSUPPORTED:
1093 bException = true;
1094 xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
1095 break;
1097 default:
1099 bException = true;
1100 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1101 break;
1105 bResultAchieved |= bException;
1106 bResultAchieved |= bAborted;
1107 if(nTimeout == 5000) nTimeout *= 2;
1110 if(pMod) pMod->setReply(Moderator::EXIT);
1112 if ( bAborted || bException )
1114 if( xHandler.Is() )
1115 xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
1117 Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
1118 if ( xActiveSink.is() )
1119 xActiveSink->setInputStream( Reference < XInputStream >() );
1121 Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
1122 if ( xStreamer.is() )
1123 xStreamer->setStream( Reference < XStream >() );
1126 Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
1127 if ( xControl.is() )
1128 xControl->terminate();
1130 if ( xProps.is() )
1131 xProps->removePropertiesChangeListener(
1132 Sequence< ::rtl::OUString >(),
1133 xListener );
1135 return ( bAborted || bException );
1139 Function for opening UCB contents synchronously
1141 static sal_Bool _UCBOpenContentSync(
1142 UcbLockBytesRef xLockBytes,
1143 Reference < XContent > xContent,
1144 const Command& rArg,
1145 Reference < XInterface > xSink,
1146 Reference < XInteractionHandler > xInteract,
1147 Reference < XProgressHandler > xProgress,
1148 UcbLockBytesHandlerRef xHandler )
1150 ::ucbhelper::Content aContent(
1151 xContent, new UcbTaskEnvironment( xInteract, xProgress ),
1152 comphelper::getProcessComponentContext() );
1153 Reference < XContentIdentifier > xIdent = xContent->getIdentifier();
1154 ::rtl::OUString aScheme = xIdent->getContentProviderScheme();
1156 // http protocol must be handled in a special way: during the opening process the input stream may change
1157 // only the last inputstream after notifying the document headers is valid
1158 if ( aScheme.compareToAscii("http") != COMPARE_EQUAL )
1159 xLockBytes->SetStreamValid_Impl();
1161 Reference< XPropertiesChangeListener > xListener = new UcbPropertiesChangeListener_Impl( xLockBytes );
1162 Reference< XPropertiesChangeNotifier > xProps ( xContent, UNO_QUERY );
1163 if ( xProps.is() )
1164 xProps->addPropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
1166 Any aResult;
1167 bool bException = false;
1168 bool bAborted = false;
1172 aResult = aContent.executeCommand( rArg.Name, rArg.Argument );
1174 catch (const CommandAbortedException&)
1176 bAborted = true;
1177 xLockBytes->SetError( ERRCODE_ABORT );
1179 catch (const CommandFailedException&)
1181 bAborted = true;
1182 xLockBytes->SetError( ERRCODE_ABORT );
1184 catch (const InteractiveIOException& r)
1186 bException = true;
1187 if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
1188 xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
1189 else if ( r.Code == IOErrorCode_NOT_EXISTING )
1190 xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
1191 else if ( r.Code == IOErrorCode_CANT_READ )
1192 xLockBytes->SetError( ERRCODE_IO_CANTREAD );
1193 else
1194 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1196 catch (const UnsupportedDataSinkException&)
1198 bException = true;
1199 xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
1201 catch (const Exception&)
1203 bException = true;
1204 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1207 if ( bAborted || bException )
1209 if( xHandler.Is() )
1210 xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
1212 Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
1213 if ( xActiveSink.is() )
1214 xActiveSink->setInputStream( Reference < XInputStream >() );
1216 Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
1217 if ( xStreamer.is() )
1218 xStreamer->setStream( Reference < XStream >() );
1221 Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
1222 if ( xControl.is() )
1223 xControl->terminate();
1226 if ( xProps.is() )
1227 xProps->removePropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
1229 return ( bAborted || bException );
1232 //----------------------------------------------------------------------------
1233 UcbLockBytes::UcbLockBytes( UcbLockBytesHandler* pHandler )
1234 : m_aExpireDate( DateTime::EMPTY )
1235 , m_xInputStream (NULL)
1236 , m_pCommandThread( NULL )
1237 , m_xHandler( pHandler )
1238 , m_nError( ERRCODE_NONE )
1239 , m_bTerminated (sal_False)
1240 , m_bDontClose( sal_False )
1241 , m_bStreamValid (sal_False)
1243 SetSynchronMode( sal_True );
1246 //----------------------------------------------------------------------------
1247 UcbLockBytes::~UcbLockBytes()
1249 if ( !m_bDontClose )
1251 if ( m_xInputStream.is() )
1255 m_xInputStream->closeInput();
1257 catch (const RuntimeException&)
1260 catch (const IOException&)
1266 if ( !m_xInputStream.is() && m_xOutputStream.is() )
1270 m_xOutputStream->closeOutput();
1272 catch (const RuntimeException&)
1275 catch (const IOException&)
1281 Reference < XInputStream > UcbLockBytes::getInputStream()
1283 osl::MutexGuard aGuard( m_aMutex );
1284 m_bDontClose = sal_True;
1285 return m_xInputStream;
1288 //----------------------------------------------------------------------------
1290 sal_Bool UcbLockBytes::setStream_Impl( const Reference<XStream>& aStream )
1292 osl::MutexGuard aGuard( m_aMutex );
1293 if ( aStream.is() )
1295 m_xOutputStream = aStream->getOutputStream();
1296 setInputStream_Impl( aStream->getInputStream(), sal_False );
1297 m_xSeekable = Reference < XSeekable > ( aStream, UNO_QUERY );
1299 else
1301 m_xOutputStream = Reference < XOutputStream >();
1302 setInputStream_Impl( Reference < XInputStream >() );
1305 return m_xInputStream.is();
1308 sal_Bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream, sal_Bool bSetXSeekable )
1310 sal_Bool bRet = sal_False;
1314 osl::MutexGuard aGuard( m_aMutex );
1316 if ( !m_bDontClose && m_xInputStream.is() )
1317 m_xInputStream->closeInput();
1319 m_xInputStream = rxInputStream;
1321 if( bSetXSeekable )
1323 m_xSeekable = Reference < XSeekable > ( rxInputStream, UNO_QUERY );
1324 if( !m_xSeekable.is() && rxInputStream.is() )
1326 Reference < XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1327 Reference< XOutputStream > rxTempOut = Reference < XOutputStream > ( TempFile::create(xContext), UNO_QUERY_THROW );
1329 ::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream, rxTempOut );
1330 m_xInputStream = Reference< XInputStream >( rxTempOut, UNO_QUERY );
1331 m_xSeekable = Reference < XSeekable > ( rxTempOut, UNO_QUERY );
1335 bRet = m_xInputStream.is();
1337 catch (const Exception&)
1341 if ( m_bStreamValid && m_xInputStream.is() )
1342 m_aInitialized.set();
1344 return bRet;
1347 void UcbLockBytes::SetStreamValid_Impl()
1349 m_bStreamValid = sal_True;
1350 if ( m_xInputStream.is() )
1351 m_aInitialized.set();
1354 //----------------------------------------------------------------------------
1355 void UcbLockBytes::terminate_Impl()
1357 m_bTerminated = sal_True;
1358 m_aInitialized.set();
1359 m_aTerminated.set();
1361 if ( GetError() == ERRCODE_NONE && !m_xInputStream.is() )
1363 OSL_FAIL("No InputStream, but no error set!" );
1364 SetError( ERRCODE_IO_NOTEXISTS );
1367 if ( m_xHandler.Is() )
1368 m_xHandler->Handle( UcbLockBytesHandler::DONE, this );
1371 //----------------------------------------------------------------------------
1372 void UcbLockBytes::SetSynchronMode (sal_Bool bSynchron)
1374 SvLockBytes::SetSynchronMode (bSynchron);
1377 //----------------------------------------------------------------------------
1378 ErrCode UcbLockBytes::ReadAt ( sal_uLong nPos, void *pBuffer, sal_uLong nCount, sal_uLong *pRead) const
1380 if ( IsSynchronMode() )
1382 UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
1383 pThis->m_aInitialized.wait();
1386 Reference <XInputStream> xStream = getInputStream_Impl();
1387 if ( !xStream.is() )
1389 if ( m_bTerminated )
1390 return ERRCODE_IO_CANTREAD;
1391 else
1392 return ERRCODE_IO_PENDING;
1395 if ( pRead )
1396 *pRead = 0;
1398 Reference <XSeekable> xSeekable = getSeekable_Impl();
1399 if ( !xSeekable.is() )
1400 return ERRCODE_IO_CANTREAD;
1404 xSeekable->seek( nPos );
1406 catch (const IOException&)
1408 return ERRCODE_IO_CANTSEEK;
1410 catch (const com::sun::star::lang::IllegalArgumentException&)
1412 return ERRCODE_IO_CANTSEEK;
1415 Sequence<sal_Int8> aData;
1416 sal_Int32 nSize;
1418 if(nCount > 0x7FFFFFFF)
1420 nCount = 0x7FFFFFFF;
1424 if ( !m_bTerminated && !IsSynchronMode() )
1426 sal_uInt64 nLen = xSeekable->getLength();
1427 if ( nPos + nCount > nLen )
1428 return ERRCODE_IO_PENDING;
1431 nSize = xStream->readBytes( aData, sal_Int32(nCount) );
1433 catch (const IOException&)
1435 return ERRCODE_IO_CANTREAD;
1438 memcpy (pBuffer, aData.getConstArray(), nSize);
1439 if (pRead)
1440 *pRead = sal_uLong(nSize);
1442 return ERRCODE_NONE;
1445 //----------------------------------------------------------------------------
1446 ErrCode UcbLockBytes::WriteAt ( sal_uLong nPos, const void *pBuffer, sal_uLong nCount, sal_uLong *pWritten)
1448 if ( pWritten )
1449 *pWritten = 0;
1451 DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" );
1452 DBG_ASSERT( m_aInitialized.check(), "Writing bevor stream is ready!" );
1454 Reference <XSeekable> xSeekable = getSeekable_Impl();
1455 Reference <XOutputStream> xOutputStream = getOutputStream_Impl();
1456 if ( !xOutputStream.is() || !xSeekable.is() )
1457 return ERRCODE_IO_CANTWRITE;
1461 xSeekable->seek( nPos );
1463 catch (const IOException&)
1465 return ERRCODE_IO_CANTSEEK;
1468 sal_Int8* pData = (sal_Int8*) pBuffer;
1469 Sequence<sal_Int8> aData( pData, nCount );
1472 xOutputStream->writeBytes( aData );
1473 if ( pWritten )
1474 *pWritten = nCount;
1476 catch (const Exception&)
1478 return ERRCODE_IO_CANTWRITE;
1481 return ERRCODE_NONE;
1484 //----------------------------------------------------------------------------
1485 ErrCode UcbLockBytes::Flush() const
1487 Reference <XOutputStream > xOutputStream = getOutputStream_Impl();
1488 if ( !xOutputStream.is() )
1489 return ERRCODE_IO_CANTWRITE;
1493 xOutputStream->flush();
1495 catch (const Exception&)
1497 return ERRCODE_IO_CANTWRITE;
1500 return ERRCODE_NONE;
1503 //----------------------------------------------------------------------------
1504 ErrCode UcbLockBytes::SetSize (sal_uLong nNewSize)
1506 SvLockBytesStat aStat;
1507 Stat( &aStat, (SvLockBytesStatFlag) 0 );
1508 sal_uLong nSize = aStat.nSize;
1510 if ( nSize > nNewSize )
1512 Reference < XTruncate > xTrunc( getOutputStream_Impl(), UNO_QUERY );
1513 if ( xTrunc.is() )
1515 xTrunc->truncate();
1516 nSize = 0;
1518 else {
1519 DBG_WARNING("Not truncatable!");
1523 if ( nSize < nNewSize )
1525 sal_uLong nDiff = nNewSize-nSize, nCount=0;
1526 sal_uInt8* pBuffer = new sal_uInt8[ nDiff ];
1527 memset(pBuffer, 0, nDiff); // initialize for enhanced security
1528 WriteAt( nSize, pBuffer, nDiff, &nCount );
1529 delete[] pBuffer;
1530 if ( nCount != nDiff )
1531 return ERRCODE_IO_CANTWRITE;
1534 return ERRCODE_NONE;
1537 //----------------------------------------------------------------------------
1538 ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const
1540 if ( IsSynchronMode() )
1542 UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
1543 pThis->m_aInitialized.wait();
1546 if (!pStat)
1547 return ERRCODE_IO_INVALIDPARAMETER;
1549 Reference <XInputStream> xStream = getInputStream_Impl();
1550 Reference <XSeekable> xSeekable = getSeekable_Impl();
1552 if ( !xStream.is() )
1554 if ( m_bTerminated )
1555 return ERRCODE_IO_INVALIDACCESS;
1556 else
1557 return ERRCODE_IO_PENDING;
1559 else if( !xSeekable.is() )
1560 return ERRCODE_IO_CANTTELL;
1564 pStat->nSize = sal_uLong(xSeekable->getLength());
1566 catch (const IOException&)
1568 return ERRCODE_IO_CANTTELL;
1571 return ERRCODE_NONE;
1574 //----------------------------------------------------------------------------
1575 IMPL_LINK_NOARG(UcbLockBytes, DataAvailHdl)
1577 if ( hasInputStream_Impl() && m_xHandler.Is() )
1578 m_xHandler->Handle( UcbLockBytesHandler::DATA_AVAILABLE, this );
1580 return 0;
1583 UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( const Reference< XInputStream >& xInputStream )
1585 if( !xInputStream.is() )
1586 return NULL;
1588 UcbLockBytesRef xLockBytes = new UcbLockBytes();
1589 xLockBytes->setDontClose_Impl();
1590 xLockBytes->setInputStream_Impl( xInputStream );
1591 xLockBytes->terminate_Impl();
1592 return xLockBytes;
1595 UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference< XStream >& xStream )
1597 if( !xStream.is() )
1598 return NULL;
1600 UcbLockBytesRef xLockBytes = new UcbLockBytes();
1601 xLockBytes->setDontClose_Impl();
1602 xLockBytes->setStream_Impl( xStream );
1603 xLockBytes->terminate_Impl();
1604 return xLockBytes;
1607 UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const Sequence < PropertyValue >& rProps,
1608 StreamMode eOpenMode, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
1610 if( !xContent.is() )
1611 return NULL;
1613 UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
1614 xLockBytes->SetSynchronMode( !pHandler );
1615 Reference< XActiveDataControl > xSink;
1616 if ( eOpenMode & STREAM_WRITE )
1617 xSink = (XActiveDataControl*) new UcbStreamer_Impl( xLockBytes );
1618 else
1619 xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );
1621 if ( rProps.getLength() )
1623 Reference < XCommandProcessor > xProcessor( xContent, UNO_QUERY );
1624 Command aCommand;
1625 aCommand.Name = ::rtl::OUString("setPropertyValues");
1626 aCommand.Handle = -1; /* unknown */
1627 aCommand.Argument <<= rProps;
1628 xProcessor->execute( aCommand, 0, Reference < XCommandEnvironment >() );
1631 OpenCommandArgument2 aArgument;
1632 aArgument.Sink = xSink;
1633 aArgument.Mode = OpenMode::DOCUMENT;
1635 Command aCommand;
1636 aCommand.Name = ::rtl::OUString( "open" );
1637 aCommand.Argument <<= aArgument;
1639 Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );
1641 sal_Bool bError = UCBOpenContentSync( xLockBytes,
1642 xContent,
1643 aCommand,
1644 xSink,
1645 xInteractionHandler,
1646 xProgressHdl,
1647 pHandler );
1649 if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
1651 OSL_FAIL("No InputStream, but no error set!" );
1652 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1655 return xLockBytes;
1660 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */