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_svl.hxx" 30 31 #include "ostreamcontainer.hxx" 32 33 34 using namespace ::com::sun::star; 35 36 //----------------------------------------------- 37 OFSStreamContainer::OFSStreamContainer( const uno::Reference < io::XStream >& xStream ) 38 : m_bDisposed( sal_False ) 39 , m_bInputClosed( sal_False ) 40 , m_bOutputClosed( sal_False ) 41 , m_pListenersContainer( NULL ) 42 , m_pTypeCollection( NULL ) 43 { 44 try 45 { 46 m_xStream = xStream; 47 if ( !m_xStream.is() ) 48 throw uno::RuntimeException(); 49 50 m_xSeekable = uno::Reference< io::XSeekable >( xStream, uno::UNO_QUERY ); 51 m_xInputStream = xStream->getInputStream(); 52 m_xOutputStream = xStream->getOutputStream(); 53 m_xTruncate = uno::Reference< io::XTruncate >( m_xOutputStream, uno::UNO_QUERY ); 54 m_xAsyncOutputMonitor = uno::Reference< io::XAsyncOutputMonitor >( m_xOutputStream, uno::UNO_QUERY ); 55 } 56 catch( uno::Exception& ) 57 { 58 m_xStream = uno::Reference< io::XStream >(); 59 m_xSeekable = uno::Reference< io::XSeekable >(); 60 m_xInputStream = uno::Reference< io::XInputStream >(); 61 m_xOutputStream = uno::Reference< io::XOutputStream >(); 62 m_xTruncate = uno::Reference< io::XTruncate >(); 63 m_xAsyncOutputMonitor = uno::Reference< io::XAsyncOutputMonitor >(); 64 } 65 } 66 67 //----------------------------------------------- 68 OFSStreamContainer::~OFSStreamContainer() 69 { 70 if ( m_pListenersContainer ) 71 { 72 delete m_pListenersContainer; 73 m_pListenersContainer = NULL; 74 } 75 } 76 77 // XInterface 78 //----------------------------------------------- 79 uno::Any SAL_CALL OFSStreamContainer::queryInterface( const uno::Type& rType ) 80 throw( uno::RuntimeException ) 81 { 82 uno::Any aReturn; 83 84 aReturn <<= ::cppu::queryInterface 85 ( rType 86 , static_cast<lang::XTypeProvider*> ( this ) 87 , static_cast<io::XStream*> ( this ) 88 , static_cast<embed::XExtendedStorageStream*> ( this ) 89 , static_cast<lang::XComponent*> ( this ) ); 90 91 if ( aReturn.hasValue() == sal_True ) 92 return aReturn ; 93 94 if ( m_xSeekable.is() ) 95 { 96 aReturn <<= ::cppu::queryInterface 97 ( rType 98 , static_cast<io::XSeekable*> ( this ) ); 99 100 if ( aReturn.hasValue() == sal_True ) 101 return aReturn ; 102 } 103 104 if ( m_xInputStream.is() ) 105 { 106 aReturn <<= ::cppu::queryInterface 107 ( rType 108 , static_cast<io::XInputStream*> ( this ) ); 109 110 if ( aReturn.hasValue() == sal_True ) 111 return aReturn ; 112 } 113 if ( m_xOutputStream.is() ) 114 { 115 aReturn <<= ::cppu::queryInterface 116 ( rType 117 , static_cast<io::XOutputStream*> ( this ) ); 118 119 if ( aReturn.hasValue() == sal_True ) 120 return aReturn ; 121 } 122 if ( m_xTruncate.is() ) 123 { 124 aReturn <<= ::cppu::queryInterface 125 ( rType 126 , static_cast<io::XTruncate*> ( this ) ); 127 128 if ( aReturn.hasValue() == sal_True ) 129 return aReturn ; 130 } 131 if ( m_xAsyncOutputMonitor.is() ) 132 { 133 aReturn <<= ::cppu::queryInterface 134 ( rType 135 , static_cast<io::XAsyncOutputMonitor*> ( this ) ); 136 137 if ( aReturn.hasValue() == sal_True ) 138 return aReturn ; 139 } 140 141 return OWeakObject::queryInterface( rType ); 142 } 143 144 //----------------------------------------------- 145 void SAL_CALL OFSStreamContainer::acquire() 146 throw() 147 { 148 OWeakObject::acquire(); 149 } 150 151 //----------------------------------------------- 152 void SAL_CALL OFSStreamContainer::release() 153 throw() 154 { 155 OWeakObject::release(); 156 } 157 158 // XTypeProvider 159 //----------------------------------------------- 160 uno::Sequence< uno::Type > SAL_CALL OFSStreamContainer::getTypes() 161 throw( uno::RuntimeException ) 162 { 163 if ( m_pTypeCollection == NULL ) 164 { 165 ::osl::MutexGuard aGuard( m_aMutex ); 166 167 if ( m_pTypeCollection == NULL ) 168 { 169 ::cppu::OTypeCollection aTypeCollection 170 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL ) 171 , ::getCppuType( ( const uno::Reference< embed::XExtendedStorageStream >* )NULL ) ); 172 173 if ( m_xSeekable.is() ) 174 aTypeCollection = ::cppu::OTypeCollection 175 ( ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL ), 176 aTypeCollection.getTypes() ); 177 if ( m_xInputStream.is() ) 178 aTypeCollection = ::cppu::OTypeCollection 179 ( ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL ), 180 aTypeCollection.getTypes() ); 181 182 if ( m_xOutputStream.is() ) 183 aTypeCollection = ::cppu::OTypeCollection 184 ( ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL ), 185 aTypeCollection.getTypes() ); 186 if ( m_xTruncate.is() ) 187 aTypeCollection = ::cppu::OTypeCollection 188 ( ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL ), 189 aTypeCollection.getTypes() ); 190 if ( m_xAsyncOutputMonitor.is() ) 191 aTypeCollection = ::cppu::OTypeCollection 192 ( ::getCppuType( ( const uno::Reference< io::XAsyncOutputMonitor >* )NULL ), 193 aTypeCollection.getTypes() ); 194 195 m_pTypeCollection = new ::cppu::OTypeCollection( aTypeCollection ); 196 } 197 } 198 return m_pTypeCollection->getTypes() ; 199 } 200 201 //----------------------------------------------- 202 uno::Sequence< sal_Int8 > SAL_CALL OFSStreamContainer::getImplementationId() 203 throw( uno::RuntimeException ) 204 { 205 static ::cppu::OImplementationId* pID = NULL ; 206 207 if ( pID == NULL ) 208 { 209 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; 210 211 if ( pID == NULL ) 212 { 213 static ::cppu::OImplementationId aID( sal_False ) ; 214 pID = &aID ; 215 } 216 } 217 218 return pID->getImplementationId() ; 219 } 220 221 // XStream 222 //----------------------------------------------- 223 uno::Reference< io::XInputStream > SAL_CALL OFSStreamContainer::getInputStream() 224 throw ( uno::RuntimeException ) 225 { 226 ::osl::MutexGuard aGuard( m_aMutex ); 227 228 if ( m_bDisposed ) 229 throw lang::DisposedException(); 230 231 if ( !m_xStream.is() ) 232 throw uno::RuntimeException(); 233 234 if ( m_xInputStream.is() ) 235 return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ) ); 236 237 return uno::Reference< io::XInputStream >(); 238 } 239 240 //----------------------------------------------- 241 uno::Reference< io::XOutputStream > SAL_CALL OFSStreamContainer::getOutputStream() 242 throw ( uno::RuntimeException ) 243 { 244 ::osl::MutexGuard aGuard( m_aMutex ); 245 246 if ( m_bDisposed ) 247 throw lang::DisposedException(); 248 249 if ( !m_xStream.is() ) 250 throw uno::RuntimeException(); 251 252 if ( m_xOutputStream.is() ) 253 return uno::Reference< io::XOutputStream >( static_cast< io::XOutputStream* >( this ) ); 254 255 return uno::Reference< io::XOutputStream >(); 256 } 257 258 // XComponent 259 //----------------------------------------------- 260 void SAL_CALL OFSStreamContainer::dispose() 261 throw ( uno::RuntimeException ) 262 { 263 ::osl::MutexGuard aGuard( m_aMutex ); 264 265 if ( m_bDisposed ) 266 throw lang::DisposedException(); 267 268 if ( !m_xStream.is() ) 269 throw uno::RuntimeException(); 270 271 if ( m_xInputStream.is() && !m_bInputClosed ) 272 { 273 m_xInputStream->closeInput(); 274 m_bInputClosed = sal_True; 275 } 276 277 if ( m_xOutputStream.is() && !m_bOutputClosed ) 278 { 279 m_xOutputStream->closeOutput(); 280 m_bOutputClosed = sal_True; 281 } 282 283 if ( m_pListenersContainer ) 284 { 285 lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>( this ) ); 286 m_pListenersContainer->disposeAndClear( aSource ); 287 } 288 289 m_bDisposed = sal_True; 290 } 291 292 //----------------------------------------------- 293 void SAL_CALL OFSStreamContainer::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) 294 throw ( uno::RuntimeException ) 295 { 296 ::osl::MutexGuard aGuard( m_aMutex ); 297 298 if ( m_bDisposed ) 299 throw lang::DisposedException(); 300 301 if ( !m_pListenersContainer ) 302 m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex ); 303 304 m_pListenersContainer->addInterface( xListener ); 305 } 306 307 //----------------------------------------------- 308 void SAL_CALL OFSStreamContainer::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) 309 throw ( uno::RuntimeException ) 310 { 311 ::osl::MutexGuard aGuard( m_aMutex ); 312 313 if ( m_bDisposed ) 314 throw lang::DisposedException(); 315 316 if ( m_pListenersContainer ) 317 m_pListenersContainer->removeInterface( xListener ); 318 } 319 320 321 // XSeekable 322 //----------------------------------------------- 323 void SAL_CALL OFSStreamContainer::seek( sal_Int64 location ) 324 throw ( lang::IllegalArgumentException, 325 io::IOException, 326 uno::RuntimeException ) 327 { 328 ::osl::MutexGuard aGuard( m_aMutex ); 329 330 if ( m_bDisposed ) 331 throw lang::DisposedException(); 332 333 if ( !m_xStream.is() || !m_xSeekable.is() ) 334 throw uno::RuntimeException(); 335 336 m_xSeekable->seek( location ); 337 } 338 339 //----------------------------------------------- 340 sal_Int64 SAL_CALL OFSStreamContainer::getPosition() 341 throw ( io::IOException, 342 uno::RuntimeException ) 343 { 344 ::osl::MutexGuard aGuard( m_aMutex ); 345 346 if ( m_bDisposed ) 347 throw lang::DisposedException(); 348 349 if ( !m_xStream.is() || !m_xSeekable.is() ) 350 throw uno::RuntimeException(); 351 352 return m_xSeekable->getPosition(); 353 } 354 355 //----------------------------------------------- 356 sal_Int64 SAL_CALL OFSStreamContainer::getLength() 357 throw ( io::IOException, 358 uno::RuntimeException ) 359 { 360 ::osl::MutexGuard aGuard( m_aMutex ); 361 362 if ( m_bDisposed ) 363 throw lang::DisposedException(); 364 365 if ( !m_xStream.is() || !m_xSeekable.is() ) 366 throw uno::RuntimeException(); 367 368 return m_xSeekable->getLength(); 369 } 370 371 372 // XInputStream 373 //----------------------------------------------- 374 sal_Int32 SAL_CALL OFSStreamContainer::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) 375 throw( io::NotConnectedException, 376 io::BufferSizeExceededException, 377 io::IOException, 378 uno::RuntimeException ) 379 { 380 ::osl::MutexGuard aGuard( m_aMutex ); 381 382 if ( m_bDisposed ) 383 throw lang::DisposedException(); 384 385 if ( !m_xStream.is() || !m_xInputStream.is() ) 386 throw uno::RuntimeException(); 387 388 return m_xInputStream->readBytes( aData, nBytesToRead ); 389 } 390 391 //----------------------------------------------- 392 sal_Int32 SAL_CALL OFSStreamContainer::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) 393 throw( io::NotConnectedException, 394 io::BufferSizeExceededException, 395 io::IOException, 396 uno::RuntimeException ) 397 { 398 ::osl::MutexGuard aGuard( m_aMutex ); 399 400 if ( m_bDisposed ) 401 throw lang::DisposedException(); 402 403 if ( !m_xStream.is() || !m_xInputStream.is() ) 404 throw uno::RuntimeException(); 405 406 return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead ); 407 } 408 409 //----------------------------------------------- 410 void SAL_CALL OFSStreamContainer::skipBytes( sal_Int32 nBytesToSkip ) 411 throw( io::NotConnectedException, 412 io::BufferSizeExceededException, 413 io::IOException, 414 uno::RuntimeException ) 415 { 416 ::osl::MutexGuard aGuard( m_aMutex ); 417 418 if ( m_bDisposed ) 419 throw lang::DisposedException(); 420 421 if ( !m_xStream.is() || !m_xInputStream.is() ) 422 throw uno::RuntimeException(); 423 424 m_xInputStream->skipBytes( nBytesToSkip ); 425 } 426 427 //----------------------------------------------- 428 sal_Int32 SAL_CALL OFSStreamContainer::available() 429 throw( io::NotConnectedException, 430 io::IOException, 431 uno::RuntimeException ) 432 { 433 ::osl::MutexGuard aGuard( m_aMutex ); 434 435 if ( m_bDisposed ) 436 throw lang::DisposedException(); 437 438 if ( !m_xStream.is() || !m_xInputStream.is() ) 439 throw uno::RuntimeException(); 440 441 return m_xInputStream->available(); 442 } 443 444 //----------------------------------------------- 445 void SAL_CALL OFSStreamContainer::closeInput() 446 throw( io::NotConnectedException, 447 io::IOException, 448 uno::RuntimeException ) 449 { 450 ::osl::MutexGuard aGuard( m_aMutex ); 451 452 if ( m_bDisposed ) 453 throw lang::DisposedException(); 454 455 if ( !m_xStream.is() || !m_xInputStream.is() ) 456 throw uno::RuntimeException(); 457 458 if ( m_xInputStream.is() ) 459 { 460 m_xInputStream->closeInput(); 461 m_bInputClosed = sal_True; 462 } 463 464 if ( m_bOutputClosed ) 465 dispose(); 466 } 467 468 // XOutputStream 469 //----------------------------------------------- 470 void SAL_CALL OFSStreamContainer::writeBytes( const uno::Sequence< sal_Int8 >& aData ) 471 throw ( io::NotConnectedException, 472 io::BufferSizeExceededException, 473 io::IOException, 474 uno::RuntimeException ) 475 { 476 ::osl::MutexGuard aGuard( m_aMutex ); 477 478 if ( m_bDisposed ) 479 throw lang::DisposedException(); 480 481 if ( !m_xStream.is() || !m_xOutputStream.is() ) 482 throw uno::RuntimeException(); 483 484 return m_xOutputStream->writeBytes( aData ); 485 } 486 487 //----------------------------------------------- 488 void SAL_CALL OFSStreamContainer::flush() 489 throw ( io::NotConnectedException, 490 io::BufferSizeExceededException, 491 io::IOException, 492 uno::RuntimeException ) 493 { 494 ::osl::MutexGuard aGuard( m_aMutex ); 495 496 if ( m_bDisposed ) 497 throw lang::DisposedException(); 498 499 if ( !m_xStream.is() || !m_xOutputStream.is() ) 500 throw uno::RuntimeException(); 501 502 return m_xOutputStream->flush(); 503 } 504 505 //----------------------------------------------- 506 void SAL_CALL OFSStreamContainer::closeOutput() 507 throw ( io::NotConnectedException, 508 io::BufferSizeExceededException, 509 io::IOException, 510 uno::RuntimeException ) 511 { 512 ::osl::MutexGuard aGuard( m_aMutex ); 513 514 if ( m_bDisposed ) 515 throw lang::DisposedException(); 516 517 if ( !m_xStream.is() || !m_xOutputStream.is() ) 518 throw uno::RuntimeException(); 519 520 if ( m_xOutputStream.is() ) 521 { 522 m_xOutputStream->closeOutput(); 523 m_bOutputClosed = sal_True; 524 } 525 526 if ( m_bInputClosed ) 527 dispose(); 528 } 529 530 531 // XTruncate 532 //----------------------------------------------- 533 void SAL_CALL OFSStreamContainer::truncate() 534 throw ( io::IOException, 535 uno::RuntimeException ) 536 { 537 ::osl::MutexGuard aGuard( m_aMutex ); 538 539 if ( m_bDisposed ) 540 throw lang::DisposedException(); 541 542 if ( !m_xStream.is() || !m_xTruncate.is() ) 543 throw uno::RuntimeException(); 544 545 m_xTruncate->truncate(); 546 } 547 548 549 // XAsyncOutputMonitor 550 //----------------------------------------------- 551 void SAL_CALL OFSStreamContainer::waitForCompletion() 552 throw ( io::IOException, 553 uno::RuntimeException ) 554 { 555 ::osl::MutexGuard aGuard( m_aMutex ); 556 557 if ( m_bDisposed ) 558 throw lang::DisposedException(); 559 560 if ( !m_xStream.is() || !m_xAsyncOutputMonitor.is() ) 561 throw uno::RuntimeException(); 562 563 m_xAsyncOutputMonitor->waitForCompletion(); 564 } 565 566 567 568