Bump version to 6.4-15
[LibreOffice.git] / include / tools / stream.hxx
blob4e4cf58cffda0aa469a86531d61cd1cedbd291bb
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 .
19 #ifndef INCLUDED_TOOLS_STREAM_HXX
20 #define INCLUDED_TOOLS_STREAM_HXX
22 #include <tools/toolsdllapi.h>
23 #include <tools/lineend.hxx>
24 #include <tools/ref.hxx>
25 #include <vcl/errcode.hxx>
26 #include <rtl/string.hxx>
27 #include <o3tl/typed_flags_set.hxx>
28 #include <memory>
30 class StreamData;
32 inline rtl_TextEncoding GetStoreCharSet( rtl_TextEncoding eEncoding )
34 if ( eEncoding == RTL_TEXTENCODING_ISO_8859_1 )
35 return RTL_TEXTENCODING_MS_1252;
36 else
37 return eEncoding;
40 // StreamTypes
42 // read, write, create,... options
43 enum class StreamMode {
44 NONE = 0x0000,
45 READ = 0x0001, ///< allow read accesses
46 WRITE = 0x0002, ///< allow write accesses
47 // file i/o
48 NOCREATE = 0x0004, ///< 1 == Don't create file
49 TRUNC = 0x0008, ///< Truncate _existing_ file to zero length
50 COPY_ON_SYMLINK = 0x0010, ///< copy-on-write for symlinks (Unix)
51 // sharing options
52 SHARE_DENYNONE = 0x0100,
53 SHARE_DENYREAD = 0x0200, // overrides denynone
54 SHARE_DENYWRITE = 0x0400, // overrides denynone
55 SHARE_DENYALL = 0x0800, // overrides denyread,write,none
56 // masks
57 READWRITE = READ | WRITE,
58 STD_READ = READ | SHARE_DENYNONE | NOCREATE,
59 STD_WRITE = WRITE | SHARE_DENYALL,
60 STD_READWRITE = READWRITE | SHARE_DENYALL
62 namespace o3tl
64 template<> struct typed_flags<StreamMode> : is_typed_flags<StreamMode, 0x0f1f> {};
67 #define STREAM_SEEK_TO_BEGIN 0L
68 #define STREAM_SEEK_TO_END SAL_MAX_UINT64
70 enum class SvStreamEndian { BIG, LITTLE };
72 enum class SvStreamCompressFlags {
73 NONE = 0x0000,
74 ZBITMAP = 0x0001,
75 NATIVE = 0x0010,
77 namespace o3tl
79 template<> struct typed_flags<SvStreamCompressFlags> : is_typed_flags<SvStreamCompressFlags, 0x0011> {};
82 class SvStream;
84 typedef SvStream& (*SvStrPtr)( SvStream& );
86 inline SvStream& operator<<( SvStream& rStr, SvStrPtr f );
88 // SvLockBytes
90 struct SvLockBytesStat
92 std::size_t nSize;
94 SvLockBytesStat() : nSize(0) {}
97 class TOOLS_DLLPUBLIC SvLockBytes: public virtual SvRefBase
99 SvStream * m_pStream;
100 bool const m_bOwner;
101 bool m_bSync;
103 protected:
104 void close();
106 public:
108 SvLockBytes() : m_pStream(nullptr), m_bOwner(false), m_bSync(false) {}
110 SvLockBytes(SvStream * pTheStream, bool bTheOwner = false) :
111 m_pStream(pTheStream), m_bOwner(bTheOwner), m_bSync(false) {}
113 virtual ~SvLockBytes() override { close(); }
115 const SvStream * GetStream() const { return m_pStream; }
117 void SetSynchronMode(bool bTheSync = true) { m_bSync = bTheSync; }
118 bool IsSynchronMode() const { return m_bSync; }
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);
125 virtual ErrCode Flush() const;
127 virtual ErrCode SetSize(sal_uInt64 nSize);
129 virtual ErrCode Stat(SvLockBytesStat * pStat) const;
132 typedef tools::SvRef<SvLockBytes> SvLockBytesRef;
134 // SvStream
136 class TOOLS_DLLPUBLIC SvStream
138 private:
139 // LockBytes Interface
140 SvLockBytesRef m_xLockBytes; ///< Default implementation
141 sal_uInt64 m_nActPos;
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;
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 SvStreamEndian m_nEndian;
161 SvStreamCompressFlags m_nCompressMode;
162 LineEnd m_eLineDelimiter;
163 rtl_TextEncoding m_eStreamCharSet;
165 // Encryption
166 OString m_aCryptMaskKey;// aCryptMaskKey.getLength != 0 -> Encryption used
167 unsigned char m_nCryptMask;
169 // Userdata
170 sal_Int32 m_nVersion; // for external use
172 SvStream ( const SvStream& rStream ) = delete;
173 SvStream& operator=( const SvStream& rStream ) = delete;
175 protected:
176 sal_uInt64 m_nBufFilePos; ///< File position of pBuf[0]
177 StreamMode m_eStreamMode;
178 bool m_isWritable;
180 virtual std::size_t GetData( void* pData, std::size_t nSize );
181 virtual std::size_t PutData( const void* pData, std::size_t nSize );
182 virtual sal_uInt64 SeekPos( sal_uInt64 nPos );
183 virtual void FlushData();
184 virtual void SetSize(sal_uInt64 nSize);
186 void FlushBuffer();
187 void ClearError();
188 void ClearBuffer();
190 // encrypt and write in blocks
191 std::size_t CryptAndWriteBuffer( const void* pStart, std::size_t nLen );
192 void EncryptBuffer( void* pStart, std::size_t nLen ) const;
194 public:
195 SvStream();
196 SvStream( SvLockBytes *pLockBytes);
197 virtual ~SvStream();
199 SvLockBytes* GetLockBytes() const { return m_xLockBytes.get(); }
201 ErrCode GetError() const { return m_nError.IgnoreWarning(); }
202 ErrCode const & GetErrorCode() const { return m_nError; }
203 void SetError( ErrCode nErrorCode );
204 virtual void ResetError();
206 void SetEndian( SvStreamEndian SvStreamEndian );
207 SvStreamEndian GetEndian() const { return m_nEndian; }
208 /// returns status of endian swap flag
209 bool IsEndianSwap() const { return m_isSwap; }
211 void SetCompressMode( SvStreamCompressFlags nNewMode )
212 { m_nCompressMode = nNewMode; }
213 SvStreamCompressFlags GetCompressMode() const { return m_nCompressMode; }
215 void SetCryptMaskKey(const OString& rCryptMaskKey);
217 void SetStreamCharSet( rtl_TextEncoding eCharSet )
218 { m_eStreamCharSet = eCharSet; }
219 rtl_TextEncoding GetStreamCharSet() const { return m_eStreamCharSet; }
221 void SetLineDelimiter( LineEnd eLineEnd )
222 { m_eLineDelimiter = eLineEnd; }
223 LineEnd GetLineDelimiter() const { return m_eLineDelimiter; }
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 );
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(const OString& rStr)
249 { WriteBytes(rStr.getStr(), rStr.getLength()); return *this; }
250 SvStream& WriteStream( SvStream& rStream );
251 sal_uInt64 WriteStream( SvStream& rStream, sal_uInt64 nSize );
253 SvStream& WriteBool( bool b )
254 { 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( const double& rDouble );
260 SvStream& WriteCharPtr( const char* pBuf );
262 SvStream& WriteUInt32AsString( sal_uInt32 nUInt32 );
263 SvStream& WriteInt32AsString( sal_Int32 nInt32 );
265 std::size_t ReadBytes( void* pData, std::size_t nSize );
266 std::size_t WriteBytes( const void* pData, std::size_t nSize );
267 sal_uInt64 Seek( sal_uInt64 nPos );
268 sal_uInt64 SeekRel( sal_Int64 nPos );
269 sal_uInt64 Tell() const { return m_nBufFilePos + m_nBufActualPos; }
270 virtual sal_uInt64 TellEnd();
271 // length between current (Tell()) pos and end of stream
272 sal_uInt64 remainingSize();
273 void Flush();
274 // next Tell() <= nSize
275 bool SetStreamSize( sal_uInt64 nSize );
277 /** Read a line of bytes.
279 @param nMaxBytesToRead
280 Maximum of bytes to read, if line is longer it will be
281 truncated.
283 @note NOTE that the default is one character less than STRING_MAXLEN to
284 prevent problems after conversion to String that may be lurking
285 in various places doing something like
286 @code
287 for (sal_uInt16 i=0; i < aString.Len(); ++i)
288 @endcode
289 causing endless loops ...
291 bool ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead = 0xFFFE );
292 bool WriteLine( const OString& rStr );
294 /** Read a line of bytes.
296 @param nMaxBytesToRead
297 Maximum of bytes to read, if line is longer it will be
298 truncated.
300 @note NOTE that the default is one character less than STRING_MAXLEN to
301 prevent problems after conversion to String that may be lurking
302 in various places doing something like
303 @code
304 for (sal_uInt16 i=0; i < aString.Len(); ++i)
305 @endcode
306 causing endless loops ...
308 bool ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
309 sal_Int32 nMaxBytesToRead = 0xFFFE );
310 bool WriteByteStringLine( const OUString& rStr, rtl_TextEncoding eDestCharSet );
312 /// Switch to no endian swapping and write 0xfeff
313 void StartWritingUnicodeText();
315 /** If eReadBomCharSet==RTL_TEXTENCODING_DONTKNOW: read 16bit, if 0xfeff do
316 nothing (UTF-16), if 0xfffe switch endian swapping (UTF-16), if 0xefbb
317 or 0xbbef read another byte and check for UTF-8. If no UTF-* BOM was
318 detected put all read bytes back. This means that if 2 bytes were read
319 it was an UTF-16 BOM, if 3 bytes were read it was an UTF-8 BOM. There
320 is no UTF-7, UTF-32 or UTF-EBCDIC BOM detection!
322 If eReadBomCharSet!=RTL_TEXTENCODING_DONTKNOW: only read a BOM of that
323 encoding and switch endian swapping if UTF-16 and 0xfffe. */
324 void StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet );
326 /** Read a line of Unicode.
328 @param nMaxCodepointsToRead
329 Maximum of codepoints (UCS-2 or UTF-16 pairs, not bytes) to
330 read, if line is longer it will be truncated.
332 bool ReadUniStringLine(OUString& rStr, sal_Int32 nMaxCodepointsToRead);
333 /** Read a 32bit length prefixed sequence of utf-16 if
334 eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise read a 16bit length
335 prefixed sequence of bytes and convert from eSrcCharSet */
336 OUString ReadUniOrByteString(rtl_TextEncoding eSrcCharSet);
337 /** Write a 32bit length prefixed sequence of utf-16 if
338 eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise convert to eSrcCharSet
339 and write a 16bit length prefixed sequence of bytes */
340 SvStream& WriteUniOrByteString( const OUString& rStr, rtl_TextEncoding eDestCharSet );
342 /** Read a line of Unicode if eSrcCharSet==RTL_TEXTENCODING_UNICODE,
343 otherwise read a line of Bytecode and convert from eSrcCharSet
345 @param nMaxCodepointsToRead
346 Maximum of codepoints (2 bytes if Unicode, bytes if not
347 Unicode) to read, if line is longer it will be truncated.
349 @note NOTE that the default is one character less than STRING_MAXLEN to
350 prevent problems after conversion to String that may be lurking in
351 various places doing something like
352 @code
353 for (sal_uInt16 i=0; i < aString.Len(); ++i)
354 @endcode
355 causing endless loops ...
357 bool ReadUniOrByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
358 sal_Int32 nMaxCodepointsToRead = 0xFFFE );
359 /** Write a sequence of Unicode characters if
360 eDestCharSet==RTL_TEXTENCODING_UNICODE, otherwise write a sequence of
361 Bytecodes converted to eDestCharSet */
362 bool WriteUnicodeOrByteText( const OUString& rStr, rtl_TextEncoding eDestCharSet );
363 bool WriteUnicodeOrByteText( const OUString& rStr )
364 { return WriteUnicodeOrByteText( rStr, GetStreamCharSet() ); }
366 /** Write a Unicode character if eDestCharSet==RTL_TEXTENCODING_UNICODE,
367 otherwise write as Bytecode converted to eDestCharSet.
369 This may result in more than one byte being written if a multi byte
370 encoding (e.g. UTF7, UTF8) is chosen. */
371 bool WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet );
372 bool WriteUniOrByteChar( sal_Unicode ch )
373 { return WriteUniOrByteChar( ch, GetStreamCharSet() ); }
375 void SetBufferSize( sal_uInt16 m_nBufSize );
376 sal_uInt16 GetBufferSize() const { return m_nBufSize; }
378 void RefreshBuffer();
380 bool IsWritable() const { return m_isWritable; }
381 StreamMode GetStreamMode() const { return m_eStreamMode; }
383 sal_Int32 GetVersion() const { return m_nVersion; }
384 void SetVersion( sal_Int32 n ) { m_nVersion = n; }
386 friend SvStream& operator<<( SvStream& rStr, SvStrPtr f ); // for Manips
388 /// end of input seen during previous i/o operation
389 bool eof() const { return m_isEof; }
391 /// stream is broken
392 bool bad() const { return GetError() != ERRCODE_NONE; }
394 /** Get state
396 If the state is good() the previous i/o operation succeeded.
398 If the state is good(), the next input operation might succeed;
399 otherwise, it will fail.
401 Applying an input operation to a stream that is not in the good() state
402 is a null operation as far as the variable being read into is concerned.
404 If we try to read into a variable v and the operation fails, the value
405 of v should be unchanged,
407 bool good() const { return !(eof() || bad()); }
409 private:
410 template<typename T>
411 void readNumberWithoutSwap(T& rDataDest)
412 { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
414 void readNumberWithoutSwap_(void * pDataDest, int nDataSize);
416 template<typename T>
417 void writeNumberWithoutSwap(T const & rDataSrc)
418 { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
420 void writeNumberWithoutSwap_(const void * pDataSrc, int nDataSize);
423 inline SvStream& operator<<( SvStream& rStr, SvStrPtr f )
425 (*f)(rStr);
426 return rStr;
429 TOOLS_DLLPUBLIC SvStream& endl( SvStream& rStr );
430 /// same as endl() but Unicode
431 TOOLS_DLLPUBLIC SvStream& endlu( SvStream& rStr );
432 /// call endlu() if m_eStreamCharSet==RTL_TEXTECODING_UNICODE otherwise endl()
433 TOOLS_DLLPUBLIC SvStream& endlub( SvStream& rStr );
435 /// Attempt to read nUnits 8bit units to an OString, returned OString's
436 /// length is number of units successfully read
437 TOOLS_DLLPUBLIC OString read_uInt8s_ToOString(SvStream& rStrm,
438 std::size_t nUnits);
440 /// Attempt to read nUnits 8bit units to an OUString
441 inline OUString read_uInt8s_ToOUString(SvStream& rStrm,
442 std::size_t nUnits, rtl_TextEncoding eEnc)
444 return OStringToOUString(read_uInt8s_ToOString(rStrm, nUnits), eEnc);
447 /// Attempt to read nUnits 16bit units to an OUString, returned
448 /// OUString's length is number of units successfully read
449 TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream& rStrm,
450 std::size_t nUnits);
452 /// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
453 /// 16bit units to an OUString, returned OString's length is number of
454 /// units successfully read.
455 inline OUString read_uInt16_lenPrefixed_uInt16s_ToOUString(SvStream& rStrm)
457 sal_uInt16 nUnits = 0;
458 rStrm.ReadUInt16( nUnits );
459 return read_uInt16s_ToOUString(rStrm, nUnits);
462 inline OUString read_uInt32_lenPrefixed_uInt16s_ToOUString(SvStream& rStrm)
464 sal_uInt32 nUnits = 0;
465 rStrm.ReadUInt32( nUnits );
466 return read_uInt16s_ToOUString(rStrm, nUnits);
469 /// Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
470 /// returned value is number of bytes written
471 TOOLS_DLLPUBLIC std::size_t write_uInt16s_FromOUString(SvStream& rStrm,
472 const OUString& rStr, std::size_t nUnits);
474 inline std::size_t write_uInt16s_FromOUString(SvStream& rStrm,
475 const OUString& rStr)
477 return write_uInt16s_FromOUString(rStrm, rStr, rStr.getLength());
480 /// Attempt to write a pascal-style length (of type prefix) prefixed sequence
481 /// of 16bit units from an OUString, returned value is number of bytes written
482 /// (including byte-count of prefix)
483 std::size_t write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
484 const OUString &rStr);
486 /// Attempt to write a pascal-style length (of type prefix) prefixed sequence
487 /// of 16bit units from an OUString, returned value is number of bytes written
488 /// (including byte-count of prefix)
489 TOOLS_DLLPUBLIC std::size_t write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
490 const OUString &rStr);
492 /// Attempt to read 8bit units to an OString until a zero terminator is
493 /// encountered, returned OString's length is number of units *definitely*
494 /// successfully read, check SvStream::good() to see if null terminator was
495 /// successfully read
496 TOOLS_DLLPUBLIC OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStrm);
498 /// Attempt to read 8bit units assuming source encoding eEnc to an OUString
499 /// until a zero terminator is encountered. Check SvStream::good() to see if
500 /// null terminator was successfully read
501 TOOLS_DLLPUBLIC OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStrm, rtl_TextEncoding eEnc);
503 /// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
504 /// 8bit units to an OString, returned OString's length is number of units
505 /// successfully read.
506 inline OString read_uInt32_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
508 sal_uInt32 nUnits = 0;
509 rStrm.ReadUInt32(nUnits);
510 return read_uInt8s_ToOString(rStrm, nUnits);
512 inline OString read_uInt16_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
514 sal_uInt16 nUnits = 0;
515 rStrm.ReadUInt16(nUnits);
516 return read_uInt8s_ToOString(rStrm, nUnits);
519 inline OString read_uInt8_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
521 sal_uInt8 nUnits = 0;
522 rStrm.ReadUChar(nUnits);
523 return read_uInt8s_ToOString(rStrm, nUnits);
526 inline OUString read_uInt16_lenPrefixed_uInt8s_ToOUString(SvStream& rStrm,
527 rtl_TextEncoding eEnc)
529 return OStringToOUString(read_uInt16_lenPrefixed_uInt8s_ToOString(rStrm), eEnc);
532 inline OUString read_uInt8_lenPrefixed_uInt8s_ToOUString(SvStream& rStrm,
533 rtl_TextEncoding eEnc)
535 return OStringToOUString(read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm), eEnc);
538 /// Attempt to write a prefixed sequence of nUnits 8bit units from an OString,
539 /// returned value is number of bytes written
540 inline std::size_t write_uInt8s_FromOString(SvStream& rStrm, const OString& rStr,
541 std::size_t nUnits)
543 return rStrm.WriteBytes(rStr.getStr(), nUnits);
546 inline std::size_t write_uInt8s_FromOString(SvStream& rStrm, const OString& rStr)
548 return write_uInt8s_FromOString(rStrm, rStr, rStr.getLength());
551 /// Attempt to write a pascal-style length (of type prefix) prefixed
552 /// sequence of units from a string-type, returned value is number of bytes
553 /// written (including byte-count of prefix)
554 TOOLS_DLLPUBLIC std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
555 const OString &rStr);
557 /// Attempt to write a pascal-style length (of type prefix) prefixed sequence
558 /// of 8bit units from an OUString, returned value is number of bytes written
559 /// (including byte-count of prefix)
560 inline std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm,
561 const OUString &rStr,
562 rtl_TextEncoding eEnc)
564 return write_uInt16_lenPrefixed_uInt8s_FromOString(rStrm, OUStringToOString(rStr, eEnc));
567 [[nodiscard]] TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset);
569 namespace tools
571 /// Is rUrl a file:// URL with no contents?
572 TOOLS_DLLPUBLIC bool isEmptyFileUrl(const OUString& rUrl);
575 // FileStream
577 class TOOLS_DLLPUBLIC SvFileStream final : public SvStream
579 private:
580 std::unique_ptr<StreamData>
581 pInstanceData;
582 OUString aFilename;
583 #if defined(_WIN32)
584 sal_uInt16 nLockCounter;
585 #endif
586 bool bIsOpen;
588 SvFileStream (const SvFileStream&) = delete;
589 SvFileStream & operator= (const SvFileStream&) = delete;
591 bool LockRange( sal_uInt64 nByteOffset, std::size_t nBytes );
592 bool UnlockRange( sal_uInt64 nByteOffset, std::size_t nBytes );
593 bool LockFile();
594 void UnlockFile();
596 virtual std::size_t GetData( void* pData, std::size_t nSize ) override;
597 virtual std::size_t PutData( const void* pData, std::size_t nSize ) override;
598 virtual sal_uInt64 SeekPos( sal_uInt64 nPos ) override;
599 virtual void SetSize( sal_uInt64 nSize ) override;
600 virtual void FlushData() override;
602 public:
603 // Switches to Read StreamMode on failed attempt of Write opening
604 SvFileStream( const OUString& rFileName, StreamMode eOpenMode );
605 SvFileStream();
606 virtual ~SvFileStream() override;
608 virtual void ResetError() override;
610 void Open( const OUString& rFileName, StreamMode eOpenMode );
611 void Close();
612 bool IsOpen() const { return bIsOpen; }
614 const OUString& GetFileName() const { return aFilename; }
617 // MemoryStream
619 class TOOLS_DLLPUBLIC SvMemoryStream : public SvStream
621 SvMemoryStream (const SvMemoryStream&) = delete;
622 SvMemoryStream & operator= (const SvMemoryStream&) = delete;
624 protected:
625 std::size_t nSize;
626 std::size_t nResize;
627 std::size_t nPos;
628 std::size_t nEndOfData;
629 sal_uInt8* pBuf;
630 bool bOwnsData;
632 virtual std::size_t GetData( void* pData, std::size_t nSize ) override;
633 virtual std::size_t PutData( const void* pData, std::size_t nSize ) override;
634 virtual sal_uInt64 SeekPos( sal_uInt64 nPos ) override;
635 virtual void SetSize( sal_uInt64 nSize ) override;
636 virtual void FlushData() override;
638 /// AllocateMemory must update pBuf accordingly
639 /// - pBuf: Address of new block
640 void AllocateMemory( std::size_t nSize );
642 /// ReAllocateMemory must update the following variables:
643 /// - pBuf: Address of new block
644 /// - nEndOfData: Set to nNewSize-1 , if outside of block
645 /// Set to 0 , if new block size is 0 bytes
646 /// - nSize: New block size
647 /// - nPos: Set to 0 if position outside of block
648 bool ReAllocateMemory( long nDiff );
650 /// Is called when this stream allocated the buffer or the buffer is
651 /// resized. FreeMemory may need to NULLify handles in derived classes.
652 void FreeMemory();
654 public:
655 SvMemoryStream( void* pBuf, std::size_t nSize, StreamMode eMode);
656 SvMemoryStream( std::size_t nInitSize=512, std::size_t nResize=64 );
657 virtual ~SvMemoryStream() override;
659 virtual void ResetError() override;
661 sal_uInt64 GetSize();
662 std::size_t GetEndOfData() const { return nEndOfData; }
663 const void* GetData() { Flush(); return pBuf; }
665 // return the buffer currently in use, and allocate a new buffer internally
666 void* SwitchBuffer();
667 // the buffer is not owned by this class
668 void SetBuffer( void* pBuf, std::size_t nSize, std::size_t nEOF );
670 void ObjectOwnsMemory( bool bOwn ) { bOwnsData = bOwn; }
671 void SetResizeOffset( std::size_t nNewResize ) { nResize = nNewResize; }
672 virtual sal_uInt64 TellEnd() override { FlushBuffer(); return nEndOfData; }
675 #endif
677 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */