Branch data 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 : :
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/ucb/DocumentHeaderField.hpp>
35 : : #include <com/sun/star/ucb/XCommandInfo.hpp>
36 : : #include <com/sun/star/ucb/XCommandProcessor.hpp>
37 : : #include <com/sun/star/task/XInteractionHandler.hpp>
38 : : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
39 : : #include <com/sun/star/ucb/PostCommandArgument2.hpp>
40 : : #include <com/sun/star/ucb/OpenMode.hpp>
41 : : #include <com/sun/star/beans/Property.hpp>
42 : : #include <com/sun/star/beans/PropertyValue.hpp>
43 : : #include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
44 : : #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
45 : : #include <com/sun/star/sdbc/XRow.hpp>
46 : : #include <com/sun/star/io/XActiveDataSink.hpp>
47 : : #include <com/sun/star/io/XActiveDataControl.hpp>
48 : : #include <com/sun/star/io/XSeekable.hpp>
49 : : #include <cppuhelper/implbase1.hxx>
50 : : #include <cppuhelper/implbase2.hxx>
51 : : #include <tools/inetmsg.hxx>
52 : : #include <com/sun/star/io/XTruncate.hpp>
53 : : #include <com/sun/star/lang/IllegalArgumentException.hpp>
54 : :
55 : : #include <comphelper/storagehelper.hxx>
56 : :
57 : : #include <ucbhelper/contentbroker.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::uno;
63 : : using namespace ::com::sun::star::ucb;
64 : : using namespace ::com::sun::star::task;
65 : : using namespace ::com::sun::star::lang;
66 : : using namespace ::com::sun::star::beans;
67 : :
68 : :
69 : : namespace utl
70 : : {
71 : :
72 : : /**
73 : : Helper class for getting a XInputStream when opening a content
74 : : */
75 [ + - ][ - + ]: 8218 : class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink >
76 : : {
77 : : UcbLockBytesRef m_xLockBytes;
78 : :
79 : : public:
80 : 4109 : UcbDataSink_Impl( UcbLockBytes* pLockBytes )
81 : 4109 : : m_xLockBytes( pLockBytes )
82 : 4109 : {}
83 : :
84 : : SvLockBytes* getLockBytes (void)
85 : : { return m_xLockBytes; }
86 : :
87 : : // XActiveDataControl.
88 : 0 : virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
89 : 0 : virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
90 : 0 : virtual void SAL_CALL start (void) throw(RuntimeException) {}
91 : 4109 : virtual void SAL_CALL terminate (void) throw(RuntimeException)
92 : 4109 : { m_xLockBytes->terminate_Impl(); }
93 : :
94 : : // XActiveDataSink.
95 : 6293 : virtual void SAL_CALL setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException)
96 : 6293 : { m_xLockBytes->setInputStream_Impl (rxInputStream); }
97 : 0 : virtual Reference<XInputStream> SAL_CALL getInputStream (void) throw(RuntimeException)
98 : 0 : { return m_xLockBytes->getInputStream_Impl(); }
99 : : };
100 : :
101 : : /**
102 : : Helper class for getting a XStream when opening a content
103 : : */
104 [ + - ][ - + ]: 15510 : class UcbStreamer_Impl : public ::cppu::WeakImplHelper2< XActiveDataStreamer, XActiveDataControl >
105 : : {
106 : : Reference < XStream > m_xStream;
107 : : UcbLockBytesRef m_xLockBytes;
108 : :
109 : : public:
110 : 7755 : UcbStreamer_Impl( UcbLockBytes* pLockBytes )
111 : 7755 : : m_xLockBytes( pLockBytes )
112 : 7755 : {}
113 : :
114 : : // XActiveDataControl.
115 : 0 : virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
116 : 0 : virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
117 : 0 : virtual void SAL_CALL start (void) throw(RuntimeException) {}
118 : 7755 : virtual void SAL_CALL terminate (void) throw(RuntimeException)
119 : 7755 : { m_xLockBytes->terminate_Impl(); }
120 : :
121 : : // XActiveDataStreamer
122 : 7773 : virtual void SAL_CALL setStream( const Reference< XStream >& aStream ) throw(RuntimeException)
123 : 7773 : { m_xStream = aStream; m_xLockBytes->setStream_Impl( aStream ); }
124 : 0 : virtual Reference< XStream > SAL_CALL getStream() throw(RuntimeException)
125 : 0 : { return m_xStream; }
126 : : };
127 : :
128 : : /**
129 : : Helper class for progress handling while executing UCB commands
130 : : */
131 [ - + ]: 23728 : class ProgressHandler_Impl: public ::cppu::WeakImplHelper1< XProgressHandler >
132 : : {
133 : : Link m_aProgress;
134 : :
135 : : public:
136 : 11864 : ProgressHandler_Impl( const Link& rLink )
137 : 11864 : : m_aProgress( rLink )
138 : 11864 : {}
139 : : // XProgressHandler
140 : 0 : virtual void SAL_CALL push(const Any & /*rStatus*/) throw (RuntimeException) {}
141 : 0 : virtual void SAL_CALL pop() throw (RuntimeException) {}
142 : 0 : virtual void SAL_CALL update(const Any & /*rStatus*/) throw (RuntimeException)
143 [ # # ]: 0 : { if ( m_aProgress.IsSet() ) m_aProgress.Call( 0 ); }
144 : : };
145 : :
146 : : /**
147 : : Helper class for managing interactions and progress when executing UCB commands
148 : : */
149 [ - + ]: 23728 : class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment >
150 : : {
151 : : Reference< XInteractionHandler > m_xInteractionHandler;
152 : : Reference< XProgressHandler > m_xProgressHandler;
153 : :
154 : : public:
155 : 11864 : UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler,
156 : : const Reference< XProgressHandler>& rxProgressHandler )
157 : : : m_xInteractionHandler( rxInteractionHandler )
158 : 11864 : , m_xProgressHandler( rxProgressHandler )
159 : 11864 : {}
160 : :
161 : 2202 : virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException)
162 : 2202 : { return m_xInteractionHandler; }
163 : :
164 : 0 : virtual Reference<XProgressHandler> SAL_CALL getProgressHandler() throw (RuntimeException)
165 : 0 : { return m_xProgressHandler; }
166 : : };
167 : :
168 : :
169 : : /**
170 : : Helper class for property change notifies when executing UCB commands
171 : : */
172 [ + - ][ - + ]: 23728 : class UcbPropertiesChangeListener_Impl : public ::cppu::WeakImplHelper1< XPropertiesChangeListener >
173 : : {
174 : : public:
175 : : UcbLockBytesRef m_xLockBytes;
176 : :
177 : 11864 : UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef )
178 : 11864 : : m_xLockBytes( rRef )
179 : 11864 : {}
180 : :
181 : 0 : virtual void SAL_CALL disposing ( const EventObject &/*rEvent*/) throw(RuntimeException) {}
182 : : virtual void SAL_CALL propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException);
183 : : };
184 : :
185 : 0 : void SAL_CALL UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException)
186 : : {
187 : 0 : sal_Int32 i, n = rEvent.getLength();
188 [ # # ]: 0 : for (i = 0; i < n; i++)
189 : : {
190 [ # # ]: 0 : PropertyChangeEvent evt (rEvent[i]);
191 [ # # ][ # # ]: 0 : if (evt.PropertyName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("DocumentHeader")))
192 : : {
193 [ # # ]: 0 : Sequence<DocumentHeaderField> aHead;
194 [ # # ][ # # ]: 0 : if (evt.NewValue >>= aHead)
195 : : {
196 : 0 : sal_Int32 k, m = aHead.getLength();
197 [ # # ]: 0 : for (k = 0; k < m; k++)
198 : : {
199 [ # # ][ # # ]: 0 : String aName( aHead[k].Name );
200 [ # # ][ # # ]: 0 : String aValue( aHead[k].Value );
201 : :
202 [ # # ][ # # ]: 0 : if (aName.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL)
203 : : {
204 [ # # ]: 0 : DateTime aExpires (0, 0);
205 [ # # ][ # # ]: 0 : if (INetRFC822Message::ParseDateField (aValue, aExpires))
[ # # ]
206 : : {
207 [ # # ]: 0 : aExpires.ConvertToLocalTime();
208 [ # # ]: 0 : m_xLockBytes->SetExpireDate_Impl( aExpires );
209 : : }
210 : : }
211 [ # # ][ # # ]: 0 : }
212 : : }
213 : :
214 [ # # ][ # # ]: 0 : m_xLockBytes->SetStreamValid_Impl();
215 : : }
216 [ # # ][ # # ]: 0 : else if (evt.PropertyName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("PresentationURL")))
217 : : {
218 : 0 : ::rtl::OUString aUrl;
219 [ # # ]: 0 : if (evt.NewValue >>= aUrl)
220 : : {
221 [ # # ]: 0 : ::rtl::OUString aBad (RTL_CONSTASCII_USTRINGPARAM ("private:"));
222 [ # # ]: 0 : if (!(aUrl.compareTo (aBad, aBad.getLength()) == 0))
223 : : {
224 : : // URL changed (Redirection).
225 [ # # ][ # # ]: 0 : m_xLockBytes->SetRealURL_Impl( aUrl );
[ # # ]
226 : 0 : }
227 : 0 : }
228 : : }
229 [ # # ][ # # ]: 0 : else if (evt.PropertyName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("MediaType")))
230 : : {
231 : 0 : ::rtl::OUString aContentType;
232 [ # # ]: 0 : if (evt.NewValue >>= aContentType)
233 [ # # ][ # # ]: 0 : m_xLockBytes->SetContentType_Impl( aContentType );
[ # # ]
234 : : }
235 [ # # ]: 0 : }
236 : 0 : }
237 : :
238 : :
239 : :
240 : : class Moderator
241 : : : public osl::Thread
242 : : {
243 : : // usage restriction:
244 : : // It might be possible, that the call to the interactionhandler and/or
245 : : // progresshandler is done asynchrounsly, while the 'execute' simply
246 : : // returns. This would imply that these class must be refcounted !!!
247 : :
248 : : public:
249 : : Moderator(
250 : : Reference < XContent >& xContent,
251 : : Reference < XInteractionHandler >& xInteract,
252 : : Reference < XProgressHandler >& xProgress,
253 : : const Command& rArg
254 : : )
255 : : throw(
256 : : ContentCreationException,
257 : : RuntimeException
258 : : );
259 : :
260 : : ~Moderator();
261 : :
262 : :
263 : : enum ResultType {
264 : : NORESULT,
265 : :
266 : : INTERACTIONREQUEST, // reply expected
267 : :
268 : : PROGRESSPUSH,
269 : : PROGRESSUPDATE,
270 : : PROGRESSPOP,
271 : :
272 : : INPUTSTREAM,
273 : : STREAM,
274 : :
275 : : RESULT,
276 : : TIMEDOUT,
277 : : COMMANDABORTED,
278 : : COMMANDFAILED,
279 : : INTERACTIVEIO,
280 : : UNSUPPORTED,
281 : : GENERAL
282 : : };
283 : :
284 : :
285 [ # # ]: 0 : class ConditionRes
286 : : : public salhelper::Condition
287 : : {
288 : : public:
289 : 0 : ConditionRes(osl::Mutex& aMutex,Moderator& aModerator)
290 : : : salhelper::Condition(aMutex),
291 : 0 : m_aModerator(aModerator)
292 : : {
293 : 0 : }
294 : :
295 : : protected:
296 : 0 : bool applies() const {
297 : 0 : return m_aModerator.m_aResultType != NORESULT;
298 : : }
299 : :
300 : : private:
301 : : Moderator& m_aModerator;
302 : : };
303 : :
304 : :
305 : 0 : struct Result {
306 : : ResultType type;
307 : : Any result;
308 : : sal_Int32 ioErrorCode;
309 : : };
310 : :
311 : : Result getResult(const sal_uInt32 milliSec);
312 : :
313 : : enum ReplyType {
314 : : NOREPLY,
315 : : EXIT,
316 : : RETRY,
317 : : REQUESTHANDLED
318 : : };
319 : :
320 [ # # ]: 0 : class ConditionRep
321 : : : public salhelper::Condition
322 : : {
323 : : public:
324 : 0 : ConditionRep(osl::Mutex& aMutex,Moderator& aModerator)
325 : : : salhelper::Condition(aMutex),
326 : 0 : m_aModerator(aModerator)
327 : : {
328 : 0 : }
329 : :
330 : : protected:
331 : 0 : bool applies() const {
332 : 0 : return m_aModerator.m_aReplyType != NOREPLY;
333 : : }
334 : :
335 : : private:
336 : : Moderator& m_aModerator;
337 : : };
338 : :
339 : : void setReply(ReplyType);
340 : :
341 : : void handle( const Reference<XInteractionRequest >& Request );
342 : : void push( const Any& Status );
343 : : void update( const Any& Status );
344 : : void pop( );
345 : :
346 : : void setStream(const Reference< XStream >& aStream);
347 : : void setInputStream(const Reference<XInputStream> &rxInputStream);
348 : :
349 : :
350 : : protected:
351 : : virtual void SAL_CALL run();
352 : : virtual void SAL_CALL onTerminated();
353 : :
354 : : private:
355 : : osl::Mutex m_aMutex;
356 : :
357 : : friend class ConditionRes;
358 : :
359 : : ConditionRes m_aRes;
360 : : ResultType m_aResultType;
361 : : sal_Int32 m_nIOErrorCode;
362 : : Any m_aResult;
363 : :
364 : : friend class ConditionRep;
365 : :
366 : : ConditionRep m_aRep;
367 : : ReplyType m_aReplyType;
368 : :
369 : : Command m_aArg;
370 : : ::ucbhelper::Content m_aContent;
371 : : };
372 : :
373 : :
374 : : class ModeratorsActiveDataStreamer
375 : : : public ::cppu::WeakImplHelper1<XActiveDataStreamer>
376 : : {
377 : : public:
378 : :
379 : : ModeratorsActiveDataStreamer(Moderator &theModerator);
380 : :
381 : : ~ModeratorsActiveDataStreamer();
382 : :
383 : : // XActiveDataStreamer
384 : : virtual void SAL_CALL
385 : : setStream(
386 : : const Reference< XStream >& aStream
387 : : )
388 : : throw(
389 : : RuntimeException
390 : : );
391 : :
392 : : virtual Reference<XStream> SAL_CALL
393 : 0 : getStream (
394 : : void
395 : : ) throw(
396 : : RuntimeException
397 : : )
398 : : {
399 [ # # ]: 0 : osl::MutexGuard aGuard(m_aMutex);
400 [ # # ]: 0 : return m_xStream;
401 : : }
402 : :
403 : :
404 : : private:
405 : : Moderator& m_aModerator;
406 : :
407 : : osl::Mutex m_aMutex;
408 : : Reference<XStream> m_xStream;
409 : : };
410 : :
411 : :
412 : : class ModeratorsActiveDataSink
413 : : : public ::cppu::WeakImplHelper1<XActiveDataSink>
414 : : {
415 : : public:
416 : :
417 : : ModeratorsActiveDataSink(Moderator &theModerator);
418 : :
419 : : ~ModeratorsActiveDataSink();
420 : :
421 : : // XActiveDataSink.
422 : : virtual void SAL_CALL
423 : : setInputStream (
424 : : const Reference<XInputStream> &rxInputStream
425 : : )
426 : : throw(
427 : : RuntimeException
428 : : );
429 : :
430 : : virtual Reference<XInputStream> SAL_CALL
431 : 0 : getInputStream (
432 : : void
433 : : ) throw(
434 : : RuntimeException
435 : : )
436 : : {
437 [ # # ]: 0 : osl::MutexGuard aGuard(m_aMutex);
438 [ # # ]: 0 : return m_xStream;
439 : : }
440 : :
441 : :
442 : : private:
443 : : Moderator& m_aModerator;
444 : : osl::Mutex m_aMutex;
445 : : Reference<XInputStream> m_xStream;
446 : : };
447 : :
448 : :
449 : :
450 : 0 : ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator &theModerator)
451 [ # # ]: 0 : : m_aModerator(theModerator)
452 : : {
453 : 0 : }
454 : :
455 : :
456 [ # # ]: 0 : ModeratorsActiveDataSink::~ModeratorsActiveDataSink()
457 : : {
458 [ # # ]: 0 : }
459 : :
460 : : // XActiveDataSink.
461 : : void SAL_CALL
462 : 0 : ModeratorsActiveDataSink::setInputStream (
463 : : const Reference<XInputStream> &rxInputStream
464 : : )
465 : : throw(
466 : : RuntimeException
467 : : )
468 : : {
469 [ # # ]: 0 : m_aModerator.setInputStream(rxInputStream);
470 [ # # ]: 0 : osl::MutexGuard aGuard(m_aMutex);
471 [ # # ][ # # ]: 0 : m_xStream = rxInputStream;
472 : 0 : }
473 : :
474 : :
475 : 0 : ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer(
476 : : Moderator &theModerator
477 : : )
478 [ # # ]: 0 : : m_aModerator(theModerator)
479 : : {
480 : 0 : }
481 : :
482 : :
483 [ # # ]: 0 : ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer()
484 : : {
485 [ # # ]: 0 : }
486 : :
487 : : // XActiveDataStreamer.
488 : : void SAL_CALL
489 : 0 : ModeratorsActiveDataStreamer::setStream (
490 : : const Reference<XStream> &rxStream
491 : : )
492 : : throw(
493 : : RuntimeException
494 : : )
495 : : {
496 [ # # ]: 0 : m_aModerator.setStream(rxStream);
497 [ # # ]: 0 : osl::MutexGuard aGuard(m_aMutex);
498 [ # # ][ # # ]: 0 : m_xStream = rxStream;
499 : 0 : }
500 : :
501 : :
502 : :
503 : : class ModeratorsInteractionHandler
504 : : : public ::cppu::WeakImplHelper1<XInteractionHandler>
505 : : {
506 : : public:
507 : :
508 : : ModeratorsInteractionHandler(Moderator &theModerator);
509 : :
510 : : ~ModeratorsInteractionHandler();
511 : :
512 : : virtual void SAL_CALL
513 : : handle( const Reference<XInteractionRequest >& Request )
514 : : throw (RuntimeException);
515 : :
516 : : private:
517 : :
518 : : Moderator& m_aModerator;
519 : : };
520 : :
521 : :
522 : : class ModeratorsProgressHandler
523 : : : public ::cppu::WeakImplHelper1<XProgressHandler>
524 : : {
525 : : public:
526 : : ModeratorsProgressHandler(Moderator &theModerator);
527 : :
528 : : ~ModeratorsProgressHandler();
529 : :
530 : : virtual void SAL_CALL push( const Any& Status )
531 : : throw (
532 : : RuntimeException);
533 : :
534 : : virtual void SAL_CALL update( const Any& Status )
535 : : throw (RuntimeException);
536 : :
537 : : virtual void SAL_CALL pop( )
538 : : throw (RuntimeException);
539 : :
540 : :
541 : : private:
542 : : Moderator& m_aModerator;
543 : : };
544 : :
545 : :
546 : 0 : ModeratorsProgressHandler::ModeratorsProgressHandler(Moderator &theModerator)
547 : 0 : : m_aModerator(theModerator)
548 : : {
549 : 0 : }
550 : :
551 : 0 : ModeratorsProgressHandler::~ModeratorsProgressHandler()
552 : : {
553 [ # # ]: 0 : }
554 : :
555 : :
556 : 0 : void SAL_CALL ModeratorsProgressHandler::push( const Any& Status )
557 : : throw (
558 : : RuntimeException)
559 : : {
560 : 0 : m_aModerator.push(Status);
561 : 0 : }
562 : :
563 : :
564 : 0 : void SAL_CALL ModeratorsProgressHandler::update( const Any& Status )
565 : : throw (RuntimeException)
566 : : {
567 : 0 : m_aModerator.update(Status);
568 : 0 : }
569 : :
570 : :
571 : 0 : void SAL_CALL ModeratorsProgressHandler::pop( )
572 : : throw (RuntimeException)
573 : : {
574 : 0 : m_aModerator.pop();
575 : 0 : }
576 : :
577 : :
578 : 0 : ModeratorsInteractionHandler::ModeratorsInteractionHandler(
579 : : Moderator &aModerator)
580 : 0 : : m_aModerator(aModerator)
581 : : {
582 : 0 : }
583 : :
584 : :
585 : 0 : ModeratorsInteractionHandler::~ModeratorsInteractionHandler()
586 : : {
587 [ # # ]: 0 : }
588 : :
589 : :
590 : : void SAL_CALL
591 : 0 : ModeratorsInteractionHandler::handle(
592 : : const Reference<XInteractionRequest >& Request
593 : : )
594 : : throw (
595 : : RuntimeException
596 : : )
597 : : {
598 : : // wakes up the mainthread
599 : 0 : m_aModerator.handle(Request);
600 : 0 : }
601 : :
602 : :
603 : :
604 : :
605 : 0 : Moderator::Moderator(
606 : : Reference < XContent >& xContent,
607 : : Reference < XInteractionHandler >& xInteract,
608 : : Reference < XProgressHandler >& xProgress,
609 : : const Command& rArg
610 : : )
611 : : throw(
612 : : ::com::sun::star::ucb::ContentCreationException,
613 : : ::com::sun::star::uno::RuntimeException
614 : : )
615 : : : m_aMutex(),
616 : :
617 : : m_aRes(m_aMutex,*this),
618 : : m_aResultType(NORESULT),
619 : : m_nIOErrorCode(0),
620 : : m_aResult(),
621 : :
622 : : m_aRep(m_aMutex,*this),
623 : : m_aReplyType(NOREPLY),
624 : :
625 : : m_aArg(rArg),
626 : : m_aContent(
627 : : xContent,
628 : : new UcbTaskEnvironment(
629 [ # # ]: 0 : xInteract.is() ? new ModeratorsInteractionHandler(*this) : 0,
630 [ # # ]: 0 : xProgress.is() ? new ModeratorsProgressHandler(*this) : 0
631 [ # # ][ # # ]: 0 : ))
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
632 : : {
633 : : // now exchange the whole data sink stuff
634 : : // with a thread safe version
635 : :
636 : 0 : Reference<XInterface> *pxSink = NULL;
637 : :
638 [ # # ]: 0 : PostCommandArgument2 aPostArg;
639 [ # # ]: 0 : OpenCommandArgument2 aOpenArg;
640 : :
641 : 0 : int dec(2);
642 [ # # ][ # # ]: 0 : if(m_aArg.Argument >>= aPostArg) {
643 : 0 : pxSink = &aPostArg.Sink;
644 : 0 : dec = 0;
645 : : }
646 [ # # ][ # # ]: 0 : else if(m_aArg.Argument >>= aOpenArg) {
647 : 0 : pxSink = &aOpenArg.Sink;
648 : 0 : dec = 1;
649 : : }
650 : :
651 [ # # ]: 0 : if(dec ==2)
652 [ # # ]: 0 : throw ContentCreationException();
653 : :
654 [ # # ]: 0 : Reference < XActiveDataSink > xActiveSink(*pxSink,UNO_QUERY);
655 [ # # ]: 0 : if(xActiveSink.is())
656 : : *pxSink = Reference<XInterface>(
657 [ # # ][ # # ]: 0 : (cppu::OWeakObject*)new ModeratorsActiveDataSink(*this));
[ # # ]
658 : :
659 [ # # ]: 0 : Reference<XActiveDataStreamer> xStreamer( *pxSink, UNO_QUERY );
660 [ # # ]: 0 : if ( xStreamer.is() )
661 : : *pxSink = Reference<XInterface>(
662 [ # # ][ # # ]: 0 : (cppu::OWeakObject*)new ModeratorsActiveDataStreamer(*this));
[ # # ]
663 : :
664 [ # # ]: 0 : if(dec == 0)
665 [ # # ]: 0 : m_aArg.Argument <<= aPostArg;
666 [ # # ]: 0 : else if(dec == 1)
667 [ # # ][ # # ]: 0 : m_aArg.Argument <<= aOpenArg;
[ # # ]
668 : 0 : }
669 : :
670 : :
671 [ # # ][ # # ]: 0 : Moderator::~Moderator()
[ # # ][ # # ]
672 : : {
673 [ # # ]: 0 : }
674 : :
675 : :
676 : 0 : Moderator::Result Moderator::getResult(const sal_uInt32 milliSec)
677 : : {
678 : 0 : Result ret;
679 : : try {
680 [ # # ]: 0 : salhelper::ConditionWaiter aWaiter(m_aRes,milliSec);
681 : 0 : ret.type = m_aResultType;
682 : 0 : ret.result = m_aResult;
683 : 0 : ret.ioErrorCode = m_nIOErrorCode;
684 : :
685 : : // reset
686 [ # # ]: 0 : m_aResultType = NORESULT;
687 : : }
688 [ # # ]: 0 : catch (const salhelper::ConditionWaiter::timedout&)
689 : : {
690 : 0 : ret.type = TIMEDOUT;
691 : : }
692 : :
693 [ # # ]: 0 : return ret;
694 : : }
695 : :
696 : :
697 : 0 : void Moderator::setReply(ReplyType aReplyType )
698 : : {
699 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRep);
700 [ # # ]: 0 : m_aReplyType = aReplyType;
701 : 0 : }
702 : :
703 : :
704 : 0 : void Moderator::handle( const Reference<XInteractionRequest >& Request )
705 : : {
706 : : ReplyType aReplyType;
707 : :
708 [ # # ]: 0 : do {
709 : : {
710 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRes);
711 : 0 : m_aResultType = INTERACTIONREQUEST;
712 [ # # ][ # # ]: 0 : m_aResult <<= Request;
713 : : }
714 : :
715 : : {
716 [ # # ]: 0 : salhelper::ConditionWaiter aWait(m_aRep);
717 : 0 : aReplyType = m_aReplyType;
718 : :
719 : : // reset
720 [ # # ]: 0 : m_aReplyType = NOREPLY;
721 : : }
722 : :
723 [ # # ]: 0 : if(aReplyType == EXIT) {
724 : : Sequence<Reference<XInteractionContinuation> > aSeq(
725 [ # # ][ # # ]: 0 : Request->getContinuations());
726 [ # # ]: 0 : for(sal_Int32 i = 0; i < aSeq.getLength(); ++i) {
727 [ # # ][ # # ]: 0 : Reference<XInteractionAbort> aRef(aSeq[i],UNO_QUERY);
728 [ # # ]: 0 : if(aRef.is()) {
729 [ # # ][ # # ]: 0 : aRef->select();
730 : : }
731 : 0 : }
732 : :
733 : : // resignal the exitcondition
734 [ # # ]: 0 : setReply(EXIT);
735 [ # # ]: 0 : break;
736 : : }
737 : : } while(aReplyType != REQUESTHANDLED);
738 : 0 : }
739 : :
740 : :
741 : 0 : void Moderator::push( const Any& Status )
742 : : {
743 : : {
744 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRes);
745 : 0 : m_aResultType = PROGRESSPUSH;
746 [ # # ]: 0 : m_aResult = Status;
747 : : }
748 : : ReplyType aReplyType;
749 : : {
750 [ # # ]: 0 : salhelper::ConditionWaiter aWait(m_aRep);
751 : 0 : aReplyType = m_aReplyType;
752 [ # # ]: 0 : m_aReplyType = NOREPLY;
753 : : }
754 [ # # ]: 0 : if(aReplyType == EXIT)
755 : 0 : setReply(EXIT);
756 : 0 : }
757 : :
758 : :
759 : 0 : void Moderator::update( const Any& Status )
760 : : {
761 : : {
762 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRes);
763 : 0 : m_aResultType = PROGRESSUPDATE;
764 [ # # ]: 0 : m_aResult = Status;
765 : : }
766 : : ReplyType aReplyType;
767 : : {
768 [ # # ]: 0 : salhelper::ConditionWaiter aWait(m_aRep);
769 : 0 : aReplyType = m_aReplyType;
770 [ # # ]: 0 : m_aReplyType = NOREPLY;
771 : : }
772 [ # # ]: 0 : if(aReplyType == EXIT)
773 : 0 : setReply(EXIT);
774 : 0 : }
775 : :
776 : :
777 : 0 : void Moderator::pop( )
778 : : {
779 : : {
780 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRes);
781 [ # # ]: 0 : m_aResultType = PROGRESSPOP;
782 : : }
783 : : ReplyType aReplyType;
784 : : {
785 [ # # ]: 0 : salhelper::ConditionWaiter aWait(m_aRep);
786 : 0 : aReplyType = m_aReplyType;
787 [ # # ]: 0 : m_aReplyType = NOREPLY;
788 : : }
789 [ # # ]: 0 : if(aReplyType == EXIT)
790 : 0 : setReply(EXIT);
791 : 0 : }
792 : :
793 : :
794 : 0 : void Moderator::setStream(const Reference< XStream >& aStream)
795 : : {
796 : : {
797 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRes);
798 : 0 : m_aResultType = STREAM;
799 [ # # ][ # # ]: 0 : m_aResult <<= aStream;
800 : : }
801 : : ReplyType aReplyType;
802 : : {
803 [ # # ]: 0 : salhelper::ConditionWaiter aWait(m_aRep);
804 : 0 : aReplyType = m_aReplyType;
805 [ # # ]: 0 : m_aReplyType = NOREPLY;
806 : : }
807 [ # # ]: 0 : if(aReplyType == EXIT)
808 : 0 : setReply(EXIT);
809 : 0 : }
810 : :
811 : :
812 : 0 : void Moderator::setInputStream(const Reference<XInputStream> &rxInputStream)
813 : : {
814 : : {
815 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRes);
816 : 0 : m_aResultType = INPUTSTREAM;
817 [ # # ][ # # ]: 0 : m_aResult <<= rxInputStream;
818 : : }
819 : : ReplyType aReplyType;
820 : : {
821 [ # # ]: 0 : salhelper::ConditionWaiter aWait(m_aRep);
822 : 0 : aReplyType = m_aReplyType;
823 [ # # ]: 0 : m_aReplyType = NOREPLY;
824 : : }
825 [ # # ]: 0 : if(aReplyType == EXIT)
826 : 0 : setReply(EXIT);
827 : 0 : }
828 : :
829 : :
830 : 0 : void SAL_CALL Moderator::run()
831 : : {
832 : : ResultType aResultType;
833 : 0 : Any aResult;
834 : 0 : sal_Int32 nIOErrorCode = 0;
835 : :
836 : : try
837 : : {
838 [ # # ]: 0 : aResult = m_aContent.executeCommand(m_aArg.Name,m_aArg.Argument);
839 : 0 : aResultType = RESULT;
840 : : }
841 [ # # ]: 0 : catch (const CommandAbortedException&)
842 : : {
843 : 0 : aResultType = COMMANDABORTED;
844 : : }
845 [ # # ]: 0 : catch (const CommandFailedException&)
846 : : {
847 : 0 : aResultType = COMMANDFAILED;
848 : : }
849 [ # # ]: 0 : catch (const InteractiveIOException& r)
850 : : {
851 : 0 : nIOErrorCode = r.Code;
852 : 0 : aResultType = INTERACTIVEIO;
853 : : }
854 [ # # ]: 0 : catch (const UnsupportedDataSinkException &)
855 : : {
856 : 0 : aResultType = UNSUPPORTED;
857 : : }
858 [ # # ]: 0 : catch (const Exception&)
859 : : {
860 : 0 : aResultType = GENERAL;
861 : : }
862 : :
863 : : {
864 [ # # ]: 0 : salhelper::ConditionModifier aMod(m_aRes);
865 : 0 : m_aResultType = aResultType;
866 : 0 : m_aResult = aResult;
867 [ # # ]: 0 : m_nIOErrorCode = nIOErrorCode;
868 : 0 : }
869 [ # # # # : 0 : }
# # ]
870 : :
871 : 0 : void SAL_CALL Moderator::onTerminated()
872 : : {
873 : : {
874 [ # # ][ # # ]: 0 : salhelper::ConditionWaiter aWaiter(m_aRep);
875 : : }
876 [ # # ]: 0 : delete this;
877 : 0 : }
878 : :
879 : : /**
880 : : Function for opening UCB contents synchronously,
881 : : but with handled timeout;
882 : : */
883 : : static sal_Bool _UCBOpenContentSync(
884 : : UcbLockBytesRef xLockBytes,
885 : : Reference < XContent > xContent,
886 : : const Command& rArg,
887 : : Reference < XInterface > xSink,
888 : : Reference < XInteractionHandler > xInteract,
889 : : Reference < XProgressHandler > xProgress,
890 : : UcbLockBytesHandlerRef xHandler );
891 : :
892 : :
893 : 11864 : static sal_Bool UCBOpenContentSync(
894 : : UcbLockBytesRef xLockBytes,
895 : : Reference < XContent > xContent,
896 : : const Command& rArg,
897 : : Reference < XInterface > xSink,
898 : : Reference < XInteractionHandler > xInteract,
899 : : Reference < XProgressHandler > xProgress,
900 : : UcbLockBytesHandlerRef xHandler )
901 : : {
902 : : // http protocol must be handled in a special way:
903 : : // during the opening process the input stream may change
904 : : // only the last inputstream after notifying the document
905 : : // headers is valid
906 : :
907 : : Reference<XContentIdentifier> xContId(
908 [ + - ][ + - ]: 11864 : xContent.is() ? xContent->getIdentifier() : 0 );
[ + - ][ # # ]
909 : :
910 : 11864 : rtl::OUString aScheme;
911 [ + - ]: 11864 : if(xContId.is())
912 [ + - ][ + - ]: 11864 : aScheme = xContId->getContentProviderScheme();
913 : :
914 : : // now determine whether we use a timeout or not;
915 [ + - + - : 47456 : if( ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("http")) &&
+ - + - ]
[ + - ]
916 : 11864 : ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("https")) &&
917 : 11864 : ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.webdav")) &&
918 : 11864 : ! aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("ftp")))
919 : : return _UCBOpenContentSync(
920 [ + - ][ + - ]: 11864 : xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler);
[ + - ]
921 : :
922 [ # # # # ]: 0 : if ( (aScheme.compareToAscii( "http" ) != COMPARE_EQUAL) ||
[ # # ]
923 : 0 : (aScheme.compareToAscii( "https" ) != COMPARE_EQUAL) )
924 [ # # ]: 0 : xLockBytes->SetStreamValid_Impl();
925 : :
926 : 0 : Reference< XPropertiesChangeListener > xListener;
927 [ # # ]: 0 : Reference< XPropertiesChangeNotifier > xProps(xContent,UNO_QUERY);
928 [ # # ]: 0 : if(xProps.is()) {
929 : : xListener =
930 [ # # ][ # # ]: 0 : new UcbPropertiesChangeListener_Impl(xLockBytes);
[ # # ][ # # ]
931 [ # # ]: 0 : xProps->addPropertiesChangeListener(
932 : : Sequence< ::rtl::OUString >(),
933 [ # # ][ # # ]: 0 : xListener);
[ # # ]
934 : : }
935 : :
936 : 0 : Any aResult;
937 : 0 : bool bException(false);
938 : 0 : bool bAborted(false);
939 : 0 : bool bResultAchieved(false);
940 : :
941 : 0 : Moderator* pMod = 0;
942 : : try
943 : : {
944 [ # # # # ]: 0 : pMod = new Moderator(xContent,xInteract,xProgress,rArg);
945 [ # # ]: 0 : pMod->create();
946 : : }
947 [ # # ]: 0 : catch (const ContentCreationException&)
948 : : {
949 : 0 : bResultAchieved = bException = true;
950 : 0 : xLockBytes->SetError( ERRCODE_IO_GENERAL );
951 : : }
952 : :
953 : 0 : sal_uInt32 nTimeout(5000); // initially 5000 milliSec
954 [ # # ]: 0 : while(!bResultAchieved) {
955 : :
956 : 0 : Moderator::Result res;
957 : : // try to get the result for with timeout
958 [ # # ]: 0 : res = pMod->getResult(nTimeout);
959 : :
960 [ # # # # : 0 : switch(res.type) {
# # # # #
# # # # ]
961 : : case Moderator::PROGRESSPUSH:
962 : : {
963 [ # # ]: 0 : if(xProgress.is())
964 [ # # ][ # # ]: 0 : xProgress->push(res.result);
965 [ # # ]: 0 : pMod->setReply(Moderator::REQUESTHANDLED);
966 : 0 : break;
967 : : }
968 : : case Moderator::PROGRESSUPDATE:
969 : : {
970 [ # # ]: 0 : if(xProgress.is())
971 [ # # ][ # # ]: 0 : xProgress->update(res.result);
972 [ # # ]: 0 : pMod->setReply(Moderator::REQUESTHANDLED);
973 : 0 : break;
974 : : }
975 : : case Moderator::PROGRESSPOP:
976 : : {
977 [ # # ]: 0 : if(xProgress.is())
978 [ # # ][ # # ]: 0 : xProgress->pop();
979 [ # # ]: 0 : pMod->setReply(Moderator::REQUESTHANDLED);
980 : 0 : break;
981 : : }
982 : : case Moderator::STREAM:
983 : : {
984 : 0 : Reference<XStream> result;
985 [ # # ][ # # ]: 0 : if(res.result >>= result) {
986 : : Reference < XActiveDataStreamer > xStreamer(
987 : : xSink, UNO_QUERY
988 [ # # ]: 0 : );
989 : :
990 [ # # ]: 0 : if(xStreamer.is())
991 [ # # ][ # # ]: 0 : xStreamer->setStream(result);
992 : : }
993 [ # # ]: 0 : pMod->setReply(Moderator::REQUESTHANDLED);
994 : 0 : break;
995 : : }
996 : : case Moderator::INPUTSTREAM:
997 : : {
998 : 0 : Reference<XInputStream> result;
999 [ # # ]: 0 : res.result >>= result;
1000 : : Reference < XActiveDataSink > xActiveSink(
1001 : : xSink, UNO_QUERY
1002 [ # # ]: 0 : );
1003 : :
1004 [ # # ]: 0 : if(xActiveSink.is())
1005 [ # # ][ # # ]: 0 : xActiveSink->setInputStream(result);
1006 [ # # ]: 0 : pMod->setReply(Moderator::REQUESTHANDLED);
1007 : 0 : break;
1008 : : }
1009 : : case Moderator::TIMEDOUT:
1010 : : {
1011 : 0 : Reference<XInteractionRetry> xRet;
1012 [ # # ]: 0 : if(xInteract.is()) {
1013 [ # # ]: 0 : InteractiveNetworkConnectException aExcep;
1014 : : INetURLObject aURL(
1015 : 0 : xContId.is() ?
1016 [ # # ]: 0 : xContId->getContentIdentifier() :
1017 [ # # ][ # # ]: 0 : rtl::OUString() );
[ # # ]
1018 [ # # ]: 0 : aExcep.Server = aURL.GetHost();
1019 : 0 : aExcep.Classification = InteractionClassification_ERROR;
1020 : : aExcep.Message =
1021 : 0 : rtl::OUString( "server not responding after five seconds");
1022 : 0 : Any request;
1023 [ # # ]: 0 : request <<= aExcep;
1024 : : ucbhelper::InteractionRequest *ir =
1025 [ # # ]: 0 : new ucbhelper::InteractionRequest(request);
1026 [ # # ][ # # ]: 0 : Reference<XInteractionRequest> xIR(ir);
1027 [ # # ]: 0 : Sequence<Reference<XInteractionContinuation> > aSeq(2);
1028 : : ucbhelper::InteractionRetry *retryP =
1029 [ # # ]: 0 : new ucbhelper::InteractionRetry(ir);
1030 [ # # ][ # # ]: 0 : aSeq[0] = retryP;
[ # # ]
1031 : : ucbhelper::InteractionAbort *abortP =
1032 [ # # ]: 0 : new ucbhelper::InteractionAbort(ir);
1033 [ # # ][ # # ]: 0 : aSeq[1] = abortP;
[ # # ]
1034 : :
1035 [ # # ]: 0 : ir->setContinuations(aSeq);
1036 [ # # ][ # # ]: 0 : xInteract->handle(xIR);
1037 : : rtl::Reference< ucbhelper::InteractionContinuation > ref
1038 [ # # ]: 0 : = ir->getSelection();
1039 [ # # ]: 0 : if(ref.is()) {
1040 [ # # ]: 0 : Reference<XInterface> xInt(ref.get());
1041 [ # # ][ # # ]: 0 : xRet = Reference<XInteractionRetry>(xInt,UNO_QUERY);
1042 [ # # ][ # # ]: 0 : }
[ # # ]
1043 : : }
1044 : :
1045 [ # # ]: 0 : if(!xRet.is()) {
1046 : 0 : bAborted = true;
1047 : 0 : xLockBytes->SetError(ERRCODE_ABORT);
1048 : : }
1049 : :
1050 : 0 : break;
1051 : : }
1052 : : case Moderator::INTERACTIONREQUEST:
1053 : : {
1054 : 0 : Reference<XInteractionRequest> Request;
1055 [ # # ]: 0 : res.result >>= Request;
1056 [ # # ][ # # ]: 0 : xInteract->handle(Request);
1057 [ # # ]: 0 : pMod->setReply(Moderator::REQUESTHANDLED);
1058 : 0 : break;
1059 : : }
1060 : : case Moderator::RESULT:
1061 : : {
1062 : 0 : bResultAchieved = true;
1063 : 0 : aResult = res.result;
1064 : 0 : break;
1065 : : }
1066 : : case Moderator::COMMANDABORTED:
1067 : : {
1068 : 0 : bAborted = true;
1069 : 0 : xLockBytes->SetError( ERRCODE_ABORT );
1070 : 0 : break;
1071 : : }
1072 : : case Moderator::COMMANDFAILED:
1073 : : {
1074 : 0 : bAborted = true;
1075 : 0 : xLockBytes->SetError( ERRCODE_ABORT );
1076 : 0 : break;
1077 : : }
1078 : : case Moderator::INTERACTIVEIO:
1079 : : {
1080 : 0 : bException = true;
1081 [ # # ][ # # ]: 0 : if ( res.ioErrorCode == IOErrorCode_ACCESS_DENIED ||
1082 : : res.ioErrorCode == IOErrorCode_LOCKING_VIOLATION )
1083 : 0 : xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
1084 [ # # ]: 0 : else if ( res.ioErrorCode == IOErrorCode_NOT_EXISTING )
1085 : 0 : xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
1086 [ # # ]: 0 : else if ( res.ioErrorCode == IOErrorCode_CANT_READ )
1087 : 0 : xLockBytes->SetError( ERRCODE_IO_CANTREAD );
1088 : : else
1089 : 0 : xLockBytes->SetError( ERRCODE_IO_GENERAL );
1090 : 0 : break;
1091 : : }
1092 : : case Moderator::UNSUPPORTED:
1093 : : {
1094 : 0 : bException = true;
1095 : 0 : xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
1096 : 0 : break;
1097 : : }
1098 : : default:
1099 : : {
1100 : 0 : bException = true;
1101 : 0 : xLockBytes->SetError( ERRCODE_IO_GENERAL );
1102 : 0 : break;
1103 : : }
1104 : : }
1105 : :
1106 : 0 : bResultAchieved |= bException;
1107 : 0 : bResultAchieved |= bAborted;
1108 [ # # ]: 0 : if(nTimeout == 5000) nTimeout *= 2;
1109 : 0 : }
1110 : :
1111 [ # # ][ # # ]: 0 : if(pMod) pMod->setReply(Moderator::EXIT);
1112 : :
1113 [ # # ][ # # ]: 0 : if ( bAborted || bException )
1114 : : {
1115 [ # # ]: 0 : if( xHandler.Is() )
1116 [ # # ][ # # ]: 0 : xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
1117 : :
1118 [ # # ]: 0 : Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
1119 [ # # ]: 0 : if ( xActiveSink.is() )
1120 [ # # ][ # # ]: 0 : xActiveSink->setInputStream( Reference < XInputStream >() );
1121 : :
1122 [ # # ]: 0 : Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
1123 [ # # ]: 0 : if ( xStreamer.is() )
1124 [ # # ][ # # ]: 0 : xStreamer->setStream( Reference < XStream >() );
1125 : : }
1126 : :
1127 [ # # ]: 0 : Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
1128 [ # # ]: 0 : if ( xControl.is() )
1129 [ # # ][ # # ]: 0 : xControl->terminate();
1130 : :
1131 [ # # ]: 0 : if ( xProps.is() )
1132 [ # # ]: 0 : xProps->removePropertiesChangeListener(
1133 : : Sequence< ::rtl::OUString >(),
1134 [ # # ][ # # ]: 0 : xListener );
[ # # ]
1135 : :
1136 [ # # ][ # # ]: 11864 : return ( bAborted || bException );
1137 : : }
1138 : :
1139 : : /**
1140 : : Function for opening UCB contents synchronously
1141 : : */
1142 : 11864 : static sal_Bool _UCBOpenContentSync(
1143 : : UcbLockBytesRef xLockBytes,
1144 : : Reference < XContent > xContent,
1145 : : const Command& rArg,
1146 : : Reference < XInterface > xSink,
1147 : : Reference < XInteractionHandler > xInteract,
1148 : : Reference < XProgressHandler > xProgress,
1149 : : UcbLockBytesHandlerRef xHandler )
1150 : : {
1151 [ + - ][ + - ]: 11864 : ::ucbhelper::Content aContent( xContent, new UcbTaskEnvironment( xInteract, xProgress ) );
[ + - ][ + - ]
1152 [ + - ][ + - ]: 11864 : Reference < XContentIdentifier > xIdent = xContent->getIdentifier();
1153 [ + - ][ + - ]: 11864 : ::rtl::OUString aScheme = xIdent->getContentProviderScheme();
1154 : :
1155 : : // http protocol must be handled in a special way: during the opening process the input stream may change
1156 : : // only the last inputstream after notifying the document headers is valid
1157 [ + - ]: 11864 : if ( aScheme.compareToAscii("http") != COMPARE_EQUAL )
1158 [ + - ]: 11864 : xLockBytes->SetStreamValid_Impl();
1159 : :
1160 [ + - ][ + - ]: 11864 : Reference< XPropertiesChangeListener > xListener = new UcbPropertiesChangeListener_Impl( xLockBytes );
[ + - ][ + - ]
1161 [ + - ]: 11864 : Reference< XPropertiesChangeNotifier > xProps ( xContent, UNO_QUERY );
1162 [ + - ]: 11864 : if ( xProps.is() )
1163 [ + - ][ + - ]: 14066 : xProps->addPropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
[ + - ][ + - ]
[ - - - +
- - ]
1164 : :
1165 : 11864 : Any aResult;
1166 : 11864 : bool bException = false;
1167 : 11864 : bool bAborted = false;
1168 : :
1169 : : try
1170 : : {
1171 [ + + ]: 11864 : aResult = aContent.executeCommand( rArg.Name, rArg.Argument );
1172 : : }
1173 [ # # ]: 0 : catch (const CommandAbortedException&)
1174 : : {
1175 : 0 : bAborted = true;
1176 : 0 : xLockBytes->SetError( ERRCODE_ABORT );
1177 : : }
1178 [ # # ]: 0 : catch (const CommandFailedException&)
1179 : : {
1180 : 0 : bAborted = true;
1181 : 0 : xLockBytes->SetError( ERRCODE_ABORT );
1182 : : }
1183 [ + - ]: 4404 : catch (const InteractiveIOException& r)
1184 : : {
1185 : 2202 : bException = true;
1186 [ - + ][ + - ]: 2202 : if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
1187 : 0 : xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
1188 [ + - ]: 2202 : else if ( r.Code == IOErrorCode_NOT_EXISTING )
1189 : 2202 : xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
1190 [ # # ]: 0 : else if ( r.Code == IOErrorCode_CANT_READ )
1191 : 0 : xLockBytes->SetError( ERRCODE_IO_CANTREAD );
1192 : : else
1193 : 0 : xLockBytes->SetError( ERRCODE_IO_GENERAL );
1194 : : }
1195 [ # # ]: 0 : catch (const UnsupportedDataSinkException&)
1196 : : {
1197 : 0 : bException = true;
1198 : 0 : xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
1199 : : }
1200 [ # # ]: 0 : catch (const Exception&)
1201 : : {
1202 : 0 : bException = true;
1203 : 0 : xLockBytes->SetError( ERRCODE_IO_GENERAL );
1204 : : }
1205 : :
1206 [ + - ][ + + ]: 11864 : if ( bAborted || bException )
1207 : : {
1208 [ - + ]: 2202 : if( xHandler.Is() )
1209 [ # # ][ # # ]: 0 : xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
1210 : :
1211 [ + - ]: 2202 : Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
1212 [ + + ]: 2202 : if ( xActiveSink.is() )
1213 [ + - ][ + - ]: 2184 : xActiveSink->setInputStream( Reference < XInputStream >() );
1214 : :
1215 [ + - ]: 2202 : Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
1216 [ + + ]: 2202 : if ( xStreamer.is() )
1217 [ + - ][ + - ]: 2202 : xStreamer->setStream( Reference < XStream >() );
1218 : : }
1219 : :
1220 [ + - ]: 11864 : Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
1221 [ + - ]: 11864 : if ( xControl.is() )
1222 [ + - ][ + - ]: 11864 : xControl->terminate();
1223 : :
1224 : :
1225 [ + - ]: 11864 : if ( xProps.is() )
1226 [ + - ][ + - ]: 11864 : xProps->removePropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
[ + - ][ + - ]
1227 : :
1228 [ + - ][ + + ]: 11864 : return ( bAborted || bException );
[ + - ]
1229 : : }
1230 : :
1231 : : //----------------------------------------------------------------------------
1232 : 22367 : UcbLockBytes::UcbLockBytes( UcbLockBytesHandler* pHandler )
1233 : : : m_aExpireDate( DateTime::EMPTY )
1234 : : , m_xInputStream (NULL)
1235 : : , m_pCommandThread( NULL )
1236 : : , m_xHandler( pHandler )
1237 : : , m_nError( ERRCODE_NONE )
1238 : : , m_bTerminated (sal_False)
1239 : : , m_bDontClose( sal_False )
1240 [ + - ][ + - ]: 22367 : , m_bStreamValid (sal_False)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1241 : : {
1242 [ + - # # ]: 22367 : SetSynchronMode( sal_True );
1243 : 22367 : }
1244 : :
1245 : : //----------------------------------------------------------------------------
1246 [ + - ][ + - ]: 66486 : UcbLockBytes::~UcbLockBytes()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1247 : : {
1248 [ + + ][ # # ]: 22162 : if ( !m_bDontClose )
1249 : : {
1250 [ - + ][ # # ]: 2202 : if ( m_xInputStream.is() )
1251 : : {
1252 : : try
1253 : : {
1254 [ # # ][ # # ]: 0 : m_xInputStream->closeInput();
[ # # ][ # # ]
1255 : : }
1256 [ # # # # ]: 0 : catch (const RuntimeException&)
1257 : : {
1258 : : }
1259 [ # # # # : 0 : catch (const IOException&)
# # # # #
# ]
1260 : : {
1261 : : }
1262 : : }
1263 : : }
1264 : :
1265 [ + + ][ - + ]: 22162 : if ( !m_xInputStream.is() && m_xOutputStream.is() )
[ - + ][ # # ]
[ # # ][ # # ]
1266 : : {
1267 : : try
1268 : : {
1269 [ # # ][ # # ]: 0 : m_xOutputStream->closeOutput();
[ # # ][ # # ]
1270 : : }
1271 [ # # # # ]: 0 : catch (const RuntimeException&)
1272 : : {
1273 : : }
1274 [ # # # # ]: 0 : catch (const IOException&)
1275 : : {
1276 : : }
1277 : : }
1278 [ + - ][ + - ]: 88648 : }
[ - + ][ # #
# # # #
# ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # ]
1279 : :
1280 : 9662 : Reference < XInputStream > UcbLockBytes::getInputStream()
1281 : : {
1282 [ + - ]: 9662 : osl::MutexGuard aGuard( m_aMutex );
1283 : 9662 : m_bDontClose = sal_True;
1284 [ + - ]: 9662 : return m_xInputStream;
1285 : : }
1286 : :
1287 : : //----------------------------------------------------------------------------
1288 : :
1289 : 8930 : sal_Bool UcbLockBytes::setStream_Impl( const Reference<XStream>& aStream )
1290 : : {
1291 [ + - ]: 8930 : osl::MutexGuard aGuard( m_aMutex );
1292 [ + + ]: 8930 : if ( aStream.is() )
1293 : : {
1294 [ + - ][ + - ]: 8894 : m_xOutputStream = aStream->getOutputStream();
[ + - ]
1295 [ + - ][ + - ]: 8894 : setInputStream_Impl( aStream->getInputStream(), sal_False );
[ + - ]
1296 [ + - ][ + - ]: 8894 : m_xSeekable = Reference < XSeekable > ( aStream, UNO_QUERY );
1297 : : }
1298 : : else
1299 : : {
1300 [ + - ]: 36 : m_xOutputStream = Reference < XOutputStream >();
1301 [ + - ]: 36 : setInputStream_Impl( Reference < XInputStream >() );
1302 : : }
1303 : :
1304 [ + - ]: 8930 : return m_xInputStream.is();
1305 : : }
1306 : :
1307 : 24569 : sal_Bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream, sal_Bool bSetXSeekable )
1308 : : {
1309 : 24569 : sal_Bool bRet = sal_False;
1310 : :
1311 : : try
1312 : : {
1313 [ + - ]: 24569 : osl::MutexGuard aGuard( m_aMutex );
1314 : :
1315 [ + + ][ - + ]: 24569 : if ( !m_bDontClose && m_xInputStream.is() )
[ - + ]
1316 [ # # ][ # # ]: 0 : m_xInputStream->closeInput();
1317 : :
1318 [ + - ]: 24569 : m_xInputStream = rxInputStream;
1319 : :
1320 [ + + ]: 24569 : if( bSetXSeekable )
1321 : : {
1322 [ + - ][ + - ]: 15675 : m_xSeekable = Reference < XSeekable > ( rxInputStream, UNO_QUERY );
1323 [ + + ][ + + ]: 15675 : if( !m_xSeekable.is() && rxInputStream.is() )
[ + + ]
1324 : : {
1325 [ + - ]: 249 : Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
1326 : : Reference< XOutputStream > rxTempOut = Reference < XOutputStream > (
1327 [ + - ]: 249 : xFactory->createInstance ( ::rtl::OUString("com.sun.star.io.TempFile") ),
1328 [ + - ][ + - ]: 249 : UNO_QUERY );
1329 : :
1330 [ + - ]: 249 : if( rxTempOut.is() )
1331 : : {
1332 [ + - ]: 249 : ::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream, rxTempOut );
1333 [ + - ][ + - ]: 249 : m_xInputStream = Reference< XInputStream >( rxTempOut, UNO_QUERY );
1334 [ + - ][ + - ]: 249 : m_xSeekable = Reference < XSeekable > ( rxTempOut, UNO_QUERY );
1335 : 249 : }
1336 : : }
1337 : : }
1338 : :
1339 [ + - ][ # # ]: 24569 : bRet = m_xInputStream.is();
1340 : : }
1341 : 0 : catch (const Exception&)
1342 : : {
1343 : : }
1344 : :
1345 [ + + ][ + + ]: 24569 : if ( m_bStreamValid && m_xInputStream.is() )
[ + + ]
1346 : 9662 : m_aInitialized.set();
1347 : :
1348 : 24569 : return bRet;
1349 : : }
1350 : :
1351 : 11864 : void UcbLockBytes::SetStreamValid_Impl()
1352 : : {
1353 : 11864 : m_bStreamValid = sal_True;
1354 [ - + ]: 11864 : if ( m_xInputStream.is() )
1355 : 0 : m_aInitialized.set();
1356 : 11864 : }
1357 : :
1358 : : //----------------------------------------------------------------------------
1359 : 22367 : void UcbLockBytes::terminate_Impl()
1360 : : {
1361 : 22367 : m_bTerminated = sal_True;
1362 : 22367 : m_aInitialized.set();
1363 : 22367 : m_aTerminated.set();
1364 : :
1365 [ - + ][ - + ]: 22367 : if ( GetError() == ERRCODE_NONE && !m_xInputStream.is() )
[ + + ]
1366 : : {
1367 : : OSL_FAIL("No InputStream, but no error set!" );
1368 : 0 : SetError( ERRCODE_IO_NOTEXISTS );
1369 : : }
1370 : :
1371 [ - + ]: 22367 : if ( m_xHandler.Is() )
1372 [ # # ]: 0 : m_xHandler->Handle( UcbLockBytesHandler::DONE, this );
1373 : 22367 : }
1374 : :
1375 : : //----------------------------------------------------------------------------
1376 : 34234 : void UcbLockBytes::SetSynchronMode (sal_Bool bSynchron)
1377 : : {
1378 : 34234 : SvLockBytes::SetSynchronMode (bSynchron);
1379 : 34234 : }
1380 : :
1381 : : //----------------------------------------------------------------------------
1382 : 58735 : ErrCode UcbLockBytes::ReadAt ( sal_uLong nPos, void *pBuffer, sal_uLong nCount, sal_uLong *pRead) const
1383 : : {
1384 [ + - ][ + - ]: 58735 : if ( IsSynchronMode() )
1385 : : {
1386 : 58735 : UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
1387 [ + - ]: 58735 : pThis->m_aInitialized.wait();
1388 : : }
1389 : :
1390 [ + - ]: 58735 : Reference <XInputStream> xStream = getInputStream_Impl();
1391 [ - + ]: 58735 : if ( !xStream.is() )
1392 : : {
1393 [ # # ]: 0 : if ( m_bTerminated )
1394 : 0 : return ERRCODE_IO_CANTREAD;
1395 : : else
1396 : 0 : return ERRCODE_IO_PENDING;
1397 : : }
1398 : :
1399 [ + - ]: 58735 : if ( pRead )
1400 : 58735 : *pRead = 0;
1401 : :
1402 [ + - ]: 58735 : Reference <XSeekable> xSeekable = getSeekable_Impl();
1403 [ - + ]: 58735 : if ( !xSeekable.is() )
1404 : 0 : return ERRCODE_IO_CANTREAD;
1405 : :
1406 : : try
1407 : : {
1408 [ + - ][ + - ]: 58735 : xSeekable->seek( nPos );
1409 : : }
1410 [ # # ]: 0 : catch (const IOException&)
1411 : : {
1412 : 0 : return ERRCODE_IO_CANTSEEK;
1413 : : }
1414 [ # # # # ]: 0 : catch (const com::sun::star::lang::IllegalArgumentException&)
1415 : : {
1416 : 0 : return ERRCODE_IO_CANTSEEK;
1417 : : }
1418 : :
1419 [ + - ]: 58735 : Sequence<sal_Int8> aData;
1420 : : sal_Int32 nSize;
1421 : :
1422 : 58735 : nCount = SAL_MIN(nCount, 0x7FFFFFFF);
1423 : : try
1424 : : {
1425 [ - + ][ # # ]: 58735 : if ( !m_bTerminated && !IsSynchronMode() )
[ # # ][ - + ]
1426 : : {
1427 [ # # ][ # # ]: 0 : sal_uInt64 nLen = xSeekable->getLength();
1428 [ # # ]: 0 : if ( nPos + nCount > nLen )
1429 : 0 : return ERRCODE_IO_PENDING;
1430 : : }
1431 : :
1432 [ + - ][ + - ]: 58735 : nSize = xStream->readBytes( aData, sal_Int32(nCount) );
1433 : : }
1434 [ # # ]: 0 : catch (const IOException&)
1435 : : {
1436 : 0 : return ERRCODE_IO_CANTREAD;
1437 : : }
1438 : :
1439 [ + - ]: 58735 : rtl_copyMemory (pBuffer, aData.getConstArray(), nSize);
1440 [ + - ]: 58735 : if (pRead)
1441 : 58735 : *pRead = sal_uLong(nSize);
1442 : :
1443 [ + - ]: 58735 : return ERRCODE_NONE;
[ # # # ]
1444 : : }
1445 : :
1446 : : //----------------------------------------------------------------------------
1447 : 8948 : ErrCode UcbLockBytes::WriteAt ( sal_uLong nPos, const void *pBuffer, sal_uLong nCount, sal_uLong *pWritten)
1448 : : {
1449 [ + - ]: 8948 : if ( pWritten )
1450 : 8948 : *pWritten = 0;
1451 : :
1452 : : DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" );
1453 : : DBG_ASSERT( m_aInitialized.check(), "Writing bevor stream is ready!" );
1454 : :
1455 [ + - ]: 8948 : Reference <XSeekable> xSeekable = getSeekable_Impl();
1456 [ + - ]: 8948 : Reference <XOutputStream> xOutputStream = getOutputStream_Impl();
1457 [ + + ][ - + ]: 8948 : if ( !xOutputStream.is() || !xSeekable.is() )
[ + + ]
1458 : 18 : return ERRCODE_IO_CANTWRITE;
1459 : :
1460 : : try
1461 : : {
1462 [ + - ][ + - ]: 8930 : xSeekable->seek( nPos );
1463 : : }
1464 [ # # # # ]: 0 : catch (const IOException&)
1465 : : {
1466 : 0 : return ERRCODE_IO_CANTSEEK;
1467 : : }
1468 : :
1469 : 8930 : sal_Int8* pData = (sal_Int8*) pBuffer;
1470 [ + - ]: 8930 : Sequence<sal_Int8> aData( pData, nCount );
1471 : : try
1472 : : {
1473 [ + - ][ + - ]: 8930 : xOutputStream->writeBytes( aData );
1474 [ + - ]: 8930 : if ( pWritten )
1475 : 8930 : *pWritten = nCount;
1476 : : }
1477 [ # # ]: 0 : catch (const Exception&)
1478 : : {
1479 : 0 : return ERRCODE_IO_CANTWRITE;
1480 : : }
1481 : :
1482 [ + - ][ # # ]: 8948 : return ERRCODE_NONE;
1483 : : }
1484 : :
1485 : : //----------------------------------------------------------------------------
1486 : 21110 : ErrCode UcbLockBytes::Flush() const
1487 : : {
1488 [ + - ]: 21110 : Reference <XOutputStream > xOutputStream = getOutputStream_Impl();
1489 [ + + ]: 21110 : if ( !xOutputStream.is() )
1490 : 11239 : return ERRCODE_IO_CANTWRITE;
1491 : :
1492 : : try
1493 : : {
1494 [ + - ][ + + ]: 9871 : xOutputStream->flush();
1495 : : }
1496 [ + - ]: 10 : catch (const Exception&)
1497 : : {
1498 : 10 : return ERRCODE_IO_CANTWRITE;
1499 : : }
1500 : :
1501 [ - + ]: 21120 : return ERRCODE_NONE;
1502 : : }
1503 : :
1504 : : //----------------------------------------------------------------------------
1505 : 1872 : ErrCode UcbLockBytes::SetSize (sal_uLong nNewSize)
1506 : : {
1507 : 1872 : SvLockBytesStat aStat;
1508 [ + - ]: 1872 : Stat( &aStat, (SvLockBytesStatFlag) 0 );
1509 : 1872 : sal_uLong nSize = aStat.nSize;
1510 : :
1511 [ - + ]: 1872 : if ( nSize > nNewSize )
1512 : : {
1513 [ # # ][ # # ]: 0 : Reference < XTruncate > xTrunc( getOutputStream_Impl(), UNO_QUERY );
1514 [ # # ]: 0 : if ( xTrunc.is() )
1515 : : {
1516 [ # # ][ # # ]: 0 : xTrunc->truncate();
1517 : 0 : nSize = 0;
1518 : : }
1519 : : else {
1520 : : DBG_WARNING("Not truncatable!");
1521 : 0 : }
1522 : : }
1523 : :
1524 [ + - ]: 1872 : if ( nSize < nNewSize )
1525 : : {
1526 : 1872 : sal_uLong nDiff = nNewSize-nSize, nCount=0;
1527 [ + - ]: 1872 : sal_uInt8* pBuffer = new sal_uInt8[ nDiff ];
1528 : 1872 : memset(pBuffer, 0, nDiff); // initialize for enhanced security
1529 [ + - ]: 1872 : WriteAt( nSize, pBuffer, nDiff, &nCount );
1530 [ + - ]: 1872 : delete[] pBuffer;
1531 [ - + ]: 1872 : if ( nCount != nDiff )
1532 : 1872 : return ERRCODE_IO_CANTWRITE;
1533 : : }
1534 : :
1535 : 1872 : return ERRCODE_NONE;
1536 : : }
1537 : :
1538 : : //----------------------------------------------------------------------------
1539 : 28884 : ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const
1540 : : {
1541 [ + - ][ + - ]: 28884 : if ( IsSynchronMode() )
1542 : : {
1543 : 28884 : UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
1544 [ + - ]: 28884 : pThis->m_aInitialized.wait();
1545 : : }
1546 : :
1547 [ - + ]: 28884 : if (!pStat)
1548 : 0 : return ERRCODE_IO_INVALIDPARAMETER;
1549 : :
1550 [ + - ]: 28884 : Reference <XInputStream> xStream = getInputStream_Impl();
1551 [ + - ]: 28884 : Reference <XSeekable> xSeekable = getSeekable_Impl();
1552 : :
1553 [ - + ]: 28884 : if ( !xStream.is() )
1554 : : {
1555 [ # # ]: 0 : if ( m_bTerminated )
1556 : 0 : return ERRCODE_IO_INVALIDACCESS;
1557 : : else
1558 : 0 : return ERRCODE_IO_PENDING;
1559 : : }
1560 [ - + ]: 28884 : else if( !xSeekable.is() )
1561 : 0 : return ERRCODE_IO_CANTTELL;
1562 : :
1563 : : try
1564 : : {
1565 [ + - ][ + - ]: 28884 : pStat->nSize = sal_uLong(xSeekable->getLength());
1566 : : }
1567 [ # # ]: 0 : catch (const IOException&)
1568 : : {
1569 : 0 : return ERRCODE_IO_CANTTELL;
1570 : : }
1571 : :
1572 [ # # ]: 28884 : return ERRCODE_NONE;
1573 : : }
1574 : :
1575 : : //----------------------------------------------------------------------------
1576 : 0 : void UcbLockBytes::Cancel()
1577 : : {
1578 : : // is alive only for compatibility reasons
1579 : : OSL_ENSURE( m_bTerminated, "UcbLockBytes is not thread safe so it can be used only syncronously!\n" );
1580 : 0 : }
1581 : :
1582 : : //----------------------------------------------------------------------------
1583 : 0 : IMPL_LINK_NOARG(UcbLockBytes, DataAvailHdl)
1584 : : {
1585 [ # # ][ # # ]: 0 : if ( hasInputStream_Impl() && m_xHandler.Is() )
[ # # ]
1586 [ # # ]: 0 : m_xHandler->Handle( UcbLockBytesHandler::DATA_AVAILABLE, this );
1587 : :
1588 : 0 : return 0;
1589 : : }
1590 : :
1591 : 9346 : UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( const Reference< XInputStream >& xInputStream )
1592 : : {
1593 [ - + ]: 9346 : if( !xInputStream.is() )
1594 : 0 : return NULL;
1595 : :
1596 [ + - ][ + - ]: 9346 : UcbLockBytesRef xLockBytes = new UcbLockBytes();
1597 : 9346 : xLockBytes->setDontClose_Impl();
1598 [ + - ]: 9346 : xLockBytes->setInputStream_Impl( xInputStream );
1599 [ + - ]: 9346 : xLockBytes->terminate_Impl();
1600 [ + - ]: 9346 : return xLockBytes;
1601 : : }
1602 : :
1603 : 1157 : UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference< XStream >& xStream )
1604 : : {
1605 [ - + ]: 1157 : if( !xStream.is() )
1606 : 0 : return NULL;
1607 : :
1608 [ + - ][ + - ]: 1157 : UcbLockBytesRef xLockBytes = new UcbLockBytes();
1609 : 1157 : xLockBytes->setDontClose_Impl();
1610 [ + - ]: 1157 : xLockBytes->setStream_Impl( xStream );
1611 [ + - ]: 1157 : xLockBytes->terminate_Impl();
1612 [ + - ]: 1157 : return xLockBytes;
1613 : : }
1614 : :
1615 : 0 : UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const ::rtl::OUString& rReferer, const ::rtl::OUString& rMediaType,
1616 : : const Reference < XInputStream >& xPostData, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
1617 : : {
1618 [ # # ]: 0 : if( !xContent.is() )
1619 : 0 : return NULL;
1620 : :
1621 [ # # ][ # # ]: 0 : UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
1622 [ # # ]: 0 : xLockBytes->SetSynchronMode( !pHandler );
1623 [ # # ][ # # ]: 0 : Reference< XActiveDataControl > xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );
[ # # ]
1624 : :
1625 [ # # ]: 0 : PostCommandArgument2 aArgument;
1626 [ # # ]: 0 : aArgument.Source = xPostData;
1627 [ # # ]: 0 : aArgument.Sink = xSink;
1628 : 0 : aArgument.MediaType = rMediaType;
1629 : 0 : aArgument.Referer = rReferer;
1630 : :
1631 : 0 : Command aCommand;
1632 [ # # ]: 0 : aCommand.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("post"));
1633 [ # # ]: 0 : aCommand.Argument <<= aArgument;
1634 : :
1635 [ # # ][ # # ]: 0 : Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );
[ # # ][ # # ]
1636 : :
1637 : : sal_Bool bError = UCBOpenContentSync( xLockBytes,
1638 : : xContent,
1639 : : aCommand,
1640 : : xSink,
1641 : : xInteractionHandler,
1642 : : xProgressHdl,
1643 [ # # ][ # # ]: 0 : pHandler );
[ # # ]
1644 : :
1645 [ # # ][ # # ]: 0 : if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1646 : : {
1647 : : OSL_FAIL("No InputStream, but no error set!" );
1648 : 0 : xLockBytes->SetError( ERRCODE_IO_GENERAL );
1649 : : }
1650 : :
1651 [ # # ][ # # ]: 0 : return xLockBytes;
1652 : : }
1653 : :
1654 : 11864 : UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const Sequence < PropertyValue >& rProps,
1655 : : StreamMode eOpenMode, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
1656 : : {
1657 [ - + ]: 11864 : if( !xContent.is() )
1658 : 0 : return NULL;
1659 : :
1660 [ + - ][ + - ]: 11864 : UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
1661 [ + - ]: 11864 : xLockBytes->SetSynchronMode( !pHandler );
1662 : 11864 : Reference< XActiveDataControl > xSink;
1663 [ + + ]: 11864 : if ( eOpenMode & STREAM_WRITE )
1664 [ + - ][ + - ]: 7755 : xSink = (XActiveDataControl*) new UcbStreamer_Impl( xLockBytes );
[ + - ]
1665 : : else
1666 [ + - ][ + - ]: 4109 : xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );
[ + - ]
1667 : :
1668 [ - + ]: 11864 : if ( rProps.getLength() )
1669 : : {
1670 [ # # ]: 0 : Reference < XCommandProcessor > xProcessor( xContent, UNO_QUERY );
1671 : 0 : Command aCommand;
1672 : 0 : aCommand.Name = ::rtl::OUString("setPropertyValues");
1673 : 0 : aCommand.Handle = -1; /* unknown */
1674 [ # # ]: 0 : aCommand.Argument <<= rProps;
1675 [ # # ][ # # ]: 0 : xProcessor->execute( aCommand, 0, Reference < XCommandEnvironment >() );
1676 : : }
1677 : :
1678 [ + - ]: 11864 : OpenCommandArgument2 aArgument;
1679 [ + - ]: 11864 : aArgument.Sink = xSink;
1680 : 11864 : aArgument.Mode = OpenMode::DOCUMENT;
1681 : :
1682 : 11864 : Command aCommand;
1683 : 11864 : aCommand.Name = ::rtl::OUString( "open" );
1684 [ + - ]: 11864 : aCommand.Argument <<= aArgument;
1685 : :
1686 [ + - ][ + - ]: 11864 : Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );
[ + - ][ + - ]
1687 : :
1688 : : sal_Bool bError = UCBOpenContentSync( xLockBytes,
1689 : : xContent,
1690 : : aCommand,
1691 : : xSink,
1692 : : xInteractionHandler,
1693 : : xProgressHdl,
1694 [ + - ][ + - ]: 11864 : pHandler );
[ + - ]
1695 : :
1696 [ + + ][ + - ]: 11864 : if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
[ + - ][ - + ]
[ + + ]
[ - + # # ]
1697 : : {
1698 : : OSL_FAIL("No InputStream, but no error set!" );
1699 : 0 : xLockBytes->SetError( ERRCODE_IO_GENERAL );
1700 : : }
1701 : :
1702 [ + - ][ + - ]: 11864 : return xLockBytes;
1703 : : }
1704 : :
1705 : : }
1706 : :
1707 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|