LibreOffice Module svl (master) 1
ostreamcontainer.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "ostreamcontainer.hxx"
21
24
25
26using namespace ::com::sun::star;
27
28OFSStreamContainer::OFSStreamContainer( const uno::Reference < io::XStream >& xStream )
29: m_bDisposed( false )
30, m_bInputClosed( false )
31, m_bOutputClosed( false )
32{
33 try
34 {
36 if ( !m_xStream.is() )
37 throw uno::RuntimeException();
38
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 );
44 }
45 catch( uno::Exception& )
46 {
47 m_xStream.clear();
48 m_xSeekable.clear();
49 m_xInputStream.clear();
50 m_xOutputStream.clear();
51 m_xTruncate.clear();
53 }
54}
55
57{
58}
59
60// XInterface
62{
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 ) );
69
70 if ( aReturn.hasValue() )
71 return aReturn ;
72
73 if ( m_xSeekable.is() )
74 {
75 aReturn = ::cppu::queryInterface
76 ( rType
77 , static_cast<io::XSeekable*> ( this ) );
78
79 if ( aReturn.hasValue() )
80 return aReturn ;
81 }
82
83 if ( m_xInputStream.is() )
84 {
85 aReturn = ::cppu::queryInterface
86 ( rType
87 , static_cast<io::XInputStream*> ( this ) );
88
89 if ( aReturn.hasValue() )
90 return aReturn ;
91 }
92 if ( m_xOutputStream.is() )
93 {
94 aReturn = ::cppu::queryInterface
95 ( rType
96 , static_cast<io::XOutputStream*> ( this ) );
97
98 if ( aReturn.hasValue() )
99 return aReturn ;
100 }
101 if ( m_xTruncate.is() )
102 {
103 aReturn = ::cppu::queryInterface
104 ( rType
105 , static_cast<io::XTruncate*> ( this ) );
106
107 if ( aReturn.hasValue() )
108 return aReturn ;
109 }
110 if ( m_xAsyncOutputMonitor.is() )
111 {
112 aReturn = ::cppu::queryInterface
113 ( rType
114 , static_cast<io::XAsyncOutputMonitor*> ( this ) );
115
116 if ( aReturn.hasValue() )
117 return aReturn ;
118 }
119
120 return OWeakObject::queryInterface( rType );
121}
122
124 noexcept
125{
126 OWeakObject::acquire();
127}
128
130 noexcept
131{
132 OWeakObject::release();
133}
134
135// XTypeProvider
136uno::Sequence< uno::Type > SAL_CALL OFSStreamContainer::getTypes()
137{
138 if ( !m_aTypes.hasElements() )
139 {
140 std::scoped_lock aGuard( m_aMutex );
141
142 if ( !m_aTypes.hasElements() )
143 {
144 std::vector<uno::Type> tmp
145 {
148 };
149
150 if ( m_xSeekable.is() )
151 tmp.push_back(cppu::UnoType<io::XSeekable>::get());
152 if ( m_xInputStream.is() )
154 if ( m_xOutputStream.is() )
156 if ( m_xTruncate.is() )
157 tmp.push_back(cppu::UnoType<io::XTruncate>::get());
158 if ( m_xAsyncOutputMonitor.is() )
160
162 }
163 }
164 return m_aTypes;
165}
166
167uno::Sequence< sal_Int8 > SAL_CALL OFSStreamContainer::getImplementationId()
168{
169 return css::uno::Sequence<sal_Int8>();
170}
171
172// XStream
173uno::Reference< io::XInputStream > SAL_CALL OFSStreamContainer::getInputStream()
174{
175 std::scoped_lock aGuard( m_aMutex );
176
177 if ( m_bDisposed )
178 throw lang::DisposedException();
179
180 if ( !m_xStream.is() )
181 throw uno::RuntimeException();
182
183 if ( m_xInputStream.is() )
184 return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ) );
185
186 return uno::Reference< io::XInputStream >();
187}
188
189uno::Reference< io::XOutputStream > SAL_CALL OFSStreamContainer::getOutputStream()
190{
191 std::scoped_lock aGuard( m_aMutex );
192
193 if ( m_bDisposed )
194 throw lang::DisposedException();
195
196 if ( !m_xStream.is() )
197 throw uno::RuntimeException();
198
199 if ( m_xOutputStream.is() )
200 return uno::Reference< io::XOutputStream >( static_cast< io::XOutputStream* >( this ) );
201
202 return uno::Reference< io::XOutputStream >();
203}
204
205// XComponent
207{
208 std::unique_lock aGuard( m_aMutex );
209
210 if ( m_bDisposed )
211 return;
212
213 if ( !m_xStream.is() )
214 throw uno::RuntimeException();
215
216 if ( m_xInputStream.is() && !m_bInputClosed )
217 {
218 m_xInputStream->closeInput();
219 m_bInputClosed = true;
220 }
221
222 if ( m_xOutputStream.is() && !m_bOutputClosed )
223 {
224 m_xOutputStream->closeOutput();
225 m_bOutputClosed = true;
226 }
227
228 lang::EventObject aSource( getXWeak() );
229 m_aListenersContainer.disposeAndClear( aGuard, aSource );
230 m_bDisposed = true;
231}
232
233void SAL_CALL OFSStreamContainer::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
234{
235 std::unique_lock aGuard( m_aMutex );
236
237 if ( m_bDisposed )
238 throw lang::DisposedException();
239
240 m_aListenersContainer.addInterface( aGuard, xListener );
241}
242
243void SAL_CALL OFSStreamContainer::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
244{
245 std::unique_lock aGuard( m_aMutex );
246
247 if ( m_bDisposed )
248 throw lang::DisposedException();
249
250 m_aListenersContainer.removeInterface( aGuard, xListener );
251}
252
253
254// XSeekable
255void SAL_CALL OFSStreamContainer::seek( sal_Int64 location )
256{
257 std::scoped_lock aGuard( m_aMutex );
258
259 if ( m_bDisposed )
260 throw lang::DisposedException();
261
262 if ( !m_xStream.is() || !m_xSeekable.is() )
263 throw uno::RuntimeException();
264
265 m_xSeekable->seek( location );
266}
267
269{
270 std::scoped_lock aGuard( m_aMutex );
271
272 if ( m_bDisposed )
273 throw lang::DisposedException();
274
275 if ( !m_xStream.is() || !m_xSeekable.is() )
276 throw uno::RuntimeException();
277
278 return m_xSeekable->getPosition();
279}
280
282{
283 std::scoped_lock aGuard( m_aMutex );
284
285 if ( m_bDisposed )
286 throw lang::DisposedException();
287
288 if ( !m_xStream.is() || !m_xSeekable.is() )
289 throw uno::RuntimeException();
290
291 return m_xSeekable->getLength();
292}
293
294
295// XInputStream
296sal_Int32 SAL_CALL OFSStreamContainer::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
297{
298 std::scoped_lock aGuard( m_aMutex );
299
300 if ( m_bDisposed )
301 throw lang::DisposedException();
302
303 if ( !m_xStream.is() || !m_xInputStream.is() )
304 throw uno::RuntimeException();
305
306 return m_xInputStream->readBytes( aData, nBytesToRead );
307}
308
309sal_Int32 SAL_CALL OFSStreamContainer::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
310{
311 std::scoped_lock aGuard( m_aMutex );
312
313 if ( m_bDisposed )
314 throw lang::DisposedException();
315
316 if ( !m_xStream.is() || !m_xInputStream.is() )
317 throw uno::RuntimeException();
318
319 return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead );
320}
321
322void SAL_CALL OFSStreamContainer::skipBytes( sal_Int32 nBytesToSkip )
323{
324 std::scoped_lock aGuard( m_aMutex );
325
326 if ( m_bDisposed )
327 throw lang::DisposedException();
328
329 if ( !m_xStream.is() || !m_xInputStream.is() )
330 throw uno::RuntimeException();
331
332 m_xInputStream->skipBytes( nBytesToSkip );
333}
334
336{
337 std::scoped_lock aGuard( m_aMutex );
338
339 if ( m_bDisposed )
340 throw lang::DisposedException();
341
342 if ( !m_xStream.is() || !m_xInputStream.is() )
343 throw uno::RuntimeException();
344
345 return m_xInputStream->available();
346}
347
349{
350 {
351 std::scoped_lock aGuard( m_aMutex );
352
353 if ( m_bDisposed )
354 throw lang::DisposedException();
355
356 if ( !m_xStream.is() || !m_xInputStream.is() )
357 throw uno::RuntimeException();
358
359 if ( m_xInputStream.is() )
360 {
361 m_xInputStream->closeInput();
362 m_bInputClosed = true;
363 }
364 if ( !m_bOutputClosed )
365 return;
366 }
367
368 dispose();
369}
370
371// XOutputStream
372void SAL_CALL OFSStreamContainer::writeBytes( const uno::Sequence< sal_Int8 >& aData )
373{
374 std::scoped_lock aGuard( m_aMutex );
375
376 if ( m_bDisposed )
377 throw lang::DisposedException();
378
379 if ( !m_xStream.is() || !m_xOutputStream.is() )
380 throw uno::RuntimeException();
381
382 return m_xOutputStream->writeBytes( aData );
383}
384
386{
387 std::scoped_lock aGuard( m_aMutex );
388
389 if ( m_bDisposed )
390 throw lang::DisposedException();
391
392 if ( !m_xStream.is() || !m_xOutputStream.is() )
393 throw uno::RuntimeException();
394
395 return m_xOutputStream->flush();
396}
397
399{
400 {
401 std::scoped_lock aGuard( m_aMutex );
402
403 if ( m_bDisposed )
404 throw lang::DisposedException();
405
406 if ( !m_xStream.is() || !m_xOutputStream.is() )
407 throw uno::RuntimeException();
408
409 if ( m_xOutputStream.is() )
410 {
411 m_xOutputStream->closeOutput();
412 m_bOutputClosed = true;
413 }
414 if ( !m_bInputClosed )
415 return;
416 }
417 dispose();
418}
419
420
421// XTruncate
423{
424 std::scoped_lock aGuard( m_aMutex );
425
426 if ( m_bDisposed )
427 throw lang::DisposedException();
428
429 if ( !m_xStream.is() || !m_xTruncate.is() )
430 throw uno::RuntimeException();
431
432 m_xTruncate->truncate();
433}
434
435
436// XAsyncOutputMonitor
438{
439 std::scoped_lock aGuard( m_aMutex );
440
441 if ( m_bDisposed )
442 throw lang::DisposedException();
443
444 if ( !m_xStream.is() || !m_xAsyncOutputMonitor.is() )
445 throw uno::RuntimeException();
446
447 m_xAsyncOutputMonitor->waitForCompletion();
448}
449
450
451/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
css::uno::Reference< css::io::XAsyncOutputMonitor > m_xAsyncOutputMonitor
css::uno::Reference< css::io::XOutputStream > m_xOutputStream
virtual void SAL_CALL closeInput() override
OFSStreamContainer(const css::uno::Reference< css::io::XStream > &xStream)
virtual void SAL_CALL release() noexcept override
virtual css::uno::Reference< css::io::XOutputStream > SAL_CALL getOutputStream() override
::comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_aListenersContainer
virtual sal_Int64 SAL_CALL getPosition() override
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getInputStream() override
virtual void SAL_CALL flush() override
css::uno::Reference< css::io::XInputStream > m_xInputStream
virtual sal_Int32 SAL_CALL available() override
virtual ~OFSStreamContainer() override
virtual sal_Int32 SAL_CALL readSomeBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nMaxBytesToRead) override
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
virtual void SAL_CALL acquire() noexcept override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
virtual void SAL_CALL writeBytes(const css::uno::Sequence< sal_Int8 > &aData) override
virtual void SAL_CALL dispose() override
css::uno::Reference< css::io::XTruncate > m_xTruncate
virtual void SAL_CALL closeOutput() override
virtual sal_Int64 SAL_CALL getLength() override
css::uno::Reference< css::io::XSeekable > m_xSeekable
virtual void SAL_CALL waitForCompletion() override
virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override
virtual void SAL_CALL truncate() override
virtual void SAL_CALL seek(sal_Int64 location) override
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
css::uno::Sequence< css::uno::Type > m_aTypes
css::uno::Reference< css::io::XStream > m_xStream
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
virtual sal_Int32 SAL_CALL readBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nBytesToRead) override
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
css::uno::Type const & get()
bool m_bDisposed
constexpr OUStringLiteral aData
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
bool hasValue()