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