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 //#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 211 uno::Sequence< uno::Type > SAL_CALL Storage::getTypes() 212 throw ( uno::RuntimeException ) 213 { 214 return m_xWrappedTypeProv->getTypes(); 215 } 216 217 //========================================================================= 218 // virtual 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 231 void SAL_CALL Storage::dispose() 232 throw ( uno::RuntimeException ) 233 { 234 m_xWrappedStorage->dispose(); 235 } 236 237 //========================================================================= 238 // virtual 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 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 261 uno::Type SAL_CALL Storage::getElementType() 262 throw ( uno::RuntimeException ) 263 { 264 return m_xWrappedStorage->getElementType(); 265 } 266 267 //========================================================================= 268 // virtual 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 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 292 uno::Sequence< ::rtl::OUString > SAL_CALL Storage::getElementNames() 293 throw ( uno::RuntimeException ) 294 { 295 return m_xWrappedStorage->getElementNames(); 296 } 297 298 //========================================================================= 299 // virtual 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 680 uno::Sequence< uno::Type > SAL_CALL OutputStream::getTypes() 681 throw ( uno::RuntimeException ) 682 { 683 return m_xWrappedTypeProv->getTypes(); 684 } 685 686 //========================================================================= 687 // virtual 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 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 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 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 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 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 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 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 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 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 881 uno::Sequence< uno::Type > SAL_CALL Stream::getTypes() 882 throw ( uno::RuntimeException ) 883 { 884 return m_xWrappedTypeProv->getTypes(); 885 } 886 887 //========================================================================= 888 // virtual 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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