update dev300-m58
[ooovba.git] / unotools / source / ucbhelper / ucblockbytes.cxx
blobb8937cb6af5936678b9b40ddd707283d1a3c735c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ucblockbytes.cxx,v $
10 * $Revision: 1.60 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_unotools.hxx"
34 #include <unotools/ucblockbytes.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <salhelper/condition.hxx>
37 #ifndef _OSL_THREAD_HXX_
38 #include <osl/thread.hxx>
39 #endif
40 #include <tools/urlobj.hxx>
41 #include <ucbhelper/interactionrequest.hxx>
42 #include <com/sun/star/task/XInteractionAbort.hpp>
43 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
44 #include <com/sun/star/ucb/CommandFailedException.hpp>
45 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
46 #ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_
47 #include <com/sun/star/ucb/InteractiveIOException.hpp>
48 #endif
49 #include <com/sun/star/io/XActiveDataStreamer.hpp>
50 #include <com/sun/star/ucb/DocumentHeaderField.hpp>
51 #include <com/sun/star/ucb/XCommandInfo.hpp>
52 #include <com/sun/star/ucb/XCommandProcessor.hpp>
53 #include <com/sun/star/task/XInteractionHandler.hpp>
54 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
55 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
56 #include <com/sun/star/ucb/OpenMode.hpp>
57 #include <com/sun/star/beans/Property.hpp>
58 #include <com/sun/star/beans/PropertyValue.hpp>
59 #include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
60 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
61 #include <com/sun/star/sdbc/XRow.hpp>
62 #include <com/sun/star/io/XActiveDataSink.hpp>
63 #include <com/sun/star/io/XActiveDataControl.hpp>
64 #include <com/sun/star/io/XSeekable.hpp>
65 #include <cppuhelper/implbase1.hxx>
66 #include <cppuhelper/implbase2.hxx>
67 #include <tools/inetmsg.hxx>
68 #include <com/sun/star/io/XTruncate.hpp>
69 #include <com/sun/star/lang/IllegalArgumentException.hpp>
71 #include <comphelper/storagehelper.hxx>
73 #include <ucbhelper/contentbroker.hxx>
74 #include <ucbhelper/content.hxx>
76 using namespace ::com::sun::star::uno;
77 using namespace ::com::sun::star::io;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::ucb;
80 using namespace ::com::sun::star::task;
81 using namespace ::com::sun::star::lang;
82 using namespace ::com::sun::star::beans;
85 namespace utl
88 /**
89 Helper class for getting a XInputStream when opening a content
91 class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink >
93 UcbLockBytesRef m_xLockBytes;
95 public:
96 UcbDataSink_Impl( UcbLockBytes* pLockBytes )
97 : m_xLockBytes( pLockBytes )
100 SvLockBytes* getLockBytes (void)
101 { return m_xLockBytes; }
103 // XActiveDataControl.
104 virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
105 virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
106 virtual void SAL_CALL start (void) throw(RuntimeException) {}
107 virtual void SAL_CALL terminate (void) throw(RuntimeException)
108 { m_xLockBytes->terminate_Impl(); }
110 // XActiveDataSink.
111 virtual void SAL_CALL setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException)
112 { m_xLockBytes->setInputStream_Impl (rxInputStream); }
113 virtual Reference<XInputStream> SAL_CALL getInputStream (void) throw(RuntimeException)
114 { return m_xLockBytes->getInputStream_Impl(); }
118 Helper class for getting a XStream when opening a content
120 class UcbStreamer_Impl : public ::cppu::WeakImplHelper2< XActiveDataStreamer, XActiveDataControl >
122 Reference < XStream > m_xStream;
123 UcbLockBytesRef m_xLockBytes;
125 public:
127 UcbStreamer_Impl( UcbLockBytes* pLockBytes )
128 : m_xLockBytes( pLockBytes )
131 // XActiveDataControl.
132 virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
133 virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
134 virtual void SAL_CALL start (void) throw(RuntimeException) {}
135 virtual void SAL_CALL terminate (void) throw(RuntimeException)
136 { m_xLockBytes->terminate_Impl(); }
138 // XActiveDataStreamer
139 virtual void SAL_CALL setStream( const Reference< XStream >& aStream ) throw(RuntimeException)
140 { m_xStream = aStream; m_xLockBytes->setStream_Impl( aStream ); }
141 virtual Reference< XStream > SAL_CALL getStream() throw(RuntimeException)
142 { return m_xStream; }
146 Helper class for progress handling while executing UCB commands
148 class ProgressHandler_Impl: public ::cppu::WeakImplHelper1< XProgressHandler >
150 Link m_aProgress;
152 public:
153 ProgressHandler_Impl( const Link& rLink )
154 : m_aProgress( rLink )
156 // XProgressHandler
157 virtual void SAL_CALL push(const Any & /*rStatus*/) throw (RuntimeException) {}
158 virtual void SAL_CALL pop() throw (RuntimeException) {}
159 virtual void SAL_CALL update(const Any & /*rStatus*/) throw (RuntimeException)
160 { if ( m_aProgress.IsSet() ) m_aProgress.Call( 0 ); }
164 Helper class for managing interactions and progress when executing UCB commands
166 class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment >
168 Reference< XInteractionHandler > m_xInteractionHandler;
169 Reference< XProgressHandler > m_xProgressHandler;
171 public:
172 UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler,
173 const Reference< XProgressHandler>& rxProgressHandler )
174 : m_xInteractionHandler( rxInteractionHandler )
175 , m_xProgressHandler( rxProgressHandler )
179 virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException)
180 { return m_xInteractionHandler; }
182 virtual Reference<XProgressHandler> SAL_CALL getProgressHandler() throw (RuntimeException)
183 { return m_xProgressHandler; }
188 Helper class for property change notifies when executing UCB commands
190 class UcbPropertiesChangeListener_Impl : public ::cppu::WeakImplHelper1< XPropertiesChangeListener >
192 public:
193 UcbLockBytesRef m_xLockBytes;
195 UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef )
196 : m_xLockBytes( rRef )
199 virtual void SAL_CALL disposing ( const EventObject &/*rEvent*/) throw(RuntimeException) {}
200 virtual void SAL_CALL propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException);
203 void SAL_CALL UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException)
205 sal_Int32 i, n = rEvent.getLength();
206 for (i = 0; i < n; i++)
208 PropertyChangeEvent evt (rEvent[i]);
209 if (evt.PropertyName == ::rtl::OUString::createFromAscii ("DocumentHeader"))
211 Sequence<DocumentHeaderField> aHead;
212 if (evt.NewValue >>= aHead)
214 sal_Int32 k, m = aHead.getLength();
215 for (k = 0; k < m; k++)
217 String aName( aHead[k].Name );
218 String aValue( aHead[k].Value );
220 if (aName.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL)
222 DateTime aExpires (0, 0);
223 if (INetRFC822Message::ParseDateField (aValue, aExpires))
225 aExpires.ConvertToLocalTime();
226 m_xLockBytes->SetExpireDate_Impl( aExpires );
232 m_xLockBytes->SetStreamValid_Impl();
234 else if (evt.PropertyName == rtl::OUString::createFromAscii ("PresentationURL"))
236 ::rtl::OUString aUrl;
237 if (evt.NewValue >>= aUrl)
239 ::rtl::OUString aBad (::rtl::OUString::createFromAscii ("private:"));
240 if (!(aUrl.compareTo (aBad, aBad.getLength()) == 0))
242 // URL changed (Redirection).
243 m_xLockBytes->SetRealURL_Impl( aUrl );
247 else if (evt.PropertyName == ::rtl::OUString::createFromAscii ("MediaType"))
249 ::rtl::OUString aContentType;
250 if (evt.NewValue >>= aContentType)
251 m_xLockBytes->SetContentType_Impl( aContentType );
258 class Moderator
259 : public osl::Thread
261 // usage restriction:
262 // It might be possible, that the call to the interactionhandler and/or
263 // progresshandler is done asynchrounsly, while the 'execute' simply
264 // returns. This would imply that these class must be refcounted !!!
266 public:
268 Moderator(
269 Reference < XContent >& xContent,
270 Reference < XInteractionHandler >& xInteract,
271 Reference < XProgressHandler >& xProgress,
272 const Command& rArg
274 throw(
275 ContentCreationException,
276 RuntimeException
279 ~Moderator();
282 enum ResultType {
283 NORESULT,
285 INTERACTIONREQUEST, // reply expected
287 PROGRESSPUSH,
288 PROGRESSUPDATE,
289 PROGRESSPOP,
291 INPUTSTREAM,
292 STREAM,
294 RESULT,
295 TIMEDOUT,
296 COMMANDABORTED,
297 COMMANDFAILED,
298 INTERACTIVEIO,
299 UNSUPPORTED,
300 GENERAL
304 class ConditionRes
305 : public salhelper::Condition
307 public:
309 ConditionRes(osl::Mutex& aMutex,Moderator& aModerator)
310 : salhelper::Condition(aMutex),
311 m_aModerator(aModerator)
315 protected:
317 bool applies() const {
318 return m_aModerator.m_aResultType != NORESULT;
321 private:
323 Moderator& m_aModerator;
327 struct Result {
328 ResultType type;
329 Any result;
330 sal_Int32 ioErrorCode;
334 Result getResult(const sal_uInt32 milliSec);
337 enum ReplyType {
338 NOREPLY,
339 EXIT,
340 RETRY,
341 REQUESTHANDLED
345 class ConditionRep
346 : public salhelper::Condition
348 public:
350 ConditionRep(osl::Mutex& aMutex,Moderator& aModerator)
351 : salhelper::Condition(aMutex),
352 m_aModerator(aModerator)
356 protected:
358 bool applies() const {
359 return m_aModerator.m_aReplyType != NOREPLY;
362 private:
364 Moderator& m_aModerator;
367 void setReply(ReplyType);
370 void handle( const Reference<XInteractionRequest >& Request );
372 void push( const Any& Status );
374 void update( const Any& Status );
376 void pop( );
378 void setStream(const Reference< XStream >& aStream);
380 void setInputStream(const Reference<XInputStream> &rxInputStream);
383 protected:
385 virtual void SAL_CALL run();
387 virtual void SAL_CALL onTerminated();
389 private:
391 osl::Mutex m_aMutex;
393 friend class ConditionRes;
395 ConditionRes m_aRes;
396 ResultType m_aResultType;
397 sal_Int32 m_nIOErrorCode;
398 Any m_aResult;
400 friend class ConditionRep;
402 ConditionRep m_aRep;
403 ReplyType m_aReplyType;
405 Command m_aArg;
406 ::ucbhelper::Content m_aContent;
410 class ModeratorsActiveDataStreamer
411 : public ::cppu::WeakImplHelper1<XActiveDataStreamer>
413 public:
415 ModeratorsActiveDataStreamer(Moderator &theModerator);
417 ~ModeratorsActiveDataStreamer();
419 // XActiveDataStreamer
420 virtual void SAL_CALL
421 setStream(
422 const Reference< XStream >& aStream
424 throw(
425 RuntimeException
428 virtual Reference<XStream> SAL_CALL
429 getStream (
430 void
431 ) throw(
432 RuntimeException
435 osl::MutexGuard aGuard(m_aMutex);
436 return m_xStream;
440 private:
442 Moderator& m_aModerator;
444 osl::Mutex m_aMutex;
445 Reference<XStream> m_xStream;
450 class ModeratorsActiveDataSink
451 : public ::cppu::WeakImplHelper1<XActiveDataSink>
453 public:
455 ModeratorsActiveDataSink(Moderator &theModerator);
457 ~ModeratorsActiveDataSink();
459 // XActiveDataSink.
460 virtual void SAL_CALL
461 setInputStream (
462 const Reference<XInputStream> &rxInputStream
464 throw(
465 RuntimeException
468 virtual Reference<XInputStream> SAL_CALL
469 getInputStream (
470 void
471 ) throw(
472 RuntimeException
475 osl::MutexGuard aGuard(m_aMutex);
476 return m_xStream;
480 private:
482 Moderator& m_aModerator;
483 osl::Mutex m_aMutex;
484 Reference<XInputStream> m_xStream;
489 ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator &theModerator)
490 : m_aModerator(theModerator)
495 ModeratorsActiveDataSink::~ModeratorsActiveDataSink()
499 // XActiveDataSink.
500 void SAL_CALL
501 ModeratorsActiveDataSink::setInputStream (
502 const Reference<XInputStream> &rxInputStream
504 throw(
505 RuntimeException
508 m_aModerator.setInputStream(rxInputStream);
509 osl::MutexGuard aGuard(m_aMutex);
510 m_xStream = rxInputStream;
514 ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer(
515 Moderator &theModerator
517 : m_aModerator(theModerator)
522 ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer()
526 // XActiveDataStreamer.
527 void SAL_CALL
528 ModeratorsActiveDataStreamer::setStream (
529 const Reference<XStream> &rxStream
531 throw(
532 RuntimeException
535 m_aModerator.setStream(rxStream);
536 osl::MutexGuard aGuard(m_aMutex);
537 m_xStream = rxStream;
542 class ModeratorsInteractionHandler
543 : public ::cppu::WeakImplHelper1<XInteractionHandler>
545 public:
547 ModeratorsInteractionHandler(Moderator &theModerator);
549 ~ModeratorsInteractionHandler();
551 virtual void SAL_CALL
552 handle( const Reference<XInteractionRequest >& Request )
553 throw (RuntimeException);
555 private:
557 Moderator& m_aModerator;
561 class ModeratorsProgressHandler
562 : public ::cppu::WeakImplHelper1<XProgressHandler>
564 public:
566 ModeratorsProgressHandler(Moderator &theModerator);
568 ~ModeratorsProgressHandler();
570 virtual void SAL_CALL push( const Any& Status )
571 throw (
572 RuntimeException);
574 virtual void SAL_CALL update( const Any& Status )
575 throw (RuntimeException);
577 virtual void SAL_CALL pop( )
578 throw (RuntimeException);
581 private:
583 Moderator& m_aModerator;
587 ModeratorsProgressHandler::ModeratorsProgressHandler(Moderator &theModerator)
588 : m_aModerator(theModerator)
592 ModeratorsProgressHandler::~ModeratorsProgressHandler()
597 void SAL_CALL ModeratorsProgressHandler::push( const Any& Status )
598 throw (
599 RuntimeException)
601 m_aModerator.push(Status);
605 void SAL_CALL ModeratorsProgressHandler::update( const Any& Status )
606 throw (RuntimeException)
608 m_aModerator.update(Status);
612 void SAL_CALL ModeratorsProgressHandler::pop( )
613 throw (RuntimeException)
615 m_aModerator.pop();
621 ModeratorsInteractionHandler::ModeratorsInteractionHandler(
622 Moderator &aModerator)
623 : m_aModerator(aModerator)
628 ModeratorsInteractionHandler::~ModeratorsInteractionHandler()
633 void SAL_CALL
634 ModeratorsInteractionHandler::handle(
635 const Reference<XInteractionRequest >& Request
637 throw (
638 RuntimeException
641 // wakes up the mainthread
642 m_aModerator.handle(Request);
648 Moderator::Moderator(
649 Reference < XContent >& xContent,
650 Reference < XInteractionHandler >& xInteract,
651 Reference < XProgressHandler >& xProgress,
652 const Command& rArg
654 throw(
655 ::com::sun::star::ucb::ContentCreationException,
656 ::com::sun::star::uno::RuntimeException
658 : m_aMutex(),
660 m_aRes(m_aMutex,*this),
661 m_aResultType(NORESULT),
662 m_nIOErrorCode(0),
663 m_aResult(),
665 m_aRep(m_aMutex,*this),
666 m_aReplyType(NOREPLY),
668 m_aArg(rArg),
669 m_aContent(
670 xContent,
671 new UcbTaskEnvironment(
672 xInteract.is() ? new ModeratorsInteractionHandler(*this) : 0,
673 xProgress.is() ? new ModeratorsProgressHandler(*this) : 0
676 // now exchange the whole data sink stuff
677 // with a thread safe version
679 Reference<XInterface> *pxSink = NULL;
681 PostCommandArgument2 aPostArg;
682 OpenCommandArgument2 aOpenArg;
684 int dec(2);
685 if(m_aArg.Argument >>= aPostArg) {
686 pxSink = &aPostArg.Sink;
687 dec = 0;
689 else if(m_aArg.Argument >>= aOpenArg) {
690 pxSink = &aOpenArg.Sink;
691 dec = 1;
694 if(dec ==2)
695 throw ContentCreationException();
697 Reference < XActiveDataSink > xActiveSink(*pxSink,UNO_QUERY);
698 if(xActiveSink.is())
699 *pxSink = Reference<XInterface>(
700 (cppu::OWeakObject*)new ModeratorsActiveDataSink(*this));
702 Reference<XActiveDataStreamer> xStreamer( *pxSink, UNO_QUERY );
703 if ( xStreamer.is() )
704 *pxSink = Reference<XInterface>(
705 (cppu::OWeakObject*)new ModeratorsActiveDataStreamer(*this));
707 if(dec == 0)
708 m_aArg.Argument <<= aPostArg;
709 else if(dec == 1)
710 m_aArg.Argument <<= aOpenArg;
714 Moderator::~Moderator()
719 Moderator::Result Moderator::getResult(const sal_uInt32 milliSec)
721 Result ret;
722 try {
723 salhelper::ConditionWaiter aWaiter(m_aRes,milliSec);
724 ret.type = m_aResultType;
725 ret.result = m_aResult;
726 ret.ioErrorCode = m_nIOErrorCode;
728 // reset
729 m_aResultType = NORESULT;
731 catch(const salhelper::ConditionWaiter::timedout&)
733 ret.type = TIMEDOUT;
736 return ret;
740 void Moderator::setReply(ReplyType aReplyType )
742 salhelper::ConditionModifier aMod(m_aRep);
743 m_aReplyType = aReplyType;
747 void Moderator::handle( const Reference<XInteractionRequest >& Request )
749 ReplyType aReplyType;
751 do {
753 salhelper::ConditionModifier aMod(m_aRes);
754 m_aResultType = INTERACTIONREQUEST;
755 m_aResult <<= Request;
759 salhelper::ConditionWaiter aWait(m_aRep);
760 aReplyType = m_aReplyType;
762 // reset
763 m_aReplyType = NOREPLY;
766 if(aReplyType == EXIT) {
767 Sequence<Reference<XInteractionContinuation> > aSeq(
768 Request->getContinuations());
769 for(sal_Int32 i = 0; i < aSeq.getLength(); ++i) {
770 Reference<XInteractionAbort> aRef(aSeq[i],UNO_QUERY);
771 if(aRef.is()) {
772 aRef->select();
776 // resignal the exitcondition
777 setReply(EXIT);
778 break;
780 } while(aReplyType != REQUESTHANDLED);
785 void Moderator::push( const Any& Status )
788 salhelper::ConditionModifier aMod(m_aRes);
789 m_aResultType = PROGRESSPUSH;
790 m_aResult = Status;
792 ReplyType aReplyType;
794 salhelper::ConditionWaiter aWait(m_aRep);
795 aReplyType = m_aReplyType;
796 m_aReplyType = NOREPLY;
798 if(aReplyType == EXIT)
799 setReply(EXIT);
803 void Moderator::update( const Any& Status )
806 salhelper::ConditionModifier aMod(m_aRes);
807 m_aResultType = PROGRESSUPDATE;
808 m_aResult = Status;
810 ReplyType aReplyType;
812 salhelper::ConditionWaiter aWait(m_aRep);
813 aReplyType = m_aReplyType;
814 m_aReplyType = NOREPLY;
816 if(aReplyType == EXIT)
817 setReply(EXIT);
821 void Moderator::pop( )
824 salhelper::ConditionModifier aMod(m_aRes);
825 m_aResultType = PROGRESSPOP;
827 ReplyType aReplyType;
829 salhelper::ConditionWaiter aWait(m_aRep);
830 aReplyType = m_aReplyType;
831 m_aReplyType = NOREPLY;
833 if(aReplyType == EXIT)
834 setReply(EXIT);
838 void Moderator::setStream(const Reference< XStream >& aStream)
841 salhelper::ConditionModifier aMod(m_aRes);
842 m_aResultType = STREAM;
843 m_aResult <<= aStream;
845 ReplyType aReplyType;
847 salhelper::ConditionWaiter aWait(m_aRep);
848 aReplyType = m_aReplyType;
849 m_aReplyType = NOREPLY;
851 if(aReplyType == EXIT)
852 setReply(EXIT);
856 void Moderator::setInputStream(const Reference<XInputStream> &rxInputStream)
859 salhelper::ConditionModifier aMod(m_aRes);
860 m_aResultType = INPUTSTREAM;
861 m_aResult <<= rxInputStream;
863 ReplyType aReplyType;
865 salhelper::ConditionWaiter aWait(m_aRep);
866 aReplyType = m_aReplyType;
867 m_aReplyType = NOREPLY;
869 if(aReplyType == EXIT)
870 setReply(EXIT);
875 void SAL_CALL Moderator::run()
877 ResultType aResultType;
878 Any aResult;
879 sal_Int32 nIOErrorCode = 0;
883 aResult = m_aContent.executeCommand(m_aArg.Name,m_aArg.Argument);
884 aResultType = RESULT;
886 catch ( CommandAbortedException )
888 aResultType = COMMANDABORTED;
890 catch ( CommandFailedException )
892 aResultType = COMMANDFAILED;
894 catch ( InteractiveIOException& r )
896 nIOErrorCode = r.Code;
897 aResultType = INTERACTIVEIO;
899 catch ( UnsupportedDataSinkException& )
901 aResultType = UNSUPPORTED;
903 catch ( Exception )
905 aResultType = GENERAL;
909 salhelper::ConditionModifier aMod(m_aRes);
910 m_aResultType = aResultType;
911 m_aResult = aResult;
912 m_nIOErrorCode = nIOErrorCode;
918 void SAL_CALL Moderator::onTerminated()
921 salhelper::ConditionWaiter aWaiter(m_aRep);
923 delete this;
928 Function for opening UCB contents synchronously,
929 but with handled timeout;
932 static sal_Bool _UCBOpenContentSync(
933 UcbLockBytesRef xLockBytes,
934 Reference < XContent > xContent,
935 const Command& rArg,
936 Reference < XInterface > xSink,
937 Reference < XInteractionHandler > xInteract,
938 Reference < XProgressHandler > xProgress,
939 UcbLockBytesHandlerRef xHandler );
942 static sal_Bool UCBOpenContentSync(
943 UcbLockBytesRef xLockBytes,
944 Reference < XContent > xContent,
945 const Command& rArg,
946 Reference < XInterface > xSink,
947 Reference < XInteractionHandler > xInteract,
948 Reference < XProgressHandler > xProgress,
949 UcbLockBytesHandlerRef xHandler )
951 // http protocol must be handled in a special way:
952 // during the opening process the input stream may change
953 // only the last inputstream after notifying the document
954 // headers is valid
956 Reference<XContentIdentifier> xContId(
957 xContent.is() ? xContent->getIdentifier() : 0 );
959 rtl::OUString aScheme;
960 if(xContId.is())
961 aScheme = xContId->getContentProviderScheme();
963 // now determine wether we use a timeout or not;
964 if( ! aScheme.equalsIgnoreAsciiCaseAscii("http") &&
965 ! aScheme.equalsIgnoreAsciiCaseAscii("https") &&
966 ! aScheme.equalsIgnoreAsciiCaseAscii("vnd.sun.star.webdav") &&
967 ! aScheme.equalsIgnoreAsciiCaseAscii("dav") &&
968 ! aScheme.equalsIgnoreAsciiCaseAscii("davs") &&
969 ! aScheme.equalsIgnoreAsciiCaseAscii("webdav") &&
970 ! aScheme.equalsIgnoreAsciiCaseAscii("webdavs") &&
971 ! aScheme.equalsIgnoreAsciiCaseAscii("ftp"))
972 return _UCBOpenContentSync(
973 xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler);
975 if ( (aScheme.compareToAscii( "http" ) != COMPARE_EQUAL) ||
976 (aScheme.compareToAscii( "https" ) != COMPARE_EQUAL) )
977 xLockBytes->SetStreamValid_Impl();
979 Reference< XPropertiesChangeListener > xListener;
980 Reference< XPropertiesChangeNotifier > xProps(xContent,UNO_QUERY);
981 if(xProps.is()) {
982 xListener =
983 new UcbPropertiesChangeListener_Impl(xLockBytes);
984 xProps->addPropertiesChangeListener(
985 Sequence< ::rtl::OUString >(),
986 xListener);
989 Any aResult;
990 bool bException(false);
991 bool bAborted(false);
992 bool bResultAchieved(false);
994 Moderator* pMod = 0;
995 try {
996 pMod = new Moderator(xContent,xInteract,xProgress,rArg);
997 pMod->create();
998 } catch(const ContentCreationException&) {
999 bResultAchieved = bException = true;
1000 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1003 sal_uInt32 nTimeout(5000); // initially 5000 milliSec
1004 while(!bResultAchieved) {
1006 Moderator::Result res;
1007 // try to get the result for with timeout
1008 res = pMod->getResult(nTimeout);
1010 switch(res.type) {
1011 case Moderator::PROGRESSPUSH:
1013 if(xProgress.is())
1014 xProgress->push(res.result);
1015 pMod->setReply(Moderator::REQUESTHANDLED);
1016 break;
1018 case Moderator::PROGRESSUPDATE:
1020 if(xProgress.is())
1021 xProgress->update(res.result);
1022 pMod->setReply(Moderator::REQUESTHANDLED);
1023 break;
1025 case Moderator::PROGRESSPOP:
1027 if(xProgress.is())
1028 xProgress->pop();
1029 pMod->setReply(Moderator::REQUESTHANDLED);
1030 break;
1032 case Moderator::STREAM:
1034 Reference<XStream> result;
1035 if(res.result >>= result) {
1036 Reference < XActiveDataStreamer > xStreamer(
1037 xSink, UNO_QUERY
1040 if(xStreamer.is())
1041 xStreamer->setStream(result);
1043 pMod->setReply(Moderator::REQUESTHANDLED);
1044 break;
1046 case Moderator::INPUTSTREAM:
1048 Reference<XInputStream> result;
1049 res.result >>= result;
1050 Reference < XActiveDataSink > xActiveSink(
1051 xSink, UNO_QUERY
1054 if(xActiveSink.is())
1055 xActiveSink->setInputStream(result);
1056 pMod->setReply(Moderator::REQUESTHANDLED);
1057 break;
1059 case Moderator::TIMEDOUT:
1061 Reference<XInteractionRetry> xRet;
1062 if(xInteract.is()) {
1063 InteractiveNetworkConnectException aExcep;
1064 INetURLObject aURL(
1065 xContId.is() ?
1066 xContId->getContentIdentifier() :
1067 rtl::OUString() );
1068 aExcep.Server = aURL.GetHost();
1069 aExcep.Classification = InteractionClassification_ERROR;
1070 aExcep.Message =
1071 rtl::OUString(
1072 RTL_CONSTASCII_USTRINGPARAM(
1073 "server not responding after five seconds"));
1074 Any request;
1075 request <<= aExcep;
1076 ucbhelper::InteractionRequest *ir =
1077 new ucbhelper::InteractionRequest(request);
1078 Reference<XInteractionRequest> xIR(ir);
1079 Sequence<Reference<XInteractionContinuation> > aSeq(2);
1080 ucbhelper::InteractionRetry *retryP =
1081 new ucbhelper::InteractionRetry(ir);
1082 aSeq[0] = retryP;
1083 ucbhelper::InteractionAbort *abortP =
1084 new ucbhelper::InteractionAbort(ir);
1085 aSeq[1] = abortP;
1087 ir->setContinuations(aSeq);
1088 xInteract->handle(xIR);
1089 rtl::Reference< ucbhelper::InteractionContinuation > ref
1090 = ir->getSelection();
1091 if(ref.is()) {
1092 Reference<XInterface> xInt(ref.get());
1093 xRet = Reference<XInteractionRetry>(xInt,UNO_QUERY);
1097 if(!xRet.is()) {
1098 bAborted = true;
1099 xLockBytes->SetError(ERRCODE_ABORT);
1102 break;
1104 case Moderator::INTERACTIONREQUEST:
1106 Reference<XInteractionRequest> Request;
1107 res.result >>= Request;
1108 xInteract->handle(Request);
1109 pMod->setReply(Moderator::REQUESTHANDLED);
1110 break;
1112 case Moderator::RESULT:
1114 bResultAchieved = true;
1115 aResult = res.result;
1116 break;
1118 case Moderator::COMMANDABORTED:
1120 bAborted = true;
1121 xLockBytes->SetError( ERRCODE_ABORT );
1122 break;
1124 case Moderator::COMMANDFAILED:
1126 bAborted = true;
1127 xLockBytes->SetError( ERRCODE_ABORT );
1128 break;
1130 case Moderator::INTERACTIVEIO:
1132 bException = true;
1133 if ( res.ioErrorCode == IOErrorCode_ACCESS_DENIED ||
1134 res.ioErrorCode == IOErrorCode_LOCKING_VIOLATION )
1135 xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
1136 else if ( res.ioErrorCode == IOErrorCode_NOT_EXISTING )
1137 xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
1138 else if ( res.ioErrorCode == IOErrorCode_CANT_READ )
1139 xLockBytes->SetError( ERRCODE_IO_CANTREAD );
1140 else
1141 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1142 break;
1144 case Moderator::UNSUPPORTED:
1146 bException = true;
1147 xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
1148 break;
1150 default:
1152 bException = true;
1153 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1154 break;
1158 bResultAchieved |= bException;
1159 bResultAchieved |= bAborted;
1160 if(nTimeout == 5000) nTimeout *= 2;
1163 if(pMod) pMod->setReply(Moderator::EXIT);
1165 if ( bAborted || bException )
1167 if( xHandler.Is() )
1168 xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
1170 Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
1171 if ( xActiveSink.is() )
1172 xActiveSink->setInputStream( Reference < XInputStream >() );
1174 Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
1175 if ( xStreamer.is() )
1176 xStreamer->setStream( Reference < XStream >() );
1179 Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
1180 if ( xControl.is() )
1181 xControl->terminate();
1183 if ( xProps.is() )
1184 xProps->removePropertiesChangeListener(
1185 Sequence< ::rtl::OUString >(),
1186 xListener );
1188 return ( bAborted || bException );
1192 Function for opening UCB contents synchronously
1194 static sal_Bool _UCBOpenContentSync(
1195 UcbLockBytesRef xLockBytes,
1196 Reference < XContent > xContent,
1197 const Command& rArg,
1198 Reference < XInterface > xSink,
1199 Reference < XInteractionHandler > xInteract,
1200 Reference < XProgressHandler > xProgress,
1201 UcbLockBytesHandlerRef xHandler )
1203 ::ucbhelper::Content aContent( xContent, new UcbTaskEnvironment( xInteract, xProgress ) );
1204 Reference < XContentIdentifier > xIdent = xContent->getIdentifier();
1205 ::rtl::OUString aScheme = xIdent->getContentProviderScheme();
1207 // http protocol must be handled in a special way: during the opening process the input stream may change
1208 // only the last inputstream after notifying the document headers is valid
1209 if ( aScheme.compareToAscii("http") != COMPARE_EQUAL )
1210 xLockBytes->SetStreamValid_Impl();
1212 Reference< XPropertiesChangeListener > xListener = new UcbPropertiesChangeListener_Impl( xLockBytes );
1213 Reference< XPropertiesChangeNotifier > xProps ( xContent, UNO_QUERY );
1214 if ( xProps.is() )
1215 xProps->addPropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
1217 Any aResult;
1218 bool bException = false;
1219 bool bAborted = false;
1223 aResult = aContent.executeCommand( rArg.Name, rArg.Argument );
1225 catch ( CommandAbortedException )
1227 bAborted = true;
1228 xLockBytes->SetError( ERRCODE_ABORT );
1230 catch ( CommandFailedException )
1232 bAborted = true;
1233 xLockBytes->SetError( ERRCODE_ABORT );
1235 catch ( InteractiveIOException& r )
1237 bException = true;
1238 if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
1239 xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
1240 else if ( r.Code == IOErrorCode_NOT_EXISTING )
1241 xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
1242 else if ( r.Code == IOErrorCode_CANT_READ )
1243 xLockBytes->SetError( ERRCODE_IO_CANTREAD );
1244 else
1245 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1247 catch ( UnsupportedDataSinkException& )
1249 bException = true;
1250 xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
1252 catch ( Exception )
1254 bException = true;
1255 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1258 if ( bAborted || bException )
1260 if( xHandler.Is() )
1261 xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
1263 Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
1264 if ( xActiveSink.is() )
1265 xActiveSink->setInputStream( Reference < XInputStream >() );
1267 Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
1268 if ( xStreamer.is() )
1269 xStreamer->setStream( Reference < XStream >() );
1272 Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
1273 if ( xControl.is() )
1274 xControl->terminate();
1277 if ( xProps.is() )
1278 xProps->removePropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
1280 return ( bAborted || bException );
1284 //----------------------------------------------------------------------------
1285 UcbLockBytes::UcbLockBytes( UcbLockBytesHandler* pHandler )
1286 : m_xInputStream (NULL)
1287 , m_pCommandThread( NULL )
1288 , m_xHandler( pHandler )
1289 , m_nError( ERRCODE_NONE )
1290 , m_bTerminated (sal_False)
1291 , m_bDontClose( sal_False )
1292 , m_bStreamValid (sal_False)
1294 SetSynchronMode( TRUE );
1297 //----------------------------------------------------------------------------
1298 UcbLockBytes::~UcbLockBytes()
1300 if ( !m_bDontClose )
1302 if ( m_xInputStream.is() )
1306 m_xInputStream->closeInput();
1308 catch ( RuntimeException const & )
1310 catch ( IOException const & )
1315 if ( !m_xInputStream.is() && m_xOutputStream.is() )
1319 m_xOutputStream->closeOutput();
1321 catch ( RuntimeException const & )
1323 catch ( IOException const & )
1328 Reference < XInputStream > UcbLockBytes::getInputStream()
1330 vos::OClearableGuard aGuard( m_aMutex );
1331 m_bDontClose = sal_True;
1332 return m_xInputStream;
1335 Reference < XStream > UcbLockBytes::getStream()
1337 vos::OClearableGuard aGuard( m_aMutex );
1338 Reference < XStream > xStream( m_xSeekable, UNO_QUERY );
1339 if ( xStream.is() )
1340 m_bDontClose = sal_True;
1341 return xStream;
1344 //----------------------------------------------------------------------------
1346 sal_Bool UcbLockBytes::setStream_Impl( const Reference<XStream>& aStream )
1348 vos::OClearableGuard aGuard( m_aMutex );
1349 if ( aStream.is() )
1351 m_xOutputStream = aStream->getOutputStream();
1352 setInputStream_Impl( aStream->getInputStream(), sal_False );
1353 m_xSeekable = Reference < XSeekable > ( aStream, UNO_QUERY );
1355 else
1357 m_xOutputStream = Reference < XOutputStream >();
1358 setInputStream_Impl( Reference < XInputStream >() );
1361 return m_xInputStream.is();
1364 sal_Bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream, sal_Bool bSetXSeekable )
1366 sal_Bool bRet = sal_False;
1370 vos::OClearableGuard aGuard( m_aMutex );
1372 if ( !m_bDontClose && m_xInputStream.is() )
1373 m_xInputStream->closeInput();
1375 m_xInputStream = rxInputStream;
1377 if( bSetXSeekable )
1379 m_xSeekable = Reference < XSeekable > ( rxInputStream, UNO_QUERY );
1380 if( !m_xSeekable.is() && rxInputStream.is() )
1382 Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
1383 Reference< XOutputStream > rxTempOut = Reference < XOutputStream > (
1384 xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1385 UNO_QUERY );
1387 if( rxTempOut.is() )
1389 ::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream, rxTempOut );
1390 m_xInputStream = Reference< XInputStream >( rxTempOut, UNO_QUERY );
1391 m_xSeekable = Reference < XSeekable > ( rxTempOut, UNO_QUERY );
1396 bRet = m_xInputStream.is();
1397 // aGuard.clear();
1399 catch( Exception& )
1402 if ( m_bStreamValid && m_xInputStream.is() )
1403 m_aInitialized.set();
1405 return bRet;
1408 void UcbLockBytes::SetStreamValid_Impl()
1410 m_bStreamValid = sal_True;
1411 if ( m_xInputStream.is() )
1412 m_aInitialized.set();
1415 //----------------------------------------------------------------------------
1416 void UcbLockBytes::terminate_Impl()
1418 m_bTerminated = sal_True;
1419 m_aInitialized.set();
1420 m_aTerminated.set();
1422 if ( GetError() == ERRCODE_NONE && !m_xInputStream.is() )
1424 DBG_ERROR("No InputStream, but no error set!" );
1425 SetError( ERRCODE_IO_NOTEXISTS );
1428 if ( m_xHandler.Is() )
1429 m_xHandler->Handle( UcbLockBytesHandler::DONE, this );
1432 //----------------------------------------------------------------------------
1433 void UcbLockBytes::SetSynchronMode (BOOL bSynchron)
1435 SvLockBytes::SetSynchronMode (bSynchron);
1438 //----------------------------------------------------------------------------
1439 ErrCode UcbLockBytes::ReadAt ( ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const
1441 if ( IsSynchronMode() )
1443 UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
1444 pThis->m_aInitialized.wait();
1447 Reference <XInputStream> xStream = getInputStream_Impl();
1448 if ( !xStream.is() )
1450 if ( m_bTerminated )
1451 return ERRCODE_IO_CANTREAD;
1452 else
1453 return ERRCODE_IO_PENDING;
1456 if ( pRead )
1457 *pRead = 0;
1459 Reference <XSeekable> xSeekable = getSeekable_Impl();
1460 if ( !xSeekable.is() )
1461 return ERRCODE_IO_CANTREAD;
1465 xSeekable->seek( nPos );
1467 catch ( IOException )
1469 return ERRCODE_IO_CANTSEEK;
1471 catch (com::sun::star::lang::IllegalArgumentException)
1473 return ERRCODE_IO_CANTSEEK;
1476 Sequence<sal_Int8> aData;
1477 sal_Int32 nSize;
1479 nCount = VOS_MIN(nCount, 0x7FFFFFFF);
1482 if ( !m_bTerminated && !IsSynchronMode() )
1484 sal_uInt64 nLen = xSeekable->getLength();
1485 if ( nPos + nCount > nLen )
1486 return ERRCODE_IO_PENDING;
1489 nSize = xStream->readBytes( aData, sal_Int32(nCount) );
1491 catch (IOException)
1493 return ERRCODE_IO_CANTREAD;
1496 rtl_copyMemory (pBuffer, aData.getConstArray(), nSize);
1497 if (pRead)
1498 *pRead = ULONG(nSize);
1500 return ERRCODE_NONE;
1503 //----------------------------------------------------------------------------
1504 ErrCode UcbLockBytes::WriteAt ( ULONG nPos, const void *pBuffer, ULONG nCount, ULONG *pWritten)
1506 if ( pWritten )
1507 *pWritten = 0;
1509 DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" );
1510 DBG_ASSERT( m_aInitialized.check(), "Writing bevor stream is ready!" );
1512 Reference <XSeekable> xSeekable = getSeekable_Impl();
1513 Reference <XOutputStream> xOutputStream = getOutputStream_Impl();
1514 if ( !xOutputStream.is() || !xSeekable.is() )
1515 return ERRCODE_IO_CANTWRITE;
1519 xSeekable->seek( nPos );
1521 catch ( IOException )
1523 return ERRCODE_IO_CANTSEEK;
1526 sal_Int8* pData = (sal_Int8*) pBuffer;
1527 Sequence<sal_Int8> aData( pData, nCount );
1530 xOutputStream->writeBytes( aData );
1531 if ( pWritten )
1532 *pWritten = nCount;
1534 catch ( Exception )
1536 return ERRCODE_IO_CANTWRITE;
1539 return ERRCODE_NONE;
1542 //----------------------------------------------------------------------------
1543 ErrCode UcbLockBytes::Flush() const
1545 Reference <XOutputStream > xOutputStream = getOutputStream_Impl();
1546 if ( !xOutputStream.is() )
1547 return ERRCODE_IO_CANTWRITE;
1548 try {
1549 xOutputStream->flush();
1551 catch (...)
1553 return ERRCODE_IO_CANTWRITE;
1555 return ERRCODE_NONE;
1558 //----------------------------------------------------------------------------
1559 ErrCode UcbLockBytes::SetSize (ULONG nNewSize)
1561 SvLockBytesStat aStat;
1562 Stat( &aStat, (SvLockBytesStatFlag) 0 );
1563 ULONG nSize = aStat.nSize;
1565 if ( nSize > nNewSize )
1567 Reference < XTruncate > xTrunc( getOutputStream_Impl(), UNO_QUERY );
1568 if ( xTrunc.is() )
1570 xTrunc->truncate();
1571 nSize = 0;
1573 else {
1574 DBG_WARNING("Not truncatable!");
1578 if ( nSize < nNewSize )
1580 ULONG nDiff = nNewSize-nSize, nCount=0;
1581 BYTE* pBuffer = new BYTE[ nDiff ];
1582 memset(pBuffer, 0, nDiff); // initialize for enhanced security
1583 WriteAt( nSize, pBuffer, nDiff, &nCount );
1584 delete[] pBuffer;
1585 if ( nCount != nDiff )
1586 return ERRCODE_IO_CANTWRITE;
1589 return ERRCODE_NONE;
1592 //----------------------------------------------------------------------------
1593 ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const
1595 if ( IsSynchronMode() )
1597 UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
1598 pThis->m_aInitialized.wait();
1601 if (!pStat)
1602 return ERRCODE_IO_INVALIDPARAMETER;
1604 Reference <XInputStream> xStream = getInputStream_Impl();
1605 Reference <XSeekable> xSeekable = getSeekable_Impl();
1607 if ( !xStream.is() )
1609 if ( m_bTerminated )
1610 return ERRCODE_IO_INVALIDACCESS;
1611 else
1612 return ERRCODE_IO_PENDING;
1614 else if( !xSeekable.is() )
1615 return ERRCODE_IO_CANTTELL;
1619 pStat->nSize = ULONG(xSeekable->getLength());
1621 catch (IOException)
1623 return ERRCODE_IO_CANTTELL;
1626 return ERRCODE_NONE;
1629 //----------------------------------------------------------------------------
1630 void UcbLockBytes::Cancel()
1632 // is alive only for compatibility reasons
1633 OSL_ENSURE( m_bTerminated, "UcbLockBytes is not thread safe so it can be used only syncronously!\n" );
1636 //----------------------------------------------------------------------------
1637 IMPL_LINK( UcbLockBytes, DataAvailHdl, void*, EMPTYARG )
1639 if ( hasInputStream_Impl() && m_xHandler.Is() )
1640 m_xHandler->Handle( UcbLockBytesHandler::DATA_AVAILABLE, this );
1642 return 0;
1645 UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( const Reference< XInputStream >& xInputStream )
1647 if( !xInputStream.is() )
1648 return NULL;;
1650 UcbLockBytesRef xLockBytes = new UcbLockBytes();
1651 xLockBytes->setDontClose_Impl();
1652 xLockBytes->setInputStream_Impl( xInputStream );
1653 xLockBytes->terminate_Impl();
1654 return xLockBytes;
1657 UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference< XStream >& xStream )
1659 if( !xStream.is() )
1660 return NULL;;
1662 UcbLockBytesRef xLockBytes = new UcbLockBytes();
1663 xLockBytes->setDontClose_Impl();
1664 xLockBytes->setStream_Impl( xStream );
1665 xLockBytes->terminate_Impl();
1666 return xLockBytes;
1669 UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const ::rtl::OUString& rReferer, const ::rtl::OUString& rMediaType,
1670 const Reference < XInputStream >& xPostData, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
1672 if( !xContent.is() )
1673 return NULL;;
1675 UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
1676 xLockBytes->SetSynchronMode( !pHandler );
1677 Reference< XActiveDataControl > xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );
1679 PostCommandArgument2 aArgument;
1680 aArgument.Source = xPostData;
1681 aArgument.Sink = xSink;
1682 aArgument.MediaType = rMediaType;
1683 aArgument.Referer = rReferer;
1685 Command aCommand;
1686 aCommand.Name = ::rtl::OUString::createFromAscii ("post");
1687 aCommand.Argument <<= aArgument;
1689 Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );
1691 sal_Bool bError = UCBOpenContentSync( xLockBytes,
1692 xContent,
1693 aCommand,
1694 xSink,
1695 xInteractionHandler,
1696 xProgressHdl,
1697 pHandler );
1699 if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
1701 DBG_ERROR("No InputStream, but no error set!" );
1702 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1705 return xLockBytes;
1708 UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const Sequence < PropertyValue >& rProps,
1709 StreamMode eOpenMode, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
1711 if( !xContent.is() )
1712 return NULL;;
1714 UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
1715 xLockBytes->SetSynchronMode( !pHandler );
1716 Reference< XActiveDataControl > xSink;
1717 if ( eOpenMode & STREAM_WRITE )
1718 xSink = (XActiveDataControl*) new UcbStreamer_Impl( xLockBytes );
1719 else
1720 xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );
1722 if ( rProps.getLength() )
1724 Reference < XCommandProcessor > xProcessor( xContent, UNO_QUERY );
1725 Command aCommand;
1726 aCommand.Name = ::rtl::OUString::createFromAscii("setPropertyValues");
1727 aCommand.Handle = -1; /* unknown */
1728 aCommand.Argument <<= rProps;
1729 xProcessor->execute( aCommand, 0, Reference < XCommandEnvironment >() );
1732 OpenCommandArgument2 aArgument;
1733 aArgument.Sink = xSink;
1734 aArgument.Mode = OpenMode::DOCUMENT;
1736 Command aCommand;
1737 aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("open") );
1738 aCommand.Argument <<= aArgument;
1740 Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );
1742 sal_Bool bError = UCBOpenContentSync( xLockBytes,
1743 xContent,
1744 aCommand,
1745 xSink,
1746 xInteractionHandler,
1747 xProgressHdl,
1748 pHandler );
1750 if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
1752 DBG_ERROR("No InputStream, but no error set!" );
1753 xLockBytes->SetError( ERRCODE_IO_GENERAL );
1756 return xLockBytes;