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 nBufActualLen
29 #include <osl/endian.h>
30 #include <osl/diagnose.h>
31 #include <sal/log.hxx>
33 #include <comphelper/string.hxx>
35 #define SWAPNIBBLES(c) \
36 unsigned char nSwapTmp=c; \
41 #include <tools/debug.hxx>
42 #include <tools/stream.hxx>
43 #include <osl/thread.h>
46 // !!! Do not inline if already the operators <<,>> are inline
47 inline static void SwapUShort( sal_uInt16
& r
)
48 { r
= OSL_SWAPWORD(r
); }
49 inline static void SwapShort( short& r
)
50 { r
= OSL_SWAPWORD(r
); }
51 inline static void SwapULong( sal_uInt32
& r
)
52 { r
= OSL_SWAPDWORD(r
); }
53 inline static void SwapLongInt( sal_Int32
& r
)
54 { r
= OSL_SWAPDWORD(r
); }
56 inline static void SwapUInt64( sal_uInt64
& r
)
65 s
.c
[0] ^= s
.c
[1]; // swap the 32 bit words
68 // swap the bytes in the words
69 s
.c
[0] = OSL_SWAPDWORD(s
.c
[0]);
70 s
.c
[1] = OSL_SWAPDWORD(s
.c
[1]);
73 inline static void SwapInt64( sal_Int64
& r
)
82 s
.c
[0] ^= s
.c
[1]; // swap the 32 bit words
85 // swap the bytes in the words
86 s
.c
[0] = OSL_SWAPDWORD(s
.c
[0]);
87 s
.c
[1] = OSL_SWAPDWORD(s
.c
[1]);
92 inline static void SwapFloat( float& r
)
101 s
.c
= OSL_SWAPDWORD( s
.c
);
105 inline static void SwapDouble( double& r
)
107 if( sizeof(double) != 8 )
109 DBG_ASSERT( false, "Can only swap 8-Byte-doubles\n" );
120 s
.c
[0] ^= s
.c
[1]; // swap 32-bit values in situ
123 s
.c
[0] = OSL_SWAPDWORD(s
.c
[0]); // swap dword itself in situ
124 s
.c
[1] = OSL_SWAPDWORD(s
.c
[1]);
132 #define READNUMBER_WITHOUT_SWAP(datatype,value) \
133 if( bIoRead && sizeof(datatype)<=nBufFree) \
135 for (std::size_t i = 0; i < sizeof(datatype); i++) \
136 reinterpret_cast<char *>(&value)[i] = pBufPos[i]; \
137 nBufActualPos += sizeof(datatype); \
138 pBufPos += sizeof(datatype); \
139 nBufFree -= sizeof(datatype); \
143 Read( &value, sizeof(datatype) ); \
147 #define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
148 if( bIoWrite && sizeof(datatype) <= nBufFree) \
150 for (std::size_t i = 0; i < sizeof(datatype); i++) \
151 pBufPos[i] = reinterpret_cast<char const *>(&value)[i]; \
152 nBufFree -= sizeof(datatype); \
153 nBufActualPos += sizeof(datatype); \
154 if( nBufActualPos > nBufActualLen ) \
155 nBufActualLen = nBufActualPos; \
156 pBufPos += sizeof(datatype); \
161 Write( &value, sizeof(datatype) ); \
166 void SvLockBytes::close()
173 TYPEINIT0(SvLockBytes
);
176 ErrCode
SvLockBytes::ReadAt(sal_uInt64
const nPos
, void * pBuffer
, sal_Size nCount
,
177 sal_Size
* pRead
) const
181 OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
185 m_pStream
->Seek(nPos
);
186 sal_Size nTheRead
= m_pStream
->Read(pBuffer
, nCount
);
189 return m_pStream
->GetErrorCode();
193 ErrCode
SvLockBytes::WriteAt(sal_uInt64
const nPos
, const void * pBuffer
, sal_Size nCount
,
198 OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
202 m_pStream
->Seek(nPos
);
203 sal_Size nTheWritten
= m_pStream
->Write(pBuffer
, nCount
);
205 *pWritten
= nTheWritten
;
206 return m_pStream
->GetErrorCode();
210 ErrCode
SvLockBytes::Flush() const
214 OSL_FAIL("SvLockBytes::Flush(): Bad stream");
219 return m_pStream
->GetErrorCode();
223 ErrCode
SvLockBytes::SetSize(sal_uInt64
const nSize
)
227 OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
231 m_pStream
->SetStreamSize(nSize
);
232 return m_pStream
->GetErrorCode();
235 ErrCode
SvLockBytes::Stat(SvLockBytesStat
* pStat
, SvLockBytesStatFlag
) const
239 OSL_FAIL("SvLockBytes::Stat(): Bad stream");
245 sal_uInt64
const nPos
= m_pStream
->Tell();
246 pStat
->nSize
= m_pStream
->Seek(STREAM_SEEK_TO_END
);
247 m_pStream
->Seek(nPos
);
252 // class SvOpenLockBytes
254 TYPEINIT1(SvOpenLockBytes
, SvLockBytes
);
256 // class SvAsyncLockBytes
258 TYPEINIT1(SvAsyncLockBytes
, SvOpenLockBytes
);
261 ErrCode
SvAsyncLockBytes::ReadAt(sal_uInt64
const nPos
, void * pBuffer
, sal_Size nCount
,
262 sal_Size
* pRead
) const
265 return SvOpenLockBytes::ReadAt(nPos
, pBuffer
, nCount
, pRead
);
269 std::min
<sal_Size
>(nPos
< m_nSize
? m_nSize
- nPos
: 0, nCount
);
270 ErrCode nError
= SvOpenLockBytes::ReadAt(nPos
, pBuffer
, nTheCount
,
272 return !nCount
|| nTheCount
== nCount
|| nError
? nError
:
278 ErrCode
SvAsyncLockBytes::WriteAt(sal_uInt64
const nPos
, const void * pBuffer
,
279 sal_Size nCount
, sal_Size
* pWritten
)
282 return SvOpenLockBytes::WriteAt(nPos
, pBuffer
, nCount
, pWritten
);
286 std::min
<sal_Size
>(nPos
< m_nSize
? m_nSize
- nPos
: 0, nCount
);
287 ErrCode nError
= SvOpenLockBytes::WriteAt(nPos
, pBuffer
, nTheCount
,
289 return !nCount
|| nTheCount
== nCount
|| nError
? nError
:
295 ErrCode
SvAsyncLockBytes::FillAppend(const void * pBuffer
, sal_Size nCount
,
298 sal_Size
nTheWritten(0);
299 ErrCode nError
= SvOpenLockBytes::WriteAt(m_nSize
, pBuffer
, nCount
,
302 m_nSize
+= nTheWritten
;
304 *pWritten
= nTheWritten
;
309 sal_uInt64
SvAsyncLockBytes::Seek(sal_uInt64
const nPos
)
311 // check if a truncated STREAM_SEEK_TO_END was passed
312 assert(nPos
!= SAL_MAX_UINT32
);
313 if (nPos
!= STREAM_SEEK_TO_END
)
320 sal_Size
SvStream::GetData( void* pData
, sal_Size nSize
)
324 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
326 nError
= xLockBytes
->ReadAt(m_nActPos
, pData
, nSize
, &nRet
);
333 sal_Size
SvStream::PutData( const void* pData
, sal_Size nSize
)
337 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
339 nError
= xLockBytes
->WriteAt(m_nActPos
, pData
, nSize
, &nRet
);
346 sal_uInt64
SvStream::SeekPos(sal_uInt64
const nPos
)
348 // check if a truncated STREAM_SEEK_TO_END was passed
349 assert(nPos
!= SAL_MAX_UINT32
);
350 if( !GetError() && nPos
== STREAM_SEEK_TO_END
)
352 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
353 SvLockBytesStat aStat
;
354 xLockBytes
->Stat( &aStat
, SVSTATFLAG_DEFAULT
);
355 m_nActPos
= aStat
.nSize
;
362 void SvStream::FlushData()
366 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
367 nError
= xLockBytes
->Flush();
371 void SvStream::SetSize(sal_uInt64
const nSize
)
373 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
374 nError
= xLockBytes
->SetSize( nSize
);
377 void SvStream::ImpInit()
380 nCompressMode
= SvStreamCompressFlags::NONE
;
381 eStreamCharSet
= osl_getThreadTextEncoding();
385 eLineDelimiter
= LINEEND_LF
; // UNIX-Format
387 eLineDelimiter
= LINEEND_CRLF
; // DOS-Format
390 SetEndian( SvStreamEndian::LITTLE
);
395 bIsConsistent
= true;
406 eStreamMode
= StreamMode::NONE
;
413 SvStream::SvStream( SvLockBytes
* pLockBytesP
)
416 xLockBytes
= pLockBytesP
;
418 const SvStream
* pStrm
= pLockBytesP
->GetStream();
420 SetError( pStrm
->GetErrorCode() );
423 SetBufferSize( 256 );
431 SvStream::~SvStream()
433 if ( xLockBytes
.Is() )
440 void SvStream::ClearError()
443 nError
= SVSTREAM_OK
;
446 void SvStream::SetError( sal_uInt32 nErrorCode
)
448 if ( nError
== SVSTREAM_OK
)
452 void SvStream::SetEndian( SvStreamEndian nNewFormat
)
454 nEndian
= nNewFormat
;
457 if( nEndian
== SvStreamEndian::LITTLE
)
460 if( nEndian
== SvStreamEndian::BIG
)
465 void SvStream::SetBufferSize( sal_uInt16 nBufferSize
)
467 sal_uInt64
const nActualFilePos
= Tell();
468 bool bDontSeek
= (pRWBuf
== 0);
470 if( bIsDirty
&& bIsConsistent
&& bIsWritable
) // due to Windows NT: Access denied
476 m_nBufFilePos
+= nBufActualPos
;
482 nBufSize
= nBufferSize
;
484 pRWBuf
= new sal_uInt8
[ nBufSize
];
485 bIsConsistent
= true;
487 bIoRead
= bIoWrite
= false;
489 SeekPos( nActualFilePos
);
492 void SvStream::ClearBuffer()
499 bIsConsistent
= true;
500 bIoRead
= bIoWrite
= false;
505 void SvStream::ResetError()
510 bool SvStream::ReadByteStringLine( OUString
& rStr
, rtl_TextEncoding eSrcCharSet
,
511 sal_Int32 nMaxBytesToRead
)
514 bool bRet
= ReadLine( aStr
, nMaxBytesToRead
);
515 rStr
= OStringToOUString(aStr
, eSrcCharSet
);
519 bool SvStream::ReadLine( OString
& rStr
, sal_Int32 nMaxBytesToRead
)
523 sal_uInt64 nOldFilePos
= Tell();
525 sal_Size nTotalLen
= 0;
527 OStringBuffer
aBuf(4096);
528 while( !bEnd
&& !GetError() ) // Don't test for EOF as we
529 // are reading block-wise!
531 sal_uInt16 nLen
= (sal_uInt16
)Read( buf
, sizeof(buf
)-1 );
534 if ( aBuf
.isEmpty() )
536 // Exit on first block-read error
546 for( j
= n
= 0; j
< nLen
; ++j
)
549 if ( c
== '\n' || c
== '\r' )
559 if (nTotalLen
> static_cast<sal_Size
>(nMaxBytesToRead
))
561 n
-= nTotalLen
- nMaxBytesToRead
;
562 nTotalLen
= nMaxBytesToRead
;
569 if ( !bEnd
&& !GetError() && !aBuf
.isEmpty() )
572 nOldFilePos
+= nTotalLen
;
573 if( Tell() > nOldFilePos
)
575 Seek( nOldFilePos
); // Seek pointer due to BlockRead above
577 if ( bEnd
&& (c
=='\r' || c
=='\n') ) // Special treatment for DOS files
580 sal_Size nLen
= Read(&cTemp
, sizeof(cTemp
) );
582 if( cTemp
== c
|| (cTemp
!= '\n' && cTemp
!= '\r') )
589 rStr
= aBuf
.makeStringAndClear();
593 bool SvStream::ReadUniStringLine( OUString
& rStr
, sal_Int32 nMaxCodepointsToRead
)
595 sal_Unicode buf
[256+1];
597 sal_uInt64 nOldFilePos
= Tell();
599 sal_Size nTotalLen
= 0;
601 DBG_ASSERT( sizeof(sal_Unicode
) == sizeof(sal_uInt16
), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
603 OUStringBuffer
aBuf(4096);
604 while( !bEnd
&& !GetError() ) // Don't test for EOF as we
605 // are reading block-wise!
607 sal_uInt16 nLen
= (sal_uInt16
)Read( buf
, sizeof(buf
)-sizeof(sal_Unicode
) );
608 nLen
/= sizeof(sal_Unicode
);
611 if ( aBuf
.isEmpty() )
613 // exit on first BlockRead error
623 for( j
= n
= 0; j
< nLen
; ++j
)
626 SwapUShort( buf
[n
] );
628 if ( c
== '\n' || c
== '\r' )
633 // erAck 26.02.01: Old behavior was no special treatment of '\0'
634 // character here, but a following rStr+=c did ignore it. Is this
635 // really intended? Or should a '\0' better terminate a line?
636 // The nOldFilePos stuff wasn't correct then anyways.
645 if (nTotalLen
> static_cast<sal_Size
>(nMaxCodepointsToRead
))
647 n
-= nTotalLen
- nMaxCodepointsToRead
;
648 nTotalLen
= nMaxCodepointsToRead
;
652 aBuf
.append( buf
, n
);
655 if ( !bEnd
&& !GetError() && !aBuf
.isEmpty() )
658 nOldFilePos
+= nTotalLen
* sizeof(sal_Unicode
);
659 if( Tell() > nOldFilePos
)
660 nOldFilePos
+= sizeof(sal_Unicode
);
661 Seek( nOldFilePos
); // seek due to BlockRead above
663 if ( bEnd
&& (c
=='\r' || c
=='\n') ) // special treatment for DOS files
666 Read( &cTemp
, sizeof(cTemp
) );
669 if( cTemp
== c
|| (cTemp
!= '\n' && cTemp
!= '\r') )
675 rStr
= aBuf
.makeStringAndClear();
679 bool SvStream::ReadUniOrByteStringLine( OUString
& rStr
, rtl_TextEncoding eSrcCharSet
,
680 sal_Int32 nMaxCodepointsToRead
)
682 if ( eSrcCharSet
== RTL_TEXTENCODING_UNICODE
)
683 return ReadUniStringLine( rStr
, nMaxCodepointsToRead
);
685 return ReadByteStringLine( rStr
, eSrcCharSet
, nMaxCodepointsToRead
);
688 OString
read_zeroTerminated_uInt8s_ToOString(SvStream
& rStream
)
690 OStringBuffer
aOutput(256);
692 sal_Char buf
[ 256 + 1 ];
694 sal_uInt64 nFilePos
= rStream
.Tell();
696 while( !bEnd
&& !rStream
.GetError() )
698 sal_Size nLen
= rStream
.Read(buf
, sizeof(buf
)-1);
702 sal_Size nReallyRead
= nLen
;
703 const sal_Char
* pPtr
= buf
;
704 while (nLen
&& *pPtr
)
707 bEnd
= ( nReallyRead
< sizeof(buf
)-1 ) // read less than attempted to read
708 || ( ( nLen
> 0 ) // OR it is inside the block we read
709 && ( 0 == *pPtr
) // AND found a string terminator
712 aOutput
.append(buf
, pPtr
- buf
);
715 nFilePos
+= aOutput
.getLength();
716 if (rStream
.Tell() > nFilePos
)
717 rStream
.Seek(nFilePos
+1); // seek due to FileRead above
718 return aOutput
.makeStringAndClear();
721 OUString
read_zeroTerminated_uInt8s_ToOUString(SvStream
& rStream
, rtl_TextEncoding eEnc
)
723 return OStringToOUString(
724 read_zeroTerminated_uInt8s_ToOString(rStream
), eEnc
);
727 /** Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
728 returned value is number of bytes written */
729 sal_Size
write_uInt16s_FromOUString(SvStream
& rStrm
, const OUString
& rStr
,
732 DBG_ASSERT( sizeof(sal_Unicode
) == sizeof(sal_uInt16
), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
734 if (!rStrm
.IsEndianSwap())
735 nWritten
= rStrm
.Write( rStr
.getStr(), nUnits
* sizeof(sal_Unicode
) );
738 sal_Size nLen
= nUnits
;
739 sal_Unicode aBuf
[384];
740 sal_Unicode
* const pTmp
= ( nLen
> 384 ? new sal_Unicode
[nLen
] : aBuf
);
741 memcpy( pTmp
, rStr
.getStr(), nLen
* sizeof(sal_Unicode
) );
742 sal_Unicode
* p
= pTmp
;
743 const sal_Unicode
* const pStop
= pTmp
+ nLen
;
749 nWritten
= rStrm
.Write( pTmp
, nLen
* sizeof(sal_Unicode
) );
756 bool SvStream::WriteUnicodeOrByteText( const OUString
& rStr
, rtl_TextEncoding eDestCharSet
)
758 if ( eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
760 write_uInt16s_FromOUString(*this, rStr
, rStr
.getLength());
761 return nError
== SVSTREAM_OK
;
765 OString
aStr(OUStringToOString(rStr
, eDestCharSet
));
766 write_uInt8s_FromOString(*this, aStr
, aStr
.getLength());
767 return nError
== SVSTREAM_OK
;
771 bool SvStream::WriteByteStringLine( const OUString
& rStr
, rtl_TextEncoding eDestCharSet
)
773 return WriteLine(OUStringToOString(rStr
, eDestCharSet
));
776 bool SvStream::WriteLine(const OString
& rStr
)
778 Write(rStr
.getStr(), rStr
.getLength());
780 return nError
== SVSTREAM_OK
;
783 bool SvStream::WriteUniOrByteChar( sal_Unicode ch
, rtl_TextEncoding eDestCharSet
)
785 if ( eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
789 OString
aStr(&ch
, 1, eDestCharSet
);
790 Write(aStr
.getStr(), aStr
.getLength());
792 return nError
== SVSTREAM_OK
;
795 bool SvStream::StartWritingUnicodeText()
797 // BOM, Byte Order Mark, U+FEFF, see
798 // http://www.unicode.org/faq/utf_bom.html#BOM
799 // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
800 sal_uInt16 v
= 0xfeff;
801 WRITENUMBER_WITHOUT_SWAP(sal_uInt16
, v
); // write native format
802 return nError
== SVSTREAM_OK
;
805 bool SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet
)
807 if (!( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
808 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
||
809 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
810 return true; // nothing to read
812 bool bTryUtf8
= false;
814 sal_sSize nBack
= sizeof(nFlag
);
815 this->ReadUInt16( nFlag
);
820 if ( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
821 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
)
826 if ( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
827 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
)
829 SetEndian( nEndian
== SvStreamEndian::BIG
? SvStreamEndian::LITTLE
: SvStreamEndian::BIG
);
834 if (nEndian
== SvStreamEndian::BIG
&&
835 (eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
836 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
840 if (nEndian
== SvStreamEndian::LITTLE
&&
841 (eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
842 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
850 unsigned char nChar(0);
851 nBack
+= sizeof(nChar
);
852 this->ReadUChar( nChar
);
854 nBack
= 0; // it is UTF-8
857 SeekRel( -nBack
); // no BOM, pure data
858 return nError
== SVSTREAM_OK
;
861 sal_uInt64
SvStream::SeekRel(sal_Int64
const nPos
)
863 sal_uInt64 nActualPos
= Tell();
867 if (SAL_MAX_UINT64
- nActualPos
> static_cast<sal_uInt64
>(nPos
))
872 sal_uInt64
const nAbsPos
= static_cast<sal_uInt64
>(-nPos
);
873 if ( nActualPos
>= nAbsPos
)
874 nActualPos
-= nAbsPos
;
877 pBufPos
= pRWBuf
+ nActualPos
;
878 return Seek( nActualPos
);
881 SvStream
& SvStream::ReadUInt16(sal_uInt16
& r
)
884 READNUMBER_WITHOUT_SWAP(sal_uInt16
, n
)
894 SvStream
& SvStream::ReadUInt32(sal_uInt32
& r
)
897 READNUMBER_WITHOUT_SWAP(sal_uInt32
, n
)
907 SvStream
& SvStream::ReadUInt64(sal_uInt64
& r
)
910 READNUMBER_WITHOUT_SWAP(sal_uInt64
, n
)
920 SvStream
& SvStream::ReadInt16(sal_Int16
& r
)
923 READNUMBER_WITHOUT_SWAP(sal_Int16
, n
)
933 SvStream
& SvStream::ReadInt32(sal_Int32
& r
)
936 READNUMBER_WITHOUT_SWAP(sal_Int32
, n
)
946 SvStream
& SvStream::ReadInt64(sal_Int64
& r
)
949 READNUMBER_WITHOUT_SWAP(sal_Int64
, n
)
959 SvStream
& SvStream::ReadSChar( signed char& r
)
961 if( (bIoRead
|| !bIsConsistent
) &&
962 sizeof(signed char) <= nBufFree
)
965 nBufActualPos
+= sizeof(signed char);
966 pBufPos
+= sizeof(signed char);
967 nBufFree
-= sizeof(signed char);
970 Read( &r
, sizeof(signed char) );
974 // Special treatment for Chars due to PutBack
976 SvStream
& SvStream::ReadChar( char& r
)
978 if( (bIoRead
|| !bIsConsistent
) &&
979 sizeof(char) <= nBufFree
)
982 nBufActualPos
+= sizeof(char);
983 pBufPos
+= sizeof(char);
984 nBufFree
-= sizeof(char);
987 Read( &r
, sizeof(char) );
991 SvStream
& SvStream::ReadUChar( unsigned char& r
)
993 if( (bIoRead
|| !bIsConsistent
) &&
994 sizeof(char) <= nBufFree
)
997 nBufActualPos
+= sizeof(char);
998 pBufPos
+= sizeof(char);
999 nBufFree
-= sizeof(char);
1002 Read( &r
, sizeof(char) );
1006 SvStream
& SvStream::ReadCharAsBool( bool& r
)
1008 if( (bIoRead
|| !bIsConsistent
) &&
1009 sizeof(char) <= nBufFree
)
1012 *pBufPos
> 1, "tools.stream", unsigned(*pBufPos
) << " not 0/1");
1014 nBufActualPos
+= sizeof(char);
1015 pBufPos
+= sizeof(char);
1016 nBufFree
-= sizeof(char);
1021 if (Read(&c
, 1) == 1)
1023 SAL_WARN_IF(c
> 1, "tools.stream", unsigned(c
) << " not 0/1");
1030 SvStream
& SvStream::ReadFloat(float& r
)
1033 READNUMBER_WITHOUT_SWAP(float, n
)
1045 SvStream
& SvStream::ReadDouble(double& r
)
1048 READNUMBER_WITHOUT_SWAP(double, n
)
1060 SvStream
& SvStream::ReadStream( SvStream
& rStream
)
1062 const sal_uInt32 cBufLen
= 0x8000;
1063 char* pBuf
= new char[ cBufLen
];
1067 nCount
= Read( pBuf
, cBufLen
);
1068 rStream
.Write( pBuf
, nCount
);
1069 } while( nCount
== cBufLen
);
1075 SvStream
& SvStream::WriteUInt16( sal_uInt16 v
)
1079 WRITENUMBER_WITHOUT_SWAP(sal_uInt16
,v
)
1083 SvStream
& SvStream::WriteUInt32( sal_uInt32 v
)
1087 WRITENUMBER_WITHOUT_SWAP(sal_uInt32
,v
)
1091 SvStream
& SvStream::WriteUInt64( sal_uInt64 v
)
1095 WRITENUMBER_WITHOUT_SWAP(sal_uInt64
,v
)
1099 SvStream
& SvStream::WriteInt16( sal_Int16 v
)
1103 WRITENUMBER_WITHOUT_SWAP(sal_Int16
,v
)
1107 SvStream
& SvStream::WriteInt32( sal_Int32 v
)
1111 WRITENUMBER_WITHOUT_SWAP(sal_Int32
,v
)
1115 SvStream
& SvStream::WriteInt64 (sal_Int64 v
)
1119 WRITENUMBER_WITHOUT_SWAP(sal_Int64
,v
)
1123 SvStream
& SvStream::WriteSChar( signed char v
)
1126 if(bIoWrite
&& sizeof(signed char) <= nBufFree
)
1129 pBufPos
++; // sizeof(char);
1131 if( nBufActualPos
> nBufActualLen
) // Append ?
1132 nBufActualLen
= nBufActualPos
;
1133 nBufFree
--; // = sizeof(char);
1137 Write( &v
, sizeof(signed char) );
1141 // Special treatment for Chars due to PutBack
1143 SvStream
& SvStream::WriteChar( char v
)
1146 if(bIoWrite
&& sizeof(char) <= nBufFree
)
1149 pBufPos
++; // sizeof(char);
1151 if( nBufActualPos
> nBufActualLen
) // Append ?
1152 nBufActualLen
= nBufActualPos
;
1153 nBufFree
--; // = sizeof(char);
1157 Write( &v
, sizeof(char) );
1161 SvStream
& SvStream::WriteUChar( unsigned char v
)
1164 if(bIoWrite
&& sizeof(char) <= nBufFree
)
1166 *(unsigned char*)pBufPos
= v
;
1167 pBufPos
++; // = sizeof(char);
1168 nBufActualPos
++; // = sizeof(char);
1169 if( nBufActualPos
> nBufActualLen
) // Append ?
1170 nBufActualLen
= nBufActualPos
;
1175 Write( &v
, sizeof(char) );
1179 SvStream
& SvStream::WriteUInt8( sal_uInt8 v
)
1181 return WriteUChar(v
);
1184 SvStream
& SvStream::WriteUnicode( sal_Unicode v
)
1186 return WriteUInt16(v
);
1189 SvStream
& SvStream::WriteFloat( float v
)
1195 WRITENUMBER_WITHOUT_SWAP(float,v
)
1199 SvStream
& SvStream::WriteDouble ( const double& r
)
1206 WRITENUMBER_WITHOUT_SWAP(double,nHelp
)
1212 WRITENUMBER_WITHOUT_SWAP(double,r
);
1217 SvStream
& SvStream::WriteCharPtr( const char* pBuf
)
1219 Write( pBuf
, strlen( pBuf
) );
1223 SvStream
& SvStream::WriteStream( SvStream
& rStream
)
1225 const sal_uInt32 cBufLen
= 0x8000;
1226 char* pBuf
= new char[ cBufLen
];
1229 nCount
= rStream
.Read( pBuf
, cBufLen
);
1230 Write( pBuf
, nCount
);
1231 } while( nCount
== cBufLen
);
1237 OUString
SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet
)
1239 // read UTF-16 string directly from stream ?
1240 if (eSrcCharSet
== RTL_TEXTENCODING_UNICODE
)
1241 return read_uInt32_lenPrefixed_uInt16s_ToOUString(*this);
1242 return read_uInt16_lenPrefixed_uInt8s_ToOUString(*this, eSrcCharSet
);
1245 SvStream
& SvStream::WriteUniOrByteString( const OUString
& rStr
, rtl_TextEncoding eDestCharSet
)
1247 // write UTF-16 string directly into stream ?
1248 if (eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
1249 write_uInt32_lenPrefixed_uInt16s_FromOUString(*this, rStr
);
1251 write_uInt16_lenPrefixed_uInt8s_FromOUString(*this, rStr
, eDestCharSet
);
1255 sal_Size
SvStream::Read( void* pData
, sal_Size nCount
)
1257 sal_Size nSaveCount
= nCount
;
1258 if( !bIsConsistent
)
1263 nCount
= GetData( pData
,nCount
);
1265 EncryptBuffer(pData
, nCount
);
1266 m_nBufFilePos
+= nCount
;
1270 // check if block is completely within buffer
1273 if( nCount
<= (sal_Size
)(nBufActualLen
- nBufActualPos
) )
1276 memcpy(pData
, pBufPos
, (size_t) nCount
);
1277 nBufActualPos
= nBufActualPos
+ (sal_uInt16
)nCount
;
1279 nBufFree
= nBufFree
- (sal_uInt16
)nCount
;
1283 if( bIsDirty
) // Does stream require a flush?
1285 SeekPos(m_nBufFilePos
);
1287 CryptAndWriteBuffer(pRWBuf
, nBufActualLen
);
1289 PutData( pRWBuf
, nBufActualLen
);
1293 // Does data block fit into buffer?
1294 if( nCount
> nBufSize
)
1296 // => No! Thus read directly
1297 // into target area without using the buffer
1301 SeekPos(m_nBufFilePos
+ nBufActualPos
);
1304 nCount
= GetData( pData
, nCount
);
1306 EncryptBuffer(pData
, nCount
);
1307 m_nBufFilePos
+= nCount
;
1308 m_nBufFilePos
+= nBufActualPos
;
1313 // => Yes. Fill buffer first, then copy to target area
1315 m_nBufFilePos
+= nBufActualPos
;
1316 SeekPos(m_nBufFilePos
);
1318 // TODO: Typecast before GetData, sal_uInt16 nCountTmp
1319 sal_Size nCountTmp
= GetData( pRWBuf
, nBufSize
);
1321 EncryptBuffer(pRWBuf
, nCountTmp
);
1322 nBufActualLen
= (sal_uInt16
)nCountTmp
;
1323 if( nCount
> nCountTmp
)
1325 nCount
= nCountTmp
; // trim count back, EOF see below
1327 memcpy( pData
, pRWBuf
, (size_t)nCount
);
1328 nBufActualPos
= (sal_uInt16
)nCount
;
1329 pBufPos
= pRWBuf
+ nCount
;
1334 nBufFree
= nBufActualLen
- nBufActualPos
;
1335 if( nCount
!= nSaveCount
&& nError
!= ERRCODE_IO_PENDING
)
1337 if( nCount
== nSaveCount
&& nError
== ERRCODE_IO_PENDING
)
1338 nError
= ERRCODE_NONE
;
1342 sal_Size
SvStream::Write( const void* pData
, sal_Size nCount
)
1348 SetError( ERRCODE_IO_CANTWRITE
);
1351 if( !bIsConsistent
)
1352 RefreshBuffer(); // Remove changes in buffer through PutBack
1357 nCount
= CryptAndWriteBuffer( pData
, nCount
);
1359 nCount
= PutData( pData
, nCount
);
1360 m_nBufFilePos
+= nCount
;
1366 if( nCount
<= (sal_Size
)(nBufSize
- nBufActualPos
) )
1368 memcpy( pBufPos
, pData
, (size_t)nCount
);
1369 nBufActualPos
= nBufActualPos
+ (sal_uInt16
)nCount
;
1370 // Update length if buffer was updated
1371 if( nBufActualPos
> nBufActualLen
)
1372 nBufActualLen
= nBufActualPos
;
1379 // Does stream require flushing?
1382 SeekPos(m_nBufFilePos
);
1384 CryptAndWriteBuffer( pRWBuf
, (sal_Size
)nBufActualLen
);
1386 PutData( pRWBuf
, nBufActualLen
);
1390 // Does data block fit into buffer?
1391 if( nCount
> nBufSize
)
1394 m_nBufFilePos
+= nBufActualPos
;
1398 SeekPos(m_nBufFilePos
);
1400 nCount
= CryptAndWriteBuffer( pData
, nCount
);
1402 nCount
= PutData( pData
, nCount
);
1403 m_nBufFilePos
+= nCount
;
1407 // Copy block to buffer
1408 memcpy( pRWBuf
, pData
, (size_t)nCount
);
1411 m_nBufFilePos
+= nBufActualPos
;
1412 nBufActualPos
= (sal_uInt16
)nCount
;
1413 pBufPos
= pRWBuf
+ nCount
;
1414 nBufActualLen
= (sal_uInt16
)nCount
;
1418 nBufFree
= nBufSize
- nBufActualPos
;
1422 sal_uInt64
SvStream::Seek(sal_uInt64
const nFilePos
)
1424 bIoRead
= bIoWrite
= false;
1428 m_nBufFilePos
= SeekPos( nFilePos
);
1429 DBG_ASSERT(Tell() == m_nBufFilePos
,"Out Of Sync!");
1430 return m_nBufFilePos
;
1433 // Is seek position within buffer?
1434 if (nFilePos
>= m_nBufFilePos
&& nFilePos
<= (m_nBufFilePos
+ nBufActualLen
))
1436 nBufActualPos
= (sal_uInt16
)(nFilePos
- m_nBufFilePos
);
1437 pBufPos
= pRWBuf
+ nBufActualPos
;
1438 // Update nBufFree to avoid crash upon PutBack
1439 nBufFree
= nBufActualLen
- nBufActualPos
;
1443 if( bIsDirty
&& bIsConsistent
)
1445 SeekPos(m_nBufFilePos
);
1447 CryptAndWriteBuffer( pRWBuf
, nBufActualLen
);
1449 PutData( pRWBuf
, nBufActualLen
);
1455 m_nBufFilePos
= SeekPos( nFilePos
);
1457 return m_nBufFilePos
+ nBufActualPos
;
1460 //STREAM_SEEK_TO_END in the some of the Seek backends is special cased to be
1461 //efficient, in others e.g. SotStorageStream it's really horribly slow, and in
1462 //those this should be overridden
1463 sal_uInt64
SvStream::remainingSize()
1465 sal_uInt64
const nCurr
= Tell();
1466 sal_uInt64
const nEnd
= Seek(STREAM_SEEK_TO_END
);
1467 sal_uInt64 nMaxAvailable
= nEnd
> nCurr
? (nEnd
-nCurr
) : 0;
1469 return nMaxAvailable
;
1472 void SvStream::Flush()
1474 if( bIsDirty
&& bIsConsistent
)
1476 SeekPos(m_nBufFilePos
);
1478 CryptAndWriteBuffer( pRWBuf
, (sal_Size
)nBufActualLen
);
1480 if( PutData( pRWBuf
, nBufActualLen
) != nBufActualLen
)
1481 SetError( SVSTREAM_WRITE_ERROR
);
1488 void SvStream::RefreshBuffer()
1490 if( bIsDirty
&& bIsConsistent
)
1492 SeekPos(m_nBufFilePos
);
1494 CryptAndWriteBuffer( pRWBuf
, (sal_Size
)nBufActualLen
);
1496 PutData( pRWBuf
, nBufActualLen
);
1499 SeekPos(m_nBufFilePos
);
1500 nBufActualLen
= (sal_uInt16
)GetData( pRWBuf
, nBufSize
);
1501 if( nBufActualLen
&& nError
== ERRCODE_IO_PENDING
)
1502 nError
= ERRCODE_NONE
;
1504 EncryptBuffer(pRWBuf
, (sal_Size
)nBufActualLen
);
1505 bIsConsistent
= true;
1506 bIoRead
= bIoWrite
= false;
1509 SvStream
& SvStream::WriteInt32AsString(sal_Int32 nInt32
)
1512 sal_Size nLen
= sprintf(buffer
, "%" SAL_PRIdINT32
, nInt32
);
1513 Write(buffer
, nLen
);
1517 SvStream
& SvStream::WriteUInt32AsString(sal_uInt32 nUInt32
)
1520 sal_Size nLen
= sprintf(buffer
, "%" SAL_PRIuUINT32
, nUInt32
);
1521 Write(buffer
, nLen
);
1525 #define CRYPT_BUFSIZE 1024
1527 /// Encrypt and write
1528 sal_Size
SvStream::CryptAndWriteBuffer( const void* pStart
, sal_Size nLen
)
1530 unsigned char pTemp
[CRYPT_BUFSIZE
];
1531 unsigned char const * pDataPtr
= static_cast<unsigned char const *>(pStart
);
1532 sal_Size nCount
= 0;
1534 unsigned char nMask
= nCryptMask
;
1537 if( nLen
>= CRYPT_BUFSIZE
)
1538 nBufCount
= CRYPT_BUFSIZE
;
1542 memcpy( pTemp
, pDataPtr
, (sal_uInt16
)nBufCount
);
1543 // **** Verschluesseln *****
1544 for ( sal_uInt16 n
=0; n
< CRYPT_BUFSIZE
; n
++ )
1546 unsigned char aCh
= pTemp
[n
];
1551 // *************************
1552 nCount
+= PutData( pTemp
, nBufCount
);
1553 pDataPtr
+= nBufCount
;
1559 bool SvStream::EncryptBuffer(void* pStart
, sal_Size nLen
)
1561 unsigned char* pTemp
= static_cast<unsigned char*>(pStart
);
1562 unsigned char nMask
= nCryptMask
;
1564 for ( sal_Size n
=0; n
< nLen
; n
++, pTemp
++ )
1566 unsigned char aCh
= *pTemp
;
1574 static unsigned char implGetCryptMask(const sal_Char
* pStr
, sal_Int32 nLen
, long nVersion
)
1576 unsigned char nCryptMask
= 0;
1581 if( nVersion
<= SOFFICE_FILEFORMAT_31
)
1585 nCryptMask
^= *pStr
;
1590 else // BugFix #25888#
1592 for( sal_uInt16 i
= 0; i
< nLen
; i
++ ) {
1593 nCryptMask
^= pStr
[i
];
1594 if( nCryptMask
& 0x80 ) {
1609 void SvStream::SetCryptMaskKey(const OString
& rCryptMaskKey
)
1611 m_aCryptMaskKey
= rCryptMaskKey
;
1612 nCryptMask
= implGetCryptMask(m_aCryptMaskKey
.getStr(),
1613 m_aCryptMaskKey
.getLength(), GetVersion());
1616 void SvStream::SyncSvStream( sal_Size nNewStreamPos
)
1619 SvStream::m_nBufFilePos
= nNewStreamPos
;
1622 void SvStream::SyncSysStream()
1628 bool SvStream::SetStreamSize(sal_uInt64
const nSize
)
1631 sal_uInt64 nFPos
= Tell();
1633 sal_uInt16 nBuf
= nBufSize
;
1636 SetBufferSize( nBuf
);
1637 DBG_ASSERT(Tell()==nFPos
,"SetStreamSize failed");
1638 return (nError
== 0);
1641 SvStream
& endl( SvStream
& rStr
)
1643 LineEnd eDelim
= rStr
.GetLineDelimiter();
1644 if ( eDelim
== LINEEND_CR
)
1645 rStr
.WriteChar('\r');
1646 else if( eDelim
== LINEEND_LF
)
1647 rStr
.WriteChar('\n');
1649 rStr
.WriteChar('\r').WriteChar('\n');
1653 SvStream
& endlu( SvStream
& rStrm
)
1655 switch ( rStrm
.GetLineDelimiter() )
1658 rStrm
.WriteUnicode('\r');
1661 rStrm
.WriteUnicode('\n');
1664 rStrm
.WriteUnicode('\r').WriteUnicode('\n');
1669 SvStream
& endlub( SvStream
& rStrm
)
1671 if ( rStrm
.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE
)
1672 return endlu( rStrm
);
1674 return endl( rStrm
);
1677 SvMemoryStream::SvMemoryStream( void* pBuffer
, sal_Size bufSize
,
1680 if( eMode
& StreamMode::WRITE
)
1683 bIsWritable
= false;
1684 nEndOfData
= bufSize
;
1686 pBuf
= static_cast<sal_uInt8
*>(pBuffer
);
1693 SvMemoryStream::SvMemoryStream( sal_Size nInitSize
, sal_Size nResizeOffset
)
1698 nResize
= nResizeOffset
;
1701 if( nResize
!= 0 && nResize
< 16 )
1703 if( nInitSize
&& !AllocateMemory( nInitSize
) )
1705 SetError( SVSTREAM_OUTOFMEMORY
);
1710 SetBufferSize( 64 );
1713 SvMemoryStream::~SvMemoryStream()
1724 const void* SvMemoryStream::GetBuffer()
1730 sal_uIntPtr
SvMemoryStream::GetSize()
1733 sal_uInt64
const nTemp
= Tell();
1734 sal_uInt64
const nLength
= Seek( STREAM_SEEK_TO_END
);
1739 void* SvMemoryStream::SetBuffer( void* pNewBuf
, sal_Size nCount
,
1740 bool bOwnsDat
, sal_Size nEOF
)
1743 SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
1748 if( pNewBuf
!= pBuf
)
1754 pBuf
= static_cast<sal_uInt8
*>(pNewBuf
);
1758 bOwnsData
= bOwnsDat
;
1769 sal_Size
SvMemoryStream::GetData( void* pData
, sal_Size nCount
)
1771 sal_Size nMaxCount
= nEndOfData
-nPos
;
1772 if( nCount
> nMaxCount
)
1774 memcpy( pData
, pBuf
+nPos
, (size_t)nCount
);
1779 sal_Size
SvMemoryStream::PutData( const void* pData
, sal_Size nCount
)
1784 sal_Size nMaxCount
= nSize
-nPos
;
1786 // check for overflow
1787 if( nCount
> nMaxCount
)
1791 // copy as much as possible
1793 SetError( SVSTREAM_OUTOFMEMORY
);
1798 if( nSize
&& nSize
> nResize
)
1801 nNewResize
= nResize
;
1803 if( (nCount
-nMaxCount
) < nResize
)
1805 // lacking memory is smaller than nResize,
1806 // resize accordingly
1807 if( !ReAllocateMemory( nNewResize
) )
1810 SetError( SVSTREAM_WRITE_ERROR
);
1815 // lacking memory is larger than nResize,
1816 // resize by (nCoount-nMaxCount) + resize offset
1817 if( !ReAllocateMemory( nCount
-nMaxCount
+nNewResize
) )
1820 SetError( SVSTREAM_WRITE_ERROR
);
1825 assert(pBuf
&& "Possibly Reallocate failed");
1826 memcpy( pBuf
+nPos
, pData
, (size_t)nCount
);
1829 if( nPos
> nEndOfData
)
1834 sal_uInt64
SvMemoryStream::SeekPos(sal_uInt64
const nNewPos
)
1836 // nEndOfData: First position in stream not allowed to read from
1837 // nSize: Size of allocated buffer
1839 // check if a truncated STREAM_SEEK_TO_END was passed
1840 assert(nNewPos
!= SAL_MAX_UINT32
);
1841 if( nNewPos
< nEndOfData
)
1843 else if( nNewPos
== STREAM_SEEK_TO_END
)
1847 if( nNewPos
>= nSize
) // Does buffer need extension?
1849 if( nResize
) // Is extension possible?
1851 long nDiff
= (long)(nNewPos
- nSize
+ 1);
1852 nDiff
+= (long)nResize
;
1853 ReAllocateMemory( nDiff
);
1855 nEndOfData
= nNewPos
;
1857 else // Extension not possible, set pos to end of data
1859 // SetError( SVSTREAM_OUTOFMEMORY );
1863 else // Expand buffer size
1866 nEndOfData
= nNewPos
;
1872 void SvMemoryStream::FlushData()
1876 void SvMemoryStream::ResetError()
1878 SvStream::ClearError();
1881 bool SvMemoryStream::AllocateMemory( sal_Size nNewSize
)
1883 pBuf
= new sal_uInt8
[nNewSize
];
1884 return( pBuf
!= 0 );
1887 // (using Bozo algorithm)
1888 bool SvMemoryStream::ReAllocateMemory( long nDiff
)
1890 bool bRetVal
= false;
1891 long nTemp
= (long)nSize
;
1893 sal_Size nNewSize
= (sal_Size
)nTemp
;
1897 sal_uInt8
* pNewBuf
= new sal_uInt8
[nNewSize
];
1899 bRetVal
= true; // Success!
1900 if( nNewSize
< nSize
) // Are we shrinking?
1902 memcpy( pNewBuf
, pBuf
, (size_t)nNewSize
);
1903 if( nPos
> nNewSize
)
1905 if( nEndOfData
>= nNewSize
)
1906 nEndOfData
= nNewSize
-1L;
1910 memcpy( pNewBuf
, pBuf
, (size_t)nSize
);
1931 void SvMemoryStream::FreeMemory()
1936 void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize
, sal_Size nResizeOffset
)
1941 Seek( STREAM_SEEK_TO_BEGIN
);
1943 void* pRetVal
= pBuf
;
1946 nResize
= nResizeOffset
;
1949 if( nResize
!= 0 && nResize
< 16 )
1954 if( nInitSize
&& !AllocateMemory(nInitSize
) )
1956 SetError( SVSTREAM_OUTOFMEMORY
);
1962 SetBufferSize( 64 );
1966 void SvMemoryStream::SetSize(sal_uInt64
const nNewSize
)
1968 long nDiff
= (long)nNewSize
- (long)nSize
;
1969 ReAllocateMemory( nDiff
);
1972 SvScriptStream::SvScriptStream(const OUString
& rUrl
):
1973 mpProcess(NULL
), mpHandle(NULL
)
1976 rc
= osl_executeProcess_WithRedirectedIO(
1984 NULL
, &mpHandle
, NULL
);
1985 if (osl_Process_E_None
!= rc
)
1992 SvScriptStream::~SvScriptStream()
1996 osl_terminateProcess(mpProcess
);
1997 osl_freeProcessHandle(mpProcess
);
2000 osl_closeFile(mpHandle
);
2003 bool SvScriptStream::ReadLine(OString
&rStr
, sal_Int32
)
2010 sal_Char
aChar('\n');
2011 sal_uInt64 nBytesRead
;
2012 while (osl_File_E_None
== osl_readFile(mpHandle
, &aChar
, 1, &nBytesRead
)
2013 && nBytesRead
== 1 && aChar
!= '\n')
2015 sBuf
.append( aChar
);
2017 rStr
= sBuf
.makeStringAndClear();
2018 if (!rStr
.isEmpty())
2024 bool SvScriptStream::good() const
2026 return mpHandle
!= NULL
;
2029 TYPEINIT0 ( SvDataCopyStream
)
2031 void SvDataCopyStream::Assign( const SvDataCopyStream
& )
2035 //Create a OString of nLen bytes from rStream
2036 OString
read_uInt8s_ToOString(SvStream
& rStrm
, sal_Size nLen
)
2038 rtl_String
*pStr
= NULL
;
2041 nLen
= std::min(nLen
, static_cast<sal_Size
>(SAL_MAX_INT32
));
2042 //alloc a (ref-count 1) rtl_String of the desired length.
2043 //rtl_String's buffer is uninitialized, except for null termination
2044 pStr
= rtl_string_alloc(sal::static_int_cast
<sal_Int32
>(nLen
));
2045 SAL_WARN_IF(!pStr
, "tools", "allocation failed");
2048 sal_Size nWasRead
= rStrm
.Read(pStr
->buffer
, nLen
);
2049 if (nWasRead
!= nLen
)
2051 //on (typically unlikely) short read set length to what we could
2052 //read, and null terminate. Excess buffer capacity remains of
2053 //course, could create a (true) replacement OString if it matters.
2054 pStr
->length
= sal::static_int_cast
<sal_Int32
>(nWasRead
);
2055 pStr
->buffer
[pStr
->length
] = 0;
2060 //take ownership of buffer and return, otherwise return empty string
2061 return pStr
? OString(pStr
, SAL_NO_ACQUIRE
) : OString();
2064 //Create a OUString of nLen sal_Unicodes from rStream
2065 OUString
read_uInt16s_ToOUString(SvStream
& rStrm
, sal_Size nLen
)
2067 rtl_uString
*pStr
= NULL
;
2070 nLen
= std::min(nLen
, static_cast<sal_Size
>(SAL_MAX_INT32
));
2071 //alloc a (ref-count 1) rtl_uString of the desired length.
2072 //rtl_String's buffer is uninitialized, except for null termination
2073 pStr
= rtl_uString_alloc(sal::static_int_cast
<sal_Int32
>(nLen
));
2074 SAL_WARN_IF(!pStr
, "tools", "allocation failed");
2077 sal_Size nWasRead
= rStrm
.Read(pStr
->buffer
, nLen
*2)/2;
2078 if (nWasRead
!= nLen
)
2080 //on (typically unlikely) short read set length to what we could
2081 //read, and null terminate. Excess buffer capacity remains of
2082 //course, could create a (true) replacement OUString if it matters.
2083 pStr
->length
= sal::static_int_cast
<sal_Int32
>(nWasRead
);
2084 pStr
->buffer
[pStr
->length
] = 0;
2086 if (rStrm
.IsEndianSwap())
2088 for (sal_Int32 i
= 0; i
< pStr
->length
; ++i
)
2089 pStr
->buffer
[i
] = OSL_SWAPWORD(pStr
->buffer
[i
]);
2094 //take ownership of buffer and return, otherwise return empty string
2095 return pStr
? OUString(pStr
, SAL_NO_ACQUIRE
) : OUString();
2100 template <typename T
, typename O
> T
tmpl_convertLineEnd(const T
&rIn
, LineEnd eLineEnd
)
2102 // Determine linebreaks and compute length
2103 bool bConvert
= false; // Needs conversion
2104 sal_Int32 nStrLen
= rIn
.getLength();
2105 sal_Int32 nLineEndLen
= (eLineEnd
== LINEEND_CRLF
) ? 2 : 1;
2106 sal_Int32 nLen
= 0; // Target length
2107 sal_Int32 i
= 0; // Source counter
2111 // \r or \n causes linebreak
2112 if ( (rIn
[i
] == '\r') || (rIn
[i
] == '\n') )
2114 nLen
= nLen
+ nLineEndLen
;
2116 // If set already, skip expensive test
2119 // Muessen wir Konvertieren
2120 if ( ((eLineEnd
!= LINEEND_LF
) && (rIn
[i
] == '\n')) ||
2121 ((eLineEnd
== LINEEND_CRLF
) && (i
+1) < nStrLen
&& (rIn
[i
+1] != '\n')) ||
2122 ((eLineEnd
== LINEEND_LF
) &&
2123 ((rIn
[i
] == '\r') || ((i
+1) < nStrLen
&& rIn
[i
+1] == '\r'))) ||
2124 ((eLineEnd
== LINEEND_CR
) &&
2125 ((rIn
[i
] == '\n') || ((i
+1) < nStrLen
&& rIn
[i
+1] == '\n'))) )
2129 // skip char if \r\n or \n\r
2130 if ( (i
+1) < nStrLen
&& ((rIn
[i
+1] == '\r') || (rIn
[i
+1] == '\n')) &&
2131 (rIn
[i
] != rIn
[i
+1]) )
2142 // convert linebreaks, insert string
2147 // \r or \n causes linebreak
2148 if ( (rIn
[i
] == '\r') || (rIn
[i
] == '\n') )
2150 if ( eLineEnd
== LINEEND_CRLF
)
2152 aNewData
.append('\r');
2153 aNewData
.append('\n');
2157 if ( eLineEnd
== LINEEND_CR
)
2158 aNewData
.append('\r');
2160 aNewData
.append('\n');
2163 if ( (i
+1) < nStrLen
&& ((rIn
[i
+1] == '\r') || (rIn
[i
+1] == '\n')) &&
2164 (rIn
[i
] != rIn
[i
+1]) )
2169 aNewData
.append(rIn
[i
]);
2175 return aNewData
.makeStringAndClear();
2179 OString
convertLineEnd(const OString
&rIn
, LineEnd eLineEnd
)
2181 return tmpl_convertLineEnd
<OString
, OStringBuffer
>(rIn
, eLineEnd
);
2184 OUString
convertLineEnd(const OUString
&rIn
, LineEnd eLineEnd
)
2186 return tmpl_convertLineEnd
<OUString
, OUStringBuffer
>(rIn
, eLineEnd
);
2189 sal_Size
write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream
& rStrm
,
2190 const OUString
&rStr
)
2192 sal_Size nWritten
= 0;
2193 sal_uInt32 nUnits
= std::min
<sal_Size
>(rStr
.getLength(), std::numeric_limits
<sal_uInt32
>::max());
2194 SAL_WARN_IF(static_cast<sal_Size
>(nUnits
) != static_cast<sal_Size
>(rStr
.getLength()),
2196 "string too long for prefix count to fit in output type");
2197 rStrm
.WriteUInt32(nUnits
);
2200 nWritten
+= sizeof(sal_uInt32
);
2201 nWritten
+= write_uInt16s_FromOUString(rStrm
, rStr
, nUnits
);
2206 sal_Size
write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream
& rStrm
,
2207 const OUString
&rStr
)
2209 sal_Size nWritten
= 0;
2210 sal_uInt16 nUnits
= std::min
<sal_Size
>(rStr
.getLength(), std::numeric_limits
<sal_uInt16
>::max());
2211 SAL_WARN_IF(nUnits
!= rStr
.getLength(),
2213 "string too long for prefix count to fit in output type");
2214 rStrm
.WriteUInt16(nUnits
);
2217 nWritten
+= sizeof(nUnits
);
2218 nWritten
+= write_uInt16s_FromOUString(rStrm
, rStr
, nUnits
);
2223 sal_Size
write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream
& rStrm
,
2224 const OString
&rStr
)
2226 sal_Size nWritten
= 0;
2227 sal_uInt16 nUnits
= std::min
<sal_Size
>(rStr
.getLength(), std::numeric_limits
<sal_uInt16
>::max());
2228 SAL_WARN_IF(static_cast<sal_Size
>(nUnits
) != static_cast<sal_Size
>(rStr
.getLength()),
2230 "string too long for sal_uInt16 count to fit in output type");
2231 rStrm
.WriteUInt16( nUnits
);
2234 nWritten
+= sizeof(sal_uInt16
);
2235 nWritten
+= write_uInt8s_FromOString(rStrm
, rStr
, nUnits
);
2240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */