Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/unotools/source/streaming/streamwrap.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 <sal/config.h>
21
22
#include <com/sun/star/io/BufferSizeExceededException.hpp>
23
#include <com/sun/star/io/NotConnectedException.hpp>
24
#include <o3tl/safeint.hxx>
25
#include <unotools/streamwrap.hxx>
26
#include <tools/stream.hxx>
27
28
namespace utl
29
{
30
31
using namespace ::com::sun::star::uno;
32
using namespace ::com::sun::star::io;
33
using namespace ::com::sun::star::lang;
34
35
OInputStreamWrapper::OInputStreamWrapper( SvStream& _rStream )
36
15.1k
                 :m_pSvStream(&_rStream)
37
15.1k
                 ,m_bSvStreamOwner(false)
38
15.1k
{
39
15.1k
}
40
41
OInputStreamWrapper::OInputStreamWrapper( SvStream* pStream, bool bOwner )
42
18
                 :m_pSvStream( pStream )
43
18
                 ,m_bSvStreamOwner( bOwner )
44
18
{
45
18
}
46
47
OInputStreamWrapper::OInputStreamWrapper( std::unique_ptr<SvStream> pStream )
48
0
                 :m_pSvStream( pStream.release() )
49
0
                 ,m_bSvStreamOwner( true )
50
0
{
51
0
}
52
53
OInputStreamWrapper::~OInputStreamWrapper()
54
244k
{
55
244k
    if( m_bSvStreamOwner )
56
0
        delete m_pSvStream;
57
244k
}
58
59
sal_Int32 SAL_CALL OInputStreamWrapper::readBytes(css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
60
858k
{
61
858k
    checkConnected();
62
63
858k
    if (nBytesToRead < 0)
64
0
        throw css::io::BufferSizeExceededException(OUString(), getXWeak());
65
66
858k
    std::scoped_lock aGuard( m_aMutex );
67
68
858k
    if (aData.getLength() < nBytesToRead)
69
213k
        aData.realloc(nBytesToRead);
70
71
858k
    sal_uInt32 nRead = m_pSvStream->ReadBytes(static_cast<void*>(aData.getArray()), nBytesToRead);
72
858k
    checkError();
73
74
    // If read characters < MaxLength, adjust css::uno::Sequence
75
858k
    if (nRead < o3tl::make_unsigned(aData.getLength()))
76
153k
        aData.realloc( nRead );
77
78
858k
    return nRead;
79
858k
}
80
81
sal_Int32 OInputStreamWrapper::readSomeBytes(sal_Int8* pData, sal_Int32 nBytesToRead)
82
2.36M
{
83
2.36M
    checkConnected();
84
85
2.36M
    if (nBytesToRead < 0)
86
0
        throw css::io::BufferSizeExceededException(OUString(), getXWeak());
87
88
2.36M
    std::scoped_lock aGuard( m_aMutex );
89
90
2.36M
    sal_uInt32 nRead = m_pSvStream->ReadBytes(static_cast<void*>(pData), nBytesToRead);
91
2.36M
    checkError();
92
93
2.36M
    return nRead;
94
2.36M
}
95
96
sal_Int32 SAL_CALL OInputStreamWrapper::readSomeBytes(css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
97
276k
{
98
276k
    checkError();
99
100
276k
    if (nMaxBytesToRead < 0)
101
0
        throw css::io::BufferSizeExceededException(OUString(), getXWeak());
102
103
276k
    if (m_pSvStream->eof())
104
113k
    {
105
113k
        aData.realloc(0);
106
113k
        return 0;
107
113k
    }
108
163k
    else
109
163k
        return readBytes(aData, nMaxBytesToRead);
110
276k
}
111
112
void SAL_CALL OInputStreamWrapper::skipBytes(sal_Int32 nBytesToSkip)
113
20.8k
{
114
20.8k
    std::scoped_lock aGuard( m_aMutex );
115
20.8k
    checkError();
116
117
20.8k
    m_pSvStream->SeekRel(nBytesToSkip);
118
20.8k
    checkError();
119
20.8k
}
120
121
sal_Int32 SAL_CALL OInputStreamWrapper::available()
122
0
{
123
0
    std::scoped_lock aGuard( m_aMutex );
124
0
    checkConnected();
125
126
0
    sal_Int64 nAvailable = m_pSvStream->remainingSize();
127
0
    checkError();
128
129
0
    return std::min<sal_Int64>(SAL_MAX_INT32, nAvailable);
130
0
}
131
132
void SAL_CALL OInputStreamWrapper::closeInput()
133
63.2k
{
134
63.2k
    std::scoped_lock aGuard( m_aMutex );
135
63.2k
    if (m_pSvStream)
136
63.2k
    {
137
63.2k
        if (m_bSvStreamOwner)
138
0
            delete m_pSvStream;
139
140
63.2k
        m_pSvStream = nullptr;
141
63.2k
    }
142
63.2k
}
143
144
void OInputStreamWrapper::checkConnected() const
145
13.9M
{
146
13.9M
    if (!m_pSvStream)
147
0
        throw css::io::NotConnectedException(OUString(), const_cast<OInputStreamWrapper*>(this)->getXWeak());
148
13.9M
}
149
150
void OInputStreamWrapper::checkError() const
151
7.12M
{
152
7.12M
    checkConnected();
153
154
7.12M
    auto const e = m_pSvStream->SvStream::GetError();
155
7.12M
    if (e != ERRCODE_NONE)
156
        // TODO: really evaluate the error
157
0
        throw css::io::NotConnectedException("utl::OInputStreamWrapper error " + e.toString(), const_cast<OInputStreamWrapper*>(this)->getXWeak());
158
7.12M
}
159
160
//= OSeekableInputStreamWrapper
161
162
229k
OSeekableInputStreamWrapper::~OSeekableInputStreamWrapper() = default;
163
164
OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream& _rStream)
165
212k
{
166
212k
    SetStream( &_rStream, false );
167
212k
}
168
169
OSeekableInputStreamWrapper::OSeekableInputStreamWrapper(SvStream* _pStream, bool _bOwner)
170
8
{
171
8
    SetStream( _pStream, _bOwner );
172
8
}
173
174
void SAL_CALL OSeekableInputStreamWrapper::seek( sal_Int64 _nLocation )
175
1.69M
{
176
1.69M
    std::scoped_lock aGuard( m_aMutex );
177
1.69M
    checkConnected();
178
179
1.69M
    m_pSvStream->Seek(static_cast<sal_uInt64>(_nLocation));
180
1.69M
    checkError();
181
1.69M
}
182
183
sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getPosition(  )
184
958k
{
185
958k
    std::scoped_lock aGuard( m_aMutex );
186
958k
    checkConnected();
187
188
958k
    sal_uInt64 nPos = m_pSvStream->Tell();
189
958k
    checkError();
190
958k
    return static_cast<sal_Int64>(nPos);
191
958k
}
192
193
sal_Int64 SAL_CALL OSeekableInputStreamWrapper::getLength(  )
194
935k
{
195
935k
    std::scoped_lock aGuard( m_aMutex );
196
935k
    checkConnected();
197
198
935k
    checkError();
199
200
935k
    sal_Int64 nEndPos = m_pSvStream->TellEnd();
201
202
935k
    return nEndPos;
203
935k
}
204
205
//= OOutputStreamWrapper
206
207
OOutputStreamWrapper::OOutputStreamWrapper(SvStream& _rStream):
208
307
    rStream(_rStream)
209
307
{}
210
211
307
OOutputStreamWrapper::~OOutputStreamWrapper() {}
212
213
void SAL_CALL OOutputStreamWrapper::writeBytes(const css::uno::Sequence< sal_Int8 >& aData)
214
284
{
215
284
    sal_uInt32 nWritten = rStream.WriteBytes(aData.getConstArray(), aData.getLength());
216
284
    ErrCode err = rStream.GetError();
217
284
    if  (   (ERRCODE_NONE != err)
218
284
        ||  (nWritten != static_cast<sal_uInt32>(aData.getLength()))
219
284
        )
220
0
    {
221
0
        throw css::io::BufferSizeExceededException(OUString(), getXWeak());
222
0
    }
223
284
}
224
225
void SAL_CALL OOutputStreamWrapper::flush()
226
0
{
227
0
    rStream.FlushBuffer();
228
0
    checkError();
229
0
}
230
231
void SAL_CALL OOutputStreamWrapper::closeOutput()
232
266
{
233
266
}
234
235
void OOutputStreamWrapper::checkError() const
236
0
{
237
0
    if (rStream.GetError() != ERRCODE_NONE)
238
        // TODO: really evaluate the error
239
0
        throw css::io::NotConnectedException(OUString(), const_cast<OOutputStreamWrapper*>(this)->getXWeak());
240
0
}
241
242
//= OSeekableOutputStreamWrapper
243
244
OSeekableOutputStreamWrapper::OSeekableOutputStreamWrapper(SvStream& _rStream)
245
0
    :OOutputStreamWrapper(_rStream)
246
0
{
247
0
}
248
249
0
OSeekableOutputStreamWrapper::~OSeekableOutputStreamWrapper() {}
250
251
Any SAL_CALL OSeekableOutputStreamWrapper::queryInterface( const Type& _rType )
252
0
{
253
0
    Any aReturn = OOutputStreamWrapper::queryInterface(_rType);
254
0
    if (!aReturn.hasValue())
255
0
        aReturn = OSeekableOutputStreamWrapper_Base::queryInterface(_rType);
256
0
    return aReturn;
257
0
}
258
259
void SAL_CALL OSeekableOutputStreamWrapper::seek( sal_Int64 _nLocation )
260
0
{
261
0
    rStream.Seek(static_cast<sal_uInt32>(_nLocation));
262
0
    checkError();
263
0
}
264
265
sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getPosition(  )
266
0
{
267
0
    sal_uInt64 nPos = rStream.Tell();
268
0
    checkError();
269
0
    return static_cast<sal_Int64>(nPos);
270
0
}
271
272
sal_Int64 SAL_CALL OSeekableOutputStreamWrapper::getLength(  )
273
0
{
274
0
    checkError();
275
276
0
    sal_Int64 nEndPos = rStream.TellEnd();
277
278
0
    return nEndPos;
279
0
}
280
281
16.9k
OStreamWrapper::~OStreamWrapper() = default;
282
283
OStreamWrapper::OStreamWrapper(SvStream& _rStream)
284
16.2k
{
285
16.2k
    SetStream( &_rStream, false );
286
16.2k
}
287
288
OStreamWrapper::OStreamWrapper(std::unique_ptr<SvStream> pStream)
289
0
{
290
0
    SetStream( pStream.release(), true );
291
0
}
292
293
OStreamWrapper::OStreamWrapper(SvStream* pStream, bool bOwner)
294
751
{
295
751
    SetStream( pStream, bOwner );
296
751
}
297
298
css::uno::Reference< css::io::XInputStream > SAL_CALL OStreamWrapper::getInputStream(  )
299
8
{
300
8
    return this;
301
8
}
302
303
css::uno::Reference< css::io::XOutputStream > SAL_CALL OStreamWrapper::getOutputStream(  )
304
139
{
305
139
    return this;
306
139
}
307
308
void SAL_CALL OStreamWrapper::writeBytes(const css::uno::Sequence< sal_Int8 >& aData)
309
5.55k
{
310
5.55k
    sal_uInt32 nWritten = m_pSvStream->WriteBytes(aData.getConstArray(), aData.getLength());
311
5.55k
    ErrCode err = m_pSvStream->GetError();
312
5.55k
    if  (   (ERRCODE_NONE != err)
313
5.55k
        ||  (nWritten != static_cast<sal_uInt32>(aData.getLength()))
314
5.55k
        )
315
0
    {
316
0
        throw css::io::BufferSizeExceededException(OUString(), getXWeak());
317
0
    }
318
5.55k
}
319
320
void SAL_CALL OStreamWrapper::flush()
321
4
{
322
4
    m_pSvStream->FlushBuffer();
323
4
    if (m_pSvStream->GetError() != ERRCODE_NONE)
324
0
        throw css::io::NotConnectedException(OUString(), getXWeak());
325
4
}
326
327
void SAL_CALL OStreamWrapper::closeOutput()
328
4.39k
{
329
4.39k
}
330
331
void SAL_CALL OStreamWrapper::truncate()
332
0
{
333
0
    m_pSvStream->SetStreamSize(0);
334
0
}
335
336
} // namespace utl
337
338
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */