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 "oinputstreamcontainer.hxx"
32 #include <cppuhelper/typeprovider.hxx>
33 
34 using namespace ::com::sun::star;
35 
36 //-----------------------------------------------
37 OFSInputStreamContainer::OFSInputStreamContainer( const uno::Reference< io::XInputStream >& xStream )
38 : m_xInputStream( xStream )
39 , m_xSeekable( xStream, uno::UNO_QUERY )
40 , m_bSeekable( sal_False )
41 , m_bDisposed( sal_False )
42 , m_pListenersContainer( NULL )
43 {
44 	m_bSeekable = m_xSeekable.is();
45 }
46 
47 //-----------------------------------------------
48 OFSInputStreamContainer::~OFSInputStreamContainer()
49 {
50 	if ( m_pListenersContainer )
51 	{
52 		delete m_pListenersContainer;
53 		m_pListenersContainer = NULL;
54 	}
55 }
56 
57 //-----------------------------------------------
58 uno::Sequence< uno::Type > SAL_CALL OFSInputStreamContainer::getTypes()
59 		throw ( uno::RuntimeException )
60 {
61 	static ::cppu::OTypeCollection* pTypeCollection = NULL ;
62 
63 	if ( pTypeCollection == NULL )
64 	{
65 		::osl::MutexGuard aGuard( m_aMutex ) ;
66 
67 		if ( pTypeCollection == NULL )
68 		{
69 			if ( m_bSeekable )
70 			{
71 				static ::cppu::OTypeCollection aTypeCollection(
72             			::getCppuType(( const uno::Reference< io::XStream >* )NULL ),
73             			::getCppuType(( const uno::Reference< io::XInputStream >* )NULL ),
74             			::getCppuType(( const uno::Reference< io::XSeekable >* )NULL ) );
75 
76 				pTypeCollection = &aTypeCollection ;
77 			}
78 			else
79 			{
80 				static ::cppu::OTypeCollection aTypeCollection(
81             			::getCppuType(( const uno::Reference< io::XStream >* )NULL ),
82             			::getCppuType(( const uno::Reference< io::XInputStream >* )NULL ) );
83 
84 				pTypeCollection = &aTypeCollection ;
85 			}
86 		}
87 	}
88 
89 	return pTypeCollection->getTypes() ;
90 
91 }
92 
93 //-----------------------------------------------
94 uno::Any SAL_CALL OFSInputStreamContainer::queryInterface( const uno::Type& rType )
95 		throw( uno::RuntimeException )
96 {
97 	// Attention:
98 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
99 
100 	uno::Any aReturn;
101 	if ( m_bSeekable )
102 		aReturn = uno::Any( ::cppu::queryInterface( rType,
103 									   	static_cast< io::XStream* >( this ),
104 									   	static_cast< io::XInputStream* >( this ),
105 									   	static_cast< io::XSeekable* >( this ) ) );
106 	else
107 		aReturn = uno::Any( ::cppu::queryInterface( rType,
108 									   	static_cast< io::XStream* >( this ),
109 									   	static_cast< io::XInputStream* >( this ) ) );
110 
111 	if ( aReturn.hasValue() == sal_True )
112 		return aReturn ;
113 
114 	return ::cppu::OWeakObject::queryInterface( rType ) ;
115 }
116 
117 //-----------------------------------------------
118 void SAL_CALL OFSInputStreamContainer::acquire()
119 		throw()
120 {
121 	::cppu::OWeakObject::acquire();
122 }
123 
124 //-----------------------------------------------
125 void SAL_CALL OFSInputStreamContainer::release()
126 		throw()
127 {
128 	::cppu::OWeakObject::release();
129 }
130 
131 //-----------------------------------------------
132 sal_Int32 SAL_CALL OFSInputStreamContainer::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
133 		throw ( io::NotConnectedException,
134 				io::BufferSizeExceededException,
135 				io::IOException,
136 				uno::RuntimeException )
137 {
138 	::osl::MutexGuard aGuard( m_aMutex );
139 
140 	if ( m_bDisposed )
141 		throw lang::DisposedException();
142 
143 	if ( !m_xInputStream.is() )
144 		throw uno::RuntimeException();
145 
146 	return m_xInputStream->readBytes( aData, nBytesToRead );
147 }
148 
149 //-----------------------------------------------
150 sal_Int32 SAL_CALL OFSInputStreamContainer::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
151 		throw ( io::NotConnectedException,
152 				io::BufferSizeExceededException,
153 				io::IOException,
154 				uno::RuntimeException )
155 {
156 	::osl::MutexGuard aGuard( m_aMutex );
157 
158 	if ( m_bDisposed )
159 		throw lang::DisposedException();
160 
161 	if ( !m_xInputStream.is() )
162 		throw uno::RuntimeException();
163 
164 	return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead );
165 }
166 
167 //-----------------------------------------------
168 void SAL_CALL OFSInputStreamContainer::skipBytes( sal_Int32 nBytesToSkip )
169 		throw ( io::NotConnectedException,
170 				io::BufferSizeExceededException,
171 				io::IOException,
172 				uno::RuntimeException )
173 {
174 	::osl::MutexGuard aGuard( m_aMutex );
175 
176 	if ( m_bDisposed )
177 		throw lang::DisposedException();
178 
179 	if ( !m_xInputStream.is() )
180 		throw uno::RuntimeException();
181 
182 	m_xInputStream->skipBytes( nBytesToSkip );
183 }
184 
185 //-----------------------------------------------
186 sal_Int32 SAL_CALL OFSInputStreamContainer::available(  )
187 		throw ( io::NotConnectedException,
188 				io::IOException,
189 				uno::RuntimeException )
190 {
191 	::osl::MutexGuard aGuard( m_aMutex );
192 
193 	if ( m_bDisposed )
194 		throw lang::DisposedException();
195 
196 	if ( !m_xInputStream.is() )
197 		throw uno::RuntimeException();
198 
199 	return m_xInputStream->available();
200 }
201 
202 //-----------------------------------------------
203 void SAL_CALL OFSInputStreamContainer::closeInput(  )
204 		throw ( io::NotConnectedException,
205 				io::IOException,
206 				uno::RuntimeException )
207 {
208 	::osl::MutexGuard aGuard( m_aMutex );
209 
210 	if ( m_bDisposed )
211 		throw lang::DisposedException();
212 
213 	if ( !m_xInputStream.is() )
214 		throw uno::RuntimeException();
215 
216 	dispose();
217 }
218 
219 //-----------------------------------------------
220 uno::Reference< io::XInputStream > SAL_CALL OFSInputStreamContainer::getInputStream()
221 		throw ( uno::RuntimeException )
222 {
223 	::osl::MutexGuard aGuard( m_aMutex );
224 
225 	if ( m_bDisposed )
226 		throw lang::DisposedException();
227 
228 	if ( !m_xInputStream.is() )
229 		return uno::Reference< io::XInputStream >();
230 
231 	return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ), uno::UNO_QUERY );
232 }
233 
234 //-----------------------------------------------
235 uno::Reference< io::XOutputStream > SAL_CALL OFSInputStreamContainer::getOutputStream()
236 		throw ( uno::RuntimeException )
237 {
238 	::osl::MutexGuard aGuard( m_aMutex );
239 
240 	if ( m_bDisposed )
241 		throw lang::DisposedException();
242 
243 	return uno::Reference< io::XOutputStream >();
244 }
245 
246 //-----------------------------------------------
247 void SAL_CALL OFSInputStreamContainer::seek( sal_Int64 location )
248 		throw ( lang::IllegalArgumentException,
249 				io::IOException,
250 				uno::RuntimeException )
251 {
252 	::osl::MutexGuard aGuard( m_aMutex );
253 
254 	if ( m_bDisposed )
255 		throw lang::DisposedException();
256 
257 	if ( !m_xSeekable.is() )
258 		throw uno::RuntimeException();
259 
260 	m_xSeekable->seek( location );
261 }
262 
263 //-----------------------------------------------
264 sal_Int64 SAL_CALL OFSInputStreamContainer::getPosition()
265 		throw ( io::IOException,
266 				uno::RuntimeException)
267 {
268 	::osl::MutexGuard aGuard( m_aMutex );
269 
270 	if ( m_bDisposed )
271 		throw lang::DisposedException();
272 
273 	if ( !m_xSeekable.is() )
274 		throw uno::RuntimeException();
275 
276 	return m_xSeekable->getPosition();
277 }
278 
279 //-----------------------------------------------
280 sal_Int64 SAL_CALL OFSInputStreamContainer::getLength()
281 		throw ( io::IOException,
282 				uno::RuntimeException )
283 {
284 	::osl::MutexGuard aGuard( m_aMutex );
285 
286 	if ( m_bDisposed )
287 		throw lang::DisposedException();
288 
289 	if ( !m_xSeekable.is() )
290 		throw uno::RuntimeException();
291 
292 	return m_xSeekable->getLength();
293 }
294 
295 //-----------------------------------------------
296 void SAL_CALL OFSInputStreamContainer::dispose(  )
297 		throw ( uno::RuntimeException )
298 {
299 	::osl::MutexGuard aGuard( m_aMutex );
300 
301 	if ( m_bDisposed )
302 		throw lang::DisposedException();
303 
304 	if ( !m_xInputStream.is() )
305 		throw uno::RuntimeException();
306 
307 	m_xInputStream->closeInput();
308 
309 	if ( m_pListenersContainer )
310 	{
311     	lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>( this ) );
312 		m_pListenersContainer->disposeAndClear( aSource );
313 	}
314 
315 	m_bDisposed = sal_True;
316 }
317 
318 //-----------------------------------------------
319 void SAL_CALL OFSInputStreamContainer::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
320 		throw ( uno::RuntimeException )
321 {
322 	::osl::MutexGuard aGuard( m_aMutex );
323 
324 	if ( m_bDisposed )
325 		throw lang::DisposedException();
326 
327 	if ( !m_pListenersContainer )
328 		m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
329 
330 	m_pListenersContainer->addInterface( xListener );
331 }
332 
333 //-----------------------------------------------
334 void SAL_CALL OFSInputStreamContainer::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
335 		throw ( uno::RuntimeException )
336 {
337 	::osl::MutexGuard aGuard( m_aMutex );
338 
339 	if ( m_bDisposed )
340 		throw lang::DisposedException();
341 
342 	if ( m_pListenersContainer )
343 		m_pListenersContainer->removeInterface( xListener );
344 }
345 
346 
347 
348