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