cid#1636690 Dereference after null check
[LibreOffice.git] / svl / source / fsstor / ostreamcontainer.cxx
blob78a168f04b49e3a17c723160411c63363d6a6144
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ostreamcontainer.hxx"
22 #include <cppuhelper/queryinterface.hxx>
23 #include <comphelper/sequence.hxx>
26 using namespace ::com::sun::star;
28 OFSStreamContainer::OFSStreamContainer( const uno::Reference < io::XStream >& xStream )
29 : m_bDisposed( false )
30 , m_bInputClosed( false )
31 , m_bOutputClosed( false )
33 try
35 m_xStream = xStream;
36 if ( !m_xStream.is() )
37 throw uno::RuntimeException();
39 m_xSeekable.set( xStream, uno::UNO_QUERY );
40 m_xInputStream = xStream->getInputStream();
41 m_xOutputStream = xStream->getOutputStream();
42 m_xTruncate.set( m_xOutputStream, uno::UNO_QUERY );
43 m_xAsyncOutputMonitor.set( m_xOutputStream, uno::UNO_QUERY );
45 catch( uno::Exception& )
47 m_xStream.clear();
48 m_xSeekable.clear();
49 m_xInputStream.clear();
50 m_xOutputStream.clear();
51 m_xTruncate.clear();
52 m_xAsyncOutputMonitor.clear();
56 OFSStreamContainer::~OFSStreamContainer()
60 // XInterface
61 uno::Any SAL_CALL OFSStreamContainer::queryInterface( const uno::Type& rType )
63 uno::Any aReturn = ::cppu::queryInterface
64 ( rType
65 , static_cast<lang::XTypeProvider*> ( this )
66 , static_cast<io::XStream*> ( this )
67 , static_cast<embed::XExtendedStorageStream*> ( this )
68 , static_cast<lang::XComponent*> ( this ) );
70 if ( aReturn.hasValue() )
71 return aReturn ;
73 if ( m_xSeekable.is() )
75 aReturn = ::cppu::queryInterface
76 ( rType
77 , static_cast<io::XSeekable*> ( this ) );
79 if ( aReturn.hasValue() )
80 return aReturn ;
83 if ( m_xInputStream.is() )
85 aReturn = ::cppu::queryInterface
86 ( rType
87 , static_cast<io::XInputStream*> ( this ) );
89 if ( aReturn.hasValue() )
90 return aReturn ;
92 if ( m_xOutputStream.is() )
94 aReturn = ::cppu::queryInterface
95 ( rType
96 , static_cast<io::XOutputStream*> ( this ) );
98 if ( aReturn.hasValue() )
99 return aReturn ;
101 if ( m_xTruncate.is() )
103 aReturn = ::cppu::queryInterface
104 ( rType
105 , static_cast<io::XTruncate*> ( this ) );
107 if ( aReturn.hasValue() )
108 return aReturn ;
110 if ( m_xAsyncOutputMonitor.is() )
112 aReturn = ::cppu::queryInterface
113 ( rType
114 , static_cast<io::XAsyncOutputMonitor*> ( this ) );
116 if ( aReturn.hasValue() )
117 return aReturn ;
120 return OWeakObject::queryInterface( rType );
123 void SAL_CALL OFSStreamContainer::acquire()
124 noexcept
126 OWeakObject::acquire();
129 void SAL_CALL OFSStreamContainer::release()
130 noexcept
132 OWeakObject::release();
135 // XTypeProvider
136 uno::Sequence< uno::Type > SAL_CALL OFSStreamContainer::getTypes()
138 std::scoped_lock aGuard( m_aMutex );
139 if ( !m_aTypes.hasElements() )
141 std::vector<uno::Type> tmp
143 cppu::UnoType<lang::XTypeProvider>::get(),
144 cppu::UnoType<embed::XExtendedStorageStream>::get()
147 if ( m_xSeekable.is() )
148 tmp.push_back(cppu::UnoType<io::XSeekable>::get());
149 if ( m_xInputStream.is() )
150 tmp.push_back(cppu::UnoType<io::XInputStream>::get());
151 if ( m_xOutputStream.is() )
152 tmp.push_back(cppu::UnoType<io::XOutputStream>::get());
153 if ( m_xTruncate.is() )
154 tmp.push_back(cppu::UnoType<io::XTruncate>::get());
155 if ( m_xAsyncOutputMonitor.is() )
156 tmp.push_back(cppu::UnoType<io::XAsyncOutputMonitor>::get());
158 m_aTypes = comphelper::containerToSequence(tmp);
160 return m_aTypes;
163 uno::Sequence< sal_Int8 > SAL_CALL OFSStreamContainer::getImplementationId()
165 return css::uno::Sequence<sal_Int8>();
168 // XStream
169 uno::Reference< io::XInputStream > SAL_CALL OFSStreamContainer::getInputStream()
171 std::scoped_lock aGuard( m_aMutex );
173 if ( m_bDisposed )
174 throw lang::DisposedException();
176 if ( !m_xStream.is() )
177 throw uno::RuntimeException();
179 if ( m_xInputStream.is() )
180 return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ) );
182 return uno::Reference< io::XInputStream >();
185 uno::Reference< io::XOutputStream > SAL_CALL OFSStreamContainer::getOutputStream()
187 std::scoped_lock aGuard( m_aMutex );
189 if ( m_bDisposed )
190 throw lang::DisposedException();
192 if ( !m_xStream.is() )
193 throw uno::RuntimeException();
195 if ( m_xOutputStream.is() )
196 return uno::Reference< io::XOutputStream >( static_cast< io::XOutputStream* >( this ) );
198 return uno::Reference< io::XOutputStream >();
201 // XComponent
202 void SAL_CALL OFSStreamContainer::dispose()
204 std::unique_lock aGuard( m_aMutex );
206 if ( m_bDisposed )
207 return;
209 if ( !m_xStream.is() )
210 throw uno::RuntimeException();
212 if ( m_xInputStream.is() && !m_bInputClosed )
214 m_xInputStream->closeInput();
215 m_bInputClosed = true;
218 if ( m_xOutputStream.is() && !m_bOutputClosed )
220 m_xOutputStream->closeOutput();
221 m_bOutputClosed = true;
224 lang::EventObject aSource( getXWeak() );
225 m_aListenersContainer.disposeAndClear( aGuard, aSource );
226 m_bDisposed = true;
229 void SAL_CALL OFSStreamContainer::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
231 std::unique_lock aGuard( m_aMutex );
233 if ( m_bDisposed )
234 throw lang::DisposedException();
236 m_aListenersContainer.addInterface( aGuard, xListener );
239 void SAL_CALL OFSStreamContainer::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
241 std::unique_lock aGuard( m_aMutex );
243 if ( m_bDisposed )
244 throw lang::DisposedException();
246 m_aListenersContainer.removeInterface( aGuard, xListener );
250 // XSeekable
251 void SAL_CALL OFSStreamContainer::seek( sal_Int64 location )
253 std::scoped_lock aGuard( m_aMutex );
255 if ( m_bDisposed )
256 throw lang::DisposedException();
258 if ( !m_xStream.is() || !m_xSeekable.is() )
259 throw uno::RuntimeException();
261 m_xSeekable->seek( location );
264 sal_Int64 SAL_CALL OFSStreamContainer::getPosition()
266 std::scoped_lock aGuard( m_aMutex );
268 if ( m_bDisposed )
269 throw lang::DisposedException();
271 if ( !m_xStream.is() || !m_xSeekable.is() )
272 throw uno::RuntimeException();
274 return m_xSeekable->getPosition();
277 sal_Int64 SAL_CALL OFSStreamContainer::getLength()
279 std::scoped_lock aGuard( m_aMutex );
281 if ( m_bDisposed )
282 throw lang::DisposedException();
284 if ( !m_xStream.is() || !m_xSeekable.is() )
285 throw uno::RuntimeException();
287 return m_xSeekable->getLength();
291 // XInputStream
292 sal_Int32 SAL_CALL OFSStreamContainer::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
294 std::scoped_lock aGuard( m_aMutex );
296 if ( m_bDisposed )
297 throw lang::DisposedException();
299 if ( !m_xStream.is() || !m_xInputStream.is() )
300 throw uno::RuntimeException();
302 return m_xInputStream->readBytes( aData, nBytesToRead );
305 sal_Int32 SAL_CALL OFSStreamContainer::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
307 std::scoped_lock aGuard( m_aMutex );
309 if ( m_bDisposed )
310 throw lang::DisposedException();
312 if ( !m_xStream.is() || !m_xInputStream.is() )
313 throw uno::RuntimeException();
315 return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead );
318 void SAL_CALL OFSStreamContainer::skipBytes( sal_Int32 nBytesToSkip )
320 std::scoped_lock aGuard( m_aMutex );
322 if ( m_bDisposed )
323 throw lang::DisposedException();
325 if ( !m_xStream.is() || !m_xInputStream.is() )
326 throw uno::RuntimeException();
328 m_xInputStream->skipBytes( nBytesToSkip );
331 sal_Int32 SAL_CALL OFSStreamContainer::available()
333 std::scoped_lock aGuard( m_aMutex );
335 if ( m_bDisposed )
336 throw lang::DisposedException();
338 if ( !m_xStream.is() || !m_xInputStream.is() )
339 throw uno::RuntimeException();
341 return m_xInputStream->available();
344 void SAL_CALL OFSStreamContainer::closeInput()
347 std::scoped_lock aGuard( m_aMutex );
349 if ( m_bDisposed )
350 throw lang::DisposedException();
352 if ( !m_xStream.is() || !m_xInputStream.is() )
353 throw uno::RuntimeException();
355 if ( m_xInputStream.is() )
357 m_xInputStream->closeInput();
358 m_bInputClosed = true;
360 if ( !m_bOutputClosed )
361 return;
364 dispose();
367 // XOutputStream
368 void SAL_CALL OFSStreamContainer::writeBytes( const uno::Sequence< sal_Int8 >& aData )
370 std::scoped_lock aGuard( m_aMutex );
372 if ( m_bDisposed )
373 throw lang::DisposedException();
375 if ( !m_xStream.is() || !m_xOutputStream.is() )
376 throw uno::RuntimeException();
378 return m_xOutputStream->writeBytes( aData );
381 void SAL_CALL OFSStreamContainer::flush()
383 std::scoped_lock aGuard( m_aMutex );
385 if ( m_bDisposed )
386 throw lang::DisposedException();
388 if ( !m_xStream.is() || !m_xOutputStream.is() )
389 throw uno::RuntimeException();
391 return m_xOutputStream->flush();
394 void SAL_CALL OFSStreamContainer::closeOutput()
397 std::scoped_lock aGuard( m_aMutex );
399 if ( m_bDisposed )
400 throw lang::DisposedException();
402 if ( !m_xStream.is() || !m_xOutputStream.is() )
403 throw uno::RuntimeException();
405 if ( m_xOutputStream.is() )
407 m_xOutputStream->closeOutput();
408 m_bOutputClosed = true;
410 if ( !m_bInputClosed )
411 return;
413 dispose();
417 // XTruncate
418 void SAL_CALL OFSStreamContainer::truncate()
420 std::scoped_lock aGuard( m_aMutex );
422 if ( m_bDisposed )
423 throw lang::DisposedException();
425 if ( !m_xStream.is() || !m_xTruncate.is() )
426 throw uno::RuntimeException();
428 m_xTruncate->truncate();
432 // XAsyncOutputMonitor
433 void SAL_CALL OFSStreamContainer::waitForCompletion()
435 std::scoped_lock aGuard( m_aMutex );
437 if ( m_bDisposed )
438 throw lang::DisposedException();
440 if ( !m_xStream.is() || !m_xAsyncOutputMonitor.is() )
441 throw uno::RuntimeException();
443 m_xAsyncOutputMonitor->waitForCompletion();
447 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */