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( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException); 56 virtual void SAL_CALL revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException); 57 }; 58 59 // ------------------------------------------------------------------------ 60 void SAL_CALL OTransactionHelper::commit( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException) 61 { 62 m_pFileStream->Commit_Impl(); 63 } 64 65 // ------------------------------------------------------------------------ 66 void SAL_CALL OTransactionHelper::revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException) 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.getLength() ) 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 throw (uno::RuntimeException) 348 { 349 ::osl::MutexGuard aGuard( m_aMutex ); 350 351 if ( m_pStreamData ) 352 m_pStreamData->m_bInOpen = sal_True; 353 return static_cast< io::XInputStream* >( this ); 354 } 355 356 357 // ------------------------------------------------------------------------ 358 uno::Reference< io::XOutputStream > SAL_CALL OTruncatedTransactedFileStream::getOutputStream( ) 359 throw (uno::RuntimeException) 360 { 361 ::osl::MutexGuard aGuard( m_aMutex ); 362 363 if ( m_pStreamData ) 364 m_pStreamData->m_bOutOpen = sal_True; 365 return static_cast< io::XOutputStream* >( this ); 366 } 367 368 369 370 // com::sun::star::io::XInputStream 371 // ------------------------------------------------------------------------ 372 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) 373 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 374 { 375 ::osl::MutexGuard aGuard( m_aMutex ); 376 377 if ( !m_pStreamData ) 378 throw io::NotConnectedException(); 379 380 if ( m_pStreamData->m_bTransacted ) 381 { 382 // temporary stream data should be provided 383 if ( !m_pStreamData->m_xTempInStream.is() ) 384 throw uno::RuntimeException(); 385 386 return m_pStreamData->m_xTempInStream->readBytes( aData, nBytesToRead ); 387 } 388 else 389 { 390 // the original stream data should be provided 391 if ( !m_pStreamData->m_xOrigInStream.is() ) 392 throw uno::RuntimeException(); 393 394 return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead ); 395 } 396 } 397 398 399 // ------------------------------------------------------------------------ 400 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) 401 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 402 { 403 ::osl::MutexGuard aGuard( m_aMutex ); 404 405 if ( !m_pStreamData ) 406 throw io::NotConnectedException(); 407 408 if ( m_pStreamData->m_bTransacted ) 409 { 410 // temporary stream data should be provided 411 if ( !m_pStreamData->m_xTempInStream.is() ) 412 throw uno::RuntimeException(); 413 414 return m_pStreamData->m_xTempInStream->readSomeBytes( aData, nMaxBytesToRead ); 415 } 416 else 417 { 418 // the original stream data should be provided 419 if ( !m_pStreamData->m_xOrigInStream.is() ) 420 throw uno::RuntimeException(); 421 422 return m_pStreamData->m_xOrigInStream->readSomeBytes( aData, nMaxBytesToRead ); 423 } 424 } 425 426 // ------------------------------------------------------------------------ 427 void SAL_CALL OTruncatedTransactedFileStream::skipBytes( ::sal_Int32 nBytesToSkip ) 428 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 429 { 430 ::osl::MutexGuard aGuard( m_aMutex ); 431 432 if ( !m_pStreamData ) 433 throw io::NotConnectedException(); 434 435 if ( m_pStreamData->m_bTransacted ) 436 { 437 // temporary stream data should be provided 438 if ( !m_pStreamData->m_xTempInStream.is() ) 439 throw uno::RuntimeException(); 440 441 m_pStreamData->m_xTempInStream->skipBytes( nBytesToSkip ); 442 } 443 else 444 { 445 // the original stream data should be provided 446 if ( !m_pStreamData->m_xOrigInStream.is() ) 447 throw uno::RuntimeException(); 448 449 m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip ); 450 } 451 } 452 453 454 // ------------------------------------------------------------------------ 455 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::available( ) 456 throw (io::NotConnectedException, io::IOException, uno::RuntimeException) 457 { 458 ::osl::MutexGuard aGuard( m_aMutex ); 459 460 if ( !m_pStreamData ) 461 throw io::NotConnectedException(); 462 463 if ( m_pStreamData->m_bTransacted ) 464 { 465 // temporary stream data should be provided 466 if ( !m_pStreamData->m_xTempInStream.is() ) 467 throw uno::RuntimeException(); 468 469 return m_pStreamData->m_xTempInStream->available(); 470 } 471 else 472 { 473 // the original stream data should be provided 474 if ( !m_pStreamData->m_xOrigInStream.is() ) 475 throw uno::RuntimeException(); 476 477 return m_pStreamData->m_xOrigInStream->available(); 478 } 479 } 480 481 482 // ------------------------------------------------------------------------ 483 void SAL_CALL OTruncatedTransactedFileStream::closeInput() 484 throw (io::NotConnectedException, io::IOException, uno::RuntimeException) 485 { 486 ::osl::MutexGuard aGuard( m_aMutex ); 487 488 if ( !m_pStreamData ) 489 throw io::NotConnectedException(); 490 491 m_pStreamData->m_bInOpen = sal_False; 492 if ( !m_pStreamData->m_bOutOpen ) 493 CloseAll_Impl(); 494 } 495 496 497 498 // com::sun::star::io::XOutputStream 499 // ------------------------------------------------------------------------ 500 void SAL_CALL OTruncatedTransactedFileStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData ) 501 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 502 { 503 ::osl::MutexGuard aGuard( m_aMutex ); 504 505 if ( !m_pStreamData ) 506 throw io::NotConnectedException(); 507 508 if ( m_pStreamData->m_bTransacted ) 509 { 510 // temporary stream data should be provided 511 if ( !m_pStreamData->m_xTempOutStream.is() ) 512 throw uno::RuntimeException(); 513 514 m_pStreamData->m_xTempOutStream->writeBytes( aData ); 515 } 516 else 517 { 518 // the original stream data should be provided 519 if ( !m_pStreamData->m_xOrigOutStream.is() ) 520 throw uno::RuntimeException(); 521 522 m_pStreamData->m_xOrigOutStream->writeBytes( aData ); 523 } 524 } 525 526 527 // ------------------------------------------------------------------------ 528 void SAL_CALL OTruncatedTransactedFileStream::flush( ) 529 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 530 { 531 ::osl::MutexGuard aGuard( m_aMutex ); 532 533 if ( !m_pStreamData ) 534 { 535 OSL_ENSURE( sal_False, "flush() call on closed stream!\n" ); 536 return; 537 // in future throw exception, for now some code might call flush() on closed stream 538 // since file ucp implementation allows it 539 // throw io::NotConnectedException(); 540 } 541 542 if ( m_pStreamData->m_bTransacted ) 543 { 544 // temporary stream data should be provided 545 if ( !m_pStreamData->m_xTempOutStream.is() ) 546 throw uno::RuntimeException(); 547 548 m_pStreamData->m_xTempOutStream->flush(); 549 } 550 else 551 { 552 // the original stream data should be provided 553 if ( !m_pStreamData->m_xOrigOutStream.is() ) 554 throw uno::RuntimeException(); 555 556 m_pStreamData->m_xOrigOutStream->flush(); 557 } 558 } 559 560 561 // ------------------------------------------------------------------------ 562 void SAL_CALL OTruncatedTransactedFileStream::closeOutput( ) 563 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 564 { 565 ::osl::MutexGuard aGuard( m_aMutex ); 566 567 if ( !m_pStreamData ) 568 throw io::NotConnectedException(); 569 570 m_pStreamData->m_bOutOpen = sal_False; 571 if ( !m_pStreamData->m_bInOpen ) 572 CloseAll_Impl(); 573 } 574 575 576 577 // com::sun::star::io::XTruncate 578 // ------------------------------------------------------------------------ 579 void SAL_CALL OTruncatedTransactedFileStream::truncate( ) 580 throw (io::IOException, uno::RuntimeException) 581 { 582 ::osl::MutexGuard aGuard( m_aMutex ); 583 584 if ( !m_pStreamData ) 585 throw io::NotConnectedException(); 586 587 if ( m_pStreamData->m_bTransacted ) 588 { 589 // temporary stream data should be provided 590 if ( !m_pStreamData->m_xTempTruncate.is() ) 591 throw uno::RuntimeException(); 592 593 m_pStreamData->m_xTempTruncate->truncate(); 594 } 595 else 596 { 597 // the original stream data should be provided 598 if ( !m_pStreamData->m_xOrigTruncate.is() ) 599 throw uno::RuntimeException(); 600 601 m_pStreamData->m_xOrigTruncate->truncate(); 602 } 603 } 604 605 606 607 // com::sun::star::io::XSeekable 608 // ------------------------------------------------------------------------ 609 void SAL_CALL OTruncatedTransactedFileStream::seek( ::sal_Int64 location ) 610 throw (lang::IllegalArgumentException, io::IOException, uno::RuntimeException) 611 { 612 ::osl::MutexGuard aGuard( m_aMutex ); 613 614 if ( !m_pStreamData ) 615 throw io::NotConnectedException(); 616 617 if ( m_pStreamData->m_bTransacted ) 618 { 619 // temporary stream data should be provided 620 if ( !m_pStreamData->m_xTempSeekable.is() ) 621 throw uno::RuntimeException(); 622 623 m_pStreamData->m_xTempSeekable->seek( location ); 624 } 625 else 626 { 627 // the original stream data should be provided 628 if ( !m_pStreamData->m_xOrigSeekable.is() ) 629 throw uno::RuntimeException(); 630 631 m_pStreamData->m_xOrigSeekable->seek( location ); 632 } 633 } 634 635 636 // ------------------------------------------------------------------------ 637 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getPosition( ) 638 throw (io::IOException, uno::RuntimeException) 639 { 640 ::osl::MutexGuard aGuard( m_aMutex ); 641 642 if ( !m_pStreamData ) 643 throw io::NotConnectedException(); 644 645 if ( m_pStreamData->m_bTransacted ) 646 { 647 // temporary stream data should be provided 648 if ( !m_pStreamData->m_xTempSeekable.is() ) 649 throw uno::RuntimeException(); 650 651 return m_pStreamData->m_xTempSeekable->getPosition(); 652 } 653 else 654 { 655 // the original stream data should be provided 656 if ( !m_pStreamData->m_xOrigSeekable.is() ) 657 throw uno::RuntimeException(); 658 659 return m_pStreamData->m_xOrigSeekable->getPosition(); 660 } 661 } 662 663 664 // ------------------------------------------------------------------------ 665 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getLength( ) 666 throw (io::IOException, uno::RuntimeException) 667 { 668 ::osl::MutexGuard aGuard( m_aMutex ); 669 670 if ( !m_pStreamData ) 671 throw io::NotConnectedException(); 672 673 if ( m_pStreamData->m_bTransacted ) 674 { 675 // temporary stream data should be provided 676 if ( !m_pStreamData->m_xTempSeekable.is() ) 677 throw uno::RuntimeException(); 678 679 return m_pStreamData->m_xTempSeekable->getLength(); 680 } 681 else 682 { 683 // the original stream data should be provided 684 if ( !m_pStreamData->m_xOrigSeekable.is() ) 685 throw uno::RuntimeException(); 686 687 return m_pStreamData->m_xOrigSeekable->getLength(); 688 } 689 } 690 691 // com::sun::star::beans::XPropertySetInfo 692 // ------------------------------------------------------------------------ 693 uno::Sequence< beans::Property > SAL_CALL OTruncatedTransactedFileStream::getProperties() 694 throw (uno::RuntimeException) 695 { 696 ::osl::MutexGuard aGuard( m_aMutex ); 697 698 uno::Sequence< beans::Property > aProps( 1 ); 699 aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 700 aProps[0].Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) ); 701 aProps[0].Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY; 702 703 return aProps; 704 } 705 706 707 // ------------------------------------------------------------------------ 708 beans::Property SAL_CALL OTruncatedTransactedFileStream::getPropertyByName( const ::rtl::OUString& aName ) 709 throw (beans::UnknownPropertyException, uno::RuntimeException) 710 { 711 ::osl::MutexGuard aGuard( m_aMutex ); 712 713 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 714 715 if ( !aName.equals( aTransactionPropName ) ) 716 throw beans::UnknownPropertyException(); 717 718 beans::Property aProp; 719 aProp.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 720 aProp.Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) ); 721 aProp.Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY; 722 723 return aProp; 724 } 725 726 727 // ------------------------------------------------------------------------ 728 ::sal_Bool SAL_CALL OTruncatedTransactedFileStream::hasPropertyByName( const ::rtl::OUString& Name ) 729 throw (uno::RuntimeException) 730 { 731 ::osl::MutexGuard aGuard( m_aMutex ); 732 733 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 734 return ( Name.equals( aTransactionPropName ) ); 735 } 736 737 738 739 // com::sun::star::beans::XPropertySet 740 // ------------------------------------------------------------------------ 741 uno::Reference< beans::XPropertySetInfo > SAL_CALL OTruncatedTransactedFileStream::getPropertySetInfo() 742 throw (uno::RuntimeException) 743 { 744 ::osl::MutexGuard aGuard( m_aMutex ); 745 746 return static_cast< beans::XPropertySetInfo* >( this ); 747 } 748 749 750 // ------------------------------------------------------------------------ 751 void SAL_CALL OTruncatedTransactedFileStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& ) 752 throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 753 { 754 ::osl::MutexGuard aGuard( m_aMutex ); 755 756 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 757 if ( aPropertyName.equals( aTransactionPropName ) ) 758 throw beans::PropertyVetoException(); 759 760 throw beans::UnknownPropertyException(); 761 } 762 763 764 // ------------------------------------------------------------------------ 765 uno::Any SAL_CALL OTruncatedTransactedFileStream::getPropertyValue( const ::rtl::OUString& PropertyName ) 766 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) 767 { 768 ::osl::MutexGuard aGuard( m_aMutex ); 769 770 if ( !m_pStreamData ) 771 throw io::NotConnectedException(); 772 773 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); 774 if ( PropertyName.equals( aTransactionPropName ) ) 775 { 776 uno::Reference< embed::XTransactedObject > xObj; 777 if ( m_pStreamData->m_bTransacted ) 778 xObj = static_cast< embed::XTransactedObject* >( new OTransactionHelper( this ) ); 779 780 return uno::makeAny( xObj ); 781 } 782 783 throw beans::UnknownPropertyException(); 784 } 785 786 787 // ------------------------------------------------------------------------ 788 void SAL_CALL OTruncatedTransactedFileStream::addPropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) 789 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) 790 { 791 // not implemented 792 } 793 794 795 // ------------------------------------------------------------------------ 796 void SAL_CALL OTruncatedTransactedFileStream::removePropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) 797 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) 798 { 799 // not implemented 800 } 801 802 803 // ------------------------------------------------------------------------ 804 void SAL_CALL OTruncatedTransactedFileStream::addVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) 805 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) 806 { 807 // not implemented 808 } 809 810 811 // ------------------------------------------------------------------------ 812 void SAL_CALL OTruncatedTransactedFileStream::removeVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) 813 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) 814 { 815 // not implemented 816 } 817 818 819 } // namespace comphelper 820 821