Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/tools/stream.hxx
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
#pragma once
20
21
#include <config_options.h>
22
#include <tools/toolsdllapi.h>
23
#include <tools/lineend.hxx>
24
#include <tools/long.hxx>
25
#include <tools/ref.hxx>
26
#include <comphelper/errcode.hxx>
27
#include <rtl/string.hxx>
28
#include <rtl/strbuf.hxx>
29
#include <o3tl/typed_flags_set.hxx>
30
#include <memory>
31
#include <string_view>
32
33
inline rtl_TextEncoding GetStoreCharSet( rtl_TextEncoding eEncoding )
34
764
{
35
764
    if ( eEncoding == RTL_TEXTENCODING_ISO_8859_1 )
36
0
        return RTL_TEXTENCODING_MS_1252;
37
764
    else
38
764
        return eEncoding;
39
764
}
40
41
// StreamTypes
42
43
// read, write, create,... options
44
enum class StreamMode {
45
    NONE                     = 0x0000,
46
    READ                     = 0x0001,  ///< allow read accesses
47
    WRITE                    = 0x0002,  ///< allow write accesses
48
// file i/o
49
    NOCREATE                 = 0x0004,  ///< 1 == Don't create file
50
    TRUNC                    = 0x0008,  ///< Truncate _existing_ file to zero length
51
    COPY_ON_SYMLINK          = 0x0010,  ///< copy-on-write for symlinks (Unix-only)
52
    TEMPORARY                = 0x0020,  ///< temporary file attribute (Windows-only)
53
    DELETE_ON_CLOSE          = 0x0040,  ///< only for temporary files (Windows-only)
54
// sharing options
55
    SHARE_DENYNONE           = 0x0100,
56
    SHARE_DENYREAD           = 0x0200,  // overrides denynone
57
    SHARE_DENYWRITE          = 0x0400,  // overrides denynone
58
    SHARE_DENYALL            = 0x0800,  // overrides denyread,write,none
59
// masks
60
    READWRITE                = READ | WRITE,
61
    STD_READ                 = READ | SHARE_DENYNONE | NOCREATE,
62
    STD_WRITE                = WRITE | SHARE_DENYALL,
63
    STD_READWRITE            = READWRITE | SHARE_DENYALL
64
};
65
namespace o3tl
66
{
67
    template<> struct typed_flags<StreamMode> : is_typed_flags<StreamMode, 0x0f7f> {};
68
}
69
70
654k
#define STREAM_SEEK_TO_BEGIN            0L
71
346M
#define STREAM_SEEK_TO_END              SAL_MAX_UINT64
72
73
enum class SvStreamEndian { BIG, LITTLE };
74
75
enum class SvStreamCompressFlags {
76
    NONE     = 0x0000,
77
    ZBITMAP  = 0x0001,
78
    NATIVE   = 0x0010,
79
};
80
namespace o3tl
81
{
82
    template<> struct typed_flags<SvStreamCompressFlags> : is_typed_flags<SvStreamCompressFlags, 0x0011> {};
83
}
84
85
class SvStream;
86
87
typedef SvStream& (*SvStrPtr)( SvStream& );
88
89
inline SvStream& operator<<( SvStream& rStr, SvStrPtr f );
90
91
// SvLockBytes
92
93
struct SvLockBytesStat
94
{
95
    std::size_t nSize;
96
97
3.51M
    SvLockBytesStat() : nSize(0) {}
98
};
99
100
/** This is only extended by UcbLockBytes in ucb/ and appears to exist
101
to allow UCB to do delayed feeding of data into a SvStream i.e. a kind of a pipe
102
mechanism to allow asynchronous fetching of data.
103
*/
104
class UNLESS_MERGELIBS(TOOLS_DLLPUBLIC) SvLockBytes: public SvRefBase
105
{
106
    bool m_bSync;
107
108
protected:
109
    void close();
110
111
public:
112
113
144k
    SvLockBytes() : m_bSync(false) {}
114
115
    virtual ~SvLockBytes() override;
116
117
206k
    void            SetSynchronMode(bool bTheSync = true) { m_bSync = bTheSync; }
118
43.6M
    bool            IsSynchronMode() const { return m_bSync; }
119
120
    virtual ErrCode ReadAt(sal_uInt64 nPos, void * pBuffer, std::size_t nCount,
121
                           std::size_t * pRead) const;
122
    virtual ErrCode WriteAt(sal_uInt64 nPos, const void * pBuffer, std::size_t nCount,
123
                            std::size_t * pWritten);
124
125
    virtual ErrCode Flush() const;
126
127
    virtual ErrCode SetSize(sal_uInt64 nSize);
128
129
    virtual ErrCode Stat(SvLockBytesStat * pStat) const;
130
};
131
132
typedef tools::SvRef<SvLockBytes> SvLockBytesRef;
133
134
// SvStream
135
136
class TOOLS_DLLPUBLIC SvStream
137
{
138
private:
139
    // LockBytes Interface
140
    SvLockBytesRef  m_xLockBytes; ///< Default implementation
141
    sal_uInt64      m_nActPos;
142
143
    // buffer management
144
    std::unique_ptr<sal_uInt8[]>
145
                    m_pRWBuf;     ///< Points to read/write buffer
146
    sal_uInt8*      m_pBufPos;    ///< m_pRWBuf + m_nBufActualPos
147
    sal_uInt16      m_nBufSize;   ///< Allocated size of buffer
148
    sal_uInt16      m_nBufActualLen; ///< Length of used segment of buffer
149
                                  ///< = m_nBufSize, if EOF did not occur
150
    sal_uInt16      m_nBufActualPos; ///< current position in buffer (0..m_nBufSize-1)
151
    sal_uInt16      m_nBufFree;   ///< number of free slots in buffer to IO of type eIOMode
152
    bool            m_isIoRead;
153
    bool            m_isIoWrite;
154
155
    // Error codes, conversion, compression, ...
156
    bool            m_isDirty;  ///< true: Stream != buffer content
157
    bool            m_isSwap;
158
    bool            m_isEof;
159
    ErrCode         m_nError;
160
    SvStreamCompressFlags m_nCompressMode;
161
    LineEnd         m_eLineDelimiter;
162
    rtl_TextEncoding m_eStreamCharSet;
163
164
    // Encryption
165
    OString m_aCryptMaskKey;// aCryptMaskKey.getLength != 0  -> Encryption used
166
    unsigned char   m_nCryptMask;
167
168
    // Userdata
169
    sal_Int32       m_nVersion;   // for external use
170
171
                    SvStream ( const SvStream& rStream ) = delete;
172
    SvStream&       operator=( const SvStream& rStream ) = delete;
173
174
protected:
175
    sal_uInt64      m_nBufFilePos; ///< File position of pBuf[0]
176
    StreamMode      m_eStreamMode;
177
    bool            m_isWritable;
178
179
    virtual std::size_t GetData( void* pData, std::size_t nSize );
180
    virtual std::size_t PutData( const void* pData, std::size_t nSize );
181
    virtual sal_uInt64 SeekPos( sal_uInt64 nPos );
182
    virtual void    FlushData();
183
    virtual void    SetSize(sal_uInt64 nSize);
184
185
    SAL_DLLPRIVATE void ClearError();
186
    SAL_DLLPRIVATE void ClearBuffer();
187
188
    // encrypt and write in blocks
189
    SAL_DLLPRIVATE std::size_t CryptAndWriteBuffer( const void* pStart, std::size_t nLen );
190
    SAL_DLLPRIVATE void EncryptBuffer( void* pStart, std::size_t nLen ) const;
191
192
public:
193
                    SvStream();
194
                    SvStream( SvLockBytes *pLockBytes);
195
    virtual         ~SvStream();
196
197
23.7k
    SvLockBytes*    GetLockBytes() const { return m_xLockBytes.get(); }
198
199
888M
    ErrCode         GetError() const { return m_nError.IgnoreWarning(); }
200
1.46M
    ErrCode const & GetErrorCode() const { return m_nError; }
201
    void            SetError( ErrCode nErrorCode );
202
    virtual void    ResetError();
203
204
    void            SetEndian( SvStreamEndian SvStreamEndian );
205
    SvStreamEndian  GetEndian() const;
206
    /// returns status of endian swap flag
207
261k
    bool            IsEndianSwap() const { return m_isSwap; }
208
    /// sets native endianness
209
24.8k
    void            ResetEndianSwap() { m_isSwap = false; }
210
211
    void            SetCompressMode( SvStreamCompressFlags nNewMode )
212
0
                        { m_nCompressMode = nNewMode; }
213
5.02k
    SvStreamCompressFlags GetCompressMode() const { return m_nCompressMode; }
214
215
    void SetCryptMaskKey(const OString& rCryptMaskKey);
216
217
    void            SetStreamCharSet( rtl_TextEncoding eCharSet )
218
70.4k
                        { m_eStreamCharSet = eCharSet; }
219
4.69M
    rtl_TextEncoding GetStreamCharSet() const { return m_eStreamCharSet; }
220
221
    void            SetLineDelimiter( LineEnd eLineEnd )
222
0
                        { m_eLineDelimiter = eLineEnd; }
223
0
    LineEnd         GetLineDelimiter() const { return m_eLineDelimiter; }
224
225
    SvStream&       ReadUInt16( sal_uInt16& rUInt16 );
226
    SvStream&       ReadUInt32( sal_uInt32& rUInt32 );
227
    SvStream&       ReadUInt64( sal_uInt64& rUInt64 );
228
    SvStream&       ReadInt16( sal_Int16& rInt16 );
229
    SvStream&       ReadInt32( sal_Int32& rInt32 );
230
    SvStream&       ReadInt64(sal_Int64 & rInt64);
231
    SvStream&       ReadSChar( signed char& rChar );
232
    SvStream&       ReadChar( char& rChar );
233
    SvStream&       ReadUChar( unsigned char& rChar );
234
    SvStream&       ReadUtf16( sal_Unicode& rUtf16 );
235
    SvStream&       ReadCharAsBool( bool& rBool );
236
    SvStream&       ReadFloat( float& rFloat );
237
    SvStream&       ReadDouble( double& rDouble );
238
    SvStream&       ReadStream( SvStream& rStream );
239
240
    SvStream&       WriteUInt16( sal_uInt16 nUInt16 );
241
    SvStream&       WriteUInt32( sal_uInt32 nUInt32 );
242
    SvStream&       WriteUInt64( sal_uInt64 nuInt64 );
243
    SvStream&       WriteInt16( sal_Int16 nInt16 );
244
    SvStream&       WriteInt32( sal_Int32 nInt32 );
245
    SvStream&       WriteInt64( sal_Int64 nInt64 );
246
    SvStream&       WriteUInt8( sal_uInt8 nuInt8 );
247
    SvStream&       WriteUnicode( sal_Unicode );
248
    SvStream&       WriteOString(std::string_view rStr)
249
75.7k
                        { WriteBytes(rStr.data(), rStr.size()); return *this; }
250
    SvStream&       WriteStream( SvStream& rStream );
251
    sal_uInt64      WriteStream( SvStream& rStream, sal_uInt64 nSize );
252
253
    SvStream&       WriteBool( bool b )
254
16.3k
                        { return WriteUChar(static_cast<unsigned char>(b)); }
255
    SvStream&       WriteSChar( signed char nChar );
256
    SvStream&       WriteChar( char nChar );
257
    SvStream&       WriteUChar( unsigned char nChar );
258
    SvStream&       WriteFloat( float nFloat );
259
    SvStream&       WriteDouble( double nDouble );
260
261
    template <typename N>
262
0
    SvStream&       WriteNumberAsString( N n ) { return WriteOString(OString::number(n)); }
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<int>(int)
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<long>(long)
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<double>(double)
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<unsigned int>(unsigned int)
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<unsigned long>(unsigned long)
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<unsigned short>(unsigned short)
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<unsigned char>(unsigned char)
Unexecuted instantiation: SvStream& SvStream::WriteNumberAsString<short>(short)
263
264
    std::size_t     ReadBytes( void* pData, std::size_t nSize );
265
    std::size_t     WriteBytes( const void* pData, std::size_t nSize );
266
    sal_uInt64      Seek( sal_uInt64 nPos );
267
    sal_uInt64      SeekRel( sal_Int64 nPos );
268
659M
    sal_uInt64      Tell() const { return m_nBufFilePos + m_nBufActualPos;  }
269
    virtual sal_uInt64 TellEnd();
270
    // length between current (Tell()) pos and end of stream
271
    sal_uInt64      remainingSize();
272
    /// If we have data in our internal buffers, write them out
273
    void            FlushBuffer();
274
    /// Call FlushBuffer() and then call flush on the underlying OS stream
275
    void            Flush();
276
    // next Tell() <= nSize
277
    bool            SetStreamSize( sal_uInt64 nSize );
278
279
    /** Read a line of bytes.
280
281
        @param nMaxBytesToRead
282
                   Maximum of bytes to read, if line is longer it will be
283
                   truncated.
284
285
        @note NOTE that the default is one character less than STRING_MAXLEN to
286
              prevent problems after conversion to String that may be lurking
287
              in various places doing something like
288
              @code
289
                for (sal_uInt16 i=0; i < aString.Len(); ++i)
290
              @endcode
291
              causing endless loops ...
292
    */
293
    bool            ReadLine( OStringBuffer& rStr, sal_Int32 nMaxBytesToRead = 0xFFFE );
294
    bool            ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead = 0xFFFE );
