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