LibreOffice Module tools (master) 1
stream.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// TODO: Read->RefreshBuffer-> React to changes from m_nBufActualLen
21
22#include <sal/config.h>
23
24#include <cassert>
25#include <cstddef>
26#include <memory>
27
28#include <string.h>
29
30#include <o3tl/safeint.hxx>
31#include <osl/endian.h>
32#include <osl/diagnose.h>
33#include <rtl/strbuf.hxx>
34#include <rtl/string.hxx>
35#include <rtl/ustrbuf.hxx>
36#include <sal/log.hxx>
37#include <tools/long.hxx>
38
41
42static void swapNibbles(unsigned char &c)
43{
44 unsigned char nSwapTmp=c;
45 nSwapTmp <<= 4;
46 c >>= 4;
47 c |= nSwapTmp;
48}
49
50#include <tools/debug.hxx>
51#include <tools/stream.hxx>
52#include <osl/thread.h>
53#include <algorithm>
54
55// !!! Do not inline if already the operators <<,>> are inline
56template <typename T, std::enable_if_t<std::is_integral_v<T> && sizeof(T) == 2, int> = 0>
57static void SwapNumber(T& r)
58 { r = OSL_SWAPWORD(r); }
59template <typename T, std::enable_if_t<std::is_integral_v<T> && sizeof(T) == 4, int> = 0>
60static void SwapNumber(T& r)
61 { r = OSL_SWAPDWORD(r); }
62template <typename T, std::enable_if_t<std::is_integral_v<T> && sizeof(T) == 8, int> = 0>
63static void SwapNumber(T& r)
64 {
65 union
66 {
67 T n;
68 sal_uInt32 c[2];
69 } s;
70
71 s.n = r;
72 std::swap(s.c[0], s.c[1]); // swap the 32 bit words
73 // swap the bytes in the words
74 s.c[0] = OSL_SWAPDWORD(s.c[0]);
75 s.c[1] = OSL_SWAPDWORD(s.c[1]);
76 r = s.n;
77 }
78
79#ifdef UNX
80static void SwapFloat( float& r )
81 {
82 union
83 {
84 float f;
85 sal_uInt32 c;
86 } s;
87
88 s.f = r;
89 s.c = OSL_SWAPDWORD( s.c );
90 r = s.f;
91 }
92
93static void SwapDouble( double& r )
94 {
95 if( sizeof(double) != 8 )
96 {
97 SAL_WARN( "tools.stream", "Can only swap 8-Byte-doubles" );
98 }
99 else
100 {
101 union
102 {
103 double d;
104 sal_uInt32 c[2];
105 } s;
106
107 s.d = r;
108 s.c[0] ^= s.c[1]; // swap 32-bit values in situ
109 s.c[1] ^= s.c[0];
110 s.c[0] ^= s.c[1];
111 s.c[0] = OSL_SWAPDWORD(s.c[0]); // swap dword itself in situ
112 s.c[1] = OSL_SWAPDWORD(s.c[1]);
113 r = s.d;
114 }
115 }
116#endif
117
118//SDO
119
120void SvStream::readNumberWithoutSwap_(void * pDataDest, int nDataSize)
121{
122 if (m_isIoRead && nDataSize <= m_nBufFree)
123 {
124 for (int i = 0; i < nDataSize; i++)
125 static_cast<char*>(pDataDest)[i] = m_pBufPos[i];
126 m_nBufActualPos += nDataSize;
127 m_pBufPos += nDataSize;
128 m_nBufFree -= nDataSize;
129 }
130 else
131 {
132 ReadBytes( pDataDest, nDataSize );
133 }
134}
135
136
137void SvStream::writeNumberWithoutSwap_(const void * pDataSrc, int nDataSize)
138{
139 if (m_isIoWrite && nDataSize <= m_nBufFree)
140 {
141 for (int i = 0; i < nDataSize; i++)
142 m_pBufPos[i] = static_cast<const char*>(pDataSrc)[i];
143 m_nBufFree -= nDataSize;
144 m_nBufActualPos += nDataSize;
147 m_pBufPos += nDataSize;
148 m_isDirty = true;
149 }
150 else
151 {
152 WriteBytes( pDataSrc, nDataSize );
153 }
154}
155
156
158{
159 if (m_bOwner)
160 delete m_pStream;
161 m_pStream = nullptr;
162}
163
164
165// virtual
166ErrCode SvLockBytes::ReadAt(sal_uInt64 const nPos, void * pBuffer, std::size_t nCount,
167 std::size_t * pRead) const
168{
169 if (!m_pStream)
170 {
171 OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
172 return ERRCODE_NONE;
173 }
174
176 std::size_t nTheRead = m_pStream->ReadBytes(pBuffer, nCount);
177 if (pRead)
178 *pRead = nTheRead;
179 return m_pStream->GetErrorCode();
180}
181
182// virtual
183ErrCode SvLockBytes::WriteAt(sal_uInt64 const nPos, const void * pBuffer, std::size_t nCount,
184 std::size_t * pWritten)
185{
186 if (!m_pStream)
187 {
188 OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
189 return ERRCODE_NONE;
190 }
191
193 std::size_t nTheWritten = m_pStream->WriteBytes(pBuffer, nCount);
194 if (pWritten)
195 *pWritten = nTheWritten;
196 return m_pStream->GetErrorCode();
197}
198
199// virtual
201{
202 if (!m_pStream)
203 {
204 OSL_FAIL("SvLockBytes::Flush(): Bad stream");
205 return ERRCODE_NONE;
206 }
207
208 m_pStream->Flush();
209 return m_pStream->GetErrorCode();
210}
211
212// virtual
213ErrCode SvLockBytes::SetSize(sal_uInt64 const nSize)
214{
215 if (!m_pStream)
216 {
217 OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
218 return ERRCODE_NONE;
219 }
220
221 m_pStream->SetStreamSize(nSize);
222 return m_pStream->GetErrorCode();
223}
224
226{
227 if (!m_pStream)
228 {
229 OSL_FAIL("SvLockBytes::Stat(): Bad stream");
230 return ERRCODE_NONE;
231 }
232
233 if (pStat)
234 pStat->nSize = m_pStream->TellEnd();
235 return ERRCODE_NONE;
236}
237
238
239std::size_t SvStream::GetData( void* pData, std::size_t nSize )
240{
241 if( !GetError() )
242 {
243 DBG_ASSERT( m_xLockBytes.is(), "pure virtual function" );
244 std::size_t nRet(0);
245 m_nError = m_xLockBytes->ReadAt(m_nActPos, pData, nSize, &nRet);
246 m_nActPos += nRet;
247 return nRet;
248 }
249 else return 0;
250}
251
252std::size_t SvStream::PutData( const void* pData, std::size_t nSize )
253{
254 if( !GetError() )
255 {
256 DBG_ASSERT( m_xLockBytes.is(), "pure virtual function" );
257 std::size_t nRet(0);
258 m_nError = m_xLockBytes->WriteAt(m_nActPos, pData, nSize, &nRet);
259 m_nActPos += nRet;
260 return nRet;
261 }
262 else return 0;
263}
264
265sal_uInt64 SvStream::SeekPos(sal_uInt64 const nPos)
266{
267 // check if a truncated STREAM_SEEK_TO_END was passed
268 assert(nPos != SAL_MAX_UINT32);
269 if( !GetError() && nPos == STREAM_SEEK_TO_END )
270 {
271 DBG_ASSERT( m_xLockBytes.is(), "pure virtual function" );
272 SvLockBytesStat aStat;
273 m_xLockBytes->Stat( &aStat );
274 m_nActPos = aStat.nSize;
275 }
276 else
277 m_nActPos = nPos;
278 return m_nActPos;
279}
280
282{
283 if( !GetError() )
284 {
285 DBG_ASSERT( m_xLockBytes.is(), "pure virtual function" );
286 m_nError = m_xLockBytes->Flush();
287 }
288}
289
290void SvStream::SetSize(sal_uInt64 const nSize)
291{
292 DBG_ASSERT( m_xLockBytes.is(), "pure virtual function" );
293 m_nError = m_xLockBytes->SetSize( nSize );
294}
295
297 m_nActPos(0)
298
299 , m_pBufPos(nullptr)
300 , m_nBufSize(0)
301 , m_nBufActualLen(0)
302 , m_nBufActualPos(0)
303 , m_nBufFree(0)
304 , m_isIoRead(false)
305 , m_isIoWrite(false)
306
307 , m_isDirty(false)
308 , m_isEof(false)
309
310 , m_nCompressMode(SvStreamCompressFlags::NONE)
311#if defined UNX
312 , m_eLineDelimiter(LINEEND_LF) // UNIX-Format
313#else
314 , m_eLineDelimiter(LINEEND_CRLF) // DOS-Format
315#endif
316 , m_eStreamCharSet(osl_getThreadTextEncoding())
317
318 , m_nCryptMask(0)
319
320 , m_nVersion(0)
321
322 , m_nBufFilePos(0)
323 , m_eStreamMode(StreamMode::NONE)
324 , m_isWritable(true)
325
326{
328
329 ClearError();
330}
331
333{
334 m_xLockBytes = pLockBytesP;
335 if( pLockBytesP ) {
336 const SvStream* pStrm = pLockBytesP->GetStream();
337 if( pStrm ) {
338 SetError( pStrm->GetErrorCode() );
339 }
340 }
341 SetBufferSize( 256 );
342}
343
345{
346 if (m_xLockBytes.is())
347 Flush();
348}
349
351{
352 m_isEof = false;
354}
355
356void SvStream::SetError( ErrCode nErrorCode )
357{
358 if (m_nError == ERRCODE_NONE)
359 m_nError = nErrorCode;
360}
361
363{
364#ifdef OSL_BIGENDIAN
365 m_isSwap = nNewFormat == SvStreamEndian::LITTLE;
366#else
367 m_isSwap = nNewFormat == SvStreamEndian::BIG;
368#endif
369}
370
372{
373#ifdef OSL_BIGENDIAN
375#else
377#endif
378}
379
380void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
381{
382 sal_uInt64 const nActualFilePos = Tell();
383 bool bDontSeek = (m_pRWBuf == nullptr);
384
385 if (m_isDirty && m_isWritable) // due to Windows NT: Access denied
386 FlushBuffer();
387
388 if (m_nBufSize)
389 {
390 m_pRWBuf.reset();
392 }
393
394 m_pRWBuf = nullptr;
395 m_nBufActualLen = 0;
396 m_nBufActualPos = 0;
397 m_nBufSize = nBufferSize;
398 if (m_nBufSize)
399 m_pRWBuf.reset(new sal_uInt8[ m_nBufSize ]);
400 m_pBufPos = m_pRWBuf.get();
401 m_isIoRead = m_isIoWrite = false;
402 if( !bDontSeek )
403 SeekPos( nActualFilePos );
404}
405
407{
408 m_nBufActualLen = 0;
409 m_nBufActualPos = 0;
410 m_nBufFilePos = 0;
411 m_pBufPos = m_pRWBuf.get();
412 m_isDirty = false;
413 m_isIoRead = m_isIoWrite = false;
414
415 m_isEof = false;
416}
417
419{
420 ClearError();
421}
422
423bool SvStream::ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
424 sal_Int32 nMaxBytesToRead )
425{
426 OString aStr;
427 bool bRet = ReadLine( aStr, nMaxBytesToRead);
428 rStr = OStringToOUString(aStr, eSrcCharSet);
429 return bRet;
430}
431
432bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
433{
434 OStringBuffer aBuf(4096);
435 bool rv = ReadLine(aBuf, nMaxBytesToRead);
436 rStr = aBuf.makeStringAndClear();
437 return rv;
438}
439
440bool SvStream::ReadLine( OStringBuffer& aBuf, sal_Int32 nMaxBytesToRead )
441{
442 char buf[256+1];
443 bool bEnd = false;
444 sal_uInt64 nOldFilePos = Tell();
445 char c = 0;
446 std::size_t nTotalLen = 0;
447
448 aBuf.setLength(0);
449 while( !bEnd && !GetError() ) // Don't test for EOF as we
450 // are reading block-wise!
451 {
452 sal_uInt16 nLen = static_cast<sal_uInt16>(ReadBytes(buf, sizeof(buf)-1));
453 if ( !nLen )
454 {
455 if ( aBuf.isEmpty() )
456 {
457 // Exit on first block-read error
458 m_isEof = true;
459 aBuf.setLength(0);
460 return false;
461 }
462 else
463 break;
464 }
465
466 sal_uInt16 j, n;
467 for( j = n = 0; j < nLen ; ++j )
468 {
469 c = buf[j];
470 if ( c == '\n' || c == '\r' )
471 {
472 bEnd = true;
473 break;
474 }
475 if ( n < j )
476 buf[n] = c;
477 ++n;
478 }
479 nTotalLen += j;
480 if (nTotalLen > o3tl::make_unsigned(nMaxBytesToRead))
481 {
482 n -= nTotalLen - nMaxBytesToRead;
483 nTotalLen = nMaxBytesToRead;
484 bEnd = true;
485 }
486 if ( n )
487 aBuf.append(buf, n);
488 }
489
490 if ( !bEnd && !GetError() && !aBuf.isEmpty() )
491 bEnd = true;
492
493 nOldFilePos += nTotalLen;
494 if( Tell() > nOldFilePos )
495 nOldFilePos++;
496 Seek( nOldFilePos ); // Seek pointer due to BlockRead above
497
498 if ( bEnd && (c=='\r' || c=='\n') ) // Special treatment for DOS files
499 {
500 char cTemp;
501 std::size_t nLen = ReadBytes(&cTemp, sizeof(cTemp));
502 if ( nLen ) {
503 if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
504 Seek( nOldFilePos );
505 }
506 }
507
508 if ( bEnd )
509 m_isEof = false;
510 return bEnd;
511}
512
513bool SvStream::ReadUniStringLine( OUString& rStr, sal_Int32 nMaxCodepointsToRead )
514{
515 sal_Unicode buf[256+1];
516 bool bEnd = false;
517 sal_uInt64 nOldFilePos = Tell();
518 sal_Unicode c = 0;
519 std::size_t nTotalLen = 0;
520
521 DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
522
523 OUStringBuffer aBuf(4096);
524 while( !bEnd && !GetError() ) // Don't test for EOF as we
525 // are reading block-wise!
526 {
527 sal_uInt16 nLen = static_cast<sal_uInt16>(ReadBytes( buf, sizeof(buf)-sizeof(sal_Unicode)));
528 nLen /= sizeof(sal_Unicode);
529 if ( !nLen )
530 {
531 if ( aBuf.isEmpty() )
532 {
533 // exit on first BlockRead error
534 m_isEof = true;
535 rStr.clear();
536 return false;
537 }
538 else
539 break;
540 }
541
542 sal_uInt16 j, n;
543 for( j = n = 0; j < nLen ; ++j )
544 {
545 if (m_isSwap)
546 SwapNumber( buf[n] );
547 c = buf[j];
548 if ( c == '\n' || c == '\r' )
549 {
550 bEnd = true;
551 break;
552 }
553 // erAck 26.02.01: Old behavior was no special treatment of '\0'
554 // character here, but a following rStr+=c did ignore it. Is this
555 // really intended? Or should a '\0' better terminate a line?
556 // The nOldFilePos stuff wasn't correct then anyways.
557 if ( c )
558 {
559 if ( n < j )
560 buf[n] = c;
561 ++n;
562 }
563 }
564 nTotalLen += j;
565 if (nTotalLen > o3tl::make_unsigned(nMaxCodepointsToRead))
566 {
567 n -= nTotalLen - nMaxCodepointsToRead;
568 nTotalLen = nMaxCodepointsToRead;
569 bEnd = true;
570 }
571 if ( n )
572 aBuf.append( buf, n );
573 }
574
575 if ( !bEnd && !GetError() && !aBuf.isEmpty() )
576 bEnd = true;
577
578 nOldFilePos += nTotalLen * sizeof(sal_Unicode);
579 if( Tell() > nOldFilePos )
580 nOldFilePos += sizeof(sal_Unicode);
581 Seek( nOldFilePos ); // seek due to BlockRead above
582
583 if ( bEnd && (c=='\r' || c=='\n') ) // special treatment for DOS files
584 {
585 sal_Unicode cTemp;
586 ReadBytes( &cTemp, sizeof(cTemp) );
587 if (m_isSwap)
588 SwapNumber( cTemp );
589 if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
590 Seek( nOldFilePos );
591 }
592
593 if ( bEnd )
594 m_isEof = false;
595 rStr = aBuf.makeStringAndClear();
596 return bEnd;
597}
598
599bool SvStream::ReadUniOrByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
600 sal_Int32 nMaxCodepointsToRead )
601{
602 if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
603 return ReadUniStringLine( rStr, nMaxCodepointsToRead );
604 else
605 return ReadByteStringLine( rStr, eSrcCharSet, nMaxCodepointsToRead );
606}
607
609{
610 OStringBuffer aOutput(256);
611
612 char buf[ 256 + 1 ];
613 bool bEnd = false;
614 sal_uInt64 nFilePos = rStream.Tell();
615
616 while( !bEnd && !rStream.GetError() )
617 {
618 std::size_t nLen = rStream.ReadBytes(buf, sizeof(buf)-1);
619 if (!nLen)
620 break;
621
622 std::size_t nReallyRead = nLen;
623 const char* pPtr = buf;
624 while (nLen && *pPtr)
625 {
626 ++pPtr;
627 --nLen;
628 }
629
630 bEnd = ( nReallyRead < sizeof(buf)-1 ) // read less than attempted to read
631 || ( ( nLen > 0 ) // OR it is inside the block we read
632 && ( 0 == *pPtr ) // AND found a string terminator
633 );
634
635 aOutput.append(buf, pPtr - buf);
636 }
637
638 nFilePos += aOutput.getLength();
639 if (rStream.Tell() > nFilePos)
640 rStream.Seek(nFilePos+1); // seek due to FileRead above
641 return aOutput.makeStringAndClear();
642}
643
644OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStream, rtl_TextEncoding eEnc)
645{
646 return OStringToOUString(
648}
649
652std::size_t write_uInt16s_FromOUString(SvStream& rStrm, std::u16string_view rStr,
653 std::size_t nUnits)
654{
655 DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
656 std::size_t nWritten;
657 if (!rStrm.IsEndianSwap())
658 nWritten = rStrm.WriteBytes(rStr.data(), nUnits * sizeof(sal_Unicode));
659 else
660 {
661 std::size_t nLen = nUnits;
662 sal_Unicode aBuf[384];
663 sal_Unicode* const pTmp = ( nLen > 384 ? new sal_Unicode[nLen] : aBuf);
664 memcpy( pTmp, rStr.data(), nLen * sizeof(sal_Unicode) );
665 sal_Unicode* p = pTmp;
666 const sal_Unicode* const pStop = pTmp + nLen;
667 while ( p < pStop )
668 {
669 SwapNumber( *p );
670 p++;
671 }
672 nWritten = rStrm.WriteBytes( pTmp, nLen * sizeof(sal_Unicode) );
673 if ( pTmp != aBuf )
674 delete [] pTmp;
675 }
676 return nWritten;
677}
678
679bool SvStream::WriteUnicodeOrByteText( std::u16string_view rStr, rtl_TextEncoding eDestCharSet )
680{
681 if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
682 {
683 write_uInt16s_FromOUString(*this, rStr, rStr.size());
684 return m_nError == ERRCODE_NONE;
685 }
686 else
687 {
688 OString aStr(OUStringToOString(rStr, eDestCharSet));
689 write_uInt8s_FromOString(*this, aStr, aStr.getLength());
690 return m_nError == ERRCODE_NONE;
691 }
692}
693
694bool SvStream::WriteByteStringLine( std::u16string_view rStr, rtl_TextEncoding eDestCharSet )
695{
696 return WriteLine(OUStringToOString(rStr, eDestCharSet));
697}
698
699bool SvStream::WriteLine(std::string_view rStr)
700{
701 WriteBytes(rStr.data(), rStr.size());
702 endl(*this);
703 return m_nError == ERRCODE_NONE;
704}
705
706bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
707{
708 if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
710 else
711 {
712 OString aStr(&ch, 1, eDestCharSet);
713 WriteBytes(aStr.getStr(), aStr.getLength());
714 }
715 return m_nError == ERRCODE_NONE;
716}
717
719{
720 m_isSwap = false; // Switch to no endian swapping
721 // BOM, Byte Order Mark, U+FEFF, see
722 // http://www.unicode.org/faq/utf_bom.html#BOM
723 // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
724 WriteUInt16(0xfeff);
725}
726
727void SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet )
728{
729 if (!( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
730 eReadBomCharSet == RTL_TEXTENCODING_UNICODE ||
731 eReadBomCharSet == RTL_TEXTENCODING_UTF8))
732 return; // nothing to read
733
734 const sal_uInt64 nOldPos = Tell();
735 bool bGetBack = true;
736 unsigned char nFlag(0);
737 ReadUChar( nFlag );
738 switch ( nFlag )
739 {
740 case 0xfe: // UTF-16BE?
741 if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
742 eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
743 {
744 ReadUChar(nFlag);
745 if (nFlag == 0xff)
746 {
748 bGetBack = false;
749 }
750 }
751 break;
752 case 0xff: // UTF-16LE?
753 if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
754 eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
755 {
756 ReadUChar(nFlag);
757 if (nFlag == 0xfe)
758 {
760 bGetBack = false;
761 }
762 }
763 break;
764 case 0xef: // UTF-8?
765 if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
766 eReadBomCharSet == RTL_TEXTENCODING_UTF8)
767 {
768 ReadUChar(nFlag);
769 if (nFlag == 0xbb)
770 {
771 ReadUChar(nFlag);
772 if (nFlag == 0xbf)
773 bGetBack = false; // it is UTF-8
774 }
775 }
776 break;
777 default:
778 ; // nothing
779 }
780 if (bGetBack)
781 Seek(nOldPos); // no BOM, pure data
782}
783
784sal_uInt64 SvStream::SeekRel(sal_Int64 const nPos)
785{
786 sal_uInt64 nActualPos = Tell();
787
788 if ( nPos >= 0 )
789 {
790 if (SAL_MAX_UINT64 - nActualPos > o3tl::make_unsigned(nPos))
791 nActualPos += nPos;
792 }
793 else
794 {
795 sal_uInt64 const nAbsPos = static_cast<sal_uInt64>(-nPos);
796 if ( nActualPos >= nAbsPos )
797 nActualPos -= nAbsPos;
798 }
799
800 assert((m_pBufPos != nullptr) == bool(m_pRWBuf));
801 if (m_pRWBuf)
802 {
803 m_pBufPos = m_pRWBuf.get() + nActualPos;
804 }
805 return Seek( nActualPos );
806}
807
808template <typename T> SvStream& SvStream::ReadNumber(T& r)
809{
810 T n = 0;
812 if (good())
813 {
814 if (m_isSwap)
815 SwapNumber(n);
816 r = n;
817 }
818 return *this;
819}
820
821SvStream& SvStream::ReadUInt16(sal_uInt16& r) { return ReadNumber(r); }
822SvStream& SvStream::ReadUInt32(sal_uInt32& r) { return ReadNumber(r); }
823SvStream& SvStream::ReadUInt64(sal_uInt64& r) { return ReadNumber(r); }
824SvStream& SvStream::ReadInt16(sal_Int16& r) { return ReadNumber(r); }
825SvStream& SvStream::ReadInt32(sal_Int32& r) { return ReadNumber(r); }
826SvStream& SvStream::ReadInt64(sal_Int64& r) { return ReadNumber(r); }
827
829{
830 if (m_isIoRead && sizeof(signed char) <= m_nBufFree)
831 {
832 r = *m_pBufPos;
833 m_nBufActualPos += sizeof(signed char);
834 m_pBufPos += sizeof(signed char);
835 m_nBufFree -= sizeof(signed char);
836 }
837 else
838 ReadBytes( &r, sizeof(signed char) );
839 return *this;
840}
841
842// Special treatment for Chars due to PutBack
843
845{
846 if (m_isIoRead && sizeof(char) <= m_nBufFree)
847 {
848 r = *m_pBufPos;
849 m_nBufActualPos += sizeof(char);
850 m_pBufPos += sizeof(char);
851 m_nBufFree -= sizeof(char);
852 }
853 else
854 ReadBytes( &r, sizeof(char) );
855 return *this;
856}
857
858SvStream& SvStream::ReadUChar( unsigned char& r )
859{
860 if (m_isIoRead && sizeof(char) <= m_nBufFree)
861 {
862 r = *m_pBufPos;
863 m_nBufActualPos += sizeof(char);
864 m_pBufPos += sizeof(char);
865 m_nBufFree -= sizeof(char);
866 }
867 else
868 ReadBytes( &r, sizeof(char) );
869 return *this;
870}
871
873
875{
876 if (m_isIoRead && sizeof(char) <= m_nBufFree)
877 {
879 *m_pBufPos > 1, "tools.stream", unsigned(*m_pBufPos) << " not 0/1");
880 r = *m_pBufPos != 0;
881 m_nBufActualPos += sizeof(char);
882 m_pBufPos += sizeof(char);
883 m_nBufFree -= sizeof(char);
884 }
885 else
886 {
887 unsigned char c;
888 if (ReadBytes(&c, 1) == 1)
889 {
890 SAL_WARN_IF(c > 1, "tools.stream", unsigned(c) << " not 0/1");
891 r = c != 0;
892 }
893 }
894 return *this;
895}
896
898{
899 float n = 0;
901 if (good())
902 {
903#if defined UNX
904 if (m_isSwap)
905 SwapFloat(n);
906#endif
907 r = n;
908 }
909 return *this;
910}
911
913{
914 double n = 0;
916 if (good())
917 {
918#if defined UNX
919 if (m_isSwap)
920 SwapDouble(n);
921#endif
922 r = n;
923 }
924 return *this;
925}
926
928{
929 const sal_uInt32 cBufLen = 0x8000;
930 std::unique_ptr<char[]> pBuf( new char[ cBufLen ] );
931
932 sal_uInt32 nCount;
933 do {
934 nCount = ReadBytes( pBuf.get(), cBufLen );
935 rStream.WriteBytes( pBuf.get(), nCount );
936 } while( nCount == cBufLen );
937
938 return *this;
939}
940
941template <typename T> SvStream& SvStream::WriteNumber(T n)
942{
943 if (m_isSwap)
944 SwapNumber(n);
946 return *this;
947}
948
949SvStream& SvStream::WriteUInt16(sal_uInt16 v) { return WriteNumber(v); }
950SvStream& SvStream::WriteUInt32(sal_uInt32 v) { return WriteNumber(v); }
951SvStream& SvStream::WriteUInt64(sal_uInt64 v) { return WriteNumber(v); }
952SvStream& SvStream::WriteInt16(sal_Int16 v) { return WriteNumber(v); }
953SvStream& SvStream::WriteInt32(sal_Int32 v) { return WriteNumber(v); }
954SvStream& SvStream::WriteInt64(sal_Int64 v) { return WriteNumber(v); }
955
957{
958 //SDO
959 if (m_isIoWrite && sizeof(signed char) <= m_nBufFree)
960 {
961 *m_pBufPos = v;
962 m_pBufPos++; // sizeof(char);
964 if (m_nBufActualPos > m_nBufActualLen) // Append ?
966 m_nBufFree--; // = sizeof(char);
967 m_isDirty = true;
968 }
969 else
970 WriteBytes( &v, sizeof(signed char) );
971 return *this;
972}
973
974// Special treatment for Chars due to PutBack
975
977{
978 //SDO
979 if (m_isIoWrite && sizeof(char) <= m_nBufFree)
980 {
981 *m_pBufPos = v;
982 m_pBufPos++; // sizeof(char);
984 if (m_nBufActualPos > m_nBufActualLen) // Append ?
986 m_nBufFree--; // = sizeof(char);
987 m_isDirty = true;
988 }
989 else
990 WriteBytes( &v, sizeof(char) );
991 return *this;
992}
993
995{
996//SDO
997 if (m_isIoWrite && sizeof(char) <= m_nBufFree)
998 {
999 *reinterpret_cast<unsigned char*>(m_pBufPos) = v;
1000 m_pBufPos++; // = sizeof(char);
1001 m_nBufActualPos++; // = sizeof(char);
1002 if (m_nBufActualPos > m_nBufActualLen) // Append ?
1004 m_nBufFree--;
1005 m_isDirty = true;
1006 }
1007 else
1008 WriteBytes( &v, sizeof(char) );
1009 return *this;
1010}
1011
1013{
1014 return WriteUChar(v);
1015}
1016
1018{
1019 return WriteUInt16(v);
1020}
1021
1023{
1024#ifdef UNX
1025 if (m_isSwap)
1026 SwapFloat(v);
1027#endif
1029 return *this;
1030}
1031
1033{
1034#if defined UNX
1035 if (m_isSwap)
1036 {
1037 double nHelp = r;
1038 SwapDouble(nHelp);
1040 return *this;
1041 }
1042 else
1043#endif
1044 {
1046 }
1047 return *this;
1048}
1049
1051{
1052 const sal_uInt32 cBufLen = 0x8000;
1053 std::unique_ptr<char[]> pBuf( new char[ cBufLen ] );
1054 sal_uInt32 nCount;
1055 do {
1056 nCount = rStream.ReadBytes( pBuf.get(), cBufLen );
1057 WriteBytes( pBuf.get(), nCount );
1058 } while( nCount == cBufLen );
1059
1060 return *this;
1061}
1062
1063sal_uInt64 SvStream::WriteStream( SvStream& rStream, sal_uInt64 nSize )
1064{
1065 const sal_uInt32 cBufLen = 0x8000;
1066 std::unique_ptr<char[]> pBuf( new char[ cBufLen ] );
1067 sal_uInt32 nCurBufLen = cBufLen;
1068 sal_uInt32 nCount;
1069 sal_uInt64 nWriteSize = nSize;
1070
1071 do
1072 {
1073 nCurBufLen = std::min<sal_uInt64>(nCurBufLen, nWriteSize);
1074 nCount = rStream.ReadBytes(pBuf.get(), nCurBufLen);
1075 WriteBytes( pBuf.get(), nCount );
1076 nWriteSize -= nCount;
1077 }
1078 while( nWriteSize && nCount == nCurBufLen );
1079
1080 return nSize - nWriteSize;
1081}
1082
1083OUString SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet )
1084{
1085 // read UTF-16 string directly from stream ?
1086 if (eSrcCharSet == RTL_TEXTENCODING_UNICODE)
1088 return read_uInt16_lenPrefixed_uInt8s_ToOUString(*this, eSrcCharSet);
1089}
1090
1091SvStream& SvStream::WriteUniOrByteString( std::u16string_view rStr, rtl_TextEncoding eDestCharSet )
1092{
1093 // write UTF-16 string directly into stream ?
1094 if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
1096 else
1097 write_uInt16_lenPrefixed_uInt8s_FromOUString(*this, rStr, eDestCharSet);
1098 return *this;
1099}
1100
1102{
1103 if (m_isDirty) // Does stream require a flush?
1104 {
1106 if (m_nCryptMask)
1108 else if (PutData(m_pRWBuf.get(), m_nBufActualLen) != m_nBufActualLen)
1110 m_isDirty = false;
1111 }
1112}
1113
1114std::size_t SvStream::ReadBytes( void* pData, std::size_t nCount )
1115{
1116 std::size_t nSaveCount = nCount;
1117
1118 if (!m_pRWBuf)
1119 {
1121 if (m_nCryptMask)
1124 }
1125 else
1126 {
1127 // check if block is completely within buffer
1128 m_isIoRead = true;
1129 m_isIoWrite = false;
1131 {
1132 // => yes
1133 if (nCount != 0)
1134 memcpy(pData, m_pBufPos, nCount);
1135 m_nBufActualPos = m_nBufActualPos + static_cast<sal_uInt16>(nCount);
1136 m_pBufPos += nCount;
1137 m_nBufFree = m_nBufFree - static_cast<sal_uInt16>(nCount);
1138 }
1139 else
1140 {
1141 FlushBuffer();
1142
1143 // Does data block fit into buffer?
1144 if (nCount > m_nBufSize)
1145 {
1146 // => No! Thus read directly
1147 // into target area without using the buffer
1148
1149 m_isIoRead = false;
1150
1152 m_nBufActualLen = 0;
1153 m_pBufPos = m_pRWBuf.get();
1154 nCount = GetData( pData, nCount );
1155 if (m_nCryptMask)
1159 m_nBufActualPos = 0;
1160 }
1161 else
1162 {
1163 // => Yes. Fill buffer first, then copy to target area
1164
1167
1168 // TODO: Typecast before GetData, sal_uInt16 nCountTmp
1169 std::size_t nCountTmp = GetData( m_pRWBuf.get(), m_nBufSize );
1170 if (m_nCryptMask)
1171 EncryptBuffer(m_pRWBuf.get(), nCountTmp);
1172 m_nBufActualLen = static_cast<sal_uInt16>(nCountTmp);
1173 if( nCount > nCountTmp )
1174 {
1175 nCount = nCountTmp; // trim count back, EOF see below
1176 }
1177 memcpy( pData, m_pRWBuf.get(), nCount );
1178 m_nBufActualPos = static_cast<sal_uInt16>(nCount);
1179 m_pBufPos = m_pRWBuf.get() + nCount;
1180 }
1181 }
1182 }
1183 m_isEof = false;
1185 if (nCount != nSaveCount && m_nError != ERRCODE_IO_PENDING)
1186 m_isEof = true;
1187 if (nCount == nSaveCount && m_nError == ERRCODE_IO_PENDING)
1189 return nCount;
1190}
1191
1192std::size_t SvStream::WriteBytes( const void* pData, std::size_t nCount )
1193{
1194 if( !nCount )
1195 return 0;
1196
1197 if (!m_isWritable)
1198 {
1200 return 0;
1201 }
1202
1203 if (!m_pRWBuf)
1204 {
1205 if (m_nCryptMask)
1207 else
1208 nCount = PutData( pData, nCount );
1210 return nCount;
1211 }
1212
1213 m_isIoRead = false;
1214 m_isIoWrite = true;
1216 {
1217 memcpy( m_pBufPos, pData, nCount );
1218 m_nBufActualPos = m_nBufActualPos + static_cast<sal_uInt16>(nCount);
1219 // Update length if buffer was updated
1222
1223 m_pBufPos += nCount;
1224 m_isDirty = true;
1225 }
1226 else
1227 {
1228 FlushBuffer();
1229
1230 // Does data block fit into buffer?
1231 if (nCount > m_nBufSize)
1232 {
1233 m_isIoWrite = false;
1235 m_nBufActualLen = 0;
1236 m_nBufActualPos = 0;
1237 m_pBufPos = m_pRWBuf.get();
1239 if (m_nCryptMask)
1241 else
1242 nCount = PutData( pData, nCount );
1244 }
1245 else
1246 {
1247 // Copy block to buffer
1248 memcpy( m_pRWBuf.get(), pData, nCount );
1249
1250 // Mind the order!
1252 m_nBufActualPos = static_cast<sal_uInt16>(nCount);
1253 m_pBufPos = m_pRWBuf.get() + nCount;
1254 m_nBufActualLen = static_cast<sal_uInt16>(nCount);
1255 m_isDirty = true;
1256 }
1257 }
1259 return nCount;
1260}
1261
1262sal_uInt64 SvStream::Seek(sal_uInt64 const nFilePos)
1263{
1264 m_isIoRead = m_isIoWrite = false;
1265 m_isEof = false;
1266 if (!m_pRWBuf)
1267 {
1268 m_nBufFilePos = SeekPos( nFilePos );
1269 DBG_ASSERT(Tell() == m_nBufFilePos,"Out Of Sync!");
1270 return m_nBufFilePos;
1271 }
1272
1273 // Is seek position within buffer?
1274 if (nFilePos >= m_nBufFilePos && nFilePos <= (m_nBufFilePos + m_nBufActualLen))
1275 {
1276 m_nBufActualPos = static_cast<sal_uInt16>(nFilePos - m_nBufFilePos);
1278 // Update m_nBufFree to avoid crash upon PutBack
1280 }
1281 else
1282 {
1283 FlushBuffer();
1284 m_nBufActualLen = 0;
1285 m_nBufActualPos = 0;
1286 m_pBufPos = m_pRWBuf.get();
1287 m_nBufFilePos = SeekPos( nFilePos );
1288 }
1290}
1291
1292bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
1293{
1294 const sal_uInt64 nMaxSeek = rSt.TellEnd();
1295 return (nOffset <= nMaxSeek && rSt.Seek(nOffset) == nOffset);
1296}
1297
1298namespace tools
1299{
1300bool isEmptyFileUrl(const OUString& rUrl)
1301{
1302 if (!comphelper::isFileUrl(rUrl))
1303 {
1304 return false;
1305 }
1306
1307 SvFileStream aStream(rUrl, StreamMode::READ);
1308 if (!aStream.IsOpen())
1309 {
1310 return false;
1311 }
1312
1313 return aStream.remainingSize() == 0;
1314}
1315}
1316
1317//STREAM_SEEK_TO_END in some of the Seek backends is special cased to be
1318//efficient, in others e.g. SotStorageStream it's really horribly slow, and in
1319//those this should be overridden
1321{
1322 sal_uInt64 const nCurr = Tell();
1323 sal_uInt64 const nEnd = TellEnd();
1324 sal_uInt64 nMaxAvailable = nEnd > nCurr ? (nEnd-nCurr) : 0;
1325 return nMaxAvailable;
1326}
1327
1329{
1330 FlushBuffer();
1331 sal_uInt64 const nCurr = Tell();
1332 sal_uInt64 const nEnd = Seek(STREAM_SEEK_TO_END);
1333 Seek(nCurr);
1334 return nEnd;
1335}
1336
1338{
1339 FlushBuffer();
1340 if (m_isWritable)
1341 FlushData();
1342}
1343
1345{
1346 FlushBuffer();
1348 m_nBufActualLen = static_cast<sal_uInt16>(GetData( m_pRWBuf.get(), m_nBufSize ));
1351 if (m_nCryptMask)
1352 EncryptBuffer(m_pRWBuf.get(), static_cast<std::size_t>(m_nBufActualLen));
1353 m_isIoRead = m_isIoWrite = false;
1354}
1355
1356#define CRYPT_BUFSIZE 1024
1357
1359std::size_t SvStream::CryptAndWriteBuffer( const void* pStart, std::size_t nLen)
1360{
1361 unsigned char pTemp[CRYPT_BUFSIZE];
1362 unsigned char const * pDataPtr = static_cast<unsigned char const *>(pStart);
1363 std::size_t nCount = 0;
1364 std::size_t nBufCount;
1365 unsigned char nMask = m_nCryptMask;
1366 do
1367 {
1368 if( nLen >= CRYPT_BUFSIZE )
1369 nBufCount = CRYPT_BUFSIZE;
1370 else
1371 nBufCount = nLen;
1372 nLen -= nBufCount;
1373 memcpy( pTemp, pDataPtr, static_cast<sal_uInt16>(nBufCount) );
1374 // ******** Encrypt ********
1375 for (unsigned char & rn : pTemp)
1376 {
1377 unsigned char aCh = rn;
1378 aCh ^= nMask;
1379 swapNibbles(aCh);
1380 rn = aCh;
1381 }
1382 // *************************
1383 nCount += PutData( pTemp, nBufCount );
1384 pDataPtr += nBufCount;
1385 }
1386 while ( nLen );
1387 return nCount;
1388}
1389
1390void SvStream::EncryptBuffer(void* pStart, std::size_t nLen) const
1391{
1392 unsigned char* pTemp = static_cast<unsigned char*>(pStart);
1393 unsigned char nMask = m_nCryptMask;
1394
1395 for ( std::size_t n=0; n < nLen; n++, pTemp++ )
1396 {
1397 unsigned char aCh = *pTemp;
1398 swapNibbles(aCh);
1399 aCh ^= nMask;
1400 *pTemp = aCh;
1401 }
1402}
1403
1404static unsigned char implGetCryptMask(const char* pStr, sal_Int32 nLen, tools::Long nVersion)
1405{
1406 unsigned char nCryptMask = 0;
1407
1408 if (!nLen)
1409 return nCryptMask;
1410
1412 {
1413 while( nLen )
1414 {
1415 nCryptMask ^= *pStr;
1416 pStr++;
1417 nLen--;
1418 }
1419 }
1420 else // BugFix #25888#
1421 {
1422 for( sal_Int32 i = 0; i < nLen; i++ ) {
1423 nCryptMask ^= pStr[i];
1424 if( nCryptMask & 0x80 ) {
1425 nCryptMask <<= 1;
1426 nCryptMask++;
1427 }
1428 else
1429 nCryptMask <<= 1;
1430 }
1431 }
1432
1433 if( !nCryptMask )
1434 nCryptMask = 67;
1435
1436 return nCryptMask;
1437}
1438
1439void SvStream::SetCryptMaskKey(const OString& rCryptMaskKey)
1440{
1441 m_aCryptMaskKey = rCryptMaskKey;
1443 m_aCryptMaskKey.getLength(), GetVersion());
1444}
1445
1446bool SvStream::SetStreamSize(sal_uInt64 const nSize)
1447{
1448#ifdef DBG_UTIL
1449 sal_uInt64 nFPos = Tell();
1450#endif
1451 sal_uInt16 nBuf = m_nBufSize;
1452 SetBufferSize( 0 );
1453 SetSize( nSize );
1454 if (nSize < m_nBufFilePos)
1455 {
1456 m_nBufFilePos = nSize;
1457 }
1458 SetBufferSize( nBuf );
1459#ifdef DBG_UTIL
1460 DBG_ASSERT(Tell()==nFPos,"SetStreamSize failed");
1461#endif
1462 return (m_nError == ERRCODE_NONE);
1463}
1464
1466{
1467 LineEnd eDelim = rStr.GetLineDelimiter();
1468 if ( eDelim == LINEEND_CR )
1469 rStr.WriteChar('\r');
1470 else if( eDelim == LINEEND_LF )
1471 rStr.WriteChar('\n');
1472 else
1473 rStr.WriteChar('\r').WriteChar('\n');
1474 return rStr;
1475}
1476
1478{
1479 switch ( rStrm.GetLineDelimiter() )
1480 {
1481 case LINEEND_CR :
1482 rStrm.WriteUnicode('\r');
1483 break;
1484 case LINEEND_LF :
1485 rStrm.WriteUnicode('\n');
1486 break;
1487 default:
1488 rStrm.WriteUnicode('\r').WriteUnicode('\n');
1489 }
1490 return rStrm;
1491}
1492
1494{
1495 if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
1496 return endlu( rStrm );
1497 else
1498 return endl( rStrm );
1499}
1500
1501SvMemoryStream::SvMemoryStream( void* pBuffer, std::size_t bufSize,
1502 StreamMode eMode )
1503{
1504 if( eMode & StreamMode::WRITE )
1505 m_isWritable = true;
1506 else
1507 m_isWritable = false;
1508 nEndOfData = bufSize;
1509 bOwnsData = false;
1510 pBuf = static_cast<sal_uInt8 *>(pBuffer);
1511 nResize = 0;
1512 nSize = bufSize;
1513 nPos = 0;
1514 SetBufferSize( 0 );
1515}
1516
1517SvMemoryStream::SvMemoryStream( std::size_t nInitSize, std::size_t nResizeOffset )
1518{
1519 m_isWritable = true;
1520 bOwnsData = true;
1521 nEndOfData = 0;
1522 nResize = nResizeOffset;
1523 nPos = 0;
1524 pBuf = nullptr;
1525 if( nResize != 0 && nResize < 16 )
1526 nResize = 16;
1527 if( nInitSize )
1528 AllocateMemory( nInitSize );
1529 nSize = nInitSize;
1530 SetBufferSize( 64 );
1531}
1532
1534{
1535 if( pBuf )
1536 {
1537 if( bOwnsData )
1538 FreeMemory();
1539 else
1540 FlushBuffer();
1541 }
1542}
1543
1544void SvMemoryStream::SetBuffer( void* pNewBuf, std::size_t nCount,
1545 std::size_t nEOF )
1546{
1547 SetBufferSize( 0 ); // Init buffering in the base class
1548 Seek( 0 );
1549 if( bOwnsData && pNewBuf != pBuf )
1550 FreeMemory();
1551
1552 pBuf = static_cast<sal_uInt8 *>(pNewBuf);
1553 nPos = 0;
1554 nSize = nCount;
1555 nResize = 0;
1556 bOwnsData = false;
1557
1558 if( nEOF > nCount )
1559 nEOF = nCount;
1560 nEndOfData = nEOF;
1561
1562 ResetError();
1563}
1564
1565std::size_t SvMemoryStream::GetData( void* pData, std::size_t nCount )
1566{
1567 std::size_t nMaxCount = nEndOfData-nPos;
1568 if( nCount > nMaxCount )
1569 nCount = nMaxCount;
1570 if (nCount != 0)
1571 {
1572 memcpy( pData, pBuf+nPos, nCount );
1573 }
1574 nPos += nCount;
1575 return nCount;
1576}
1577
1578std::size_t SvMemoryStream::PutData( const void* pData, std::size_t nCount )
1579{
1580 if( GetError() )
1581 return 0;
1582
1583 std::size_t nMaxCount = nSize-nPos;
1584
1585 // check for overflow
1586 if( nCount > nMaxCount )
1587 {
1588 if( nResize == 0 )
1589 {
1590 // copy as much as possible
1591 nCount = nMaxCount;
1593 }
1594 else
1595 {
1596 tools::Long nNewResize;
1597 if( nSize && nSize > nResize )
1598 nNewResize = nSize;
1599 else
1600 nNewResize = nResize;
1601
1602 if( (nCount-nMaxCount) < nResize )
1603 {
1604 // lacking memory is smaller than nResize,
1605 // resize accordingly
1606 if( !ReAllocateMemory( nNewResize) )
1607 {
1608 nCount = 0;
1610 }
1611 }
1612 else
1613 {
1614 // lacking memory is larger than nResize,
1615 // resize by (nCount-nMaxCount) + resize offset
1616 if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
1617 {
1618 nCount = 0;
1620 }
1621 }
1622 }
1623 }
1624 assert(pBuf && "Possibly Reallocate failed");
1625 memcpy( pBuf+nPos, pData, nCount);
1626
1627 nPos += nCount;
1628 if( nPos > nEndOfData )
1629 nEndOfData = nPos;
1630 return nCount;
1631}
1632
1633sal_uInt64 SvMemoryStream::SeekPos(sal_uInt64 const nNewPos)
1634{
1635 // nEndOfData: First position in stream not allowed to read from
1636 // nSize: Size of allocated buffer
1637
1638 // check if a truncated STREAM_SEEK_TO_END was passed
1639 assert(nNewPos != SAL_MAX_UINT32);
1640 if( nNewPos < nEndOfData )
1641 nPos = nNewPos;
1642 else if( nNewPos == STREAM_SEEK_TO_END )
1643 nPos = nEndOfData;
1644 else
1645 {
1646 if( nNewPos >= nSize ) // Does buffer need extension?
1647 {
1648 if( nResize ) // Is extension possible?
1649 {
1650 tools::Long nDiff = static_cast<tools::Long>(nNewPos - nSize + 1);
1651 nDiff += static_cast<tools::Long>(nResize);
1652 ReAllocateMemory( nDiff );
1653 nPos = nNewPos;
1654 nEndOfData = nNewPos;
1655 }
1656 else // Extension not possible, set pos to end of data
1657 {
1658 // SetError( SVSTREAM_OUTOFMEMORY );
1659 nPos = nEndOfData;
1660 }
1661 }
1662 else // Expand buffer size
1663 {
1664 nPos = nNewPos;
1665 nEndOfData = nNewPos;
1666 }
1667 }
1668 return nPos;
1669}
1670
1672{
1673}
1674
1676{
1678}
1679
1680void SvMemoryStream::AllocateMemory( std::size_t nNewSize )
1681{
1682 pBuf = new sal_uInt8[nNewSize];
1683}
1684
1685// (using Bozo algorithm)
1687{
1688 if (!m_isWritable || !bOwnsData)
1689 return false;
1690
1691 bool bRetVal = false;
1692 tools::Long nTemp = static_cast<tools::Long>(nSize);
1693 nTemp += nDiff;
1694 std::size_t nNewSize = static_cast<std::size_t>(nTemp);
1695
1696 if( nNewSize )
1697 {
1698 sal_uInt8* pNewBuf = new sal_uInt8[nNewSize];
1699
1700 bRetVal = true; // Success!
1701 if( nNewSize < nSize ) // Are we shrinking?
1702 {
1703 memcpy( pNewBuf, pBuf, nNewSize );
1704 if( nPos > nNewSize )
1705 nPos = 0;
1706 if( nEndOfData >= nNewSize )
1707 nEndOfData = nNewSize-1;
1708 }
1709 else
1710 {
1711 if (nSize != 0)
1712 {
1713 memcpy( pNewBuf, pBuf, nSize );
1714 }
1715 memset(pNewBuf + nSize, 0x00, nNewSize - nSize);
1716 }
1717
1718 FreeMemory();
1719
1720 pBuf = pNewBuf;
1721 nSize = nNewSize;
1722 }
1723 else
1724 {
1725 bRetVal = true;
1726 FreeMemory();
1727 pBuf = nullptr;
1728 nSize = 0;
1729 nEndOfData = 0;
1730 nPos = 0;
1731 }
1732
1733 return bRetVal;
1734}
1735
1737{
1738 assert(bOwnsData);
1739 if (bOwnsData)
1740 {
1741 delete[] pBuf;
1742 pBuf = nullptr;
1743 }
1744}
1745
1747{
1748 FlushBuffer();
1749 if( !bOwnsData )
1750 return nullptr;
1752
1753 void* pRetVal = pBuf;
1754 pBuf = nullptr;
1755 nEndOfData = 0;
1756 nResize = 64;
1757 nPos = 0;
1758
1759 ResetError();
1760
1761 std::size_t nInitSize = 512;
1762 AllocateMemory(nInitSize);
1763 nSize = nInitSize;
1764
1765 SetBufferSize( 64 );
1766 return pRetVal;
1767}
1768
1769void SvMemoryStream::SetSize(sal_uInt64 const nNewSize)
1770{
1771 if (!m_isWritable)
1772 {
1774 return;
1775 }
1776
1777 tools::Long nDiff = static_cast<tools::Long>(nNewSize) - static_cast<tools::Long>(nSize);
1778 ReAllocateMemory( nDiff );
1779}
1780
1782{
1783 FlushBuffer();
1784 m_isWritable = false;
1785 nResize = 0;
1786 SetBufferSize( 0 );
1787}
1788
1789// Create an OString of nLen bytes from rStream
1790// coverity[ +taint_sanitize ]
1791OString read_uInt8s_ToOString(SvStream& rStrm, std::size_t nLen)
1792{
1793 rtl_String *pStr = nullptr;
1794 if (nLen)
1795 {
1796 nLen = std::min<std::size_t>(nLen, SAL_MAX_INT32);
1797 //limit allocation to size of file, but + 1 to set eof state
1798 nLen = std::min<sal_uInt64>(nLen, rStrm.remainingSize() + 1);
1799 //alloc a (ref-count 1) rtl_String of the desired length.
1800 //rtl_String's buffer is uninitialized, except for null termination
1801 pStr = rtl_string_alloc(sal::static_int_cast<sal_Int32>(nLen));
1802 SAL_WARN_IF(!pStr, "tools.stream", "allocation failed");
1803 if (pStr)
1804 {
1805 std::size_t nWasRead = rStrm.ReadBytes(pStr->buffer, nLen);
1806 if (nWasRead != nLen)
1807 {
1808 //on (typically unlikely) short read set length to what we could
1809 //read, and null terminate. Excess buffer capacity remains of
1810 //course, could create a (true) replacement OString if it matters.
1811 pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
1812 pStr->buffer[pStr->length] = 0;
1813 }
1814 }
1815 }
1816
1817 //take ownership of buffer and return, otherwise return empty string
1818 return pStr ? OString(pStr, SAL_NO_ACQUIRE) : OString();
1819}
1820
1821// Create an OUString of nLen sal_Unicode code units from rStream
1822// coverity[ +taint_sanitize ]
1823OUString read_uInt16s_ToOUString(SvStream& rStrm, std::size_t nLen)
1824{
1825 rtl_uString *pStr = nullptr;
1826 if (nLen)
1827 {
1828 nLen = std::min<std::size_t>(nLen, SAL_MAX_INT32);
1829 //limit allocation to size of file, but + 1 to set eof state
1830 nLen = o3tl::sanitizing_min<sal_uInt64>(nLen, (rStrm.remainingSize() + 2) / 2);
1831 //alloc a (ref-count 1) rtl_uString of the desired length.
1832 //rtl_String's buffer is uninitialized, except for null termination
1833 pStr = rtl_uString_alloc(sal::static_int_cast<sal_Int32>(nLen));
1834 SAL_WARN_IF(!pStr, "tools.stream", "allocation failed");
1835 if (pStr)
1836 {
1837 std::size_t nWasRead = rStrm.ReadBytes(pStr->buffer, nLen*2)/2;
1838 if (nWasRead != nLen)
1839 {
1840 //on (typically unlikely) short read set length to what we could
1841 //read, and null terminate. Excess buffer capacity remains of
1842 //course, could create a (true) replacement OUString if it matters.
1843 pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
1844 pStr->buffer[pStr->length] = 0;
1845 }
1846 if (rStrm.IsEndianSwap())
1847 {
1848 for (sal_Int32 i = 0; i < pStr->length; ++i)
1849 pStr->buffer[i] = OSL_SWAPWORD(pStr->buffer[i]);
1850 }
1851 }
1852 }
1853
1854 // take ownership of buffer and return, otherwise return empty string
1855 // coverity[tainted_data] - unhelpful untrusted loop bound
1856 return pStr ? OUString(pStr, SAL_NO_ACQUIRE) : OUString();
1857}
1858
1859namespace
1860{
1861 template <typename T, typename O> T tmpl_convertLineEnd(const T &rIn, LineEnd eLineEnd)
1862 {
1863 // Determine linebreaks and compute length
1864 bool bConvert = false; // Needs conversion
1865 sal_Int32 nStrLen = rIn.getLength();
1866 sal_Int32 nLineEndLen = (eLineEnd == LINEEND_CRLF) ? 2 : 1;
1867 sal_Int32 nLen = 0; // Target length
1868 sal_Int32 i = 0; // Source counter
1869
1870 while (i < nStrLen)
1871 {
1872 // \r or \n causes linebreak
1873 if ( (rIn[i] == '\r') || (rIn[i] == '\n') )
1874 {
1875 nLen = nLen + nLineEndLen;
1876
1877 // If set already, skip expensive test
1878 if ( !bConvert )
1879 {
1880 // Do we need to convert?
1881 if ( ((eLineEnd != LINEEND_LF) && (rIn[i] == '\n')) ||
1882 ((eLineEnd == LINEEND_CRLF) && (i+1) < nStrLen && (rIn[i+1] != '\n')) ||
1883 ((eLineEnd == LINEEND_LF) &&
1884 ((rIn[i] == '\r') || ((i+1) < nStrLen && rIn[i+1] == '\r'))) ||
1885 ((eLineEnd == LINEEND_CR) &&
1886 ((rIn[i] == '\n') || ((i+1) < nStrLen && rIn[i+1] == '\n'))) )
1887 bConvert = true;
1888 }
1889
1890 // skip char if \r\n or \n\r
1891 if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
1892 (rIn[i] != rIn[i+1]) )
1893 ++i;
1894 }
1895 else
1896 ++nLen;
1897 ++i;
1898 }
1899
1900 if (!bConvert)
1901 return rIn;
1902
1903 // convert linebreaks, insert string
1904 O aNewData(nLen);
1905 i = 0;
1906 while (i < nStrLen)
1907 {
1908 // \r or \n causes linebreak
1909 if ( (rIn[i] == '\r') || (rIn[i] == '\n') )
1910 {
1911 if ( eLineEnd == LINEEND_CRLF )
1912 {
1913 aNewData.append('\r');
1914 aNewData.append('\n');
1915 }
1916 else
1917 {
1918 if ( eLineEnd == LINEEND_CR )
1919 aNewData.append('\r');
1920 else
1921 aNewData.append('\n');
1922 }
1923
1924 if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
1925 (rIn[i] != rIn[i+1]) )
1926 ++i;
1927 }
1928 else
1929 {
1930 aNewData.append(rIn[i]);
1931 }
1932
1933 ++i;
1934 }
1935
1936 return aNewData.makeStringAndClear();
1937 }
1938}
1939
1940OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
1941{
1942 return tmpl_convertLineEnd<OString, OStringBuffer>(rIn, eLineEnd);
1943}
1944
1945OUString convertLineEnd(const OUString &rIn, LineEnd eLineEnd)
1946{
1947 return tmpl_convertLineEnd<OUString, OUStringBuffer>(rIn, eLineEnd);
1948}
1949
1951 std::u16string_view rStr)
1952{
1953 std::size_t nWritten = 0;
1954 sal_uInt32 nUnits = std::min<std::size_t>(rStr.size(), std::numeric_limits<sal_uInt32>::max());
1955 SAL_WARN_IF(static_cast<std::size_t>(nUnits) != static_cast<std::size_t>(rStr.size()),
1956 "tools.stream",
1957 "string too long for prefix count to fit in output type");
1958 rStrm.WriteUInt32(nUnits);
1959 if (rStrm.good())
1960 {
1961 nWritten += sizeof(sal_uInt32);
1962 nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
1963 }
1964 return nWritten;
1965}
1966
1968 std::u16string_view rStr)
1969{
1970 std::size_t nWritten = 0;
1971 sal_uInt16 nUnits = std::min<std::size_t>(rStr.size(), std::numeric_limits<sal_uInt16>::max());
1972 SAL_WARN_IF(nUnits != rStr.size(),
1973 "tools.stream",
1974 "string too long for prefix count to fit in output type");
1975 rStrm.WriteUInt16(nUnits);
1976 if (rStrm.good())
1977 {
1978 nWritten += sizeof(nUnits);
1979 nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
1980 }
1981 return nWritten;
1982}
1983
1985 std::string_view rStr)
1986{
1987 std::size_t nWritten = 0;
1988 sal_uInt16 nUnits = std::min<std::size_t>(rStr.size(), std::numeric_limits<sal_uInt16>::max());
1989 SAL_WARN_IF(static_cast<std::size_t>(nUnits) != static_cast<std::size_t>(rStr.size()),
1990 "tools.stream",
1991 "string too long for sal_uInt16 count to fit in output type");
1992 rStrm.WriteUInt16( nUnits );
1993 if (rStrm.good())
1994 {
1995 nWritten += sizeof(sal_uInt16);
1996 nWritten += write_uInt8s_FromOString(rStrm, rStr, nUnits);
1997 }
1998 return nWritten;
1999}
2000
2001/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double d
bool IsOpen() const
Definition: stream.hxx:618
bool m_bOwner
Definition: stream.hxx:105
virtual ErrCode WriteAt(sal_uInt64 nPos, const void *pBuffer, std::size_t nCount, std::size_t *pWritten)
Definition: stream.cxx:183
virtual ErrCode ReadAt(sal_uInt64 nPos, void *pBuffer, std::size_t nCount, std::size_t *pRead) const
Definition: stream.cxx:166
const SvStream * GetStream() const
Definition: stream.hxx:120
virtual ErrCode Flush() const
Definition: stream.cxx:200
void close()
Definition: stream.cxx:157
SvStream * m_pStream
Definition: stream.hxx:104
virtual ErrCode Stat(SvLockBytesStat *pStat) const
Definition: stream.cxx:225
virtual ErrCode SetSize(sal_uInt64 nSize)
Definition: stream.cxx:213
std::size_t nEndOfData
Definition: stream.hxx:634
void * SwitchBuffer()
Definition: stream.cxx:1746
const void * GetData()
Definition: stream.hxx:669
std::size_t nResize
Definition: stream.hxx:632
void FreeMemory()
Is called when this stream allocated the buffer or the buffer is resized.
Definition: stream.cxx:1736
void SetBuffer(void *pBuf, std::size_t nSize, std::size_t nEOF)
Definition: stream.cxx:1544
virtual sal_uInt64 SeekPos(sal_uInt64 nPos) override
Definition: stream.cxx:1633
virtual ~SvMemoryStream() override
Definition: stream.cxx:1533
std::size_t nSize
Definition: stream.hxx:631
SvMemoryStream(const SvMemoryStream &)=delete
virtual std::size_t PutData(const void *pData, std::size_t nSize) override
Definition: stream.cxx:1578
std::size_t nPos
Definition: stream.hxx:633
bool ReAllocateMemory(tools::Long nDiff)
ReAllocateMemory must update the following variables:
Definition: stream.cxx:1686
bool bOwnsData
Definition: stream.hxx:636
sal_uInt8 * pBuf
Definition: stream.hxx:635
virtual void SetSize(sal_uInt64 nSize) override
Definition: stream.cxx:1769
virtual void ResetError() override
Definition: stream.cxx:1675
void MakeReadOnly()
Makes the stream read-only after it was (possibly) initially writable, without having to copy the dat...
Definition: stream.cxx:1781
void AllocateMemory(std::size_t nSize)
AllocateMemory must update pBuf accordingly.
Definition: stream.cxx:1680
virtual void FlushData() override
Definition: stream.cxx:1671
virtual void ResetError()
Definition: stream.cxx:418
SvStream & ReadCharAsBool(bool &rBool)
Definition: stream.cxx:874
SvStream & ReadStream(SvStream &rStream)
Definition: stream.cxx:927
SvStream & WriteInt64(sal_Int64 nInt64)
Definition: stream.cxx:954
SvStream & WriteDouble(const double &rDouble)
Definition: stream.cxx:1032
SvStream & ReadUInt64(sal_uInt64 &rUInt64)
Definition: stream.cxx:823
void StartWritingUnicodeText()
Switch to no endian swapping and write 0xfeff.
Definition: stream.cxx:718
SvStream & WriteInt32(sal_Int32 nInt32)
Definition: stream.cxx:953
sal_uInt64 Tell() const
Definition: stream.hxx:271
void StartReadingUnicodeText(rtl_TextEncoding eReadBomCharSet)
If eReadBomCharSet==RTL_TEXTENCODING_DONTKNOW: read 16bit, if 0xfeff do nothing (UTF-16),...
Definition: stream.cxx:727
SAL_DLLPRIVATE bool ReadUniStringLine(OUString &rStr, sal_Int32 nMaxCodepointsToRead)
Read a line of Unicode.
Definition: stream.cxx:513
void SetEndian(SvStreamEndian SvStreamEndian)
Definition: stream.cxx:362
bool good() const
Get state.
Definition: stream.hxx:413
SvStream & WriteUniOrByteString(std::u16string_view rStr, rtl_TextEncoding eDestCharSet)
Write a 32bit length prefixed sequence of utf-16 if eSrcCharSet==RTL_TEXTENCODING_UNICODE,...
Definition: stream.cxx:1091
sal_uInt16 m_nBufFree
number of free slots in buffer to IO of type eIOMode
Definition: stream.hxx:156
SvStream & WriteUnicode(sal_Unicode)
Definition: stream.cxx:1017
OUString ReadUniOrByteString(rtl_TextEncoding eSrcCharSet)
Read a 32bit length prefixed sequence of utf-16 if eSrcCharSet==RTL_TEXTENCODING_UNICODE,...
Definition: stream.cxx:1083
virtual sal_uInt64 TellEnd()
Definition: stream.cxx:1328
bool m_isWritable
Definition: stream.hxx:182
virtual sal_uInt64 SeekPos(sal_uInt64 nPos)
Definition: stream.cxx:265
SAL_DLLPRIVATE void ClearBuffer()
Definition: stream.cxx:406
void readNumberWithoutSwap(T &rDataDest)
Definition: stream.hxx:420
SAL_DLLPRIVATE void readNumberWithoutSwap_(void *pDataDest, int nDataSize)
Definition: stream.cxx:120
SvLockBytesRef m_xLockBytes
Default implementation.
Definition: stream.hxx:145
virtual void SetSize(sal_uInt64 nSize)
Definition: stream.cxx:290
sal_uInt8 * m_pBufPos
m_pRWBuf + m_nBufActualPos
Definition: stream.hxx:151
void SetCryptMaskKey(const OString &rCryptMaskKey)
Definition: stream.cxx:1439
SvStream & ReadDouble(double &rDouble)
Definition: stream.cxx:912
SvStream & ReadInt16(sal_Int16 &rInt16)
Definition: stream.cxx:824
bool WriteByteStringLine(std::u16string_view rStr, rtl_TextEncoding eDestCharSet)
Definition: stream.cxx:694
sal_uInt16 m_nBufActualPos
current position in buffer (0..m_nBufSize-1)
Definition: stream.hxx:155
void SetBufferSize(sal_uInt16 m_nBufSize)
Definition: stream.cxx:380
LineEnd GetLineDelimiter() const
Definition: stream.hxx:226
bool ReadByteStringLine(OUString &rStr, rtl_TextEncoding eSrcCharSet, sal_Int32 nMaxBytesToRead=0xFFFE)
Read a line of bytes.
Definition: stream.cxx:423
std::size_t WriteBytes(const void *pData, std::size_t nSize)
Definition: stream.cxx:1192
SAL_DLLPRIVATE std::size_t CryptAndWriteBuffer(const void *pStart, std::size_t nLen)
Encrypt and write.
Definition: stream.cxx:1359
virtual ~SvStream()
Definition: stream.cxx:344
bool IsEndianSwap() const
returns status of endian swap flag
Definition: stream.hxx:212
OString m_aCryptMaskKey
Definition: stream.hxx:170
SvStream & WriteInt16(sal_Int16 nInt16)
Definition: stream.cxx:952
SAL_DLLPRIVATE void ClearError()
Definition: stream.cxx:350
SvStream & WriteUChar(unsigned char nChar)
Definition: stream.cxx:994
bool SetStreamSize(sal_uInt64 nSize)
Definition: stream.cxx:1446
sal_uInt64 m_nBufFilePos
File position of pBuf[0].
Definition: stream.hxx:180
bool ReadUniOrByteStringLine(OUString &rStr, rtl_TextEncoding eSrcCharSet, sal_Int32 nMaxCodepointsToRead=0xFFFE)
Read a line of Unicode if eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise read a line of Bytecode an...
Definition: stream.cxx:599
SvStream & WriteUInt16(sal_uInt16 nUInt16)
Definition: stream.cxx:949
SvStream & WriteUInt64(sal_uInt64 nuInt64)
Definition: stream.cxx:951
std::unique_ptr< sal_uInt8[]> m_pRWBuf
Points to read/write buffer.
Definition: stream.hxx:150
SvStream & ReadNumber(T &r)
Definition: stream.cxx:808
bool WriteUnicodeOrByteText(std::u16string_view rStr, rtl_TextEncoding eDestCharSet)
Write a sequence of Unicode characters if eDestCharSet==RTL_TEXTENCODING_UNICODE, otherwise write a s...
Definition: stream.cxx:679
unsigned char m_nCryptMask
Definition: stream.hxx:171
bool WriteUniOrByteChar(sal_Unicode ch, rtl_TextEncoding eDestCharSet)
Write a Unicode character if eDestCharSet==RTL_TEXTENCODING_UNICODE, otherwise write as Bytecode conv...
Definition: stream.cxx:706
sal_Int32 GetVersion() const
Definition: stream.hxx:389
bool WriteLine(std::string_view rStr)
Definition: stream.cxx:699
bool m_isIoRead
Definition: stream.hxx:157
SAL_DLLPRIVATE void writeNumberWithoutSwap_(const void *pDataSrc, int nDataSize)
Definition: stream.cxx:137
virtual std::size_t GetData(void *pData, std::size_t nSize)
Definition: stream.cxx:239
SvStream & ReadFloat(float &rFloat)
Definition: stream.cxx:897
SvStream & WriteUInt32(sal_uInt32 nUInt32)
Definition: stream.cxx:950
bool ReadLine(OStringBuffer &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
Read a line of bytes.
Definition: stream.cxx:440
bool m_isDirty
true: Stream != buffer content
Definition: stream.hxx:161
SvStream & WriteFloat(float nFloat)
Definition: stream.cxx:1022
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
Definition: stream.cxx:822
SvStream & WriteUInt8(sal_uInt8 nuInt8)
Definition: stream.cxx:1012
SvStreamEndian GetEndian() const
Definition: stream.cxx:371
sal_uInt16 m_nBufActualLen
Length of used segment of buffer.
Definition: stream.hxx:153
bool m_isEof
Definition: stream.hxx:163
ErrCode m_nError
Definition: stream.hxx:164
SvStream & WriteNumber(T n)
Definition: stream.cxx:941
void SetError(ErrCode nErrorCode)
Definition: stream.cxx:356
void writeNumberWithoutSwap(T const &rDataSrc)
Definition: stream.hxx:426
SvStream()
Definition: stream.cxx:296
SvStream & ReadUtf16(sal_Unicode &rUtf16)
Definition: stream.cxx:872
SvStream & ReadChar(char &rChar)
Definition: stream.cxx:844
sal_uInt64 Seek(sal_uInt64 nPos)
Definition: stream.cxx:1262
void Flush()
Call FlushBuffer() and then call flush on the underlying OS stream.
Definition: stream.cxx:1337
sal_uInt64 m_nActPos
Definition: stream.hxx:146
SvStream & WriteChar(char nChar)
Definition: stream.cxx:976
SvStream & ReadInt32(sal_Int32 &rInt32)
Definition: stream.cxx:825
std::size_t ReadBytes(void *pData, std::size_t nSize)
Definition: stream.cxx:1114
rtl_TextEncoding GetStreamCharSet() const
Definition: stream.hxx:222
virtual std::size_t PutData(const void *pData, std::size_t nSize)
Definition: stream.cxx:252
sal_uInt64 SeekRel(sal_Int64 nPos)
Definition: stream.cxx:784
ErrCode GetError() const
Definition: stream.hxx:204
SvStream & ReadSChar(signed char &rChar)
Definition: stream.cxx:828
void FlushBuffer()
If we have data in our internal buffers, write them out.
Definition: stream.cxx:1101
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
Definition: stream.cxx:821
virtual void FlushData()
Definition: stream.cxx:281
void RefreshBuffer()
Definition: stream.cxx:1344
ErrCode const & GetErrorCode() const
Definition: stream.hxx:205
bool m_isSwap
Definition: stream.hxx:162
SvStream & WriteSChar(signed char nChar)
Definition: stream.cxx:956
sal_uInt64 remainingSize()
Definition: stream.cxx:1320
bool m_isIoWrite
Definition: stream.hxx:158
SvStream & ReadInt64(sal_Int64 &rInt64)
Definition: stream.cxx:826
SAL_DLLPRIVATE void EncryptBuffer(void *pStart, std::size_t nLen) const
Definition: stream.cxx:1390
sal_uInt16 m_nBufSize
Allocated size of buffer.
Definition: stream.hxx:152
SvStream & ReadUChar(unsigned char &rChar)
Definition: stream.cxx:858
SvStream & WriteStream(SvStream &rStream)
Definition: stream.cxx:1050
int nCount
#define DBG_ASSERT(sCon, aError)
Definition: debug.hxx:57
float v
#define SVSTREAM_WRITE_ERROR
#define SVSTREAM_OUTOFMEMORY
#define ERRCODE_IO_PENDING
#define ERRCODE_IO_CANTWRITE
#define SVSTREAM_INVALID_HANDLE
#define ERRCODE_NONE
sal_Int16 nVersion
#define SOFFICE_FILEFORMAT_31
Mode eMode
void * p
sal_Int64 n
LineEnd
Definition: lineend.hxx:17
@ LINEEND_LF
Definition: lineend.hxx:17
@ LINEEND_CRLF
Definition: lineend.hxx:17
@ LINEEND_CR
Definition: lineend.hxx:17
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
aStr
aBuf
std::unique_ptr< sal_Int32[]> pData
NONE
COMPHELPER_DLLPUBLIC bool isFileUrl(std::u16string_view url)
int i
void SvStream & rStrm
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Note: this class is a true marvel of engineering: because the author could not decide whether it's be...
bool isEmptyFileUrl(const OUString &rUrl)
Is rUrl a file:// URL with no contents?
Definition: stream.cxx:1300
long Long
Definition: long.hxx:34
OUString read_uInt16s_ToOUString(SvStream &rStrm, std::size_t nLen)
Attempt to read nUnits 16bit units to an OUString, returned OUString's length is number of units succ...
Definition: stream.cxx:1823
std::size_t write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream &rStrm, std::u16string_view rStr)
Definition: stream.cxx:1967
OString read_uInt8s_ToOString(SvStream &rStrm, std::size_t nLen)
Attempt to read nUnits 8bit units to an OString, returned OString's length is number of units success...
Definition: stream.cxx:1791
static unsigned char implGetCryptMask(const char *pStr, sal_Int32 nLen, tools::Long nVersion)
Definition: stream.cxx:1404
SvStream & endl(SvStream &rStr)
Definition: stream.cxx:1465
static void swapNibbles(unsigned char &c)
Definition: stream.cxx:42
static void SwapNumber(T &r)
Definition: stream.cxx:57
OString read_zeroTerminated_uInt8s_ToOString(SvStream &rStream)
Attempt to write a pascal-style length (of type prefix) prefixed sequence of 16bit units from an OUSt...
Definition: stream.cxx:608
static void SwapFloat(float &r)
Definition: stream.cxx:80
OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
Definition: stream.cxx:1940
static void SwapDouble(double &r)
Definition: stream.cxx:93
#define CRYPT_BUFSIZE
Definition: stream.cxx:1356
SvStream & endlub(SvStream &rStrm)
call endlu() if m_eStreamCharSet==RTL_TEXTECODING_UNICODE otherwise endl()
Definition: stream.cxx:1493
std::size_t write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream &rStrm, std::u16string_view rStr)
Attempt to write a pascal-style length (of type prefix) prefixed sequence of 16bit units from an OUSt...
Definition: stream.cxx:1950
SvStream & endlu(SvStream &rStrm)
same as endl() but Unicode
Definition: stream.cxx:1477
OUString read_zeroTerminated_uInt8s_ToOUString(SvStream &rStream, rtl_TextEncoding eEnc)
Attempt to read 8bit units assuming source encoding eEnc to an OUString until a zero terminator is en...
Definition: stream.cxx:644
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream &rStrm, std::string_view rStr)
Attempt to write a pascal-style length (of type prefix) prefixed sequence of units from a string-type...
Definition: stream.cxx:1984
bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
Definition: stream.cxx:1292
std::size_t write_uInt16s_FromOUString(SvStream &rStrm, std::u16string_view rStr, std::size_t nUnits)
Attempt to write a prefixed sequence of nUnits 16bit units from an OUString, returned value is number...
Definition: stream.cxx:652
#define STREAM_SEEK_TO_END
Definition: stream.hxx:73
OUString read_uInt16_lenPrefixed_uInt8s_ToOUString(SvStream &rStrm, rtl_TextEncoding eEnc)
Definition: stream.hxx:535
StreamMode
Definition: stream.hxx:46
@ READ
allow read accesses
@ WRITE
allow write accesses
OUString read_uInt32_lenPrefixed_uInt16s_ToOUString(SvStream &rStrm)
Definition: stream.hxx:471
#define STREAM_SEEK_TO_BEGIN
Definition: stream.hxx:72
std::size_t write_uInt8s_FromOString(SvStream &rStrm, std::string_view rStr, std::size_t nUnits)
Attempt to write a prefixed sequence of nUnits 8bit units from an OString, returned value is number o...
Definition: stream.hxx:549
SvStreamEndian
Definition: stream.hxx:75
SvStreamCompressFlags
Definition: stream.hxx:77
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream &rStrm, std::u16string_view rStr, rtl_TextEncoding eEnc)
Attempt to write a pascal-style length (of type prefix) prefixed sequence of 8bit units from an OUStr...
Definition: stream.hxx:569
std::size_t nSize
Definition: stream.hxx:97
unsigned char sal_uInt8
#define SAL_MAX_INT32
#define SAL_MAX_UINT64
sal_uInt16 sal_Unicode
#define SAL_MAX_UINT32