295
    bool            WriteLine( std::string_view rStr );
296
297
    /** Read a line of bytes.
298
299
        @param nMaxBytesToRead
300
                   Maximum of bytes to read, if line is longer it will be
301
                   truncated.
302
303
        @note NOTE that the default is one character less than STRING_MAXLEN to
304
              prevent problems after conversion to String that may be lurking
305
              in various places doing something like
306
              @code
307
                for (sal_uInt16 i=0; i < aString.Len(); ++i)
308
              @endcode
309
              causing endless loops ...
310
    */
311
    bool            ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
312
                                        sal_Int32 nMaxBytesToRead = 0xFFFE );
313
    bool            WriteByteStringLine( std::u16string_view rStr, rtl_TextEncoding eDestCharSet );
314
315
    /// Switch to no endian swapping and write 0xfeff
316
    void            StartWritingUnicodeText();
317
318
    /** If eReadBomCharSet==RTL_TEXTENCODING_DONTKNOW: read 16bit, if 0xfeff do
319
        nothing (UTF-16), if 0xfffe switch endian swapping (UTF-16), if 0xefbb
320
        or 0xbbef read another byte and check for UTF-8. If no UTF-* BOM was
321
        detected put all read bytes back. This means that if 2 bytes were read
322
        it was an UTF-16 BOM, if 3 bytes were read it was an UTF-8 BOM. There
323
        is no UTF-7, UTF-32 or UTF-EBCDIC BOM detection!
324
325
        If eReadBomCharSet!=RTL_TEXTENCODING_DONTKNOW: only read a BOM of that
326
        encoding and switch endian swapping if UTF-16 and 0xfffe. */
327
    void            StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet );
328
329
    /** Read a line of Unicode.
330
331
        @param nMaxCodepointsToRead
332
                   Maximum of codepoints (UCS-2 or UTF-16 pairs, not bytes) to
333
                   read, if line is longer it will be truncated.
334
    */
335
    SAL_DLLPRIVATE bool ReadUniStringLine(OUString& rStr, sal_Int32 nMaxCodepointsToRead);
336
    /** Read a 32bit length prefixed sequence of utf-16 if
337
        eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise read a 16bit length
338
        prefixed sequence of bytes and convert from eSrcCharSet */
339
    OUString        ReadUniOrByteString(rtl_TextEncoding eSrcCharSet);
340
    /** Write a 32bit length prefixed sequence of utf-16 if
341
        eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise convert to eSrcCharSet
342
        and write a 16bit length prefixed sequence of bytes */
343
    SvStream&       WriteUniOrByteString( std::u16string_view rStr, rtl_TextEncoding eDestCharSet );
344
345
    /** Read a line of Unicode if eSrcCharSet==RTL_TEXTENCODING_UNICODE,
346
        otherwise read a line of Bytecode and convert from eSrcCharSet
347
348
        @param nMaxCodepointsToRead
349
                   Maximum of codepoints (2 bytes if Unicode, bytes if not
350
                   Unicode) to read, if line is longer it will be truncated.
351
352
        @note NOTE that the default is one character less than STRING_MAXLEN to
353
              prevent problems after conversion to String that may be lurking in
354
              various places doing something like
355
              @code
356
                for (sal_uInt16 i=0; i < aString.Len(); ++i)
357
              @endcode
358
              causing endless loops ...
359
    */
360
    bool            ReadUniOrByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
361
                                             sal_Int32 nMaxCodepointsToRead = 0xFFFE );
362
    /** Write a sequence of Unicode characters if
363
        eDestCharSet==RTL_TEXTENCODING_UNICODE, otherwise write a sequence of
364
        Bytecodes converted to eDestCharSet. Write trailing zero, if bZero is true. */
365
    bool            WriteUnicodeOrByteText(std::u16string_view rStr, rtl_TextEncoding eDestCharSet, bool bZero = false);
366
    bool            WriteUnicodeOrByteText(std::u16string_view rStr)
367
46.6k
                    { return WriteUnicodeOrByteText(rStr, GetStreamCharSet(), /*bZero*/false); }
368
369
    /** Write a Unicode character if eDestCharSet==RTL_TEXTENCODING_UNICODE,
370
        otherwise write as Bytecode converted to eDestCharSet.
371
372
        This may result in more than one byte being written if a multi byte
373
        encoding (e.g. UTF7, UTF8) is chosen. */
374
    bool            WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet );
375
    bool            WriteUniOrByteChar( sal_Unicode ch )
376
0
                    { return WriteUniOrByteChar( ch, GetStreamCharSet() ); }
377
378
    void            SetBufferSize( sal_uInt16 m_nBufSize );
379
15.2k
    sal_uInt16      GetBufferSize() const { return m_nBufSize; }
380
381
    void            RefreshBuffer();
382
383
95.2k
    bool            IsWritable() const { return m_isWritable; }
384
0
    StreamMode      GetStreamMode() const { return m_eStreamMode; }
385
386
16.9k
    sal_Int32       GetVersion() const { return m_nVersion; }
387
8.31k
    void            SetVersion( sal_Int32 n ) { m_nVersion = n; }
388
389
    friend SvStream& operator<<( SvStream& rStr, SvStrPtr f ); // for Manips
390
391
    /// end of input seen during previous i/o operation
392
765M
    bool eof() const { return m_isEof; }
393
394
    /// stream is broken
395
577M
    bool bad() const { return GetError() != ERRCODE_NONE; }
396
397
    /** Get state
398
399
        If the state is good() the previous i/o operation succeeded.
400
401
        If the state is good(), the next input operation might succeed;
402
        otherwise, it will fail.
403
404
        Applying an input operation to a stream that is not in the good() state
405
        is a null operation as far as the variable being read into is concerned.
406
407
        If we try to read into a variable v and the operation fails, the value
408
        of v should be unchanged,
409
    */
410
651M
    bool good() const { return !(eof() || bad()); }
411
412
private:
413
    template <typename T> SvStream& ReadNumber(T& r);
414
    template <typename T> SvStream& WriteNumber(T n);
415
416
    template<typename T>
417
    void readNumberWithoutSwap(T& rDataDest)
418
305M
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
void SvStream::readNumberWithoutSwap<unsigned short>(unsigned short&)
Line
Count
Source
418
103M
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
void SvStream::readNumberWithoutSwap<unsigned int>(unsigned int&)
Line
Count
Source
418
38.6M
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
Unexecuted instantiation: void SvStream::readNumberWithoutSwap<unsigned long>(unsigned long&)
void SvStream::readNumberWithoutSwap<short>(short&)
Line
Count
Source
418
24.9M
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
void SvStream::readNumberWithoutSwap<int>(int&)
Line
Count
Source
418
90.3M
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
Unexecuted instantiation: void SvStream::readNumberWithoutSwap<long>(long&)
void SvStream::readNumberWithoutSwap<char16_t>(char16_t&)
Line
Count
Source
418
45.9M
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
void SvStream::readNumberWithoutSwap<float>(float&)
Line
Count
Source
418
299k
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
void SvStream::readNumberWithoutSwap<double>(double&)
Line
Count
Source
418
1.72M
    { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
419
420
    SAL_DLLPRIVATE void readNumberWithoutSwap_(void * pDataDest, int nDataSize);
421
422
    template<typename T>
423
    void writeNumberWithoutSwap(T const & rDataSrc)
424
33.0M
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
void SvStream::writeNumberWithoutSwap<unsigned short>(unsigned short const&)
Line
Count
Source
424
18.2M
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
void SvStream::writeNumberWithoutSwap<unsigned int>(unsigned int const&)
Line
Count
Source
424
1.45M
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
void SvStream::writeNumberWithoutSwap<unsigned long>(unsigned long const&)
Line
Count
Source
424
7.00k
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
void SvStream::writeNumberWithoutSwap<short>(short const&)
Line
Count
Source
424
178k
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
void SvStream::writeNumberWithoutSwap<int>(int const&)
Line
Count
Source
424
13.1M
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
Unexecuted instantiation: void SvStream::writeNumberWithoutSwap<long>(long const&)
void SvStream::writeNumberWithoutSwap<float>(float const&)
Line
Count
Source
424
1.36k
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
void SvStream::writeNumberWithoutSwap<double>(double const&)
Line
Count
Source
424
74.1k
    { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
425
426
    SAL_DLLPRIVATE void writeNumberWithoutSwap_(const void * pDataSrc, int nDataSize);
427
};
428
429
inline SvStream& operator<<( SvStream& rStr, SvStrPtr f )
430
0
{
431
0
    (*f)(rStr);
432
0
    return rStr;
433
0
}
434
435
TOOLS_DLLPUBLIC SvStream& endl( SvStream& rStr );
436
/// same as endl() but Unicode
437
TOOLS_DLLPUBLIC SvStream& endlu( SvStream& rStr );
438
/// call endlu() if m_eStreamCharSet==RTL_TEXTECODING_UNICODE otherwise endl()
439
TOOLS_DLLPUBLIC SvStream& endlub( SvStream& rStr );
440
441
/// Attempt to read nUnits 8bit units to an OString, returned OString's
442
/// length is number of units successfully read
443
TOOLS_DLLPUBLIC OString read_uInt8s_ToOString(SvStream& rStrm,
444
    std::size_t nUnits);
445
446
/// Attempt to read nUnits 8bit units to an OUString
447
inline OUString read_uInt8s_ToOUString(SvStream& rStrm,
448
    std::size_t nUnits, rtl_TextEncoding eEnc)
449
235k
{
450
235k
    return OStringToOUString(read_uInt8s_ToOString(rStrm, nUnits), eEnc);
451
235k
}
452
453
/// Attempt to read nUnits 16bit units to an OUString, returned
454
/// OUString's length is number of units successfully read
455
TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream& rStrm,
456
    std::size_t nUnits);
457
458
/// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
459
/// 16bit units to an OUString, returned OString's length is number of
460
/// units successfully read.
461
inline OUString read_uInt16_lenPrefixed_uInt16s_ToOUString(SvStream& rStrm)
462
443k
{
463
443k
    sal_uInt16 nUnits = 0;
464
443k
    rStrm.ReadUInt16( nUnits );
465
443k
    return read_uInt16s_ToOUString(rStrm, nUnits);
466
443k
}
467
468
inline OUString read_uInt32_lenPrefixed_uInt16s_ToOUString(SvStream& rStrm)
469
966
{
470
966
    sal_uInt32 nUnits = 0;
471
966
    rStrm.ReadUInt32( nUnits );
472
966
    return read_uInt16s_ToOUString(rStrm, nUnits);
473
966
}
474
475
/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
476
/// of 16bit units from an OUString, returned value is number of bytes written
477
/// (including byte-count of prefix)
478
std::size_t write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
479
                                                std::u16string_view rStr);
480
481
/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
482
/// of 16bit units from an OUString, returned value is number of bytes written
483
/// (including byte-count of prefix)
484
UNLESS_MERGELIBS(TOOLS_DLLPUBLIC) std::size_t write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
485
                                                std::u16string_view rStr);
486
487
/// Attempt to read 8bit units to an OString until a zero terminator is
488
/// encountered, returned OString's length is number of units *definitely*
489
/// successfully read, check SvStream::good() to see if null terminator was
490
/// successfully read
491
TOOLS_DLLPUBLIC OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStrm);
492
493
/// Attempt to read 8bit units assuming source encoding eEnc to an OUString
494
/// until a zero terminator is encountered. Check SvStream::good() to see if
495
/// null terminator was successfully read
496
TOOLS_DLLPUBLIC OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStrm, rtl_TextEncoding eEnc);
497
498
/// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
499
/// 8bit units to an OString, returned OString's length is number of units
500
/// successfully read.
501
inline OString read_uInt32_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
502
0
{
503
0
    sal_uInt32 nUnits = 0;
504
0
    rStrm.ReadUInt32(nUnits);
505
0
    return read_uInt8s_ToOString(rStrm, nUnits);
506
0
}
507
inline OString read_uInt16_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
508
114k
{
509
114k
    sal_uInt16 nUnits = 0;
510
114k
    rStrm.ReadUInt16(nUnits);
511
114k
    return read_uInt8s_ToOString(rStrm, nUnits);
512
114k
}
513
514
inline OString read_uInt8_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
515
3.04M
{
516
3.04M
    sal_uInt8 nUnits = 0;
517
3.04M
    rStrm.ReadUChar(nUnits);
518
3.04M
    return read_uInt8s_ToOString(rStrm, nUnits);
519
3.04M
}
520
521
inline OUString read_uInt16_lenPrefixed_uInt8s_ToOUString(SvStream& rStrm,
522
                                                          rtl_TextEncoding eEnc)
523
102k
{
524
102k
    return OStringToOUString(read_uInt16_lenPrefixed_uInt8s_ToOString(rStrm), eEnc);
525
102k
}
526
527
inline OUString read_uInt8_lenPrefixed_uInt8s_ToOUString(SvStream& rStrm,
528
                                                         rtl_TextEncoding eEnc)
529
349k
{
530
349k
    return OStringToOUString(read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm), eEnc);
531
349k
}
532
533
/// Attempt to write a pascal-style length (of type prefix) prefixed
534
/// sequence of units from a string-type, returned value is number of bytes
535
/// written (including byte-count of prefix)
536
TOOLS_DLLPUBLIC std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
537
                                              std::string_view rStr);
538
539
/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
540
/// of 8bit units from an OUString, returned value is number of bytes written
541
/// (including byte-count of prefix)
542
inline std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm,
543
                                               std::u16string_view rStr,
544
                                               rtl_TextEncoding eEnc)
