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