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_comphelper.hxx" 26 #include <osl/diagnose.h> 27 #include <com/sun/star/beans/PropertyAttribute.hpp> 28 #include <com/sun/star/io/XAsyncOutputMonitor.hpp> 29 #include <com/sun/star/embed/UseBackupException.hpp> 30 31 #include <comphelper/otransactedfilestream.hxx> 32 #include <comphelper/storagehelper.hxx> 33 #include <cppuhelper/implbase1.hxx> 34 35 using namespace ::com::sun::star; 36 37 namespace comphelper 38 { 39 40 // ======================================================================== 41 class OTransactionHelper : public ::cppu::WeakImplHelper1 < embed::XTransactedObject > 42 { 43 OTruncatedTransactedFileStream* m_pFileStream; 44 uno::Reference< io::XStream > m_xStreamHolder; 45 46 public: 47 OTransactionHelper( OTruncatedTransactedFileStream* pStream ) 48 : m_pFileStream( pStream ) 49 { 50 m_xStreamHolder = static_cast< io::XStream* >( pStream ); 51 if ( !m_xStreamHolder.is() ) 52 throw uno::RuntimeException(); 53 } 54 55 virtual void SAL_CALL commit( ); 56 virtual void SAL_CALL revert( ); 57 }; 58 59 // ------------------------------------------------------------------------ 60 void SAL_CALL OTransactionHelper::commit( ) 61 { 62 m_pFileStream->Commit_Impl(); 63 } 64 65 // ------------------------------------------------------------------------ 66 void SAL_CALL OTransactionHelper::revert( ) 67 { 68 m_pFileStream->Revert_Impl(); 69 } 70 71 // ======================================================================== 72 struct TTFileStreamData_Impl 73 { 74 uno::Reference< ucb::XSimpleFileAccess > m_xFileAccess; 75 sal_Bool m_bDelete; 76 ::rtl::OUString m_aURL; 77 78 // the streams below are not visible from outside so there is no need to remember position 79 80 // original stream related members 81 uno::Reference< io::XStream > m_xOrigStream; 82 uno::Reference< io::XTruncate > m_xOrigTruncate; 83 uno::Reference< io::XSeekable > m_xOrigSeekable; 84 uno::Reference< io::XInputStream > m_xOrigInStream; 85 uno::Reference< io::XOutputStream > m_xOrigOutStream; 86 87 // temporary stream related members 88 uno::Reference< io::XStream > m_xTempStream; 89 uno::Reference< io::XTruncate > m_xTempTruncate; 90 uno::Reference< io::XSeekable > m_xTempSeekable; 91 uno::Reference< io::XInputStream > m_xTempInStream; 92 uno::Reference< io::XOutputStream > m_xTempOutStream; 93 94 sal_Bool m_bInOpen; 95 sal_Bool m_bOutOpen; 96 97 sal_Bool m_bTransacted; 98 99 100 TTFileStreamData_Impl( 101 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, 102 sal_Bool bDelete, 103 const ::rtl::OUString& aURL, 104 const uno::Reference< io::XStream >& xOrigStream, 105 const uno::Reference< io::XTruncate >& xOrigTruncate, 106 const uno::Reference< io::XSeekable >& xOrigSeekable, 107 const uno::Reference< io::XInputStream >& xOrigInStream, 108 const uno::Reference< io::XOutputStream >& xOrigOutStream, 109 const uno::Reference< io::XStream >& xTempStream, 110 const uno::Reference< io::XTruncate >& xTempTruncate, 111 const uno::Reference< io::XSeekable >& xTempSeekable, 112 const uno::Reference< io::XInputStream >& xTempInStream, 113 const uno::Reference< io::XOutputStream >& xTempOutStream ) 114 : m_xFileAccess( xFileAccess ) 115 , m_bDelete( bDelete ) 116 , m_aURL( aURL ) 117 , m_xOrigStream( xOrigStream ) 118 , m_xOrigTruncate( xOrigTruncate ) 119 , m_xOrigSeekable( xOrigSeekable ) 120 , m_xOrigInStream( xOrigInStream ) 121 , m_xOrigOutStream( xOrigOutStream ) 122 , m_xTempStream( xTempStream ) 123 , m_xTempTruncate( xTempTruncate ) 124 , m_xTempSeekable( xTempSeekable ) 125 , m_xTempInStream( xTempInStream ) 126 , m_xTempOutStream( xTempOutStream ) 127 , m_bInOpen( sal_False ) 128 , m_bOutOpen( sal_False ) 129 , m_bTransacted( sal_True ) 130 {} 131 132 void NoTransaction() 133 { 134 m_bDelete = sal_False; 135 m_bTransacted = sal_False; 136 m_xTempStream = uno::Reference< io::XStream >(); 137 m_xTempTruncate = uno::Reference< io::XTruncate >(); 138 m_xTempSeekable = uno::Reference< io::XSeekable >(); 139 m_xTempInStream = uno::Reference< io::XInputStream >(); 140 m_xTempOutStream = uno::Reference< io::XOutputStream >(); 141 } 142 143 void FreeOriginal() 144 { 145 m_bDelete = sal_False; 146 m_bTransacted = sal_False; 147 148 m_xOrigStream = m_xTempStream; 149 m_xTempStream = uno::Reference< io::XStream >(); 150 151 m_xOrigTruncate = m_xTempTruncate; 152 m_xTempTruncate = uno::Reference< io::XTruncate >(); 153 154 m_xOrigSeekable = m_xTempSeekable; 155 m_xTempSeekable = uno::Reference< io::XSeekable >(); 156 157 m_xOrigInStream = m_xTempInStream; 158 m_xTempInStream = uno::Reference< io::XInputStream >(); 159 160 m_xOrigOutStream = m_xTempOutStream; 161 m_xTempOutStream = uno::Reference< io::XOutputStream >(); 162 } 163 }; 164 165 // ======================================================================== 166 // ------------------------------------------------------------------------ 167 OTruncatedTransactedFileStream::OTruncatedTransactedFileStream( 168 const ::rtl::OUString& aURL, 169 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 170 : m_pStreamData( NULL ) 171 { 172 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( 173 xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ), 174 uno::UNO_QUERY_THROW ); 175 176 CommonInit_Impl( aURL, xSimpleFileAccess, xFactory, sal_False ); 177 } 178 179 // ------------------------------------------------------------------------ 180 OTruncatedTransactedFileStream::OTruncatedTransactedFileStream( 181 const ::rtl::OUString& aURL, 182 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, 183 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 184 : m_pStreamData( NULL ) 185 { 186 CommonInit_Impl( aURL, xFileAccess, xFactory, sal_False ); 187 } 188 189 // ------------------------------------------------------------------------ 190 OTruncatedTransactedFileStream::OTruncatedTransactedFileStream( 191 const ::rtl::OUString& aURL, 192 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, 193 const uno::Reference< lang::XMultiServiceFactory >& xFactory, 194 sal_Bool bDeleteIfNotCommited ) 195 : m_pStreamData( NULL ) 196 { 197 CommonInit_Impl( aURL, xFileAccess, xFactory, sal_True ); 198 if ( m_pStreamData ) 199 m_pStreamData->m_bDelete = bDeleteIfNotCommited; 200 } 201 202 // ------------------------------------------------------------------------ 203 OTruncatedTransactedFileStream::~OTruncatedTransactedFileStream() 204 { 205 CloseAll_Impl(); 206 } 207 208 // ------------------------------------------------------------------------ 209 void OTruncatedTransactedFileStream::CloseAll_Impl() 210 { 211 ::osl::MutexGuard aGuard( m_aMutex ); 212 213 if ( m_pStreamData ) 214 { 215 sal_Bool bDelete = m_pStreamData->m_bDelete; 216 ::rtl::OUString aURL = m_pStreamData->m_aURL; 217 uno::Reference< ucb::XSimpleFileAccess > xFileAccess = m_pStreamData->m_xFileAccess; 218 219 delete m_pStreamData; 220 m_pStreamData = NULL; 221 222 if ( bDelete && xFileAccess.is() && !aURL.isEmpty() ) 223 { 224 // delete the file 225 try 226 { 227 xFileAccess->kill( aURL ); 228 } catch( uno::Exception& ) 229 { 230 OSL_ENSURE( sal_False, "Could not remove the file!" ); 231 } 232 } 233 } 234 } 235 236 // ------------------------------------------------------------------------ 237 void OTruncatedTransactedFileStream::CommonInit_Impl( 238 const ::rtl::OUString& aURL, 239 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, 240 const uno::Reference< lang::XMultiServiceFactory >& xFactory, 241 sal_Bool bDeleteOptionIsProvided ) 242 { 243 sal_Bool bDelete = sal_False; 244 if ( !bDeleteOptionIsProvided ) 245 bDelete = !xFileAccess->exists( aURL ); 246 247 uno::Reference< io::XStream > xOrigStream = xFileAccess->openFileReadWrite( aURL ); 248 uno::Reference< io::XTruncate > xOrigTruncate( xOrigStream, uno::UNO_QUERY_THROW ); 249 uno::Reference< io::XSeekable > xOrigSeekable( xOrigStream, uno::UNO_QUERY_THROW ); 250 uno::Reference< io::XInputStream > xOrigInStream = xOrigStream->getInputStream(); 251 uno::Reference< io::XOutputStream > xOrigOutStream = xOrigStream->getOutputStream(); 252 if ( !xOrigInStream.is() || !xOrigOutStream.is() ) 253 throw uno::RuntimeException(); 254 255 // temporary stream related members 256 uno::Reference< io::XStream > xTempStream( xFactory->createInstance( 257 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ), 258 uno::UNO_QUERY_THROW ); 259 uno::Reference< io::XTruncate > xTempTruncate( xTempStream, uno::UNO_QUERY_THROW ); 260 uno::Reference< io::XSeekable > xTempSeekable( xTempStream, uno::UNO_QUERY_THROW ); 261 uno::Reference< io::XInputStream > xTempInStream = xTempStream->getInputStream(); 262 uno::Reference< io::XOutputStream > xTempOutStream = xTempStream->getOutputStream(); 263 if ( !xTempInStream.is() || !xTempOutStream.is() ) 264 throw uno::RuntimeException(); 265 266 m_pStreamData = new TTFileStreamData_Impl( xFileAccess, bDelete, aURL, 267 xOrigStream, xOrigTruncate, xOrigSeekable, xOrigInStream, xOrigOutStream, 268 xTempStream, xTempTruncate, xTempSeekable, xTempInStream, xTempOutStream ); 269 } 270 271 // ------------------------------------------------------------------------ 272 void OTruncatedTransactedFileStream::Commit_Impl() 273 { 274 ::osl::MutexGuard aGuard( m_aMutex ); 275 276 if ( !m_pStreamData ) 277 throw io::NotConnectedException(); 278 279 if ( m_pStreamData->m_bTransacted ) 280 { 281 sal_Int64 nPos = m_pStreamData->m_xTempSeekable->getPosition(); 282 m_pStreamData->m_xTempSeekable->seek( 0 ); 283 284 // after the following step fails the information might be lost, throw an exception with URL of temporary file 285 try 286 { 287 m_pStreamData->m_xOrigTruncate->truncate(); 288 OStorageHelper::CopyInputToOutput( m_pStreamData->m_xTempInStream, m_pStreamData->m_xOrigOutStream ); 289 m_pStreamData->m_xOrigOutStream->flush(); 290 291 // in case the stream is based on a file it will implement the following interface 292 // the call should be used to be sure that the contents are written to the file system 293 uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( m_pStreamData->m_xOrigOutStream, uno::UNO_QUERY ); 294 if ( asyncOutputMonitor.is() ) 295 asyncOutputMonitor->waitForCompletion(); 296 } 297 catch( uno::Exception& ) 298 { 299 ::rtl::OUString aTempURL; 300 try { 301 uno::Reference< beans::XPropertySet > xTempFile( m_pStreamData->m_xTempStream, uno::UNO_QUERY_THROW ); 302 uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ); 303 aUrl >>= aTempURL; 304 xTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), 305 uno::makeAny( sal_False ) ); 306 307 m_pStreamData->m_xTempSeekable->seek( nPos ); 308 } 309 catch( uno::Exception& ) 310 { 311 OSL_ENSURE( sal_False, "These calls are pretty simple, they should not fail!\n" ); 312 } 313 314 m_pStreamData->FreeOriginal(); 315 316 ::rtl::OUString aErrTxt( RTL_CONSTASCII_USTRINGPARAM ( "Writing file failed!" ) ); 317 embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), aTempURL ); 318 throw lang::WrappedTargetException( aErrTxt, 319 static_cast < OWeakObject * > ( this ), 320 uno::makeAny ( aException ) ); 321 } 322 323 m_pStreamData->m_xOrigSeekable->seek( nPos ); 324 m_pStreamData->NoTransaction(); 325 } 326 else 327 throw io::NotConnectedException(); 328 } 329 330 // ------------------------------------------------------------------------ 331 void OTruncatedTransactedFileStream::Revert_Impl() 332 { 333 ::osl::MutexGuard aGuard( m_aMutex ); 334 335 if ( !m_pStreamData ) 336 throw io::NotConnectedException(); 337 338 if ( m_pStreamData->m_bTransacted ) 339 m_pStreamData->m_xTempTruncate->truncate(); 340 else 341 throw io::NotConnectedException(); 342 } 343 344 // com::sun::star::io::XStream 345 // ------------------------------------------------------------------------ 346 uno::Reference< io::XInputStream > SAL_CALL OTruncatedTransactedFileStream::getInputStream( ) 347 { 348 ::osl::MutexGuard aGuard( m_aMutex ); 349 350 if ( m_pStreamData ) 351 m_pStreamData->m_bInOpen = sal_True; 352 return static_cast< io::XInputStream* >( this ); 353 } 354 355 356 // ------------------------------------------------------------------------ 357 uno::Reference< io::XOutputStream > SAL_CALL OTruncatedTransactedFileStream::getOutputStream( ) 358 { 359 ::osl::MutexGuard aGuard( m_aMutex ); 360 361 if ( m_pStreamData ) 362 m_pStreamData->m_bOutOpen = sal_True; 363 return static_cast< io::XOutputStream* >( this ); 364 } 365 366 367 368 // com::sun::star::io::XInputStream 369 // ------------------------------------------------------------------------ 370 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) 371 { 372 ::osl::MutexGuard aGuard( m_aMutex ); 373 374 if ( !m_pStreamData ) 375 throw io::NotConnectedException(); 376 377 if ( m_pStreamData->m_bTransacted ) 378 { 379 // temporary stream data should be provided 380 if ( !m_pStreamData->m_xTempInStream.is() ) 381 throw uno::RuntimeException(); 382 383 return m_pStreamData->m_xTempInStream->readBytes( aData, nBytesToRead ); 384 } 385 else 386 { 387 // the original stream data should be provided 388 if ( !m_pStreamData->m_xOrigInStream.is() ) 389 throw uno::RuntimeException(); 390 391 return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead ); 392 } 393 } 394 395 396 // ------------------------------------------------------------------------ 397 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) 398 { 399 ::osl::MutexGuard aGuard( m_aMutex ); 400 401 if ( !m_pStreamData ) 402 throw io::NotConnectedException(); 403 404 if ( m_pStreamData->m_bTransacted ) 405 { 406 // temporary stream data should be provided 407 if ( !m_pStreamData->m_xTempInStream.is() ) 408 throw uno::RuntimeException(); 409 410 return m_pStreamData->m_xTempInStream->readSomeBytes( aData, nMaxBytesToRead ); 411 } 412 else 413 { 414 // the original stream data should be provided 415 if ( !m_pStreamData->m_xOrigInStream.is() ) 416 throw uno::RuntimeException(); 417 418 return m_pStreamData->m_xOrigInStream->readSomeBytes( aData, nMaxBytesToRead ); 419 } 420 } 421 422 // ------------------------------------------------------------------------ 423 void SAL_CALL OTruncatedTransactedFileStream::skipBytes( ::sal_Int32 nBytesToSkip ) 424 { 425 ::osl::MutexGuard aGuard( m_aMutex ); 426 427 if ( !m_pStreamData ) 428 throw io::NotConnectedException(); 429 430 if ( m_pStreamData->m_bTransacted ) 431 { 432 // temporary stream data should be provided 433 if ( !m_pStreamData->m_xTempInStream.is() ) 434 throw uno::RuntimeException(); 435 436 m_pStreamData->m_xTempInStream->skipBytes( nBytesToSkip ); 437 } 438 else 439 { 440 // the original stream data should be provided 441 if ( !m_pStreamData->m_xOrigInStream.is() ) 442 throw uno::RuntimeException(); 443 444 m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip ); 445 } 446 } 447 448 449 // ------------------------------------------------------------------------ 450 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::available( ) 451 { 452 ::osl::MutexGuard aGuard( m_aMutex ); 453 454 if ( !m_pStreamData ) 455 throw io::NotConnectedException(); 456 457 if ( m_pStreamData->m_bTransacted ) 458 { 459 // temporary stream data should be provided 460 if ( !m_pStreamData->m_xTempInStream.is() ) 461 throw uno::RuntimeException(); 462 463 return m_pStreamData->m_xTempInStream->available(); 464 } 465 else 466 { 467 // the original stream data should be provided 468 if ( !m_pStreamData->m_xOrigInStream.is() ) 469 throw uno::RuntimeException(); 470 471 return m_pStreamData->m_xOrigInStream->available(); 472 } 473 } 474 475 476 // ------------------------------------------------------------------------ 477 void SAL_CALL OTruncatedTransactedFileStream::closeInput() 478 { 479 ::osl::MutexGuard aGuard( m_aMutex ); 480 481 if ( !m_pStreamData ) 482 throw io::NotConnectedException(); 483 484 m_pStreamData->m_bInOpen = sal_False; 485 if ( !m_pStreamData->m_bOutOpen ) 486 CloseAll_Impl(); 487 } 488 489 490 491 // com::sun::star::io::XOutputStream 492 // ------------------------------------------------------------------------ 493 void SAL_CALL OTruncatedTransactedFileStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData ) 494 { 495 ::osl::MutexGuard aGuard( m_aMutex ); 496 497 if ( !m_pStreamData ) 498 throw io::NotConnectedException(); 499 500 if ( m_pStreamData->m_bTransacted ) 501 { 502 // temporary stream data should be provided 503 if ( !m_pStreamData->m_xTempOutStream.is() ) 504 throw uno::RuntimeException(); 505 506 m_pStreamData->m_xTempOutStream->writeBytes( aData ); 507 } 508 else 509 { 510 // the original stream data should be provided 511 if ( !m_pStreamData->m_xOrigOutStream.is() ) 512 throw uno::RuntimeException(); 513 514 m_pStreamData->m_xOrigOutStream->writeBytes( aData ); 515 } 516 } 517 518 519 // ------------------------------------------------------------------------ 520 void SAL_CALL OTruncatedTransactedFileStream::flush( ) 521 { 522 ::osl::MutexGuard aGuard( m_aMutex ); 523 524 if ( !m_pStreamData ) 525 { 526 OSL_ENSURE( sal_False, "flush() call on closed stream!\n" ); 527 return; 528 // in future throw exception, for now some code might call flush() on closed stream 529 // since file ucp implementation allows it 530 // throw io::NotConnectedException(); 531 } 532 533 if ( m_pStreamData->m_bTransacted ) 534 { 535 // temporary stream data should be provided 536 if ( !m_pStreamData->m_xTempOutStream.is() ) 537 throw uno::RuntimeException(); 538 539 m_pStreamData->m_xTempOutStream->flush(); 540 } 541 else 542 { 543 // the original stream data should be provided 544 if ( !m_pStreamData->m_xOrigOutStream.is() ) 545 throw uno::RuntimeException(); 546 547 m_pStreamData->m_xOrigOutStream->flush(); 548 } 549 } 550 551 552 // ------------------------------------------------------------------------ 553 void SAL_CALL OTruncatedTransactedFileStream::closeOutput( ) 554 { 555 ::osl::MutexGuard aGuard( m_aMutex ); 556 557 if ( !m_pStreamData ) 558 throw io::NotConnectedException(); 559 560 m_pStreamData->m_bOutOpen = sal_False; 561 if ( !m_pStreamData->m_bInOpen ) 562 CloseAll_Impl(); 563 } 564 565 566 567 // com::sun::star::io::XTruncate 568 // ------------------------------------------------------------------------ 569 void SAL_CALL OTruncatedTransactedFileStream::truncate( ) 570 { 571 ::osl::MutexGuard aGuard( m_aMutex ); 572 573 if ( !m_pStreamData ) 574 throw io::NotConnectedException(); 575 576 if ( m_pStreamData->m_bTransacted ) 577 { 578 // temporary stream data should be provided 579 if ( !m_pStreamData->m_xTempTruncate.is() ) 580 throw uno::RuntimeException(); 581 582 m_pStreamData->m_xTempTruncate->truncate(); 583 } 584 else 585 { 586 // the original stream data should be provided 587 if ( !m_pStreamData->m_xOrigTruncate.is() ) 588 throw uno::RuntimeException(); 589 590 m_pStreamData->m_xOrigTruncate->truncate(); 591 } 592 } 593 594 595 596 // com::sun::star::io::XSeekable 597 // ------------------------------------------------------------------------ 598 void SAL_CALL OTruncatedTransactedFileStream::seek( ::sal_Int64 location ) 599 { 600 ::osl::MutexGuard aGuard( m_aMutex ); 601 602 if ( !m_pStreamData ) 603 throw io::NotConnectedException(); 604 605 if ( m_pStreamData->m_bTransacted ) 606 { 607 // temporary stream data should be provided 608 if ( !m_pStreamData->m_xTempSeekable.is() ) 609 throw uno::RuntimeException(); 610 611 m_pStreamData->m_xTempSeekable->seek( location ); 612 } 613 else 614 { 615 // the original stream data should be provided 616 if ( !m_pStreamData->m_xOrigSeekable.is() ) 617 throw uno::RuntimeException(); 618 619 m_pStreamData->m_xOrigSeekable->seek( location ); 620 } 621 } 622 623 624 // ------------------------------------------------------------------------ 625 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getPosition( ) 626 { 627 ::osl::MutexGuard aGuard( m_aMutex ); 628 629 if ( !m_pStreamData ) 630 throw io::NotConnectedException(); 631 632 if ( m_pStreamData->m_bTransacted ) 633 { 634 // temporary stream data should be provided 635 if ( !m_pStreamData->m_xTempSeekable.is() ) 636 throw uno::RuntimeException(); 637 638 return m_pStreamData->m_xTempSeekable->getPosition(); 639 } 640 else 641 { 642 // the original stream data should be provided 643 if ( !m_pStreamData->m_xOrigSeekable.is() ) 644 throw uno::RuntimeException(); 645 646 return m_pStreamData->m_xOrigSeekable->getPosition(); 647 } 648 } 649 650 651 // ------------------------------------------------------------------------ 652 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getLength( ) 653 { 654 ::osl::MutexGuard aGuard( m_aMutex ); 655 656 if ( !m_pStreamData ) 657 throw io::NotConnectedException(); 658 659 if ( m_pStreamData->m_bTransacted ) 660 { 661 // temporary stream data should be provided 662 if ( !m_pStreamData->m_xTempSeekable.is() ) 663 throw uno::RuntimeException(); 664 665 return m_pStreamData->m_xTempSeekable->getLength(); 666 } 667 else 668 { 669 // the original stream data should be provided 670 if ( !m_pStreamData->m_xOrigSeekable.is() ) 671 throw uno::RuntimeException(); 672 673 return m_pStreamData->m_xOrigSeekable->getLength(); 674 } 675 } 676 677 // com::sun::star::beans::XPropertySetInfo 678 // ------------------------------------------------------------------------ 679 uno::Sequence< beans::Property > SAL_CALL OTruncatedTransactedFileStream::getProperties() 680 { 681 ::osl::MutexGuard aGuard( m_aMutex ); 682 683 uno::Sequence< beans::Property > aProps( 1 ); 684 aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 685 aProps[0].Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) ); 686 aProps[0].Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY; 687 688 return aProps; 689 } 690 691 692 // ------------------------------------------------------------------------ 693 beans::Property SAL_CALL OTruncatedTransactedFileStream::getPropertyByName( const ::rtl::OUString& aName ) 694 { 695 ::osl::MutexGuard aGuard( m_aMutex ); 696 697 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 698 699 if ( !aName.equals( aTransactionPropName ) ) 700 throw beans::UnknownPropertyException(); 701 702 beans::Property aProp; 703 aProp.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 704 aProp.Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) ); 705 aProp.Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY; 706 707 return aProp; 708 } 709 710 711 // ------------------------------------------------------------------------ 712 ::sal_Bool SAL_CALL OTruncatedTransactedFileStream::hasPropertyByName( const ::rtl::OUString& Name ) 713 { 714 ::osl::MutexGuard aGuard( m_aMutex ); 715 716 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 717 return ( Name.equals( aTransactionPropName ) ); 718 } 719 720 721 722 // com::sun::star::beans::XPropertySet 723 // ------------------------------------------------------------------------ 724 uno::Reference< beans::XPropertySetInfo > SAL_CALL OTruncatedTransactedFileStream::getPropertySetInfo() 725 { 726 ::osl::MutexGuard aGuard( m_aMutex ); 727 728 return static_cast< beans::XPropertySetInfo* >( this ); 729 } 730 731 732 // ------------------------------------------------------------------------ 733 void SAL_CALL OTruncatedTransactedFileStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& ) 734 { 735 ::osl::MutexGuard aGuard( m_aMutex ); 736 737 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 738 if ( aPropertyName.equals( aTransactionPropName ) ) 739 throw beans::PropertyVetoException(); 740 741 throw beans::UnknownPropertyException(); 742 } 743 744 745 // ------------------------------------------------------------------------ 746 uno::Any SAL_CALL OTruncatedTransactedFileStream::getPropertyValue( const ::rtl::OUString& PropertyName ) 747 { 748 ::osl::MutexGuard aGuard( m_aMutex ); 749 750 if ( !m_pStreamData ) 751 throw io::NotConnectedException(); 752 753 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 754 if ( PropertyName.equals( aTransactionPropName ) ) 755 { 756 uno::Reference< embed::XTransactedObject > xObj; 757 if ( m_pStreamData->m_bTransacted ) 758 xObj = static_cast< embed::XTransactedObject* >( new OTransactionHelper( this ) ); 759 760 return uno::makeAny( xObj ); 761 } 762 763 throw beans::UnknownPropertyException(); 764 } 765 766 767 // ------------------------------------------------------------------------ 768 void SAL_CALL OTruncatedTransactedFileStream::addPropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) 769 { 770 // not implemented 771 } 772 773 774 // ------------------------------------------------------------------------ 775 void SAL_CALL OTruncatedTransactedFileStream::removePropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) 776 { 777 // not implemented 778 } 779 780 781 // ------------------------------------------------------------------------ 782 void SAL_CALL OTruncatedTransactedFileStream::addVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) 783 { 784 // not implemented 785 } 786 787 788 // ------------------------------------------------------------------------ 789 void SAL_CALL OTruncatedTransactedFileStream::removeVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) 790 { 791 // not implemented 792 } 793 794 795 } // namespace comphelper 796