545
1.52k
{
546
1.52k
    return write_uInt16_lenPrefixed_uInt8s_FromOString(rStrm, OUStringToOString(rStr, eEnc));
547
1.52k
}
548
549
[[nodiscard]] TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset);
550
551
namespace tools
552
{
553
/// Is rUrl a file:// URL with no contents?
554
TOOLS_DLLPUBLIC bool isEmptyFileUrl(const OUString& rUrl);
555
}
556
557
// FileStream
558
559
class TOOLS_DLLPUBLIC SvFileStream final : public SvStream
560
{
561
private:
562
    void*           mxFileHandle = nullptr; // on windows, it is a HANDLE, otherwise, it is a oslFileHandle
563
#if defined(_WIN32)
564
    sal_uInt16      nLockCounter;
565
#endif
566
    OUString        aFilename;
567
    bool            bIsOpen;
568
569
    SvFileStream (const SvFileStream&) = delete;
570
    SvFileStream & operator= (const SvFileStream&) = delete;
571
572
    bool LockFile();
573
    void UnlockFile();
574
575
    virtual std::size_t GetData( void* pData, std::size_t nSize ) override;
576
    virtual std::size_t PutData( const void* pData, std::size_t nSize ) override;
577
    virtual sal_uInt64 SeekPos( sal_uInt64 nPos ) override;
578
    virtual void    SetSize( sal_uInt64 nSize ) override;
579
    virtual void    FlushData() override;
580
581
public:
582
                    // Switches to Read StreamMode on failed attempt of Write opening
583
                    SvFileStream( const OUString& rFileName, StreamMode eOpenMode );
584
                    SvFileStream();
585
                    virtual ~SvFileStream() override;
586
587
    virtual void    ResetError() override;
588
589
    void            Open( const OUString& rFileName, StreamMode eOpenMode );
590
    void            Close();
591
105M
    bool            IsOpen() const { return bIsOpen; }
592
593
284k
    const OUString& GetFileName() const { return aFilename; }
594
};
595
596
// MemoryStream
597
598
class TOOLS_DLLPUBLIC SvMemoryStream : public SvStream
599
{
600
    SvMemoryStream (const SvMemoryStream&) = delete;
601
    SvMemoryStream & operator= (const SvMemoryStream&) = delete;
602
603
protected:
604
    std::size_t     nSize;
605
    std::size_t     nResize;
606
    std::size_t     nPos;
607
    std::size_t     nEndOfData;
608
    sal_uInt8*      pBuf;
609
    bool            bOwnsData;
610
611
    virtual std::size_t GetData( void* pData, std::size_t nSize ) override;
612
    virtual std::size_t PutData( const void* pData, std::size_t nSize ) override;
613
    virtual sal_uInt64 SeekPos( sal_uInt64 nPos ) override;
614
    virtual void    SetSize( sal_uInt64 nSize ) override;
615
    virtual void    FlushData() override;
616
617
    /// AllocateMemory must update pBuf accordingly
618
    /// - pBuf: Address of new block
619
    void    AllocateMemory( std::size_t nSize );
620
621
    /// ReAllocateMemory must update the following variables:
622
    /// - pBuf: Address of new block
623
    /// - nEndOfData: Set to nNewSize-1 , if outside of block
624
    ///               Set to 0 , if new block size is 0 bytes
625
    /// - nSize: New block size
626
    /// - nPos: Set to 0 if position outside of block
627
    bool    ReAllocateMemory( tools::Long nDiff );
628
629
    /// Is called when this stream allocated the buffer or the buffer is
630
    /// resized. FreeMemory may need to NULLify handles in derived classes.
631
    void    FreeMemory();
632
633
public:
634
                    SvMemoryStream( void* pBuf, std::size_t nSize, StreamMode eMode);
635
                    SvMemoryStream( std::size_t nInitSize=512, std::size_t nResize=64 );
636
                    virtual ~SvMemoryStream() override;
637
638
    virtual void    ResetError() override final;
639
640
22.4k
    sal_uInt64      GetSize() { return TellEnd(); }
641
25.0k
    std::size_t     GetEndOfData() const { return nEndOfData; }
642
119k
    const void*     GetData() { FlushBuffer(); return pBuf; }
643
644
    // return the buffer currently in use, and allocate a new buffer internally
645
    void*           SwitchBuffer();
646
    // the buffer is not owned by this class
647
    void            SetBuffer( void* pBuf, std::size_t nSize, std::size_t nEOF );
648
649
61.8k
    void            ObjectOwnsMemory( bool bOwn ) { bOwnsData = bOwn; }
650
    /// Makes the stream read-only after it was (possibly) initially writable,
651
    /// without having to copy the data or change buffers.
652
    /// @since LibreOffice 7.5
653
    void            MakeReadOnly();
654
36.2k
    void            SetResizeOffset( std::size_t nNewResize ) { nResize = nNewResize; }
655
181M
    virtual sal_uInt64 TellEnd() override final { FlushBuffer(); return nEndOfData; }
656
};
657
658
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */