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