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 : /**************************************************************************
22 : TODO
23 : **************************************************************************
24 :
25 : - remove root storage access workaround
26 :
27 : *************************************************************************/
28 :
29 : #include <osl/diagnose.h>
30 :
31 : #include "com/sun/star/lang/DisposedException.hpp"
32 : #include "com/sun/star/reflection/ProxyFactory.hpp"
33 :
34 : #include "tdoc_uri.hxx"
35 :
36 : #include "tdoc_stgelems.hxx"
37 :
38 : using namespace com::sun::star;
39 : using namespace tdoc_ucp;
40 :
41 :
42 :
43 :
44 : // ParentStorageHolder Implementation.
45 :
46 :
47 :
48 :
49 328 : ParentStorageHolder::ParentStorageHolder(
50 : const uno::Reference< embed::XStorage > & xParentStorage,
51 : const OUString & rUri )
52 : : m_xParentStorage( xParentStorage ),
53 328 : m_bParentIsRootStorage( false )
54 : {
55 328 : Uri aUri( rUri );
56 328 : if ( aUri.isDocument() )
57 0 : m_bParentIsRootStorage = true;
58 328 : }
59 :
60 :
61 :
62 :
63 : // Storage Implementation.
64 :
65 :
66 :
67 :
68 328 : Storage::Storage( const uno::Reference< uno::XComponentContext > & rxContext,
69 : const rtl::Reference< StorageElementFactory > & xFactory,
70 : const OUString & rUri,
71 : const uno::Reference< embed::XStorage > & xParentStorage,
72 : const uno::Reference< embed::XStorage > & xStorageToWrap )
73 656 : : ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
74 : m_xFactory( xFactory ),
75 : m_xWrappedStorage( xStorageToWrap ),
76 : m_xWrappedTransObj( xStorageToWrap, uno::UNO_QUERY ), // optional interface
77 : m_xWrappedComponent( xStorageToWrap, uno::UNO_QUERY ),
78 : m_xWrappedTypeProv( xStorageToWrap, uno::UNO_QUERY ),
79 984 : m_bIsDocumentStorage( Uri( rUri ).isDocument() )
80 : {
81 : OSL_ENSURE( m_xWrappedStorage.is(),
82 : "Storage::Storage: No storage to wrap!" );
83 :
84 : OSL_ENSURE( m_xWrappedComponent.is(),
85 : "Storage::Storage: No component to wrap!" );
86 :
87 : OSL_ENSURE( m_xWrappedTypeProv.is(),
88 : "Storage::Storage: No Type Provider!" );
89 :
90 : // Use proxy factory service to create aggregatable proxy.
91 : try
92 : {
93 : uno::Reference< reflection::XProxyFactory > xProxyFac =
94 328 : reflection::ProxyFactory::create( rxContext );
95 328 : m_xAggProxy = xProxyFac->createProxy( m_xWrappedStorage );
96 : }
97 0 : catch ( uno::Exception const & )
98 : {
99 : OSL_FAIL( "Storage::Storage: Caught exception!" );
100 : }
101 :
102 : OSL_ENSURE( m_xAggProxy.is(),
103 : "Storage::Storage: Wrapped storage cannot be aggregated!" );
104 :
105 328 : if ( m_xAggProxy.is() )
106 : {
107 328 : osl_atomic_increment( &m_refCount );
108 : {
109 : // Solaris compiler problem:
110 : // Extra block to enforce destruction of temporary object created
111 : // in next statement _before_ osl_atomic_decrement is
112 : // called. Otherwise 'this' will destroy itself even before ctor
113 : // is completed (See impl. of XInterface::release())!
114 :
115 328 : m_xAggProxy->setDelegator(
116 328 : static_cast< cppu::OWeakObject * >( this ) );
117 : }
118 328 : osl_atomic_decrement( &m_refCount );
119 : }
120 328 : }
121 :
122 :
123 : // virtual
124 984 : Storage::~Storage()
125 : {
126 328 : if ( m_xAggProxy.is() )
127 328 : m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
128 :
129 : // Never dispose a document storage. Not owner!
130 328 : if ( !isDocumentStorage() )
131 : {
132 0 : if ( m_xWrappedComponent.is() )
133 : {
134 : // "Auto-dispose"...
135 : try
136 : {
137 0 : m_xWrappedComponent->dispose();
138 : }
139 0 : catch ( lang::DisposedException const & )
140 : {
141 : // might happen.
142 : }
143 0 : catch ( ... )
144 : {
145 : OSL_FAIL( "Storage::~Storage - Caught exception!" );
146 : }
147 : }
148 : }
149 656 : }
150 :
151 :
152 :
153 : // uno::XInterface
154 :
155 :
156 :
157 : // virtual
158 328 : uno::Any SAL_CALL Storage::queryInterface( const uno::Type& aType )
159 : throw ( uno::RuntimeException, std::exception )
160 : {
161 : // First, try to use interfaces implemented by myself and base class(es)
162 328 : uno::Any aRet = StorageUNOBase::queryInterface( aType );
163 :
164 328 : if ( aRet.hasValue() )
165 328 : return aRet;
166 :
167 : // Try to use requested interface from aggregated storage
168 0 : return m_xAggProxy->queryAggregation( aType );
169 : }
170 :
171 :
172 : // virtual
173 1312 : void SAL_CALL Storage::acquire()
174 : throw ()
175 : {
176 1312 : osl_atomic_increment( &m_refCount );
177 1312 : }
178 :
179 :
180 : // virtual
181 1312 : void SAL_CALL Storage::release()
182 : throw ()
183 : {
184 : //#i120738, Storage::release overrides OWeakObject::release(),
185 : //need call OWeakObject::release() to release OWeakObject::m_pWeakConnectionPoint
186 :
187 1312 : if ( m_refCount == 1 )
188 328 : m_xFactory->releaseElement( this );
189 :
190 : //delete this;
191 1312 : OWeakObject::release();
192 1312 : }
193 :
194 :
195 :
196 : // lang::XTypeProvider
197 :
198 :
199 :
200 : // virtual
201 0 : uno::Sequence< uno::Type > SAL_CALL Storage::getTypes()
202 : throw ( uno::RuntimeException, std::exception )
203 : {
204 0 : return m_xWrappedTypeProv->getTypes();
205 : }
206 :
207 :
208 : // virtual
209 0 : uno::Sequence< sal_Int8 > SAL_CALL Storage::getImplementationId()
210 : throw ( uno::RuntimeException, std::exception )
211 : {
212 0 : return css::uno::Sequence<sal_Int8>();
213 : }
214 :
215 :
216 :
217 : // lang::XComponent (base of embed::XStorage)
218 :
219 :
220 : // virtual
221 0 : void SAL_CALL Storage::dispose()
222 : throw ( uno::RuntimeException, std::exception )
223 : {
224 0 : m_xWrappedStorage->dispose();
225 0 : }
226 :
227 :
228 : // virtual
229 0 : void SAL_CALL Storage::addEventListener(
230 : const uno::Reference< lang::XEventListener >& xListener )
231 : throw ( uno::RuntimeException, std::exception )
232 : {
233 0 : m_xWrappedStorage->addEventListener( xListener );
234 0 : }
235 :
236 : // virtual
237 0 : void SAL_CALL Storage::removeEventListener(
238 : const uno::Reference< lang::XEventListener >& aListener )
239 : throw (uno::RuntimeException, std::exception)
240 : {
241 0 : m_xWrappedStorage->removeEventListener( aListener );
242 0 : }
243 :
244 :
245 :
246 : // container::XElementAccess (base of container::XNameAccess)
247 :
248 :
249 :
250 : // virtual
251 0 : uno::Type SAL_CALL Storage::getElementType()
252 : throw ( uno::RuntimeException, std::exception )
253 : {
254 0 : return m_xWrappedStorage->getElementType();
255 : }
256 :
257 :
258 : // virtual
259 0 : sal_Bool SAL_CALL Storage::hasElements()
260 : throw ( uno::RuntimeException, std::exception )
261 : {
262 0 : return m_xWrappedStorage->hasElements();
263 : }
264 :
265 :
266 :
267 : // container::XNameAccess (base of embed::XStorage)
268 :
269 :
270 :
271 : // virtual
272 0 : uno::Any SAL_CALL Storage::getByName( const OUString& aName )
273 : throw ( container::NoSuchElementException,
274 : lang::WrappedTargetException,
275 : uno::RuntimeException, std::exception )
276 : {
277 0 : return m_xWrappedStorage->getByName( aName );
278 : }
279 :
280 :
281 : // virtual
282 0 : uno::Sequence< OUString > SAL_CALL Storage::getElementNames()
283 : throw ( uno::RuntimeException, std::exception )
284 : {
285 0 : return m_xWrappedStorage->getElementNames();
286 : }
287 :
288 :
289 : // virtual
290 0 : sal_Bool SAL_CALL Storage::hasByName( const OUString& aName )
291 : throw ( uno::RuntimeException, std::exception )
292 : {
293 0 : return m_xWrappedStorage->hasByName( aName );
294 : }
295 :
296 :
297 :
298 : // embed::XStorage
299 :
300 :
301 :
302 : // virtual
303 0 : void SAL_CALL Storage::copyToStorage(
304 : const uno::Reference< embed::XStorage >& xDest )
305 : throw ( embed::InvalidStorageException,
306 : lang::IllegalArgumentException,
307 : io::IOException,
308 : embed::StorageWrappedTargetException,
309 : uno::RuntimeException, std::exception )
310 : {
311 0 : m_xWrappedStorage->copyToStorage( xDest );
312 0 : }
313 :
314 :
315 : // virtual
316 0 : uno::Reference< io::XStream > SAL_CALL Storage::openStreamElement(
317 : const OUString& aStreamName, sal_Int32 nOpenMode )
318 : throw ( embed::InvalidStorageException,
319 : lang::IllegalArgumentException,
320 : packages::WrongPasswordException,
321 : io::IOException,
322 : embed::StorageWrappedTargetException,
323 : uno::RuntimeException, std::exception )
324 : {
325 0 : return m_xWrappedStorage->openStreamElement( aStreamName, nOpenMode );
326 : }
327 :
328 :
329 : // virtual
330 0 : uno::Reference< io::XStream > SAL_CALL Storage::openEncryptedStreamElement(
331 : const OUString& aStreamName,
332 : sal_Int32 nOpenMode,
333 : const OUString& aPassword )
334 : throw ( embed::InvalidStorageException,
335 : lang::IllegalArgumentException,
336 : packages::NoEncryptionException,
337 : packages::WrongPasswordException,
338 : io::IOException,
339 : embed::StorageWrappedTargetException,
340 : uno::RuntimeException, std::exception )
341 : {
342 0 : return m_xWrappedStorage->openEncryptedStreamElement(
343 0 : aStreamName, nOpenMode, aPassword );
344 : }
345 :
346 :
347 : // virtual
348 0 : uno::Reference< embed::XStorage > SAL_CALL Storage::openStorageElement(
349 : const OUString& aStorName, sal_Int32 nOpenMode )
350 : throw ( embed::InvalidStorageException,
351 : lang::IllegalArgumentException,
352 : io::IOException,
353 : embed::StorageWrappedTargetException,
354 : uno::RuntimeException, std::exception )
355 : {
356 0 : return m_xWrappedStorage->openStorageElement( aStorName, nOpenMode );
357 : }
358 :
359 :
360 : // virtual
361 0 : uno::Reference< io::XStream > SAL_CALL Storage::cloneStreamElement(
362 : const OUString& aStreamName )
363 : throw ( embed::InvalidStorageException,
364 : lang::IllegalArgumentException,
365 : packages::WrongPasswordException,
366 : io::IOException,
367 : embed::StorageWrappedTargetException,
368 : uno::RuntimeException, std::exception )
369 : {
370 0 : return m_xWrappedStorage->cloneStreamElement( aStreamName );
371 : }
372 :
373 :
374 : // virtual
375 0 : uno::Reference< io::XStream > SAL_CALL Storage::cloneEncryptedStreamElement(
376 : const OUString& aStreamName,
377 : const OUString& aPassword )
378 : throw ( embed::InvalidStorageException,
379 : lang::IllegalArgumentException,
380 : packages::NoEncryptionException,
381 : packages::WrongPasswordException,
382 : io::IOException,
383 : embed::StorageWrappedTargetException,
384 : uno::RuntimeException, std::exception )
385 : {
386 0 : return m_xWrappedStorage->cloneEncryptedStreamElement( aStreamName,
387 0 : aPassword );
388 : }
389 :
390 :
391 : // virtual
392 0 : void SAL_CALL Storage::copyLastCommitTo(
393 : const uno::Reference< embed::XStorage >& xTargetStorage )
394 : throw ( embed::InvalidStorageException,
395 : lang::IllegalArgumentException,
396 : io::IOException,
397 : embed::StorageWrappedTargetException,
398 : uno::RuntimeException, std::exception)
399 : {
400 0 : m_xWrappedStorage->copyLastCommitTo( xTargetStorage );
401 0 : }
402 :
403 :
404 : // virtual
405 0 : void SAL_CALL Storage::copyStorageElementLastCommitTo(
406 : const OUString& aStorName,
407 : const uno::Reference< embed::XStorage >& xTargetStorage )
408 : throw ( embed::InvalidStorageException,
409 : lang::IllegalArgumentException,
410 : io::IOException,
411 : embed::StorageWrappedTargetException,
412 : uno::RuntimeException, std::exception)
413 : {
414 0 : m_xWrappedStorage->copyStorageElementLastCommitTo( aStorName, xTargetStorage );
415 0 : }
416 :
417 :
418 : // virtual
419 0 : sal_Bool SAL_CALL Storage::isStreamElement(
420 : const OUString& aElementName )
421 : throw ( container::NoSuchElementException,
422 : lang::IllegalArgumentException,
423 : embed::InvalidStorageException,
424 : uno::RuntimeException, std::exception )
425 : {
426 0 : return m_xWrappedStorage->isStreamElement( aElementName );
427 : }
428 :
429 :
430 : // virtual
431 0 : sal_Bool SAL_CALL Storage::isStorageElement(
432 : const OUString& aElementName )
433 : throw ( container::NoSuchElementException,
434 : lang::IllegalArgumentException,
435 : embed::InvalidStorageException,
436 : uno::RuntimeException, std::exception )
437 : {
438 0 : return m_xWrappedStorage->isStorageElement( aElementName );
439 : }
440 :
441 :
442 : // virtual
443 0 : void SAL_CALL Storage::removeElement( const OUString& aElementName )
444 : throw ( embed::InvalidStorageException,
445 : lang::IllegalArgumentException,
446 : container::NoSuchElementException,
447 : io::IOException,
448 : embed::StorageWrappedTargetException,
449 : uno::RuntimeException, std::exception )
450 : {
451 0 : m_xWrappedStorage->removeElement( aElementName );
452 0 : }
453 :
454 :
455 : // virtual
456 0 : void SAL_CALL Storage::renameElement( const OUString& aEleName,
457 : const OUString& aNewName )
458 : throw ( embed::InvalidStorageException,
459 : lang::IllegalArgumentException,
460 : container::NoSuchElementException,
461 : container::ElementExistException,
462 : io::IOException,
463 : embed::StorageWrappedTargetException,
464 : uno::RuntimeException, std::exception )
465 : {
466 0 : m_xWrappedStorage->renameElement( aEleName, aNewName );
467 0 : }
468 :
469 :
470 : // virtual
471 0 : void SAL_CALL Storage::copyElementTo(
472 : const OUString& aElementName,
473 : const uno::Reference< embed::XStorage >& xDest,
474 : const OUString& aNewName )
475 : throw ( embed::InvalidStorageException,
476 : lang::IllegalArgumentException,
477 : container::NoSuchElementException,
478 : container::ElementExistException,
479 : io::IOException,
480 : embed::StorageWrappedTargetException,
481 : uno::RuntimeException, std::exception )
482 : {
483 0 : m_xWrappedStorage->copyElementTo( aElementName, xDest, aNewName );
484 0 : }
485 :
486 :
487 : // virtual
488 0 : void SAL_CALL Storage::moveElementTo(
489 : const OUString& aElementName,
490 : const uno::Reference< embed::XStorage >& xDest,
491 : const OUString& rNewName )
492 : throw ( embed::InvalidStorageException,
493 : lang::IllegalArgumentException,
494 : container::NoSuchElementException,
495 : container::ElementExistException,
496 : io::IOException,
497 : embed::StorageWrappedTargetException,
498 : uno::RuntimeException, std::exception )
499 : {
500 0 : m_xWrappedStorage->moveElementTo( aElementName, xDest, rNewName );
501 0 : }
502 :
503 :
504 :
505 : // embed::XTransactedObject
506 :
507 :
508 :
509 : // virtual
510 0 : void SAL_CALL Storage::commit()
511 : throw ( io::IOException,
512 : lang::WrappedTargetException,
513 : uno::RuntimeException, std::exception )
514 : {
515 : // Never commit a root storage (-> has no parent)!
516 : // Would lead in writing the whole document to disk.
517 :
518 0 : uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
519 0 : if ( xParentStorage.is() )
520 : {
521 : OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
522 :
523 0 : if ( m_xWrappedTransObj.is() )
524 : {
525 0 : m_xWrappedTransObj->commit();
526 :
527 0 : if ( !isParentARootStorage() )
528 : {
529 : uno::Reference< embed::XTransactedObject > xParentTA(
530 0 : xParentStorage, uno::UNO_QUERY );
531 : OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
532 :
533 0 : if ( xParentTA.is() )
534 0 : xParentTA->commit();
535 : }
536 : }
537 0 : }
538 0 : }
539 :
540 :
541 : // virtual
542 0 : void SAL_CALL Storage::revert()
543 : throw ( io::IOException,
544 : lang::WrappedTargetException,
545 : uno::RuntimeException, std::exception )
546 : {
547 0 : uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
548 0 : if ( xParentStorage.is() )
549 : {
550 : OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
551 :
552 0 : if ( m_xWrappedTransObj.is() )
553 : {
554 0 : m_xWrappedTransObj->revert();
555 :
556 0 : if ( !isParentARootStorage() )
557 : {
558 : uno::Reference< embed::XTransactedObject > xParentTA(
559 0 : xParentStorage, uno::UNO_QUERY );
560 : OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
561 :
562 0 : if ( xParentTA.is() )
563 0 : xParentTA->revert();
564 : }
565 : }
566 0 : }
567 0 : }
568 :
569 :
570 :
571 :
572 : // OutputStream Implementation.
573 :
574 :
575 :
576 :
577 0 : OutputStream::OutputStream(
578 : const uno::Reference< uno::XComponentContext > & rxContext,
579 : const OUString & rUri,
580 : const uno::Reference< embed::XStorage > & xParentStorage,
581 : const uno::Reference< io::XOutputStream > & xStreamToWrap )
582 0 : : ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
583 : m_xWrappedStream( xStreamToWrap ),
584 : m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
585 0 : m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
586 : {
587 : OSL_ENSURE( m_xWrappedStream.is(),
588 : "OutputStream::OutputStream: No stream to wrap!" );
589 :
590 : OSL_ENSURE( m_xWrappedComponent.is(),
591 : "OutputStream::OutputStream: No component to wrap!" );
592 :
593 : OSL_ENSURE( m_xWrappedTypeProv.is(),
594 : "OutputStream::OutputStream: No Type Provider!" );
595 :
596 : // Use proxy factory service to create aggregatable proxy.
597 : try
598 : {
599 : uno::Reference< reflection::XProxyFactory > xProxyFac =
600 0 : reflection::ProxyFactory::create( rxContext );
601 0 : m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
602 : }
603 0 : catch ( uno::Exception const & )
604 : {
605 : OSL_FAIL( "OutputStream::OutputStream: Caught exception!" );
606 : }
607 :
608 : OSL_ENSURE( m_xAggProxy.is(),
609 : "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
610 :
611 0 : if ( m_xAggProxy.is() )
612 : {
613 0 : osl_atomic_increment( &m_refCount );
614 : {
615 : // Solaris compiler problem:
616 : // Extra block to enforce destruction of temporary object created
617 : // in next statement _before_ osl_atomic_decrement is
618 : // called. Otherwise 'this' will destroy itself even before ctor
619 : // is completed (See impl. of XInterface::release())!
620 :
621 0 : m_xAggProxy->setDelegator(
622 0 : static_cast< cppu::OWeakObject * >( this ) );
623 : }
624 0 : osl_atomic_decrement( &m_refCount );
625 : }
626 0 : }
627 :
628 :
629 : // virtual
630 0 : OutputStream::~OutputStream()
631 : {
632 0 : if ( m_xAggProxy.is() )
633 0 : m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
634 0 : }
635 :
636 :
637 :
638 : // uno::XInterface
639 :
640 :
641 :
642 : // virtual
643 0 : uno::Any SAL_CALL OutputStream::queryInterface( const uno::Type& aType )
644 : throw ( uno::RuntimeException, std::exception )
645 : {
646 0 : uno::Any aRet = OutputStreamUNOBase::queryInterface( aType );
647 :
648 0 : if ( aRet.hasValue() )
649 0 : return aRet;
650 :
651 0 : if ( m_xAggProxy.is() )
652 0 : return m_xAggProxy->queryAggregation( aType );
653 : else
654 0 : return uno::Any();
655 : }
656 :
657 :
658 :
659 : // lang::XTypeProvider
660 :
661 :
662 :
663 : // virtual
664 0 : uno::Sequence< uno::Type > SAL_CALL OutputStream::getTypes()
665 : throw ( uno::RuntimeException, std::exception )
666 : {
667 0 : return m_xWrappedTypeProv->getTypes();
668 : }
669 :
670 :
671 : // virtual
672 0 : uno::Sequence< sal_Int8 > SAL_CALL OutputStream::getImplementationId()
673 : throw ( uno::RuntimeException, std::exception )
674 : {
675 0 : return css::uno::Sequence<sal_Int8>();
676 : }
677 :
678 :
679 :
680 : // io::XOutputStream
681 :
682 :
683 :
684 : // virtual
685 : void SAL_CALL
686 0 : OutputStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
687 : throw ( io::NotConnectedException,
688 : io::BufferSizeExceededException,
689 : io::IOException,
690 : uno::RuntimeException, std::exception )
691 : {
692 0 : m_xWrappedStream->writeBytes( aData );
693 0 : }
694 :
695 :
696 : // virtual
697 : void SAL_CALL
698 0 : OutputStream::flush()
699 : throw ( io::NotConnectedException,
700 : io::BufferSizeExceededException,
701 : io::IOException,
702 : uno::RuntimeException, std::exception )
703 : {
704 0 : m_xWrappedStream->flush();
705 0 : }
706 :
707 :
708 : // virtual
709 : void SAL_CALL
710 0 : OutputStream::closeOutput( )
711 : throw ( io::NotConnectedException,
712 : io::BufferSizeExceededException,
713 : io::IOException,
714 : uno::RuntimeException, std::exception )
715 : {
716 0 : m_xWrappedStream->closeOutput();
717 :
718 : // Release parent storage.
719 : // Now, that the stream is closed/disposed it is not needed any longer.
720 0 : setParentStorage( uno::Reference< embed::XStorage >() );
721 0 : }
722 :
723 :
724 :
725 : // lang::XComponent
726 :
727 :
728 :
729 : // virtual
730 : void SAL_CALL
731 0 : OutputStream::dispose()
732 : throw ( uno::RuntimeException, std::exception )
733 : {
734 0 : m_xWrappedComponent->dispose();
735 :
736 : // Release parent storage.
737 : // Now, that the stream is closed/disposed it is not needed any longer.
738 0 : setParentStorage( uno::Reference< embed::XStorage >() );
739 0 : }
740 :
741 :
742 : // virtual
743 : void SAL_CALL
744 0 : OutputStream::addEventListener(
745 : const uno::Reference< lang::XEventListener >& xListener )
746 : throw ( uno::RuntimeException, std::exception )
747 : {
748 0 : m_xWrappedComponent->addEventListener( xListener );
749 0 : }
750 :
751 :
752 : // virtual
753 : void SAL_CALL
754 0 : OutputStream::removeEventListener(
755 : const uno::Reference< lang::XEventListener >& aListener )
756 : throw ( uno::RuntimeException, std::exception )
757 : {
758 0 : m_xWrappedComponent->removeEventListener( aListener );
759 0 : }
760 :
761 :
762 :
763 :
764 : // Stream Implementation.
765 :
766 :
767 :
768 :
769 0 : Stream::Stream(
770 : const uno::Reference< uno::XComponentContext > & rxContext,
771 : const OUString & rUri,
772 : const uno::Reference< embed::XStorage > & xParentStorage,
773 : const uno::Reference< io::XStream > & xStreamToWrap )
774 0 : : ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
775 : m_xWrappedStream( xStreamToWrap ),
776 0 : m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty
777 : m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be empty
778 0 : m_xWrappedInputStream( xStreamToWrap->getInputStream(), uno::UNO_QUERY ),
779 : m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
780 0 : m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
781 : {
782 : OSL_ENSURE( m_xWrappedStream.is(),
783 : "OutputStream::OutputStream: No stream to wrap!" );
784 :
785 : OSL_ENSURE( m_xWrappedComponent.is(),
786 : "OutputStream::OutputStream: No component to wrap!" );
787 :
788 : OSL_ENSURE( m_xWrappedTypeProv.is(),
789 : "OutputStream::OutputStream: No Type Provider!" );
790 :
791 : // Use proxy factory service to create aggregatable proxy.
792 : try
793 : {
794 : uno::Reference< reflection::XProxyFactory > xProxyFac =
795 0 : reflection::ProxyFactory::create( rxContext );
796 0 : m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
797 : }
798 0 : catch ( uno::Exception const & )
799 : {
800 : OSL_FAIL( "OutputStream::OutputStream: Caught exception!" );
801 : }
802 :
803 : OSL_ENSURE( m_xAggProxy.is(),
804 : "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
805 :
806 0 : if ( m_xAggProxy.is() )
807 : {
808 0 : osl_atomic_increment( &m_refCount );
809 : {
810 : // Solaris compiler problem:
811 : // Extra block to enforce destruction of temporary object created
812 : // in next statement _before_ osl_atomic_decrement is
813 : // called. Otherwise 'this' will destroy itself even before ctor
814 : // is completed (See impl. of XInterface::release())!
815 :
816 0 : m_xAggProxy->setDelegator(
817 0 : static_cast< cppu::OWeakObject * >( this ) );
818 : }
819 0 : osl_atomic_decrement( &m_refCount );
820 : }
821 0 : }
822 :
823 :
824 : // virtual
825 0 : Stream::~Stream()
826 : {
827 0 : if ( m_xAggProxy.is() )
828 0 : m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
829 0 : }
830 :
831 :
832 :
833 : // uno::XInterface
834 :
835 :
836 :
837 : // virtual
838 0 : uno::Any SAL_CALL Stream::queryInterface( const uno::Type& aType )
839 : throw ( uno::RuntimeException, std::exception )
840 : {
841 0 : uno::Any aRet = StreamUNOBase::queryInterface( aType );
842 :
843 0 : if ( aRet.hasValue() )
844 0 : return aRet;
845 :
846 0 : if ( m_xAggProxy.is() )
847 0 : return m_xAggProxy->queryAggregation( aType );
848 : else
849 0 : return uno::Any();
850 : }
851 :
852 :
853 :
854 : // lang::XTypeProvider
855 :
856 :
857 :
858 : // virtual
859 0 : uno::Sequence< uno::Type > SAL_CALL Stream::getTypes()
860 : throw ( uno::RuntimeException, std::exception )
861 : {
862 0 : return m_xWrappedTypeProv->getTypes();
863 : }
864 :
865 :
866 : // virtual
867 0 : uno::Sequence< sal_Int8 > SAL_CALL Stream::getImplementationId()
868 : throw ( uno::RuntimeException, std::exception )
869 : {
870 0 : return css::uno::Sequence<sal_Int8>();
871 : }
872 :
873 :
874 :
875 : // io::XStream.
876 :
877 :
878 :
879 : // virtual
880 0 : uno::Reference< io::XInputStream > SAL_CALL Stream::getInputStream()
881 : throw( uno::RuntimeException, std::exception )
882 : {
883 0 : return uno::Reference< io::XInputStream >( this );
884 : }
885 :
886 :
887 : // virtual
888 0 : uno::Reference< io::XOutputStream > SAL_CALL Stream::getOutputStream()
889 : throw( uno::RuntimeException, std::exception )
890 : {
891 0 : return uno::Reference< io::XOutputStream >( this );
892 : }
893 :
894 :
895 :
896 : // io::XOutputStream.
897 :
898 :
899 :
900 : // virtual
901 0 : void SAL_CALL Stream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
902 : throw( io::NotConnectedException,
903 : io::BufferSizeExceededException,
904 : io::IOException,
905 : uno::RuntimeException, std::exception )
906 : {
907 0 : if ( m_xWrappedOutputStream.is() )
908 : {
909 0 : m_xWrappedOutputStream->writeBytes( aData );
910 0 : commitChanges();
911 : }
912 0 : }
913 :
914 :
915 : // virtual
916 0 : void SAL_CALL Stream::flush()
917 : throw( io::NotConnectedException,
918 : io::BufferSizeExceededException,
919 : io::IOException,
920 : uno::RuntimeException, std::exception )
921 : {
922 0 : if ( m_xWrappedOutputStream.is() )
923 : {
924 0 : m_xWrappedOutputStream->flush();
925 0 : commitChanges();
926 : }
927 0 : }
928 :
929 :
930 : // virtual
931 0 : void SAL_CALL Stream::closeOutput()
932 : throw( io::NotConnectedException,
933 : io::IOException,
934 : uno::RuntimeException, std::exception )
935 : {
936 0 : if ( m_xWrappedOutputStream.is() )
937 : {
938 0 : m_xWrappedOutputStream->closeOutput();
939 0 : commitChanges();
940 : }
941 :
942 : // Release parent storage.
943 : // Now, that the stream is closed/disposed it is not needed any longer.
944 0 : setParentStorage( uno::Reference< embed::XStorage >() );
945 0 : }
946 :
947 :
948 :
949 : // io::XTruncate.
950 :
951 :
952 :
953 : // virtual
954 0 : void SAL_CALL Stream::truncate()
955 : throw( io::IOException,
956 : uno::RuntimeException, std::exception )
957 : {
958 0 : if ( m_xWrappedTruncate.is() )
959 : {
960 0 : m_xWrappedTruncate->truncate();
961 0 : commitChanges();
962 : }
963 0 : }
964 :
965 :
966 :
967 : // io::XInputStream.
968 :
969 :
970 :
971 : // virtual
972 0 : sal_Int32 SAL_CALL Stream::readBytes( uno::Sequence< sal_Int8 >& aData,
973 : sal_Int32 nBytesToRead )
974 : throw( io::NotConnectedException,
975 : io::BufferSizeExceededException,
976 : io::IOException,
977 : uno::RuntimeException, std::exception )
978 : {
979 0 : return m_xWrappedInputStream->readBytes( aData, nBytesToRead );
980 : }
981 :
982 :
983 : // virtual
984 0 : sal_Int32 SAL_CALL Stream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,
985 : sal_Int32 nMaxBytesToRead )
986 : throw( io::NotConnectedException,
987 : io::BufferSizeExceededException,
988 : io::IOException,
989 : uno::RuntimeException, std::exception )
990 : {
991 0 : return m_xWrappedInputStream->readSomeBytes( aData, nMaxBytesToRead );
992 : }
993 :
994 :
995 : // virtual
996 0 : void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
997 : throw( io::NotConnectedException,
998 : io::BufferSizeExceededException,
999 : io::IOException,
1000 : uno::RuntimeException, std::exception )
1001 : {
1002 0 : m_xWrappedInputStream->skipBytes( nBytesToSkip );
1003 0 : }
1004 :
1005 :
1006 : // virtual
1007 0 : sal_Int32 SAL_CALL Stream::available()
1008 : throw( io::NotConnectedException,
1009 : io::IOException,
1010 : uno::RuntimeException, std::exception )
1011 : {
1012 0 : return m_xWrappedInputStream->available();
1013 : }
1014 :
1015 :
1016 : // virtual
1017 0 : void SAL_CALL Stream::closeInput()
1018 : throw( io::NotConnectedException,
1019 : io::IOException,
1020 : uno::RuntimeException, std::exception )
1021 : {
1022 0 : m_xWrappedInputStream->closeInput();
1023 0 : }
1024 :
1025 :
1026 :
1027 : // lang::XComponent
1028 :
1029 :
1030 :
1031 : // virtual
1032 0 : void SAL_CALL Stream::dispose()
1033 : throw ( uno::RuntimeException, std::exception )
1034 : {
1035 0 : m_xWrappedComponent->dispose();
1036 :
1037 : // Release parent storage.
1038 : // Now, that the stream is closed/disposed it is not needed any longer.
1039 0 : setParentStorage( uno::Reference< embed::XStorage >() );
1040 0 : }
1041 :
1042 :
1043 : // virtual
1044 0 : void SAL_CALL Stream::addEventListener(
1045 : const uno::Reference< lang::XEventListener >& xListener )
1046 : throw ( uno::RuntimeException, std::exception )
1047 : {
1048 0 : m_xWrappedComponent->addEventListener( xListener );
1049 0 : }
1050 :
1051 :
1052 : // virtual
1053 0 : void SAL_CALL Stream::removeEventListener(
1054 : const uno::Reference< lang::XEventListener >& aListener )
1055 : throw ( uno::RuntimeException, std::exception )
1056 : {
1057 0 : m_xWrappedComponent->removeEventListener( aListener );
1058 0 : }
1059 :
1060 :
1061 :
1062 : // Non-UNO
1063 :
1064 :
1065 :
1066 0 : void Stream::commitChanges()
1067 : throw( io::IOException )
1068 : {
1069 : uno::Reference< embed::XTransactedObject >
1070 0 : xParentTA( getParentStorage(), uno::UNO_QUERY );
1071 : OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
1072 :
1073 0 : if ( xParentTA.is() )
1074 : {
1075 : try
1076 : {
1077 0 : xParentTA->commit();
1078 : }
1079 0 : catch ( lang::WrappedTargetException const & )
1080 : {
1081 0 : throw io::IOException(); // @@@
1082 : }
1083 0 : }
1084 0 : }
1085 :
1086 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|