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