Coverage Report

Created: 2026-07-10 11:04

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