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
26 #include <ctype.h> // isspace
27 #include <stdlib.h> // strtol, _crotl
29 #include "boost/static_assert.hpp"
31 #include <osl/endian.h>
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>
48 // !!! Do not inline if already the operators <<,>> are inline
49 inline static void SwapUShort( sal_uInt16
& r
)
50 { r
= OSL_SWAPWORD(r
); }
51 inline static void SwapShort( short& r
)
52 { r
= OSL_SWAPWORD(r
); }
53 inline static void SwapLong( long& r
)
54 { r
= OSL_SWAPDWORD(r
); }
55 inline static void SwapULong( sal_uInt32
& r
)
56 { r
= OSL_SWAPDWORD(r
); }
57 inline static void SwapLongInt( sal_Int32
& r
)
58 { r
= OSL_SWAPDWORD(r
); }
59 inline static void SwapLongUInt( unsigned int& r
)
60 { r
= OSL_SWAPDWORD(r
); }
62 inline 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 inline 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 inline static void SwapFloat( float& r
)
107 s
.c
= OSL_SWAPDWORD( s
.c
);
111 inline static void SwapDouble( double& r
)
113 if( sizeof(double) != 8 )
115 DBG_ASSERT( sal_False
, "Can only swap 8-Byte-doubles\n" );
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]);
138 #define READNUMBER_WITHOUT_SWAP(datatype,value) \
141 if( (tmp == STREAM_IO_READ) && sizeof(datatype)<=nBufFree) \
143 for (std::size_t i = 0; i < sizeof(datatype); i++)\
144 ((char *)&value)[i] = pBufPos[i];\
145 nBufActualPos += sizeof(datatype);\
146 pBufPos += sizeof(datatype);\
147 nBufFree -= sizeof(datatype);\
150 Read( (char*)&value, sizeof(datatype) );\
153 #define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
156 if( (tmp==STREAM_IO_WRITE) && sizeof(datatype) <= nBufFree)\
158 for (std::size_t i = 0; i < sizeof(datatype); i++)\
159 pBufPos[i] = ((char *)&value)[i];\
160 nBufFree -= sizeof(datatype);\
161 nBufActualPos += sizeof(datatype);\
162 if( nBufActualPos > nBufActualLen )\
163 nBufActualLen = nBufActualPos;\
164 pBufPos += sizeof(datatype);\
165 bIsDirty = sal_True;\
168 Write( (char*)&value, sizeof(datatype) );\
173 void SvLockBytes::close()
180 TYPEINIT0(SvLockBytes
);
183 ErrCode
SvLockBytes::ReadAt(sal_Size nPos
, void * pBuffer
, sal_Size nCount
,
184 sal_Size
* pRead
) const
188 OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
192 m_pStream
->Seek(nPos
);
193 sal_Size nTheRead
= m_pStream
->Read(pBuffer
, nCount
);
196 return m_pStream
->GetErrorCode();
200 ErrCode
SvLockBytes::WriteAt(sal_Size nPos
, const void * pBuffer
, sal_Size nCount
,
205 OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
209 m_pStream
->Seek(nPos
);
210 sal_Size nTheWritten
= m_pStream
->Write(pBuffer
, nCount
);
212 *pWritten
= nTheWritten
;
213 return m_pStream
->GetErrorCode();
217 ErrCode
SvLockBytes::Flush() const
221 OSL_FAIL("SvLockBytes::Flush(): Bad stream");
226 return m_pStream
->GetErrorCode();
230 ErrCode
SvLockBytes::SetSize(sal_Size nSize
)
234 OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
238 m_pStream
->SetStreamSize(nSize
);
239 return m_pStream
->GetErrorCode();
242 ErrCode
SvLockBytes::Stat(SvLockBytesStat
* pStat
, SvLockBytesStatFlag
) const
246 OSL_FAIL("SvLockBytes::Stat(): Bad stream");
252 sal_Size nPos
= m_pStream
->Tell();
253 pStat
->nSize
= m_pStream
->Seek(STREAM_SEEK_TO_END
);
254 m_pStream
->Seek(nPos
);
259 // class SvOpenLockBytes
261 TYPEINIT1(SvOpenLockBytes
, SvLockBytes
);
263 // class SvAsyncLockBytes
265 TYPEINIT1(SvAsyncLockBytes
, SvOpenLockBytes
);
268 ErrCode
SvAsyncLockBytes::ReadAt(sal_Size nPos
, void * pBuffer
, sal_Size nCount
,
269 sal_Size
* pRead
) const
272 return SvOpenLockBytes::ReadAt(nPos
, pBuffer
, nCount
, pRead
);
275 sal_Size nTheCount
= std::min(nPos
< m_nSize
? m_nSize
- nPos
: 0, nCount
);
276 ErrCode nError
= SvOpenLockBytes::ReadAt(nPos
, pBuffer
, nTheCount
,
278 return !nCount
|| nTheCount
== nCount
|| nError
? nError
:
284 ErrCode
SvAsyncLockBytes::WriteAt(sal_Size nPos
, const void * pBuffer
,
285 sal_Size nCount
, sal_Size
* pWritten
)
288 return SvOpenLockBytes::WriteAt(nPos
, pBuffer
, nCount
, pWritten
);
291 sal_Size nTheCount
= std::min(nPos
< m_nSize
? m_nSize
- nPos
: 0, nCount
);
292 ErrCode nError
= SvOpenLockBytes::WriteAt(nPos
, pBuffer
, nTheCount
,
294 return !nCount
|| nTheCount
== nCount
|| nError
? nError
:
300 ErrCode
SvAsyncLockBytes::FillAppend(const void * pBuffer
, sal_Size nCount
,
303 sal_Size nTheWritten
;
304 ErrCode nError
= SvOpenLockBytes::WriteAt(m_nSize
, pBuffer
, nCount
,
307 m_nSize
+= nTheWritten
;
309 *pWritten
= nTheWritten
;
314 sal_Size
SvAsyncLockBytes::Seek(sal_Size nPos
)
316 if (nPos
!= STREAM_SEEK_TO_END
)
323 sal_Size
SvStream::GetData( void* pData
, sal_Size nSize
)
327 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
329 nError
= xLockBytes
->ReadAt( nActPos
, pData
, nSize
, &nRet
);
336 sal_Size
SvStream::PutData( const void* pData
, sal_Size nSize
)
340 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
342 nError
= xLockBytes
->WriteAt( nActPos
, pData
, nSize
, &nRet
);
349 sal_Size
SvStream::SeekPos( sal_Size nPos
)
351 if( !GetError() && nPos
== STREAM_SEEK_TO_END
)
353 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
354 SvLockBytesStat aStat
;
355 xLockBytes
->Stat( &aStat
, SVSTATFLAG_DEFAULT
);
356 nActPos
= aStat
.nSize
;
363 void SvStream::FlushData()
367 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
368 nError
= xLockBytes
->Flush();
372 void SvStream::SetSize( sal_Size nSize
)
374 DBG_ASSERT( xLockBytes
.Is(), "pure virtual function" );
375 nError
= xLockBytes
->SetSize( nSize
);
378 void SvStream::ImpInit()
381 nCompressMode
= COMPRESSMODE_NONE
;
382 eStreamCharSet
= osl_getThreadTextEncoding();
386 eLineDelimiter
= LINEEND_LF
; // UNIX-Format
388 eLineDelimiter
= LINEEND_CRLF
; // DOS-Format
391 SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
395 bIsDirty
= sal_False
;
396 bIsConsistent
= sal_True
;
397 bIsWritable
= sal_True
;
403 eIOMode
= STREAM_IO_DONTKNOW
;
413 SvStream::SvStream( SvLockBytes
* pLockBytesP
)
415 DBG_CTOR( Stream
, NULL
);
418 xLockBytes
= pLockBytesP
;
420 const SvStream
* pStrm
= pLockBytesP
->GetStream();
422 SetError( pStrm
->GetErrorCode() );
425 SetBufferSize( 256 );
430 DBG_CTOR( Stream
, NULL
);
435 SvStream::~SvStream()
437 DBG_DTOR( Stream
, NULL
);
439 if ( xLockBytes
.Is() )
446 sal_uInt16
SvStream::IsA() const
448 return (sal_uInt16
)ID_STREAM
;
451 void SvStream::ClearError()
454 nError
= SVSTREAM_OK
;
457 void SvStream::SetError( sal_uInt32 nErrorCode
)
459 if ( nError
== SVSTREAM_OK
)
463 void SvStream::SetNumberFormatInt( sal_uInt16 nNewFormat
)
465 nNumberFormatInt
= nNewFormat
;
468 if( nNumberFormatInt
== NUMBERFORMAT_INT_LITTLEENDIAN
)
471 if( nNumberFormatInt
== NUMBERFORMAT_INT_BIGENDIAN
)
476 void SvStream::SetBufferSize( sal_uInt16 nBufferSize
)
478 sal_Size nActualFilePos
= Tell();
479 sal_Bool bDontSeek
= (sal_Bool
)(pRWBuf
== 0);
481 if( bIsDirty
&& bIsConsistent
&& bIsWritable
) // due to Windows NT: Access denied
487 nBufFilePos
+= nBufActualPos
;
493 nBufSize
= nBufferSize
;
495 pRWBuf
= new sal_uInt8
[ nBufSize
];
496 bIsConsistent
= sal_True
;
498 eIOMode
= STREAM_IO_DONTKNOW
;
500 SeekPos( nActualFilePos
);
503 void SvStream::ClearBuffer()
509 bIsDirty
= sal_False
;
510 bIsConsistent
= sal_True
;
511 eIOMode
= STREAM_IO_DONTKNOW
;
516 void SvStream::ResetError()
521 sal_Bool
SvStream::ReadByteStringLine( OUString
& rStr
, rtl_TextEncoding eSrcCharSet
,
522 sal_Int32 nMaxBytesToRead
)
525 sal_Bool bRet
= ReadLine( aStr
, nMaxBytesToRead
);
526 rStr
= OStringToOUString(aStr
, eSrcCharSet
);
530 sal_Bool
SvStream::ReadByteStringLine( String
& rStr
, rtl_TextEncoding eSrcCharSet
)
533 sal_Bool bRet
= ReadLine(aStr
);
534 rStr
= OStringToOUString(aStr
, eSrcCharSet
);
538 sal_Bool
SvStream::ReadLine( OString
& rStr
, sal_Int32 nMaxBytesToRead
)
541 sal_Bool bEnd
= sal_False
;
542 sal_Size nOldFilePos
= Tell();
544 sal_Size nTotalLen
= 0;
546 OStringBuffer
aBuf(4096);
547 while( !bEnd
&& !GetError() ) // Don't test for EOF as we
548 // are reading block-wise!
550 sal_uInt16 nLen
= (sal_uInt16
)Read( buf
, sizeof(buf
)-1 );
553 if ( aBuf
.isEmpty() )
555 // Exit on first block-read error
565 for( j
= n
= 0; j
< nLen
; ++j
)
568 if ( c
== '\n' || c
== '\r' )
578 if (nTotalLen
> static_cast<sal_Size
>(nMaxBytesToRead
))
580 n
-= nTotalLen
- nMaxBytesToRead
;
581 nTotalLen
= nMaxBytesToRead
;
588 if ( !bEnd
&& !GetError() && aBuf
.getLength() )
591 nOldFilePos
+= nTotalLen
;
592 if( Tell() > nOldFilePos
)
594 Seek( nOldFilePos
); // Seek pointer due to BlockRead above
596 if ( bEnd
&& (c
=='\r' || c
=='\n') ) // Special treatment for DOS files
599 sal_Size nLen
= Read((char*)&cTemp
, sizeof(cTemp
) );
601 if( cTemp
== c
|| (cTemp
!= '\n' && cTemp
!= '\r') )
608 rStr
= aBuf
.makeStringAndClear();
612 sal_Bool
SvStream::ReadUniStringLine( OUString
& rStr
, sal_Int32 nMaxCodepointsToRead
)
614 sal_Unicode buf
[256+1];
615 sal_Bool bEnd
= sal_False
;
616 sal_Size nOldFilePos
= Tell();
618 sal_Size nTotalLen
= 0;
620 DBG_ASSERT( sizeof(sal_Unicode
) == sizeof(sal_uInt16
), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
622 OUStringBuffer
aBuf(4096);
623 while( !bEnd
&& !GetError() ) // Don't test for EOF as we
624 // are reading block-wise!
626 sal_uInt16 nLen
= (sal_uInt16
)Read( (char*)buf
, sizeof(buf
)-sizeof(sal_Unicode
) );
627 nLen
/= sizeof(sal_Unicode
);
630 if ( aBuf
.getLength() == 0 )
632 // exit on first BlockRead error
642 for( j
= n
= 0; j
< nLen
; ++j
)
645 SwapUShort( buf
[n
] );
647 if ( c
== '\n' || c
== '\r' )
652 // erAck 26.02.01: Old behavior was no special treatment of '\0'
653 // character here, but a following rStr+=c did ignore it. Is this
654 // really intended? Or should a '\0' better terminate a line?
655 // The nOldFilePos stuff wasn't correct then anyways.
664 if (nTotalLen
> static_cast<sal_Size
>(nMaxCodepointsToRead
))
666 n
-= nTotalLen
- nMaxCodepointsToRead
;
667 nTotalLen
= nMaxCodepointsToRead
;
671 aBuf
.append( buf
, n
);
674 if ( !bEnd
&& !GetError() && aBuf
.getLength() )
677 nOldFilePos
+= nTotalLen
* sizeof(sal_Unicode
);
678 if( Tell() > nOldFilePos
)
679 nOldFilePos
+= sizeof(sal_Unicode
);
680 Seek( nOldFilePos
); // seek due to BlockRead above
682 if ( bEnd
&& (c
=='\r' || c
=='\n') ) // special treatment for DOS files
685 Read( (char*)&cTemp
, sizeof(cTemp
) );
688 if( cTemp
== c
|| (cTemp
!= '\n' && cTemp
!= '\r') )
694 rStr
= aBuf
.makeStringAndClear();
698 sal_Bool
SvStream::ReadUniOrByteStringLine( OUString
& rStr
, rtl_TextEncoding eSrcCharSet
,
699 sal_Int32 nMaxCodepointsToRead
)
701 if ( eSrcCharSet
== RTL_TEXTENCODING_UNICODE
)
702 return ReadUniStringLine( rStr
, nMaxCodepointsToRead
);
704 return ReadByteStringLine( rStr
, eSrcCharSet
, nMaxCodepointsToRead
);
707 OString
read_zeroTerminated_uInt8s_ToOString(SvStream
& rStream
)
709 OStringBuffer
aOutput(256);
711 sal_Char buf
[ 256 + 1 ];
712 sal_Bool bEnd
= sal_False
;
713 sal_Size nFilePos
= rStream
.Tell();
715 while( !bEnd
&& !rStream
.GetError() )
717 sal_Size nLen
= rStream
.Read(buf
, sizeof(buf
)-1);
721 sal_Size nReallyRead
= nLen
;
722 const sal_Char
* pPtr
= buf
;
723 while (nLen
&& *pPtr
)
726 bEnd
= ( nReallyRead
< sizeof(buf
)-1 ) // read less than attempted to read
727 || ( ( nLen
> 0 ) // OR it is inside the block we read
728 && ( 0 == *pPtr
) // AND found a string terminator
731 aOutput
.append(buf
, pPtr
- buf
);
734 nFilePos
+= aOutput
.getLength();
735 if (rStream
.Tell() > nFilePos
)
736 rStream
.Seek(nFilePos
+1); // seek due to FileRead above
737 return aOutput
.makeStringAndClear();
740 OUString
read_zeroTerminated_uInt8s_ToOUString(SvStream
& rStream
, rtl_TextEncoding eEnc
)
742 return OStringToOUString(
743 read_zeroTerminated_uInt8s_ToOString(rStream
), eEnc
);
746 /** Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
747 returned value is number of bytes written */
748 sal_Size
write_uInt16s_FromOUString(SvStream
& rStrm
, const OUString
& rStr
,
751 DBG_ASSERT( sizeof(sal_Unicode
) == sizeof(sal_uInt16
), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
753 if (!rStrm
.IsEndianSwap())
754 nWritten
= rStrm
.Write( (char*)rStr
.getStr(), nUnits
* sizeof(sal_Unicode
) );
757 sal_Size nLen
= nUnits
;
758 sal_Unicode aBuf
[384];
759 sal_Unicode
* const pTmp
= ( nLen
> 384 ? new sal_Unicode
[nLen
] : aBuf
);
760 memcpy( pTmp
, rStr
.getStr(), nLen
* sizeof(sal_Unicode
) );
761 sal_Unicode
* p
= pTmp
;
762 const sal_Unicode
* const pStop
= pTmp
+ nLen
;
768 nWritten
= rStrm
.Write( (char*)pTmp
, nLen
* sizeof(sal_Unicode
) );
775 sal_Bool
SvStream::WriteUnicodeOrByteText( const String
& rStr
, rtl_TextEncoding eDestCharSet
)
777 if ( eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
779 write_uInt16s_FromOUString(*this, rStr
, rStr
.Len());
780 return nError
== SVSTREAM_OK
;
784 OString
aStr(OUStringToOString(rStr
, eDestCharSet
));
785 write_uInt8s_FromOString(*this, aStr
, aStr
.getLength());
786 return nError
== SVSTREAM_OK
;
790 sal_Bool
SvStream::WriteByteStringLine( const String
& rStr
, rtl_TextEncoding eDestCharSet
)
792 return WriteLine(OUStringToOString(rStr
, eDestCharSet
));
795 sal_Bool
SvStream::WriteLine(const OString
& rStr
)
797 Write(rStr
.getStr(), rStr
.getLength());
799 return nError
== SVSTREAM_OK
;
802 sal_Bool
SvStream::WriteUniOrByteChar( sal_Unicode ch
, rtl_TextEncoding eDestCharSet
)
804 if ( eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
808 OString
aStr(&ch
, 1, eDestCharSet
);
809 Write(aStr
.getStr(), aStr
.getLength());
811 return nError
== SVSTREAM_OK
;
814 sal_Bool
SvStream::StartWritingUnicodeText()
816 SetEndianSwap( sal_False
); // write native format
817 // BOM, Byte Order Mark, U+FEFF, see
818 // http://www.unicode.org/faq/utf_bom.html#BOM
819 // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
820 *this << sal_uInt16( 0xfeff );
821 return nError
== SVSTREAM_OK
;
824 sal_Bool
SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet
)
826 if (!( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
827 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
||
828 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
829 return sal_True
; // nothing to read
831 bool bTryUtf8
= false;
833 sal_sSize nBack
= sizeof(nFlag
);
839 if ( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
840 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
)
845 if ( eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
846 eReadBomCharSet
== RTL_TEXTENCODING_UNICODE
)
848 SetEndianSwap( !bSwap
);
853 if (nNumberFormatInt
== NUMBERFORMAT_INT_BIGENDIAN
&&
854 (eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
855 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
859 if (nNumberFormatInt
== NUMBERFORMAT_INT_LITTLEENDIAN
&&
860 (eReadBomCharSet
== RTL_TEXTENCODING_DONTKNOW
||
861 eReadBomCharSet
== RTL_TEXTENCODING_UTF8
))
870 nBack
+= sizeof(nChar
);
873 nBack
= 0; // it is UTF-8
876 SeekRel( -nBack
); // no BOM, pure data
877 return nError
== SVSTREAM_OK
;
880 sal_Size
SvStream::SeekRel( sal_sSize nPos
)
882 sal_Size nActualPos
= Tell();
886 if ( SAL_MAX_SIZE
- nActualPos
> (sal_Size
)nPos
)
891 sal_Size nAbsPos
= (sal_Size
)-nPos
;
892 if ( nActualPos
>= nAbsPos
)
893 nActualPos
-= nAbsPos
;
896 pBufPos
= pRWBuf
+ nActualPos
;
897 return Seek( nActualPos
);
900 SvStream
& SvStream::operator>>(sal_uInt16
& r
)
903 READNUMBER_WITHOUT_SWAP(sal_uInt16
, n
)
913 SvStream
& SvStream::operator>>(sal_uInt32
& r
)
916 READNUMBER_WITHOUT_SWAP(sal_uInt32
, n
)
926 SvStream
& SvStream::operator>>(sal_uInt64
& r
)
929 READNUMBER_WITHOUT_SWAP(sal_uInt64
, n
)
939 SvStream
& SvStream::operator>>(sal_Int16
& r
)
942 READNUMBER_WITHOUT_SWAP(sal_Int16
, n
)
952 SvStream
& SvStream::operator>>(sal_Int32
& r
)
955 READNUMBER_WITHOUT_SWAP(sal_Int32
, n
)
965 SvStream
& SvStream::ReadInt64(sal_Int64
& r
)
968 READNUMBER_WITHOUT_SWAP(sal_Int64
, n
)
978 SvStream
& SvStream::operator>>( signed char& r
)
980 if( (eIOMode
== STREAM_IO_READ
|| !bIsConsistent
) &&
981 sizeof(signed char) <= nBufFree
)
984 nBufActualPos
+= sizeof(signed char);
985 pBufPos
+= sizeof(signed char);
986 nBufFree
-= sizeof(signed char);
989 Read( (char*)&r
, sizeof(signed char) );
993 // Special treatment for Chars due to PutBack
995 SvStream
& SvStream::operator>>( char& r
)
997 if( (eIOMode
== STREAM_IO_READ
|| !bIsConsistent
) &&
998 sizeof(char) <= nBufFree
)
1001 nBufActualPos
+= sizeof(char);
1002 pBufPos
+= sizeof(char);
1003 nBufFree
-= sizeof(char);
1006 Read( (char*)&r
, sizeof(char) );
1010 SvStream
& SvStream::operator>>( unsigned char& r
)
1012 if( (eIOMode
== STREAM_IO_READ
|| !bIsConsistent
) &&
1013 sizeof(char) <= nBufFree
)
1016 nBufActualPos
+= sizeof(char);
1017 pBufPos
+= sizeof(char);
1018 nBufFree
-= sizeof(char);
1021 Read( (char*)&r
, sizeof(char) );
1025 SvStream
& SvStream::operator>>(float& r
)
1028 READNUMBER_WITHOUT_SWAP(float, n
)
1040 SvStream
& SvStream::operator>>(double& r
)
1043 READNUMBER_WITHOUT_SWAP(double, n
)
1055 SvStream
& SvStream::operator>> ( SvStream
& rStream
)
1057 const sal_uInt32 cBufLen
= 0x8000;
1058 char* pBuf
= new char[ cBufLen
];
1062 nCount
= Read( pBuf
, cBufLen
);
1063 rStream
.Write( pBuf
, nCount
);
1064 } while( nCount
== cBufLen
);
1070 SvStream
& SvStream::operator<< ( sal_uInt16 v
)
1074 WRITENUMBER_WITHOUT_SWAP(sal_uInt16
,v
)
1078 SvStream
& SvStream::operator<< ( sal_uInt32 v
)
1082 WRITENUMBER_WITHOUT_SWAP(sal_uInt32
,v
)
1086 SvStream
& SvStream::operator<< ( sal_uInt64 v
)
1090 WRITENUMBER_WITHOUT_SWAP(sal_uInt64
,v
)
1094 SvStream
& SvStream::operator<< ( sal_Int16 v
)
1098 WRITENUMBER_WITHOUT_SWAP(sal_Int16
,v
)
1102 SvStream
& SvStream::operator<< ( sal_Int32 v
)
1106 WRITENUMBER_WITHOUT_SWAP(sal_Int32
,v
)
1110 SvStream
& SvStream::WriteInt64 (sal_Int64 v
)
1114 WRITENUMBER_WITHOUT_SWAP(sal_Int64
,v
)
1118 SvStream
& SvStream::operator<< ( signed char v
)
1122 if(tmp
== STREAM_IO_WRITE
&& sizeof(signed char) <= nBufFree
)
1125 pBufPos
++; // sizeof(char);
1127 if( nBufActualPos
> nBufActualLen
) // Append ?
1128 nBufActualLen
= nBufActualPos
;
1129 nBufFree
--; // = sizeof(char);
1130 bIsDirty
= sal_True
;
1133 Write( (char*)&v
, sizeof(signed char) );
1137 // Special treatment for Chars due to PutBack
1139 SvStream
& SvStream::operator<< ( char v
)
1143 if(tmp
== STREAM_IO_WRITE
&& sizeof(char) <= nBufFree
)
1146 pBufPos
++; // sizeof(char);
1148 if( nBufActualPos
> nBufActualLen
) // Append ?
1149 nBufActualLen
= nBufActualPos
;
1150 nBufFree
--; // = sizeof(char);
1151 bIsDirty
= sal_True
;
1154 Write( (char*)&v
, sizeof(char) );
1158 SvStream
& SvStream::operator<< ( unsigned char v
)
1162 if(tmp
== STREAM_IO_WRITE
&& sizeof(char) <= nBufFree
)
1164 *(unsigned char*)pBufPos
= v
;
1165 pBufPos
++; // = sizeof(char);
1166 nBufActualPos
++; // = sizeof(char);
1167 if( nBufActualPos
> nBufActualLen
) // Append ?
1168 nBufActualLen
= nBufActualPos
;
1170 bIsDirty
= sal_True
;
1173 Write( (char*)&v
, sizeof(char) );
1177 SvStream
& SvStream::operator<< ( float v
)
1183 WRITENUMBER_WITHOUT_SWAP(float,v
)
1187 SvStream
& SvStream::operator<< ( const double& r
)
1194 WRITENUMBER_WITHOUT_SWAP(double,nHelp
)
1199 WRITENUMBER_WITHOUT_SWAP(double,r
)
1204 SvStream
& SvStream::operator<< ( const char* pBuf
)
1206 Write( pBuf
, strlen( pBuf
) );
1210 SvStream
& SvStream::operator<< ( const unsigned char* pBuf
)
1212 Write( (char*)pBuf
, strlen( (char*)pBuf
) );
1216 SvStream
& SvStream::operator<< ( SvStream
& rStream
)
1218 const sal_uInt32 cBufLen
= 0x8000;
1219 char* pBuf
= new char[ cBufLen
];
1222 nCount
= rStream
.Read( pBuf
, cBufLen
);
1223 Write( pBuf
, nCount
);
1224 } while( nCount
== cBufLen
);
1230 OUString
SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet
)
1232 // read UTF-16 string directly from stream ?
1233 if (eSrcCharSet
== RTL_TEXTENCODING_UNICODE
)
1234 return read_lenPrefixed_uInt16s_ToOUString
<sal_uInt32
>(*this);
1235 return read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(*this, eSrcCharSet
);
1238 SvStream
& SvStream::WriteUniOrByteString( const OUString
& rStr
, rtl_TextEncoding eDestCharSet
)
1240 // write UTF-16 string directly into stream ?
1241 if (eDestCharSet
== RTL_TEXTENCODING_UNICODE
)
1242 write_lenPrefixed_uInt16s_FromOUString
<sal_uInt32
>(*this, rStr
);
1244 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(*this, rStr
, eDestCharSet
);
1248 sal_Size
SvStream::Read( void* pData
, sal_Size nCount
)
1250 sal_Size nSaveCount
= nCount
;
1251 if( !bIsConsistent
)
1256 nCount
= GetData( (char*)pData
,nCount
);
1258 EncryptBuffer(pData
, nCount
);
1259 nBufFilePos
+= nCount
;
1263 // check if block is completely within buffer
1264 eIOMode
= STREAM_IO_READ
;
1265 if( nCount
<= (sal_Size
)(nBufActualLen
- nBufActualPos
) )
1268 memcpy(pData
, pBufPos
, (size_t) nCount
);
1269 nBufActualPos
= nBufActualPos
+ (sal_uInt16
)nCount
;
1271 nBufFree
= nBufFree
- (sal_uInt16
)nCount
;
1275 if( bIsDirty
) // Does stream require a flush?
1277 SeekPos( nBufFilePos
);
1279 CryptAndWriteBuffer(pRWBuf
, nBufActualLen
);
1281 PutData( pRWBuf
, nBufActualLen
);
1282 bIsDirty
= sal_False
;
1285 // Does data block fit into buffer?
1286 if( nCount
> nBufSize
)
1288 // => No! Thus read directly
1289 // into target area without using the buffer
1291 eIOMode
= STREAM_IO_DONTKNOW
;
1293 SeekPos( nBufFilePos
+ nBufActualPos
);
1296 nCount
= GetData( (char*)pData
, nCount
);
1298 EncryptBuffer(pData
, nCount
);
1299 nBufFilePos
+= nCount
;
1300 nBufFilePos
+= nBufActualPos
;
1305 // => Yes. Fill buffer first, then copy to target area
1307 nBufFilePos
+= nBufActualPos
;
1308 SeekPos( nBufFilePos
);
1310 // TODO: Typecast before GetData, sal_uInt16 nCountTmp
1311 sal_Size nCountTmp
= GetData( pRWBuf
, nBufSize
);
1313 EncryptBuffer(pRWBuf
, nCountTmp
);
1314 nBufActualLen
= (sal_uInt16
)nCountTmp
;
1315 if( nCount
> nCountTmp
)
1317 nCount
= nCountTmp
; // trim count back, EOF see below
1319 memcpy( pData
, pRWBuf
, (size_t)nCount
);
1320 nBufActualPos
= (sal_uInt16
)nCount
;
1321 pBufPos
= pRWBuf
+ nCount
;
1326 nBufFree
= nBufActualLen
- nBufActualPos
;
1327 if( nCount
!= nSaveCount
&& nError
!= ERRCODE_IO_PENDING
)
1329 if( nCount
== nSaveCount
&& nError
== ERRCODE_IO_PENDING
)
1330 nError
= ERRCODE_NONE
;
1334 sal_Size
SvStream::Write( const void* pData
, sal_Size nCount
)
1340 SetError( ERRCODE_IO_CANTWRITE
);
1343 if( !bIsConsistent
)
1344 RefreshBuffer(); // Remove changes in buffer through PutBack
1349 nCount
= CryptAndWriteBuffer( pData
, nCount
);
1351 nCount
= PutData( (char*)pData
, nCount
);
1352 nBufFilePos
+= nCount
;
1356 eIOMode
= STREAM_IO_WRITE
;
1357 if( nCount
<= (sal_Size
)(nBufSize
- nBufActualPos
) )
1359 memcpy( pBufPos
, pData
, (size_t)nCount
);
1360 nBufActualPos
= nBufActualPos
+ (sal_uInt16
)nCount
;
1361 // Update length if buffer was updated
1362 if( nBufActualPos
> nBufActualLen
)
1363 nBufActualLen
= nBufActualPos
;
1366 bIsDirty
= sal_True
;
1370 // Does stream require flushing?
1373 SeekPos( nBufFilePos
);
1375 CryptAndWriteBuffer( pRWBuf
, (sal_Size
)nBufActualLen
);
1377 PutData( pRWBuf
, nBufActualLen
);
1378 bIsDirty
= sal_False
;
1381 // Does data block fit into buffer?
1382 if( nCount
> nBufSize
)
1384 eIOMode
= STREAM_IO_DONTKNOW
;
1385 nBufFilePos
+= nBufActualPos
;
1389 SeekPos( nBufFilePos
);
1391 nCount
= CryptAndWriteBuffer( pData
, nCount
);
1393 nCount
= PutData( (char*)pData
, nCount
);
1394 nBufFilePos
+= nCount
;
1398 // Copy block to buffer
1399 memcpy( pRWBuf
, pData
, (size_t)nCount
);
1402 nBufFilePos
+= nBufActualPos
;
1403 nBufActualPos
= (sal_uInt16
)nCount
;
1404 pBufPos
= pRWBuf
+ nCount
;
1405 nBufActualLen
= (sal_uInt16
)nCount
;
1406 bIsDirty
= sal_True
;
1409 nBufFree
= nBufSize
- nBufActualPos
;
1413 sal_Size
SvStream::Seek( sal_Size nFilePos
)
1415 eIOMode
= STREAM_IO_DONTKNOW
;
1420 nBufFilePos
= SeekPos( nFilePos
);
1421 DBG_ASSERT(Tell()==nBufFilePos
,"Out Of Sync!");
1425 // Is seek position within buffer?
1426 if( nFilePos
>= nBufFilePos
&& nFilePos
<= (nBufFilePos
+ nBufActualLen
))
1428 nBufActualPos
= (sal_uInt16
)(nFilePos
- nBufFilePos
);
1429 pBufPos
= pRWBuf
+ nBufActualPos
;
1430 // Update nBufFree to avoid crash upon PutBack
1431 nBufFree
= nBufActualLen
- nBufActualPos
;
1435 if( bIsDirty
&& bIsConsistent
)
1437 SeekPos( nBufFilePos
);
1439 CryptAndWriteBuffer( pRWBuf
, nBufActualLen
);
1441 PutData( pRWBuf
, nBufActualLen
);
1442 bIsDirty
= sal_False
;
1447 nBufFilePos
= SeekPos( nFilePos
);
1451 sal_Size nDebugTemp
= nBufFilePos
+ nBufActualPos
;
1452 DBG_ASSERT(Tell()==nDebugTemp
,"Sync?");
1455 return nBufFilePos
+ nBufActualPos
;
1458 //STREAM_SEEK_TO_END in the some of the Seek backends is special cased to be
1459 //efficient, in others e.g. SotStorageStream it's really horribly slow, and in
1460 //those this should be overridden
1461 sal_Size
SvStream::remainingSize()
1463 sal_Size nCurr
= Tell();
1464 sal_Size nEnd
= Seek(STREAM_SEEK_TO_END
);
1465 sal_Size nMaxAvailable
= nEnd
-nCurr
;
1467 return nMaxAvailable
;
1470 void SvStream::Flush()
1472 if( bIsDirty
&& bIsConsistent
)
1474 SeekPos( nBufFilePos
);
1476 CryptAndWriteBuffer( pRWBuf
, (sal_Size
)nBufActualLen
);
1478 if( PutData( pRWBuf
, nBufActualLen
) != nBufActualLen
)
1479 SetError( SVSTREAM_WRITE_ERROR
);
1480 bIsDirty
= sal_False
;
1486 void SvStream::RefreshBuffer()
1488 if( bIsDirty
&& bIsConsistent
)
1490 SeekPos( nBufFilePos
);
1492 CryptAndWriteBuffer( pRWBuf
, (sal_Size
)nBufActualLen
);
1494 PutData( pRWBuf
, nBufActualLen
);
1495 bIsDirty
= sal_False
;
1497 SeekPos( nBufFilePos
);
1498 nBufActualLen
= (sal_uInt16
)GetData( pRWBuf
, nBufSize
);
1499 if( nBufActualLen
&& nError
== ERRCODE_IO_PENDING
)
1500 nError
= ERRCODE_NONE
;
1502 EncryptBuffer(pRWBuf
, (sal_Size
)nBufActualLen
);
1503 bIsConsistent
= sal_True
;
1504 eIOMode
= STREAM_IO_DONTKNOW
;
1507 SvStream
& SvStream::WriteNumber(sal_Int32 nInt32
)
1510 sal_Size nLen
= sprintf(buffer
, "%" SAL_PRIdINT32
, nInt32
);
1511 Write(buffer
, nLen
);
1515 SvStream
& SvStream::WriteNumber(sal_uInt32 nUInt32
)
1518 sal_Size nLen
= sprintf(buffer
, "%" SAL_PRIuUINT32
, nUInt32
);
1519 Write(buffer
, nLen
);
1523 #define CRYPT_BUFSIZE 1024
1525 /// Encrypt and write
1526 sal_Size
SvStream::CryptAndWriteBuffer( const void* pStart
, sal_Size nLen
)
1528 unsigned char pTemp
[CRYPT_BUFSIZE
];
1529 unsigned char* pDataPtr
= (unsigned char*)pStart
;
1530 sal_Size nCount
= 0;
1532 unsigned char nMask
= nCryptMask
;
1535 if( nLen
>= CRYPT_BUFSIZE
)
1536 nBufCount
= CRYPT_BUFSIZE
;
1540 memcpy( pTemp
, pDataPtr
, (sal_uInt16
)nBufCount
);
1541 // **** Verschluesseln *****
1542 for ( sal_uInt16 n
=0; n
< CRYPT_BUFSIZE
; n
++ )
1544 unsigned char aCh
= pTemp
[n
];
1549 // *************************
1550 nCount
+= PutData( (char*)pTemp
, nBufCount
);
1551 pDataPtr
+= nBufCount
;
1557 sal_Bool
SvStream::EncryptBuffer(void* pStart
, sal_Size nLen
)
1559 unsigned char* pTemp
= (unsigned char*)pStart
;
1560 unsigned char nMask
= nCryptMask
;
1562 for ( sal_Size n
=0; n
< nLen
; n
++, pTemp
++ )
1564 unsigned char aCh
= *pTemp
;
1572 static unsigned char implGetCryptMask(const sal_Char
* pStr
, sal_Int32 nLen
, long nVersion
)
1574 unsigned char nCryptMask
= 0;
1579 if( nVersion
<= SOFFICE_FILEFORMAT_31
)
1583 nCryptMask
^= *pStr
;
1588 else // BugFix #25888#
1590 for( sal_uInt16 i
= 0; i
< nLen
; i
++ ) {
1591 nCryptMask
^= pStr
[i
];
1592 if( nCryptMask
& 0x80 ) {
1607 void SvStream::SetCryptMaskKey(const OString
& rCryptMaskKey
)
1609 m_aCryptMaskKey
= rCryptMaskKey
;
1610 nCryptMask
= implGetCryptMask(m_aCryptMaskKey
.getStr(),
1611 m_aCryptMaskKey
.getLength(), GetVersion());
1614 void SvStream::SyncSvStream( sal_Size nNewStreamPos
)
1617 SvStream::nBufFilePos
= nNewStreamPos
;
1620 void SvStream::SyncSysStream()
1626 sal_Bool
SvStream::SetStreamSize( sal_Size nSize
)
1629 sal_Size nFPos
= Tell();
1631 sal_uInt16 nBuf
= nBufSize
;
1634 SetBufferSize( nBuf
);
1635 DBG_ASSERT(Tell()==nFPos
,"SetStreamSize failed");
1636 return (sal_Bool
)(nError
== 0);
1639 SvStream
& endl( SvStream
& rStr
)
1641 LineEnd eDelim
= rStr
.GetLineDelimiter();
1642 if ( eDelim
== LINEEND_CR
)
1644 else if( eDelim
== LINEEND_LF
)
1647 rStr
<< '\r' << '\n';
1651 SvStream
& endlu( SvStream
& rStrm
)
1653 switch ( rStrm
.GetLineDelimiter() )
1656 rStrm
<< sal_Unicode('\r');
1659 rStrm
<< sal_Unicode('\n');
1662 rStrm
<< sal_Unicode('\r') << sal_Unicode('\n');
1667 SvStream
& endlub( SvStream
& rStrm
)
1669 if ( rStrm
.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE
)
1670 return endlu( rStrm
);
1672 return endl( rStrm
);
1675 SvMemoryStream::SvMemoryStream( void* pBuffer
, sal_Size bufSize
,
1678 if( eMode
& STREAM_WRITE
)
1679 bIsWritable
= sal_True
;
1681 bIsWritable
= sal_False
;
1682 nEndOfData
= bufSize
;
1683 bOwnsData
= sal_False
;
1684 pBuf
= (sal_uInt8
*) pBuffer
;
1691 SvMemoryStream::SvMemoryStream( sal_Size nInitSize
, sal_Size nResizeOffset
)
1693 bIsWritable
= sal_True
;
1694 bOwnsData
= sal_True
;
1696 nResize
= nResizeOffset
;
1699 if( nResize
!= 0 && nResize
< 16 )
1701 if( nInitSize
&& !AllocateMemory( nInitSize
) )
1703 SetError( SVSTREAM_OUTOFMEMORY
);
1708 SetBufferSize( 64 );
1711 SvMemoryStream::~SvMemoryStream()
1722 sal_uInt16
SvMemoryStream::IsA() const
1724 return (sal_uInt16
)ID_MEMORYSTREAM
;
1727 void* SvMemoryStream::SetBuffer( void* pNewBuf
, sal_Size nCount
,
1728 sal_Bool bOwnsDat
, sal_Size nEOF
)
1731 SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
1736 if( pNewBuf
!= pBuf
)
1742 pBuf
= (sal_uInt8
*) pNewBuf
;
1746 bOwnsData
= bOwnsDat
;
1754 DBG_ASSERT( nEndOfData
<STREAM_SEEK_TO_END
,"Invalid EOF");
1758 sal_Size
SvMemoryStream::GetData( void* pData
, sal_Size nCount
)
1760 sal_Size nMaxCount
= nEndOfData
-nPos
;
1761 if( nCount
> nMaxCount
)
1763 memcpy( pData
, pBuf
+nPos
, (size_t)nCount
);
1768 sal_Size
SvMemoryStream::PutData( const void* pData
, sal_Size nCount
)
1773 sal_Size nMaxCount
= nSize
-nPos
;
1775 // check for overflow
1776 if( nCount
> nMaxCount
)
1780 // copy as much as possible
1782 SetError( SVSTREAM_OUTOFMEMORY
);
1787 if( nSize
&& nSize
> nResize
)
1790 nNewResize
= nResize
;
1792 if( (nCount
-nMaxCount
) < nResize
)
1794 // lacking memory is smaller than nResize,
1795 // resize accordingly
1796 if( !ReAllocateMemory( nNewResize
) )
1799 SetError( SVSTREAM_WRITE_ERROR
);
1804 // lacking memory is larger than nResize,
1805 // resize by (nCoount-nMaxCount) + resize offset
1806 if( !ReAllocateMemory( nCount
-nMaxCount
+nNewResize
) )
1809 SetError( SVSTREAM_WRITE_ERROR
);
1814 DBG_ASSERT(pBuf
,"Possibly Reallocate failed");
1815 memcpy( pBuf
+nPos
, pData
, (size_t)nCount
);
1818 if( nPos
> nEndOfData
)
1823 sal_Size
SvMemoryStream::SeekPos( sal_Size nNewPos
)
1825 // nEndOfData: First position in stream not allowed to read from
1826 // nSize: Size of allocated buffer
1828 if( nNewPos
< nEndOfData
)
1830 else if( nNewPos
== STREAM_SEEK_TO_END
)
1834 if( nNewPos
>= nSize
) // Does buffer need extension?
1836 if( nResize
) // Is extension possible?
1838 long nDiff
= (long)(nNewPos
- nSize
+ 1);
1839 nDiff
+= (long)nResize
;
1840 ReAllocateMemory( nDiff
);
1842 nEndOfData
= nNewPos
;
1844 else // Extension not possible, set pos to end of data
1846 // SetError( SVSTREAM_OUTOFMEMORY );
1850 else // Expand buffer size
1853 nEndOfData
= nNewPos
;
1859 void SvMemoryStream::FlushData()
1863 void SvMemoryStream::ResetError()
1865 SvStream::ClearError();
1868 sal_Bool
SvMemoryStream::AllocateMemory( sal_Size nNewSize
)
1870 pBuf
= new sal_uInt8
[nNewSize
];
1871 return( pBuf
!= 0 );
1874 // (using Bozo algorithm)
1875 sal_Bool
SvMemoryStream::ReAllocateMemory( long nDiff
)
1877 sal_Bool bRetVal
= sal_False
;
1878 long nTemp
= (long)nSize
;
1880 sal_Size nNewSize
= (sal_Size
)nTemp
;
1884 sal_uInt8
* pNewBuf
= new sal_uInt8
[nNewSize
];
1888 bRetVal
= sal_True
; // Success!
1889 if( nNewSize
< nSize
) // Are we shrinking?
1891 memcpy( pNewBuf
, pBuf
, (size_t)nNewSize
);
1892 if( nPos
> nNewSize
)
1894 if( nEndOfData
>= nNewSize
)
1895 nEndOfData
= nNewSize
-1L;
1899 memcpy( pNewBuf
, pBuf
, (size_t)nSize
);
1921 void SvMemoryStream::FreeMemory()
1926 void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize
, sal_Size nResizeOffset
)
1931 Seek( STREAM_SEEK_TO_BEGIN
);
1933 void* pRetVal
= pBuf
;
1936 nResize
= nResizeOffset
;
1939 if( nResize
!= 0 && nResize
< 16 )
1944 if( nInitSize
&& !AllocateMemory(nInitSize
) )
1946 SetError( SVSTREAM_OUTOFMEMORY
);
1952 SetBufferSize( 64 );
1956 void SvMemoryStream::SetSize( sal_Size nNewSize
)
1958 long nDiff
= (long)nNewSize
- (long)nSize
;
1959 ReAllocateMemory( nDiff
);
1962 TYPEINIT0 ( SvDataCopyStream
)
1964 void SvDataCopyStream::Assign( const SvDataCopyStream
& )
1968 //Create a OString of nLen bytes from rStream
1969 OString
read_uInt8s_ToOString(SvStream
& rStrm
, sal_Size nLen
)
1971 rtl_String
*pStr
= NULL
;
1974 nLen
= std::min(nLen
, static_cast<sal_Size
>(SAL_MAX_INT32
));
1975 //alloc a (ref-count 1) rtl_String of the desired length.
1976 //rtl_String's buffer is uninitialized, except for null termination
1977 pStr
= rtl_string_alloc(sal::static_int_cast
<sal_Int32
>(nLen
));
1978 sal_Size nWasRead
= rStrm
.Read(pStr
->buffer
, nLen
);
1979 if (nWasRead
!= nLen
)
1981 //on (typically unlikely) short read set length to what we could
1982 //read, and null terminate. Excess buffer capacity remains of
1983 //course, could create a (true) replacement OString if it matters.
1984 pStr
->length
= sal::static_int_cast
<sal_Int32
>(nWasRead
);
1985 pStr
->buffer
[pStr
->length
] = 0;
1989 //take ownership of buffer and return, otherwise return empty string
1990 return pStr
? OString(pStr
, SAL_NO_ACQUIRE
) : OString();
1993 //Create a OUString of nLen sal_Unicodes from rStream
1994 OUString
read_uInt16s_ToOUString(SvStream
& rStrm
, sal_Size nLen
)
1996 rtl_uString
*pStr
= NULL
;
1999 nLen
= std::min(nLen
, static_cast<sal_Size
>(SAL_MAX_INT32
));
2000 //alloc a (ref-count 1) rtl_uString of the desired length.
2001 //rtl_String's buffer is uninitialized, except for null termination
2002 pStr
= rtl_uString_alloc(sal::static_int_cast
<sal_Int32
>(nLen
));
2003 sal_Size nWasRead
= rStrm
.Read(pStr
->buffer
, nLen
*2)/2;
2004 if (nWasRead
!= nLen
)
2006 //on (typically unlikely) short read set length to what we could
2007 //read, and null terminate. Excess buffer capacity remains of
2008 //course, could create a (true) replacement OUString if it matters.
2009 pStr
->length
= sal::static_int_cast
<sal_Int32
>(nWasRead
);
2010 pStr
->buffer
[pStr
->length
] = 0;
2012 if (rStrm
.IsEndianSwap())
2014 for (sal_Int32 i
= 0; i
< pStr
->length
; ++i
)
2015 pStr
->buffer
[i
] = OSL_SWAPWORD(pStr
->buffer
[i
]);
2019 //take ownership of buffer and return, otherwise return empty string
2020 return pStr
? OUString(pStr
, SAL_NO_ACQUIRE
) : OUString();
2025 template <typename T
, typename O
> T
tmpl_convertLineEnd(const T
&rIn
, LineEnd eLineEnd
)
2027 // Determine linebreaks and compute length
2028 bool bConvert
= false; // Needs conversion
2029 sal_Int32 nStrLen
= rIn
.getLength();
2030 sal_Int32 nLineEndLen
= (eLineEnd
== LINEEND_CRLF
) ? 2 : 1;
2031 sal_Int32 nLen
= 0; // Target length
2032 sal_Int32 i
= 0; // Source counter
2036 // \r or \n causes linebreak
2037 if ( (rIn
[i
] == '\r') || (rIn
[i
] == '\n') )
2039 nLen
= nLen
+ nLineEndLen
;
2041 // If set already, skip expensive test
2044 // Muessen wir Konvertieren
2045 if ( ((eLineEnd
!= LINEEND_LF
) && (rIn
[i
] == '\n')) ||
2046 ((eLineEnd
== LINEEND_CRLF
) && (rIn
[i
+1] != '\n')) ||
2047 ((eLineEnd
== LINEEND_LF
) &&
2048 ((rIn
[i
] == '\r') || (rIn
[i
+1] == '\r'))) ||
2049 ((eLineEnd
== LINEEND_CR
) &&
2050 ((rIn
[i
] == '\n') || (rIn
[i
+1] == '\n'))) )
2054 // skip char if \r\n oder \n\r
2055 if ( ((rIn
[i
+1] == '\r') || (rIn
[i
+1] == '\n')) &&
2056 (rIn
[i
] != rIn
[i
+1]) )
2067 // convert linebreaks, insert string
2072 // \r or \n causes linebreak
2073 if ( (rIn
[i
] == '\r') || (rIn
[i
] == '\n') )
2075 if ( eLineEnd
== LINEEND_CRLF
)
2077 aNewData
.append('\r');
2078 aNewData
.append('\n');
2082 if ( eLineEnd
== LINEEND_CR
)
2083 aNewData
.append('\r');
2085 aNewData
.append('\n');
2088 if ( ((rIn
[i
+1] == '\r') || (rIn
[i
+1] == '\n')) &&
2089 (rIn
[i
] != rIn
[i
+1]) )
2094 aNewData
.append(rIn
[i
]);
2100 return aNewData
.makeStringAndClear();
2104 OString
convertLineEnd(const OString
&rIn
, LineEnd eLineEnd
)
2106 return tmpl_convertLineEnd
<OString
, OStringBuffer
>(rIn
, eLineEnd
);
2109 OUString
convertLineEnd(const OUString
&rIn
, LineEnd eLineEnd
)
2111 return tmpl_convertLineEnd
<OUString
, OUStringBuffer
>(rIn
, eLineEnd
);
2114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */