1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 // TODO: Read->RefreshBuffer-> React to changes from m_nBufActualLen
22 #include <sal/config.h>
31 #include <osl/endian.h>
32 #include <osl/diagnose.h>
33 #include <rtl/strbuf.hxx>
34 #include <rtl/ustrbuf.hxx>
35 #include <sal/log.hxx>
37 #include <comphelper/fileformat.h>
39 static void swapNibbles(unsigned char &c
)
41 unsigned char nSwapTmp
=c
;
47 #include <tools/debug.hxx>
48 #include <tools/stream.hxx>
49 #include <osl/thread.h>
52 // !!! Do not inline if already the operators <<,>> are inline
53 static void SwapUShort( sal_uInt16
& r
)
54 { r
= OSL_SWAPWORD(r
); }
55 static void SwapShort( short& r
)
56 { r
= OSL_SWAPWORD(r
); }
57 static void SwapULong( sal_uInt32
& r
)
58 { r
= OSL_SWAPDWORD(r
); }
59 static void SwapLongInt( sal_Int32
& r
)
60 { r
= OSL_SWAPDWORD(r
); }
62 static void SwapUInt64( sal_uInt64
& r
)
71 s
.c
[0] ^= s
.c
[1]; // swap the 32 bit words
74 // swap the bytes in the words
75 s
.c
[0] = OSL_SWAPDWORD(s
.c
[0]);
76 s
.c
[1] = OSL_SWAPDWORD(s
.c
[1]);
79 static void SwapInt64( sal_Int64
& r
)
88 s
.c
[0] ^= s
.c
[1]; // swap the 32 bit words
91 // swap the bytes in the words
92 s
.c
[0] = OSL_SWAPDWORD(s
.c
[0]);
93 s
.c
[1] = OSL_SWAPDWORD(s
.c
[1]);
98 static void SwapFloat( float& r
)
107 s
.c
= OSL_SWAPDWORD( s
.c
);
111 static void SwapDouble( double& r
)
113 if( sizeof(double) != 8 )
115 SAL_WARN( "tools.stream", "Can only swap 8-Byte-doubles" );
126 s
.c
[0] ^= s
.c
[1]; // swap 32-bit values in situ
129 s
.c
[0] = OSL_SWAPDWORD(s
.c
[0]); // swap dword itself in situ
130 s
.c
[1] = OSL_SWAPDWORD(s
.c
[1]);
136 static void SwapUnicode(sal_Unicode
& r
) { r
= OSL_SWAPWORD(r
); }
140 void SvStream::readNumberWithoutSwap_(void * pDataDest
, int nDataSize
)
142 if (m_isIoRead
&& nDataSize
<= m_nBufFree
)
144 for (int i
= 0; i
< nDataSize
; i
++)
145 static_cast<char*>(pDataDest
)[i
] = m_pBufPos
[i
];
146 m_nBufActualPos
+= nDataSize
;
147 m_pBufPos
+= nDataSize
;
148 m_nBufFree
-= nDataSize
;
152 ReadBytes( pDataDest
, nDataSize
);
157 void SvStream::writeNumberWithoutSwap_(const void * pDataSrc
, int nDataSize
)
159 if (m_isIoWrite
&& nDataSize
<= m_nBufFree
)
161 for (int i
= 0; i
< nDataSize
; i
++)
162 m_pBufPos
[i
] = static_cast<const char*>(pDataSrc
)[i
];
163 m_nBufFree
-= nDataSize
;
164 m_nBufActualPos
+= nDataSize
;
165 if (m_nBufActualPos
> m_nBufActualLen
)
166 m_nBufActualLen
= m_nBufActualPos
;
167 m_pBufPos
+= nDataSize
;
172 WriteBytes( pDataSrc
, nDataSize
);
178 void SvLockBytes::close()
187 ErrCode
SvLockBytes::ReadAt(sal_uInt64
const nPos
, void * pBuffer
, std::size_t nCount
,
188 std::size_t * pRead
) const
192 OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
196 m_pStream
->Seek(nPos
);
197 std::size_t nTheRead
= m_pStream
->ReadBytes(pBuffer
, nCount
);
200 return m_pStream
->GetErrorCode();
204 ErrCode
SvLockBytes::WriteAt(sal_uInt64
const nPos
, const void * pBuffer
, std::size_t nCount
,
205 std::size_t * pWritten
)
209 OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
213 m_pStream
->Seek(nPos
);
214 std::size_t nTheWritten
= m_pStream
->WriteBytes(pBuffer
, nCount
);
216 *pWritten
= nTheWritten
;
217 return m_pStream
->GetErrorCode();
221 ErrCode
SvLockBytes::Flush() const
225 OSL_FAIL("SvLockBytes::Flush(): Bad stream");
230 return m_pStream
->GetErrorCode();
234 ErrCode
SvLockBytes::SetSize(sal_uInt64
const nSize
)
238 OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
242 m_pStream
->SetStreamSize(nSize
);
243 return m_pStream
->GetErrorCode();
246 ErrCode
SvLockBytes::Stat(SvLockBytesStat
* pStat
) const
250 OSL_FAIL("SvLockBytes::Stat(): Bad stream");
256 sal_uInt64
const nPos
= m_pStream
->Tell();
257 pStat
->nSize
= m_pStream
->Seek(STREAM_SEEK_TO_END
);
258 m_pStream
->Seek(nPos
);
265 std::size_t SvStream::GetData( void* pData
, std::size_t nSize
)
269 DBG_ASSERT( m_xLockBytes
.is(), "pure virtual function" );
271 m_nError
= m_xLockBytes
->ReadAt(m_nActPos
, pData
, nSize
, &nRet
);
278 std::size_t SvStream::PutData( const void* pData
, std::size_t nSize
)
282 DBG_ASSERT( m_xLockBytes
.is(), "pure virtual function" );
284 m_nError
= m_xLockBytes
->WriteAt(m_nActPos
, pData
, nSize
, &nRet
);
291 sal_uInt64
SvStream::SeekPos(sal_uInt64
const nPos
)
293 // check if a truncated STREAM_SEEK_TO_END was passed
294 assert(nPos
!= SAL_MAX_UINT32
);
295 if( !GetError() && nPos
== STREAM_SEEK_TO_END
)
297 DBG_ASSERT( m_xLockBytes
.is(), "pure virtual function" );
298 SvLockBytesStat aStat
;
299 m_xLockBytes
->Stat( &aStat
);
300 m_nActPos
= aStat
.nSize
;
307 void SvStream::FlushData()
311 DBG_ASSERT( m_xLockBytes
.is(), "pure virtual function" );
312 m_nError
= m_xLockBytes
->Flush();
316 void SvStream::SetSize(sal_uInt64
const nSize
)
318 DBG_ASSERT( m_xLockBytes
.is(), "pure virtual function" );
319 m_nError
= m_xLockBytes
->SetSize( nSize
);
322 SvStream::SvStream() :
336 , m_nCompressMode(SvStreamCompressFlags::NONE
)
338 , m_eLineDelimiter(LINEEND_LF
) // UNIX-Format
340 , m_eLineDelimiter(LINEEND_CRLF
) // DOS-Format
342 , m_eStreamCharSet(osl_getThreadTextEncoding())
349 , m_eStreamMode(StreamMode::NONE
)
353 SetEndian( SvStreamEndian::LITTLE
);
358 SvStream::SvStream( SvLockBytes
* pLockBytesP
) : SvStream()
360 m_xLockBytes
= pLockBytesP
;
362 const SvStream
* pStrm
= pLockBytesP
->GetStream();
364 SetError( pStrm
->GetErrorCode() );
367 SetBufferSize( 256 );
370 SvStream::~SvStream()
372 if (m_xLockBytes
.is())
376 void SvStream::ClearError()
379 m_nError
= ERRCODE_NONE
;
382 void SvStream::SetError( ErrCode nErrorCode
)
384 if (m_nError
== ERRCODE_NONE
)
385 m_nError
= nErrorCode
;
388 void SvStream::SetEndian( SvStreamEndian nNewFormat
)
390 m_nEndian
= nNewFormat
;
393 if (m_nEndian
== SvStreamEndian::LITTLE
)
396 if (m_nEndian
== SvStreamEndian::BIG
)
401 void SvStream::SetBufferSize( sal_uInt16 nBufferSize
)
403 sal_uInt64
const nActualFilePos
= Tell();
404 bool bDontSeek
= (m_pRWBuf
== nullptr);
406 if (m_isDirty
&& m_isWritable
) // due to Windows NT: Access denied
412 m_nBufFilePos
+= m_nBufActualPos
;
418 m_nBufSize
= nBufferSize
;
420 m_pRWBuf
.reset(new sal_uInt8
[ m_nBufSize
]);
421 m_pBufPos
= m_pRWBuf
.get();
422 m_isIoRead
= m_isIoWrite
= false;
424 SeekPos( nActualFilePos
);
427 void SvStream::ClearBuffer()
432 m_pBufPos
= m_pRWBuf
.get();
434 m_isIoRead
= m_isIoWrite
= false;
439 void SvStream::ResetError()
444 bool SvStream::ReadByteStringLine( OUString
& rStr
, rtl_TextEncoding eSrcCharSet
,
445 sal_Int32 nMaxBytesToRead
)
448 bool bRet
= ReadLine( aStr
, nMaxBytesToRead
);
449 rStr
= OStringToOUString(aStr
, eSrcCharSet
);
453 bool SvStream::ReadLine( OString
& rStr
, sal_Int32 nMaxBytesToRead
)
457 sal_uInt64 nOldFilePos
= Tell();
459 std::size_t nTotalLen
= 0;
461 OStringBuffer
aBuf(4096);
462 while( !bEnd
&& !GetError() ) // Don't test for EOF as we
463 // are reading block-wise!
465 sal_uInt16 nLen
= static_cast<sal_uInt16
>(ReadBytes(buf
, sizeof(buf
)-1));
468 if ( aBuf
.isEmpty() )
470 // Exit on first block-read error
480 for( j
= n
= 0; j
< nLen
; ++j
)
483 if ( c
== '\n' || c
== '\r' )
493 if (nTotalLen
> static_cast<std::size_t>(nMaxBytesToRead
))
495 n
-= nTotalLen
- nMaxBytesToRead
;
496 nTotalLen
= nMaxBytesToRead
;
503 if ( !bEnd
&& !GetError() && !aBuf
.isEmpty() )
506 nOldFilePos
+= nTotalLen
;
507 if( Tell() > nOldFilePos
)
509 Seek( nOldFilePos
); // Seek pointer due to BlockRead above
511 if ( bEnd
&& (c
=='\r' || c
=='\n') ) // Special treatment for DOS files
514 std::size_t nLen
= ReadBytes(&cTemp
, sizeof(cTemp
));
516 if( cTemp
== c
|| (cTemp
!= '\n' && cTemp
!= '\r') )
523 rStr
= aBuf
.makeStringAndClear();
527 bool SvStream::ReadUniStringLine( OUString
& rStr
, sal_Int32 nMaxCodepointsToRead
)
529 sal_Unicode buf
[256+1];
531 sal_uInt64 nOldFilePos
= Tell();
533 std::size_t nTotalLen
= 0;
535 DBG_ASSERT( sizeof(sal_Unicode
) == sizeof(sal_uInt16
), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
537 OUStringBuffer
aBuf(4096);
538 while( !bEnd
&& !GetError() ) // Don't test for EOF as we
539 // are reading block-wise!
541 sal_uInt16 nLen
= static_cast<sal_uInt16
>(ReadBytes( buf
, sizeof(buf
)-sizeof(sal_Unicode
)));
542 nLen
/= sizeof(sal_Unicode
);
545 if ( aBuf
.isEmpty() )
547 // exit on first BlockRead error
557 for( j
= n
= 0; j
< nLen
; ++j
)
560 SwapUnicode( buf
[n
] );
562 if ( c
== '\n' || c
== '\r' )
567 // erAck 26.02.01: Old behavior was no special treatment of '\0'
568 // character here, but a following rStr+=c did ignore it. Is this
569 // really intended? Or should a '\0' better terminate a line?
570 // The nOldFilePos stuff wasn't correct then anyways.
579 if (nTotalLen
> static_cast<std::size_t>(nMaxCodepointsToRead
))
581 n
-= nTotalLen
- nMaxCodepointsToRead
;
582 nTotalLen
= nMaxCodepointsToRead
;
586 aBuf
.append( buf
, n
);
589 if ( !bEnd
&& !GetError() && !aBuf
.isEmpty() )
592 nOldFilePos
+= nTotalLen
* sizeof(sal_Unicode
);
593 if( Tell() > nOldFilePos
)
594 nOldFilePos
+= sizeof(sal_Unicode
);
595 Seek( nOldFilePos
); // seek due to BlockRead above
597 if ( bEnd
&& (c
=='\r' || c
=='\n') ) // special treatment for DOS files
600 ReadBytes( &cTemp
, sizeof(cTemp
) );
602 SwapUnicode( cTemp
);
603 if( cTemp
== c
|| (cTemp
!= '\n' && cTemp
!= '\r') )
609 rStr
= aBuf
.makeStringAndClear();
613 bool SvStream::ReadUniOrByteStringLine( OUString
& rStr
, rtl_TextEncoding eSrcCharSet
,
614 sal_Int32 nMaxCodepointsToRead
)
616 if ( eSrcCharSet
== RTL_TEXTENCODING_UNICODE
)
617 return ReadUniStringLine( rStr
, nMaxCodepointsToRead
);
619 return ReadByteStringLine( rStr
, eSrcCharSet
, nMaxCodepointsToRead
);
622 OString
read_zeroTerminated_uInt8s_ToOString(SvStream
& rStream
)
624 OStringBuffer
aOutput(256);
626 sal_Char buf
[ 256 + 1 ];
628 sal_uInt64 nFilePos
= rStream
.Tell();
630 while( !bEnd
&& !rStream
.GetError() )
632 std::size_t nLen
= rStream
.ReadBytes(buf
, sizeof(buf
)-1);
636 std::size_t nReallyRead
= nLen
;
637 const sal_Char
* pPtr
= buf
;
638 while (nLen
&& *pPtr
)
644 bEnd
= ( nReallyRead
< sizeof(buf
)-1 ) // read less than attempted to read
645 || ( ( nLen
> 0 ) // OR it is inside the block we read
646 && ( 0 == *pPtr
) // AND found a string terminator
649 aOutput
.append(buf
, pPtr
- buf
);
652 nFilePos
+= aOutput
.getLength();
653 if (rStream
.Tell() > nFilePos
)
654 rStream
.Seek(nFilePos
+1); // seek due to FileRead above
655 return aOutput
.makeStringAndClear();
658 OUString
read_zeroTerminated_uInt8s_ToOUString(SvStream
& rStream
, rtl_TextEncoding eEnc
)
660 return OStringToOUString(
661 read_zeroTerminated_uInt8s_ToOString(rStream
), eEnc
);
664 /** Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
665 returned value is number of bytes written */
666 std::size_t write_uInt16s_FromOUString(SvStream
& rStrm
, const OUString
& rStr
,
669 DBG_ASSERT( sizeof(sal_Unicode
) == sizeof(sal_uInt16
), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
670 std::size_t nWritten
;
671 if (!rStrm
.IsEndianSwap())
672 nWritten
= rStrm
.WriteBytes(rStr
.getStr(), nUnits
* sizeof(sal_Unicode
));
675 std::size_t nLen
= nUnits
;
676 sal_Unicode aBuf
[384];
677 sal_Unicode
* const pTmp
= ( nLen
> 384 ? new sal_Unicode
[nLen
] : aBuf
);
678 memcpy( pTmp
, rStr
.getStr(), nLen
* sizeof(sal_Unicode
) );
679 sal_Unicode
* p
= pTmp
;
680 const sal_Unicode
* const pStop
= pTmp
+ nLen
;
686 nWritten
= rStrm
.WriteBytes( pTmp
, nLen
* sizeof(sal_Unicode
) );
693 bool SvStream::WriteUnicodeOrByteText( const OUString
& rStr
, rtl_TextEncoding eDestCharSet
)
695 if ( eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
697 write_uInt16s_FromOUString(*this, rStr
, rStr
.getLength());
698 return m_nError
== ERRCODE_NONE
;
702 OString
aStr(OUStringToOString(rStr
, eDestCharSet
));
703 write_uInt8s_FromOString(*this, aStr
, aStr
.getLength());
704 return m_nError
== ERRCODE_NONE
;
708 bool SvStream::WriteByteStringLine( const OUString
& rStr
, rtl_TextEncoding eDestCharSet
)
710 return WriteLine(OUStringToOString(rStr
, eDestCharSet
));
713 bool SvStream::WriteLine(const OString
& rStr
)
715 WriteBytes(rStr
.getStr(), rStr
.getLength());
717 return m_nError
== ERRCODE_NONE
;
720 bool SvStream::WriteUniOrByteChar( sal_Unicode ch
, rtl_TextEncoding eDestCharSet
)
722 if ( eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
726 OString
aStr(&ch
, 1, eDestCharSet
);
727 WriteBytes(aStr
.getStr(), aStr
.getLength());
729 return m_nError
== ERRCODE_NONE
;
732 void SvStream::StartWritingUnicodeText()
734 // BOM, Byte Order Mark, U+FEFF, see
735 // http://www.unicode.org/faq/utf_bom.html#BOM
736 // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
737 writeNumberWithoutSwap(sal_uInt16(0xfeff)); // write native format
740 void SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet
)
742 if (!( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
743 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
||
744 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
745 return; // nothing to read
747 bool bTryUtf8
= false;
749 sal_sSize nBack
= sizeof(nFlag
);
755 if ( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
756 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
)
761 if ( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
762 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
)
764 SetEndian( m_nEndian
== SvStreamEndian::BIG
? SvStreamEndian::LITTLE
: SvStreamEndian::BIG
);
769 if (m_nEndian
== SvStreamEndian::BIG
&&
770 (eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
771 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
775 if (m_nEndian
== SvStreamEndian::LITTLE
&&
776 (eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
777 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
785 unsigned char nChar(0);
786 nBack
+= sizeof(nChar
);
789 nBack
= 0; // it is UTF-8
792 SeekRel( -nBack
); // no BOM, pure data
795 sal_uInt64
SvStream::SeekRel(sal_Int64
const nPos
)
797 sal_uInt64 nActualPos
= Tell();
801 if (SAL_MAX_UINT64
- nActualPos
> static_cast<sal_uInt64
>(nPos
))
806 sal_uInt64
const nAbsPos
= static_cast<sal_uInt64
>(-nPos
);
807 if ( nActualPos
>= nAbsPos
)
808 nActualPos
-= nAbsPos
;
811 assert((m_pBufPos
!= nullptr) == bool(m_pRWBuf
));
814 m_pBufPos
= m_pRWBuf
.get() + nActualPos
;
816 return Seek( nActualPos
);
819 SvStream
& SvStream::ReadUInt16(sal_uInt16
& r
)
822 readNumberWithoutSwap(n
);
832 SvStream
& SvStream::ReadUInt32(sal_uInt32
& r
)
835 readNumberWithoutSwap(n
);
845 SvStream
& SvStream::ReadUInt64(sal_uInt64
& r
)
848 readNumberWithoutSwap(n
);
858 SvStream
& SvStream::ReadInt16(sal_Int16
& r
)
861 readNumberWithoutSwap(n
);
871 SvStream
& SvStream::ReadInt32(sal_Int32
& r
)
874 readNumberWithoutSwap(n
);
884 SvStream
& SvStream::ReadInt64(sal_Int64
& r
)
887 readNumberWithoutSwap(n
);
897 SvStream
& SvStream::ReadSChar( signed char& r
)
899 if (m_isIoRead
&& sizeof(signed char) <= m_nBufFree
)
902 m_nBufActualPos
+= sizeof(signed char);
903 m_pBufPos
+= sizeof(signed char);
904 m_nBufFree
-= sizeof(signed char);
907 ReadBytes( &r
, sizeof(signed char) );
911 // Special treatment for Chars due to PutBack
913 SvStream
& SvStream::ReadChar( char& r
)
915 if (m_isIoRead
&& sizeof(char) <= m_nBufFree
)
918 m_nBufActualPos
+= sizeof(char);
919 m_pBufPos
+= sizeof(char);
920 m_nBufFree
-= sizeof(char);
923 ReadBytes( &r
, sizeof(char) );
927 SvStream
& SvStream::ReadUChar( unsigned char& r
)
929 if (m_isIoRead
&& sizeof(char) <= m_nBufFree
)
932 m_nBufActualPos
+= sizeof(char);
933 m_pBufPos
+= sizeof(char);
934 m_nBufFree
-= sizeof(char);
937 ReadBytes( &r
, sizeof(char) );
941 SvStream
& SvStream::ReadUtf16(sal_Unicode
& r
)
944 readNumberWithoutSwap(n
);
954 SvStream
& SvStream::ReadCharAsBool( bool& r
)
956 if (m_isIoRead
&& sizeof(char) <= m_nBufFree
)
959 *m_pBufPos
> 1, "tools.stream", unsigned(*m_pBufPos
) << " not 0/1");
961 m_nBufActualPos
+= sizeof(char);
962 m_pBufPos
+= sizeof(char);
963 m_nBufFree
-= sizeof(char);
968 if (ReadBytes(&c
, 1) == 1)
970 SAL_WARN_IF(c
> 1, "tools.stream", unsigned(c
) << " not 0/1");
977 SvStream
& SvStream::ReadFloat(float& r
)
980 readNumberWithoutSwap(n
);
992 SvStream
& SvStream::ReadDouble(double& r
)
995 readNumberWithoutSwap(n
);
1007 SvStream
& SvStream::ReadStream( SvStream
& rStream
)
1009 const sal_uInt32 cBufLen
= 0x8000;
1010 std::unique_ptr
<char[]> pBuf( new char[ cBufLen
] );
1014 nCount
= ReadBytes( pBuf
.get(), cBufLen
);
1015 rStream
.WriteBytes( pBuf
.get(), nCount
);
1016 } while( nCount
== cBufLen
);
1021 SvStream
& SvStream::WriteUInt16( sal_uInt16 v
)
1025 writeNumberWithoutSwap(v
);
1029 SvStream
& SvStream::WriteUInt32( sal_uInt32 v
)
1033 writeNumberWithoutSwap(v
);
1037 SvStream
& SvStream::WriteUInt64( sal_uInt64 v
)
1041 writeNumberWithoutSwap(v
);
1045 SvStream
& SvStream::WriteInt16( sal_Int16 v
)
1049 writeNumberWithoutSwap(v
);
1053 SvStream
& SvStream::WriteInt32( sal_Int32 v
)
1057 writeNumberWithoutSwap(v
);
1061 SvStream
& SvStream::WriteInt64 (sal_Int64 v
)
1065 writeNumberWithoutSwap(v
);
1069 SvStream
& SvStream::WriteSChar( signed char v
)
1072 if (m_isIoWrite
&& sizeof(signed char) <= m_nBufFree
)
1075 m_pBufPos
++; // sizeof(char);
1077 if (m_nBufActualPos
> m_nBufActualLen
) // Append ?
1078 m_nBufActualLen
= m_nBufActualPos
;
1079 m_nBufFree
--; // = sizeof(char);
1083 WriteBytes( &v
, sizeof(signed char) );
1087 // Special treatment for Chars due to PutBack
1089 SvStream
& SvStream::WriteChar( char v
)
1092 if (m_isIoWrite
&& sizeof(char) <= m_nBufFree
)
1095 m_pBufPos
++; // sizeof(char);
1097 if (m_nBufActualPos
> m_nBufActualLen
) // Append ?
1098 m_nBufActualLen
= m_nBufActualPos
;
1099 m_nBufFree
--; // = sizeof(char);
1103 WriteBytes( &v
, sizeof(char) );
1107 SvStream
& SvStream::WriteUChar( unsigned char v
)
1110 if (m_isIoWrite
&& sizeof(char) <= m_nBufFree
)
1112 *reinterpret_cast<unsigned char*>(m_pBufPos
) = v
;
1113 m_pBufPos
++; // = sizeof(char);
1114 m_nBufActualPos
++; // = sizeof(char);
1115 if (m_nBufActualPos
> m_nBufActualLen
) // Append ?
1116 m_nBufActualLen
= m_nBufActualPos
;
1121 WriteBytes( &v
, sizeof(char) );
1125 SvStream
& SvStream::WriteUInt8( sal_uInt8 v
)
1127 return WriteUChar(v
);
1130 SvStream
& SvStream::WriteUnicode( sal_Unicode v
)
1132 return WriteUInt16(v
);
1135 SvStream
& SvStream::WriteFloat( float v
)
1141 writeNumberWithoutSwap(v
);
1145 SvStream
& SvStream::WriteDouble ( const double& r
)
1152 writeNumberWithoutSwap(nHelp
);
1158 writeNumberWithoutSwap(r
);
1163 SvStream
& SvStream::WriteCharPtr( const char* pBuf
)
1165 WriteBytes( pBuf
, strlen(pBuf
) );
1169 SvStream
& SvStream::WriteStream( SvStream
& rStream
)
1171 const sal_uInt32 cBufLen
= 0x8000;
1172 std::unique_ptr
<char[]> pBuf( new char[ cBufLen
] );
1175 nCount
= rStream
.ReadBytes( pBuf
.get(), cBufLen
);
1176 WriteBytes( pBuf
.get(), nCount
);
1177 } while( nCount
== cBufLen
);
1182 sal_uInt64
SvStream::WriteStream( SvStream
& rStream
, sal_uInt64 nSize
)
1184 const sal_uInt32 cBufLen
= 0x8000;
1185 std::unique_ptr
<char[]> pBuf( new char[ cBufLen
] );
1186 sal_uInt32 nCurBufLen
= cBufLen
;
1188 sal_uInt64 nWriteSize
= nSize
;
1192 nCurBufLen
= std::min
<sal_uInt64
>(nCurBufLen
, nWriteSize
);
1193 nCount
= rStream
.ReadBytes(pBuf
.get(), nCurBufLen
);
1194 WriteBytes( pBuf
.get(), nCount
);
1195 nWriteSize
-= nCount
;
1197 while( nWriteSize
&& nCount
== nCurBufLen
);
1199 return nSize
- nWriteSize
;
1202 OUString
SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet
)
1204 // read UTF-16 string directly from stream ?
1205 if (eSrcCharSet
== RTL_TEXTENCODING_UNICODE
)
1206 return read_uInt32_lenPrefixed_uInt16s_ToOUString(*this);
1207 return read_uInt16_lenPrefixed_uInt8s_ToOUString(*this, eSrcCharSet
);
1210 SvStream
& SvStream::WriteUniOrByteString( const OUString
& rStr
, rtl_TextEncoding eDestCharSet
)
1212 // write UTF-16 string directly into stream ?
1213 if (eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
1214 write_uInt32_lenPrefixed_uInt16s_FromOUString(*this, rStr
);
1216 write_uInt16_lenPrefixed_uInt8s_FromOUString(*this, rStr
, eDestCharSet
);
1220 void SvStream::FlushBuffer()
1222 if (m_isDirty
) // Does stream require a flush?
1224 SeekPos(m_nBufFilePos
);
1226 CryptAndWriteBuffer(m_pRWBuf
.get(), m_nBufActualLen
);
1227 else if (PutData(m_pRWBuf
.get(), m_nBufActualLen
) != m_nBufActualLen
)
1228 SetError(SVSTREAM_WRITE_ERROR
);
1233 std::size_t SvStream::ReadBytes( void* pData
, std::size_t nCount
)
1235 std::size_t nSaveCount
= nCount
;
1239 nCount
= GetData( pData
,nCount
);
1241 EncryptBuffer(pData
, nCount
);
1242 m_nBufFilePos
+= nCount
;
1246 // check if block is completely within buffer
1248 m_isIoWrite
= false;
1249 if (nCount
<= static_cast<std::size_t>(m_nBufActualLen
- m_nBufActualPos
))
1253 memcpy(pData
, m_pBufPos
, static_cast<size_t>(nCount
));
1254 m_nBufActualPos
= m_nBufActualPos
+ static_cast<sal_uInt16
>(nCount
);
1255 m_pBufPos
+= nCount
;
1256 m_nBufFree
= m_nBufFree
- static_cast<sal_uInt16
>(nCount
);
1262 // Does data block fit into buffer?
1263 if (nCount
> m_nBufSize
)
1265 // => No! Thus read directly
1266 // into target area without using the buffer
1270 SeekPos(m_nBufFilePos
+ m_nBufActualPos
);
1271 m_nBufActualLen
= 0;
1272 m_pBufPos
= m_pRWBuf
.get();
1273 nCount
= GetData( pData
, nCount
);
1275 EncryptBuffer(pData
, nCount
);
1276 m_nBufFilePos
+= nCount
;
1277 m_nBufFilePos
+= m_nBufActualPos
;
1278 m_nBufActualPos
= 0;
1282 // => Yes. Fill buffer first, then copy to target area
1284 m_nBufFilePos
+= m_nBufActualPos
;
1285 SeekPos(m_nBufFilePos
);
1287 // TODO: Typecast before GetData, sal_uInt16 nCountTmp
1288 std::size_t nCountTmp
= GetData( m_pRWBuf
.get(), m_nBufSize
);
1290 EncryptBuffer(m_pRWBuf
.get(), nCountTmp
);
1291 m_nBufActualLen
= static_cast<sal_uInt16
>(nCountTmp
);
1292 if( nCount
> nCountTmp
)
1294 nCount
= nCountTmp
; // trim count back, EOF see below
1296 memcpy( pData
, m_pRWBuf
.get(), static_cast<size_t>(nCount
) );
1297 m_nBufActualPos
= static_cast<sal_uInt16
>(nCount
);
1298 m_pBufPos
= m_pRWBuf
.get() + nCount
;
1303 m_nBufFree
= m_nBufActualLen
- m_nBufActualPos
;
1304 if (nCount
!= nSaveCount
&& m_nError
!= ERRCODE_IO_PENDING
)
1306 if (nCount
== nSaveCount
&& m_nError
== ERRCODE_IO_PENDING
)
1307 m_nError
= ERRCODE_NONE
;
1311 std::size_t SvStream::WriteBytes( const void* pData
, std::size_t nCount
)
1318 SetError( ERRCODE_IO_CANTWRITE
);
1325 nCount
= CryptAndWriteBuffer( pData
, nCount
);
1327 nCount
= PutData( pData
, nCount
);
1328 m_nBufFilePos
+= nCount
;
1334 if (nCount
<= static_cast<std::size_t>(m_nBufSize
- m_nBufActualPos
))
1336 memcpy( m_pBufPos
, pData
, static_cast<size_t>(nCount
) );
1337 m_nBufActualPos
= m_nBufActualPos
+ static_cast<sal_uInt16
>(nCount
);
1338 // Update length if buffer was updated
1339 if (m_nBufActualPos
> m_nBufActualLen
)
1340 m_nBufActualLen
= m_nBufActualPos
;
1342 m_pBufPos
+= nCount
;
1349 // Does data block fit into buffer?
1350 if (nCount
> m_nBufSize
)
1352 m_isIoWrite
= false;
1353 m_nBufFilePos
+= m_nBufActualPos
;
1354 m_nBufActualLen
= 0;
1355 m_nBufActualPos
= 0;
1356 m_pBufPos
= m_pRWBuf
.get();
1357 SeekPos(m_nBufFilePos
);
1359 nCount
= CryptAndWriteBuffer( pData
, nCount
);
1361 nCount
= PutData( pData
, nCount
);
1362 m_nBufFilePos
+= nCount
;
1366 // Copy block to buffer
1367 memcpy( m_pRWBuf
.get(), pData
, static_cast<size_t>(nCount
) );
1370 m_nBufFilePos
+= m_nBufActualPos
;
1371 m_nBufActualPos
= static_cast<sal_uInt16
>(nCount
);
1372 m_pBufPos
= m_pRWBuf
.get() + nCount
;
1373 m_nBufActualLen
= static_cast<sal_uInt16
>(nCount
);
1377 m_nBufFree
= m_nBufSize
- m_nBufActualPos
;
1381 sal_uInt64
SvStream::Seek(sal_uInt64
const nFilePos
)
1383 m_isIoRead
= m_isIoWrite
= false;
1387 m_nBufFilePos
= SeekPos( nFilePos
);
1388 DBG_ASSERT(Tell() == m_nBufFilePos
,"Out Of Sync!");
1389 return m_nBufFilePos
;
1392 // Is seek position within buffer?
1393 if (nFilePos
>= m_nBufFilePos
&& nFilePos
<= (m_nBufFilePos
+ m_nBufActualLen
))
1395 m_nBufActualPos
= static_cast<sal_uInt16
>(nFilePos
- m_nBufFilePos
);
1396 m_pBufPos
= m_pRWBuf
.get() + m_nBufActualPos
;
1397 // Update m_nBufFree to avoid crash upon PutBack
1398 m_nBufFree
= m_nBufActualLen
- m_nBufActualPos
;
1403 m_nBufActualLen
= 0;
1404 m_nBufActualPos
= 0;
1405 m_pBufPos
= m_pRWBuf
.get();
1406 m_nBufFilePos
= SeekPos( nFilePos
);
1408 return m_nBufFilePos
+ m_nBufActualPos
;
1411 bool checkSeek(SvStream
&rSt
, sal_uInt64 nOffset
)
1413 const sal_uInt64
nMaxSeek(rSt
.Tell() + rSt
.remainingSize());
1414 return (nOffset
<= nMaxSeek
&& rSt
.Seek(nOffset
) == nOffset
);
1417 //STREAM_SEEK_TO_END in some of the Seek backends is special cased to be
1418 //efficient, in others e.g. SotStorageStream it's really horribly slow, and in
1419 //those this should be overridden
1420 sal_uInt64
SvStream::remainingSize()
1422 sal_uInt64
const nCurr
= Tell();
1423 sal_uInt64
const nEnd
= TellEnd();
1424 sal_uInt64 nMaxAvailable
= nEnd
> nCurr
? (nEnd
-nCurr
) : 0;
1426 return nMaxAvailable
;
1429 sal_uInt64
SvStream::TellEnd()
1432 sal_uInt64
const nCurr
= Tell();
1433 sal_uInt64
const nEnd
= Seek(STREAM_SEEK_TO_END
);
1438 void SvStream::Flush()
1445 void SvStream::RefreshBuffer()
1448 SeekPos(m_nBufFilePos
);
1449 m_nBufActualLen
= static_cast<sal_uInt16
>(GetData( m_pRWBuf
.get(), m_nBufSize
));
1450 if (m_nBufActualLen
&& m_nError
== ERRCODE_IO_PENDING
)
1451 m_nError
= ERRCODE_NONE
;
1453 EncryptBuffer(m_pRWBuf
.get(), static_cast<std::size_t>(m_nBufActualLen
));
1454 m_isIoRead
= m_isIoWrite
= false;
1457 SvStream
& SvStream::WriteInt32AsString(sal_Int32 nInt32
)
1460 std::size_t nLen
= sprintf(buffer
, "%" SAL_PRIdINT32
, nInt32
);
1461 WriteBytes(buffer
, nLen
);
1465 SvStream
& SvStream::WriteUInt32AsString(sal_uInt32 nUInt32
)
1468 std::size_t nLen
= sprintf(buffer
, "%" SAL_PRIuUINT32
, nUInt32
);
1469 WriteBytes(buffer
, nLen
);
1473 #define CRYPT_BUFSIZE 1024
1475 /// Encrypt and write
1476 std::size_t SvStream::CryptAndWriteBuffer( const void* pStart
, std::size_t nLen
)
1478 unsigned char pTemp
[CRYPT_BUFSIZE
];
1479 unsigned char const * pDataPtr
= static_cast<unsigned char const *>(pStart
);
1480 std::size_t nCount
= 0;
1481 std::size_t nBufCount
;
1482 unsigned char nMask
= m_nCryptMask
;
1485 if( nLen
>= CRYPT_BUFSIZE
)
1486 nBufCount
= CRYPT_BUFSIZE
;
1490 memcpy( pTemp
, pDataPtr
, static_cast<sal_uInt16
>(nBufCount
) );
1491 // ******** Encrypt ********
1492 for (unsigned char & rn
: pTemp
)
1494 unsigned char aCh
= rn
;
1499 // *************************
1500 nCount
+= PutData( pTemp
, nBufCount
);
1501 pDataPtr
+= nBufCount
;
1507 void SvStream::EncryptBuffer(void* pStart
, std::size_t nLen
) const
1509 unsigned char* pTemp
= static_cast<unsigned char*>(pStart
);
1510 unsigned char nMask
= m_nCryptMask
;
1512 for ( std::size_t n
=0; n
< nLen
; n
++, pTemp
++ )
1514 unsigned char aCh
= *pTemp
;
1521 static unsigned char implGetCryptMask(const sal_Char
* pStr
, sal_Int32 nLen
, long nVersion
)
1523 unsigned char nCryptMask
= 0;
1528 if( nVersion
<= SOFFICE_FILEFORMAT_31
)
1532 nCryptMask
^= *pStr
;
1537 else // BugFix #25888#
1539 for( sal_Int32 i
= 0; i
< nLen
; i
++ ) {
1540 nCryptMask
^= pStr
[i
];
1541 if( nCryptMask
& 0x80 ) {
1556 void SvStream::SetCryptMaskKey(const OString
& rCryptMaskKey
)
1558 m_aCryptMaskKey
= rCryptMaskKey
;
1559 m_nCryptMask
= implGetCryptMask(m_aCryptMaskKey
.getStr(),
1560 m_aCryptMaskKey
.getLength(), GetVersion());
1563 bool SvStream::SetStreamSize(sal_uInt64
const nSize
)
1566 sal_uInt64 nFPos
= Tell();
1568 sal_uInt16 nBuf
= m_nBufSize
;
1571 if (nSize
< m_nBufFilePos
)
1573 m_nBufFilePos
= nSize
;
1575 SetBufferSize( nBuf
);
1577 DBG_ASSERT(Tell()==nFPos
,"SetStreamSize failed");
1579 return (m_nError
== ERRCODE_NONE
);
1582 SvStream
& endl( SvStream
& rStr
)
1584 LineEnd eDelim
= rStr
.GetLineDelimiter();
1585 if ( eDelim
== LINEEND_CR
)
1586 rStr
.WriteChar('\r');
1587 else if( eDelim
== LINEEND_LF
)
1588 rStr
.WriteChar('\n');
1590 rStr
.WriteChar('\r').WriteChar('\n');
1594 SvStream
& endlu( SvStream
& rStrm
)
1596 switch ( rStrm
.GetLineDelimiter() )
1599 rStrm
.WriteUnicode('\r');
1602 rStrm
.WriteUnicode('\n');
1605 rStrm
.WriteUnicode('\r').WriteUnicode('\n');
1610 SvStream
& endlub( SvStream
& rStrm
)
1612 if ( rStrm
.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE
)
1613 return endlu( rStrm
);
1615 return endl( rStrm
);
1618 SvMemoryStream::SvMemoryStream( void* pBuffer
, std::size_t bufSize
,
1621 if( eMode
& StreamMode::WRITE
)
1622 m_isWritable
= true;
1624 m_isWritable
= false;
1625 nEndOfData
= bufSize
;
1627 pBuf
= static_cast<sal_uInt8
*>(pBuffer
);
1634 SvMemoryStream::SvMemoryStream( std::size_t nInitSize
, std::size_t nResizeOffset
)
1636 m_isWritable
= true;
1639 nResize
= nResizeOffset
;
1642 if( nResize
!= 0 && nResize
< 16 )
1645 AllocateMemory( nInitSize
);
1647 SetBufferSize( 64 );
1650 SvMemoryStream::~SvMemoryStream()
1661 sal_uInt64
SvMemoryStream::GetSize()
1664 sal_uInt64
const nTemp
= Tell();
1665 sal_uInt64
const nLength
= Seek( STREAM_SEEK_TO_END
);
1670 void SvMemoryStream::SetBuffer( void* pNewBuf
, std::size_t nCount
,
1673 SetBufferSize( 0 ); // Init buffering in the base class
1675 if( bOwnsData
&& pNewBuf
!= pBuf
)
1678 pBuf
= static_cast<sal_uInt8
*>(pNewBuf
);
1691 std::size_t SvMemoryStream::GetData( void* pData
, std::size_t nCount
)
1693 std::size_t nMaxCount
= nEndOfData
-nPos
;
1694 if( nCount
> nMaxCount
)
1698 memcpy( pData
, pBuf
+nPos
, static_cast<size_t>(nCount
) );
1704 std::size_t SvMemoryStream::PutData( const void* pData
, std::size_t nCount
)
1709 std::size_t nMaxCount
= nSize
-nPos
;
1711 // check for overflow
1712 if( nCount
> nMaxCount
)
1716 // copy as much as possible
1718 SetError( SVSTREAM_OUTOFMEMORY
);
1723 if( nSize
&& nSize
> nResize
)
1726 nNewResize
= nResize
;
1728 if( (nCount
-nMaxCount
) < nResize
)
1730 // lacking memory is smaller than nResize,
1731 // resize accordingly
1732 if( !ReAllocateMemory( nNewResize
) )
1735 SetError( SVSTREAM_WRITE_ERROR
);
1740 // lacking memory is larger than nResize,
1741 // resize by (nCount-nMaxCount) + resize offset
1742 if( !ReAllocateMemory( nCount
-nMaxCount
+nNewResize
) )
1745 SetError( SVSTREAM_WRITE_ERROR
);
1750 assert(pBuf
&& "Possibly Reallocate failed");
1751 memcpy( pBuf
+nPos
, pData
, static_cast<size_t>(nCount
));
1754 if( nPos
> nEndOfData
)
1759 sal_uInt64
SvMemoryStream::SeekPos(sal_uInt64
const nNewPos
)
1761 // nEndOfData: First position in stream not allowed to read from
1762 // nSize: Size of allocated buffer
1764 // check if a truncated STREAM_SEEK_TO_END was passed
1765 assert(nNewPos
!= SAL_MAX_UINT32
);
1766 if( nNewPos
< nEndOfData
)
1768 else if( nNewPos
== STREAM_SEEK_TO_END
)
1772 if( nNewPos
>= nSize
) // Does buffer need extension?
1774 if( nResize
) // Is extension possible?
1776 long nDiff
= static_cast<long>(nNewPos
- nSize
+ 1);
1777 nDiff
+= static_cast<long>(nResize
);
1778 ReAllocateMemory( nDiff
);
1780 nEndOfData
= nNewPos
;
1782 else // Extension not possible, set pos to end of data
1784 // SetError( SVSTREAM_OUTOFMEMORY );
1788 else // Expand buffer size
1791 nEndOfData
= nNewPos
;
1797 void SvMemoryStream::FlushData()
1801 void SvMemoryStream::ResetError()
1803 SvStream::ClearError();
1806 void SvMemoryStream::AllocateMemory( std::size_t nNewSize
)
1808 pBuf
= new sal_uInt8
[nNewSize
];
1811 // (using Bozo algorithm)
1812 bool SvMemoryStream::ReAllocateMemory( long nDiff
)
1814 if (!m_isWritable
|| !bOwnsData
)
1817 bool bRetVal
= false;
1818 long nTemp
= static_cast<long>(nSize
);
1820 std::size_t nNewSize
= static_cast<std::size_t>(nTemp
);
1824 sal_uInt8
* pNewBuf
= new sal_uInt8
[nNewSize
];
1826 bRetVal
= true; // Success!
1827 if( nNewSize
< nSize
) // Are we shrinking?
1829 memcpy( pNewBuf
, pBuf
, static_cast<size_t>(nNewSize
) );
1830 if( nPos
> nNewSize
)
1832 if( nEndOfData
>= nNewSize
)
1833 nEndOfData
= nNewSize
-1;
1839 memcpy( pNewBuf
, pBuf
, static_cast<size_t>(nSize
) );
1841 memset(pNewBuf
+ nSize
, 0x00, nNewSize
- nSize
);
1862 void SvMemoryStream::FreeMemory()
1872 void* SvMemoryStream::SwitchBuffer()
1877 Seek( STREAM_SEEK_TO_BEGIN
);
1879 void* pRetVal
= pBuf
;
1887 std::size_t nInitSize
= 512;
1888 AllocateMemory(nInitSize
);
1891 SetBufferSize( 64 );
1895 void SvMemoryStream::SetSize(sal_uInt64
const nNewSize
)
1899 SetError(SVSTREAM_INVALID_HANDLE
);
1903 long nDiff
= static_cast<long>(nNewSize
) - static_cast<long>(nSize
);
1904 ReAllocateMemory( nDiff
);
1907 //Create an OString of nLen bytes from rStream
1908 OString
read_uInt8s_ToOString(SvStream
& rStrm
, std::size_t nLen
)
1910 rtl_String
*pStr
= nullptr;
1913 nLen
= std::min
<std::size_t>(nLen
, SAL_MAX_INT32
);
1914 //limit allocation to size of file, but + 1 to set eof state
1915 nLen
= std::min
<sal_uInt64
>(nLen
, rStrm
.remainingSize() + 1);
1916 //alloc a (ref-count 1) rtl_String of the desired length.
1917 //rtl_String's buffer is uninitialized, except for null termination
1918 pStr
= rtl_string_alloc(sal::static_int_cast
<sal_Int32
>(nLen
));
1919 SAL_WARN_IF(!pStr
, "tools.stream", "allocation failed");
1922 std::size_t nWasRead
= rStrm
.ReadBytes(pStr
->buffer
, nLen
);
1923 if (nWasRead
!= nLen
)
1925 //on (typically unlikely) short read set length to what we could
1926 //read, and null terminate. Excess buffer capacity remains of
1927 //course, could create a (true) replacement OString if it matters.
1928 pStr
->length
= sal::static_int_cast
<sal_Int32
>(nWasRead
);
1929 pStr
->buffer
[pStr
->length
] = 0;
1934 //take ownership of buffer and return, otherwise return empty string
1935 return pStr
? OString(pStr
, SAL_NO_ACQUIRE
) : OString();
1938 //Create an OUString of nLen sal_Unicode code units from rStream
1939 OUString
read_uInt16s_ToOUString(SvStream
& rStrm
, std::size_t nLen
)
1941 rtl_uString
*pStr
= nullptr;
1944 nLen
= std::min
<std::size_t>(nLen
, SAL_MAX_INT32
);
1945 //limit allocation to size of file, but + 1 to set eof state
1946 nLen
= std::min
<sal_uInt64
>(nLen
, (rStrm
.remainingSize() + 2) / 2);
1947 //alloc a (ref-count 1) rtl_uString of the desired length.
1948 //rtl_String's buffer is uninitialized, except for null termination
1949 pStr
= rtl_uString_alloc(sal::static_int_cast
<sal_Int32
>(nLen
));
1950 SAL_WARN_IF(!pStr
, "tools.stream", "allocation failed");
1953 std::size_t nWasRead
= rStrm
.ReadBytes(pStr
->buffer
, nLen
*2)/2;
1954 if (nWasRead
!= nLen
)
1956 //on (typically unlikely) short read set length to what we could
1957 //read, and null terminate. Excess buffer capacity remains of
1958 //course, could create a (true) replacement OUString if it matters.
1959 pStr
->length
= sal::static_int_cast
<sal_Int32
>(nWasRead
);
1960 pStr
->buffer
[pStr
->length
] = 0;
1962 if (rStrm
.IsEndianSwap())
1964 for (sal_Int32 i
= 0; i
< pStr
->length
; ++i
)
1965 pStr
->buffer
[i
] = OSL_SWAPWORD(pStr
->buffer
[i
]);
1970 //take ownership of buffer and return, otherwise return empty string
1971 return pStr
? OUString(pStr
, SAL_NO_ACQUIRE
) : OUString();
1976 template <typename T
, typename O
> T
tmpl_convertLineEnd(const T
&rIn
, LineEnd eLineEnd
)
1978 // Determine linebreaks and compute length
1979 bool bConvert
= false; // Needs conversion
1980 sal_Int32 nStrLen
= rIn
.getLength();
1981 sal_Int32 nLineEndLen
= (eLineEnd
== LINEEND_CRLF
) ? 2 : 1;
1982 sal_Int32 nLen
= 0; // Target length
1983 sal_Int32 i
= 0; // Source counter
1987 // \r or \n causes linebreak
1988 if ( (rIn
[i
] == '\r') || (rIn
[i
] == '\n') )
1990 nLen
= nLen
+ nLineEndLen
;
1992 // If set already, skip expensive test
1995 // Do we need to convert?
1996 if ( ((eLineEnd
!= LINEEND_LF
) && (rIn
[i
] == '\n')) ||
1997 ((eLineEnd
== LINEEND_CRLF
) && (i
+1) < nStrLen
&& (rIn
[i
+1] != '\n')) ||
1998 ((eLineEnd
== LINEEND_LF
) &&
1999 ((rIn
[i
] == '\r') || ((i
+1) < nStrLen
&& rIn
[i
+1] == '\r'))) ||
2000 ((eLineEnd
== LINEEND_CR
) &&
2001 ((rIn
[i
] == '\n') || ((i
+1) < nStrLen
&& rIn
[i
+1] == '\n'))) )
2005 // skip char if \r\n or \n\r
2006 if ( (i
+1) < nStrLen
&& ((rIn
[i
+1] == '\r') || (rIn
[i
+1] == '\n')) &&
2007 (rIn
[i
] != rIn
[i
+1]) )
2018 // convert linebreaks, insert string
2023 // \r or \n causes linebreak
2024 if ( (rIn
[i
] == '\r') || (rIn
[i
] == '\n') )
2026 if ( eLineEnd
== LINEEND_CRLF
)
2028 aNewData
.append('\r');
2029 aNewData
.append('\n');
2033 if ( eLineEnd
== LINEEND_CR
)
2034 aNewData
.append('\r');
2036 aNewData
.append('\n');
2039 if ( (i
+1) < nStrLen
&& ((rIn
[i
+1] == '\r') || (rIn
[i
+1] == '\n')) &&
2040 (rIn
[i
] != rIn
[i
+1]) )
2045 aNewData
.append(rIn
[i
]);
2051 return aNewData
.makeStringAndClear();
2055 OString
convertLineEnd(const OString
&rIn
, LineEnd eLineEnd
)
2057 return tmpl_convertLineEnd
<OString
, OStringBuffer
>(rIn
, eLineEnd
);
2060 OUString
convertLineEnd(const OUString
&rIn
, LineEnd eLineEnd
)
2062 return tmpl_convertLineEnd
<OUString
, OUStringBuffer
>(rIn
, eLineEnd
);
2065 std::size_t write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream
& rStrm
,
2066 const OUString
&rStr
)
2068 std::size_t nWritten
= 0;
2069 sal_uInt32 nUnits
= std::min
<std::size_t>(rStr
.getLength(), std::numeric_limits
<sal_uInt32
>::max());
2070 SAL_WARN_IF(static_cast<std::size_t>(nUnits
) != static_cast<std::size_t>(rStr
.getLength()),
2072 "string too long for prefix count to fit in output type");
2073 rStrm
.WriteUInt32(nUnits
);
2076 nWritten
+= sizeof(sal_uInt32
);
2077 nWritten
+= write_uInt16s_FromOUString(rStrm
, rStr
, nUnits
);
2082 std::size_t write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream
& rStrm
,
2083 const OUString
&rStr
)
2085 std::size_t nWritten
= 0;
2086 sal_uInt16 nUnits
= std::min
<std::size_t>(rStr
.getLength(), std::numeric_limits
<sal_uInt16
>::max());
2087 SAL_WARN_IF(nUnits
!= rStr
.getLength(),
2089 "string too long for prefix count to fit in output type");
2090 rStrm
.WriteUInt16(nUnits
);
2093 nWritten
+= sizeof(nUnits
);
2094 nWritten
+= write_uInt16s_FromOUString(rStrm
, rStr
, nUnits
);
2099 std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream
& rStrm
,
2100 const OString
&rStr
)
2102 std::size_t nWritten
= 0;
2103 sal_uInt16 nUnits
= std::min
<std::size_t>(rStr
.getLength(), std::numeric_limits
<sal_uInt16
>::max());
2104 SAL_WARN_IF(static_cast<std::size_t>(nUnits
) != static_cast<std::size_t>(rStr
.getLength()),
2106 "string too long for sal_uInt16 count to fit in output type");
2107 rStrm
.WriteUInt16( nUnits
);
2110 nWritten
+= sizeof(sal_uInt16
);
2111 nWritten
+= write_uInt8s_FromOString(rStrm
, rStr
, nUnits
);
2116 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */