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