fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / tools / source / stream / stream.cxx
blobf964e6e2a98acc0f47e28b86b92e89659a01c8f1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 // TODO: Read->RefreshBuffer-> React to changes from nBufActualLen
22 #include <cstddef>
24 #include <string.h>
25 #include <stdio.h>
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; \
37 nSwapTmp <<= 4; \
38 c >>= 4; \
39 c |= nSwapTmp;
41 #include <tools/debug.hxx>
42 #include <tools/stream.hxx>
43 #include <osl/thread.h>
44 #include <algorithm>
46 DBG_NAME( Stream )
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 )
64 union
66 sal_uInt64 n;
67 sal_uInt32 c[2];
68 } s;
70 s.n = r;
71 s.c[0] ^= s.c[1]; // swap the 32 bit words
72 s.c[1] ^= s.c[0];
73 s.c[0] ^= s.c[1];
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]);
77 r = s.n;
79 inline static void SwapInt64( sal_Int64& r )
81 union
83 sal_Int64 n;
84 sal_Int32 c[2];
85 } s;
87 s.n = r;
88 s.c[0] ^= s.c[1]; // swap the 32 bit words
89 s.c[1] ^= s.c[0];
90 s.c[0] ^= s.c[1];
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]);
94 r = s.n;
97 #ifdef UNX
98 inline static void SwapFloat( float& r )
100 union
102 float f;
103 sal_uInt32 c;
104 } s;
106 s.f = r;
107 s.c = OSL_SWAPDWORD( s.c );
108 r = s.f;
111 inline static void SwapDouble( double& r )
113 if( sizeof(double) != 8 )
115 DBG_ASSERT( sal_False, "Can only swap 8-Byte-doubles\n" );
117 else
119 union
121 double d;
122 sal_uInt32 c[2];
123 } s;
125 s.d = r;
126 s.c[0] ^= s.c[1]; // swap 32-bit values in situ
127 s.c[1] ^= s.c[0];
128 s.c[0] ^= s.c[1];
129 s.c[0] = OSL_SWAPDWORD(s.c[0]); // swap dword itself in situ
130 s.c[1] = OSL_SWAPDWORD(s.c[1]);
131 r = s.d;
134 #endif
136 //SDO
138 #define READNUMBER_WITHOUT_SWAP(datatype,value) \
140 int tmp = eIOMode; \
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);\
149 else\
150 Read( (char*)&value, sizeof(datatype) );\
153 #define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
155 int tmp = eIOMode; \
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;\
167 else\
168 Write( (char*)&value, sizeof(datatype) );\
171 // class SvLockBytes
173 void SvLockBytes::close()
175 if (m_bOwner)
176 delete m_pStream;
177 m_pStream = 0;
180 TYPEINIT0(SvLockBytes);
182 // virtual
183 ErrCode SvLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
184 sal_Size * pRead) const
186 if (!m_pStream)
188 OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
189 return ERRCODE_NONE;
192 m_pStream->Seek(nPos);
193 sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
194 if (pRead)
195 *pRead = nTheRead;
196 return m_pStream->GetErrorCode();
199 // virtual
200 ErrCode SvLockBytes::WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
201 sal_Size * pWritten)
203 if (!m_pStream)
205 OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
206 return ERRCODE_NONE;
209 m_pStream->Seek(nPos);
210 sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
211 if (pWritten)
212 *pWritten = nTheWritten;
213 return m_pStream->GetErrorCode();
216 // virtual
217 ErrCode SvLockBytes::Flush() const
219 if (!m_pStream)
221 OSL_FAIL("SvLockBytes::Flush(): Bad stream");
222 return ERRCODE_NONE;
225 m_pStream->Flush();
226 return m_pStream->GetErrorCode();
229 // virtual
230 ErrCode SvLockBytes::SetSize(sal_Size nSize)
232 if (!m_pStream)
234 OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
235 return ERRCODE_NONE;
238 m_pStream->SetStreamSize(nSize);
239 return m_pStream->GetErrorCode();
242 ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
244 if (!m_pStream)
246 OSL_FAIL("SvLockBytes::Stat(): Bad stream");
247 return ERRCODE_NONE;
250 if (pStat)
252 sal_Size nPos = m_pStream->Tell();
253 pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
254 m_pStream->Seek(nPos);
256 return ERRCODE_NONE;
259 // class SvOpenLockBytes
261 TYPEINIT1(SvOpenLockBytes, SvLockBytes);
263 // class SvAsyncLockBytes
265 TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
267 // virtual
268 ErrCode SvAsyncLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
269 sal_Size * pRead) const
271 if (m_bTerminated)
272 return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
273 else
275 sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
276 ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
277 pRead);
278 return !nCount || nTheCount == nCount || nError ? nError :
279 ERRCODE_IO_PENDING;
283 // virtual
284 ErrCode SvAsyncLockBytes::WriteAt(sal_Size nPos, const void * pBuffer,
285 sal_Size nCount, sal_Size * pWritten)
287 if (m_bTerminated)
288 return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
289 else
291 sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
292 ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
293 pWritten);
294 return !nCount || nTheCount == nCount || nError ? nError :
295 ERRCODE_IO_PENDING;
299 // virtual
300 ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
301 sal_Size * pWritten)
303 sal_Size nTheWritten;
304 ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
305 &nTheWritten);
306 if (!nError)
307 m_nSize += nTheWritten;
308 if (pWritten)
309 *pWritten = nTheWritten;
310 return nError;
313 // virtual
314 sal_Size SvAsyncLockBytes::Seek(sal_Size nPos)
316 if (nPos != STREAM_SEEK_TO_END)
317 m_nSize = nPos;
318 return m_nSize;
321 // class SvStream
323 sal_Size SvStream::GetData( void* pData, sal_Size nSize )
325 if( !GetError() )
327 DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
328 sal_Size nRet;
329 nError = xLockBytes->ReadAt( nActPos, pData, nSize, &nRet );
330 nActPos += nRet;
331 return nRet;
333 else return 0;
336 sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
338 if( !GetError() )
340 DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
341 sal_Size nRet;
342 nError = xLockBytes->WriteAt( nActPos, pData, nSize, &nRet );
343 nActPos += nRet;
344 return nRet;
346 else return 0;
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;
358 else
359 nActPos = nPos;
360 return nActPos;
363 void SvStream::FlushData()
365 if( !GetError() )
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()
380 nActPos = 0;
381 nCompressMode = COMPRESSMODE_NONE;
382 eStreamCharSet = osl_getThreadTextEncoding();
383 nCryptMask = 0;
384 bIsEof = sal_False;
385 #if defined UNX
386 eLineDelimiter = LINEEND_LF; // UNIX-Format
387 #else
388 eLineDelimiter = LINEEND_CRLF; // DOS-Format
389 #endif
391 SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
393 nBufFilePos = 0;
394 nBufActualPos = 0;
395 bIsDirty = sal_False;
396 bIsConsistent = sal_True;
397 bIsWritable = sal_True;
399 pRWBuf = 0;
400 pBufPos = 0;
401 nBufSize = 0;
402 nBufActualLen = 0;
403 eIOMode = STREAM_IO_DONTKNOW;
404 nBufFree = 0;
406 eStreamMode = 0;
408 nVersion = 0;
410 ClearError();
413 SvStream::SvStream( SvLockBytes* pLockBytesP )
415 DBG_CTOR( Stream, NULL );
417 ImpInit();
418 xLockBytes = pLockBytesP;
419 if( pLockBytesP ) {
420 const SvStream* pStrm = pLockBytesP->GetStream();
421 if( pStrm ) {
422 SetError( pStrm->GetErrorCode() );
425 SetBufferSize( 256 );
428 SvStream::SvStream()
430 DBG_CTOR( Stream, NULL );
432 ImpInit();
435 SvStream::~SvStream()
437 DBG_DTOR( Stream, NULL );
439 if ( xLockBytes.Is() )
440 Flush();
442 if( pRWBuf )
443 delete[] pRWBuf;
446 sal_uInt16 SvStream::IsA() const
448 return (sal_uInt16)ID_STREAM;
451 void SvStream::ClearError()
453 bIsEof = sal_False;
454 nError = SVSTREAM_OK;
457 void SvStream::SetError( sal_uInt32 nErrorCode )
459 if ( nError == SVSTREAM_OK )
460 nError = nErrorCode;
463 void SvStream::SetNumberFormatInt( sal_uInt16 nNewFormat )
465 nNumberFormatInt = nNewFormat;
466 bSwap = sal_False;
467 #ifdef OSL_BIGENDIAN
468 if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN )
469 bSwap = sal_True;
470 #else
471 if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN )
472 bSwap = sal_True;
473 #endif
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
482 Flush();
484 if( nBufSize )
486 delete[] pRWBuf;
487 nBufFilePos += nBufActualPos;
490 pRWBuf = 0;
491 nBufActualLen = 0;
492 nBufActualPos = 0;
493 nBufSize = nBufferSize;
494 if( nBufSize )
495 pRWBuf = new sal_uInt8[ nBufSize ];
496 bIsConsistent = sal_True;
497 pBufPos = pRWBuf;
498 eIOMode = STREAM_IO_DONTKNOW;
499 if( !bDontSeek )
500 SeekPos( nActualFilePos );
503 void SvStream::ClearBuffer()
505 nBufActualLen = 0;
506 nBufActualPos = 0;
507 nBufFilePos = 0;
508 pBufPos = pRWBuf;
509 bIsDirty = sal_False;
510 bIsConsistent = sal_True;
511 eIOMode = STREAM_IO_DONTKNOW;
513 bIsEof = sal_False;
516 void SvStream::ResetError()
518 ClearError();
521 sal_Bool SvStream::ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
522 sal_Int32 nMaxBytesToRead )
524 OString aStr;
525 sal_Bool bRet = ReadLine( aStr, nMaxBytesToRead);
526 rStr = OStringToOUString(aStr, eSrcCharSet);
527 return bRet;
530 sal_Bool SvStream::ReadByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
532 OString aStr;
533 sal_Bool bRet = ReadLine(aStr);
534 rStr = OStringToOUString(aStr, eSrcCharSet);
535 return bRet;
538 sal_Bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
540 sal_Char buf[256+1];
541 sal_Bool bEnd = sal_False;
542 sal_Size nOldFilePos = Tell();
543 sal_Char c = 0;
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 );
551 if ( !nLen )
553 if ( aBuf.isEmpty() )
555 // Exit on first block-read error
556 bIsEof = sal_True;
557 rStr = OString();
558 return sal_False;
560 else
561 break;
564 sal_uInt16 j, n;
565 for( j = n = 0; j < nLen ; ++j )
567 c = buf[j];
568 if ( c == '\n' || c == '\r' )
570 bEnd = sal_True;
571 break;
573 if ( n < j )
574 buf[n] = c;
575 ++n;
577 nTotalLen += j;
578 if (nTotalLen > static_cast<sal_Size>(nMaxBytesToRead))
580 n -= nTotalLen - nMaxBytesToRead;
581 nTotalLen = nMaxBytesToRead;
582 bEnd = sal_True;
584 if ( n )
585 aBuf.append(buf, n);
588 if ( !bEnd && !GetError() && aBuf.getLength() )
589 bEnd = sal_True;
591 nOldFilePos += nTotalLen;
592 if( Tell() > nOldFilePos )
593 nOldFilePos++;
594 Seek( nOldFilePos ); // Seek pointer due to BlockRead above
596 if ( bEnd && (c=='\r' || c=='\n') ) // Special treatment for DOS files
598 char cTemp;
599 sal_Size nLen = Read((char*)&cTemp , sizeof(cTemp) );
600 if ( nLen ) {
601 if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
602 Seek( nOldFilePos );
606 if ( bEnd )
607 bIsEof = sal_False;
608 rStr = aBuf.makeStringAndClear();
609 return bEnd;
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();
617 sal_Unicode c = 0;
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);
628 if ( !nLen )
630 if ( aBuf.getLength() == 0 )
632 // exit on first BlockRead error
633 bIsEof = sal_True;
634 rStr = OUString();
635 return sal_False;
637 else
638 break;
641 sal_uInt16 j, n;
642 for( j = n = 0; j < nLen ; ++j )
644 if ( bSwap )
645 SwapUShort( buf[n] );
646 c = buf[j];
647 if ( c == '\n' || c == '\r' )
649 bEnd = sal_True;
650 break;
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.
656 if ( c )
658 if ( n < j )
659 buf[n] = c;
660 ++n;
663 nTotalLen += j;
664 if (nTotalLen > static_cast<sal_Size>(nMaxCodepointsToRead))
666 n -= nTotalLen - nMaxCodepointsToRead;
667 nTotalLen = nMaxCodepointsToRead;
668 bEnd = sal_True;
670 if ( n )
671 aBuf.append( buf, n );
674 if ( !bEnd && !GetError() && aBuf.getLength() )
675 bEnd = sal_True;
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
684 sal_Unicode cTemp;
685 Read( (char*)&cTemp, sizeof(cTemp) );
686 if ( bSwap )
687 SwapUShort( cTemp );
688 if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
689 Seek( nOldFilePos );
692 if ( bEnd )
693 bIsEof = sal_False;
694 rStr = aBuf.makeStringAndClear();
695 return bEnd;
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 );
703 else
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);
718 if (!nLen)
719 break;
721 sal_Size nReallyRead = nLen;
722 const sal_Char* pPtr = buf;
723 while (nLen && *pPtr)
724 ++pPtr, --nLen;
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,
749 sal_Size nUnits)
751 DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
752 sal_Size nWritten;
753 if (!rStrm.IsEndianSwap())
754 nWritten = rStrm.Write( (char*)rStr.getStr(), nUnits * sizeof(sal_Unicode) );
755 else
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;
763 while ( p < pStop )
765 SwapUShort( *p );
766 p++;
768 nWritten = rStrm.Write( (char*)pTmp, nLen * sizeof(sal_Unicode) );
769 if ( pTmp != aBuf )
770 delete [] pTmp;
772 return nWritten;
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;
782 else
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());
798 endl(*this);
799 return nError == SVSTREAM_OK;
802 sal_Bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
804 if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
805 *this << ch;
806 else
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;
832 sal_uInt16 nFlag;
833 sal_sSize nBack = sizeof(nFlag);
834 *this >> nFlag;
835 switch ( nFlag )
837 case 0xfeff :
838 // native UTF-16
839 if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
840 eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
841 nBack = 0;
842 break;
843 case 0xfffe :
844 // swapped UTF-16
845 if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
846 eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
848 SetEndianSwap( !bSwap );
849 nBack = 0;
851 break;
852 case 0xefbb :
853 if (nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN &&
854 (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
855 eReadBomCharSet == RTL_TEXTENCODING_UTF8))
856 bTryUtf8 = true;
857 break;
858 case 0xbbef :
859 if (nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN &&
860 (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
861 eReadBomCharSet == RTL_TEXTENCODING_UTF8))
862 bTryUtf8 = true;
863 break;
864 default:
865 ; // nothing
867 if (bTryUtf8)
869 sal_uChar nChar;
870 nBack += sizeof(nChar);
871 *this >> nChar;
872 if (nChar == 0xbf)
873 nBack = 0; // it is UTF-8
875 if (nBack)
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();
884 if ( nPos >= 0 )
886 if ( SAL_MAX_SIZE - nActualPos > (sal_Size)nPos )
887 nActualPos += nPos;
889 else
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)
902 sal_uInt16 n = 0;
903 READNUMBER_WITHOUT_SWAP(sal_uInt16, n)
904 if (good())
906 if (bSwap)
907 SwapUShort(n);
908 r = n;
910 return *this;
913 SvStream& SvStream::operator>>(sal_uInt32& r)
915 sal_uInt32 n = 0;
916 READNUMBER_WITHOUT_SWAP(sal_uInt32, n)
917 if (good())
919 if (bSwap)
920 SwapULong(n);
921 r = n;
923 return *this;
926 SvStream& SvStream::operator>>(sal_uInt64& r)
928 sal_uInt64 n = 0;
929 READNUMBER_WITHOUT_SWAP(sal_uInt64, n)
930 if (good())
932 if (bSwap)
933 SwapUInt64(n);
934 r = n;
936 return *this;
939 SvStream& SvStream::operator>>(sal_Int16& r)
941 sal_Int16 n = 0;
942 READNUMBER_WITHOUT_SWAP(sal_Int16, n)
943 if (good())
945 if (bSwap)
946 SwapShort(n);
947 r = n;
949 return *this;
952 SvStream& SvStream::operator>>(sal_Int32& r)
954 sal_Int32 n = 0;
955 READNUMBER_WITHOUT_SWAP(sal_Int32, n)
956 if (good())
958 if (bSwap)
959 SwapLongInt(n);
960 r = n;
962 return *this;
965 SvStream& SvStream::ReadInt64(sal_Int64& r)
967 sal_Int64 n = 0;
968 READNUMBER_WITHOUT_SWAP(sal_Int64, n)
969 if (good())
971 if (bSwap)
972 SwapInt64(n);
973 r = n;
975 return *this;
978 SvStream& SvStream::operator>>( signed char& r )
980 if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
981 sizeof(signed char) <= nBufFree )
983 r = *pBufPos;
984 nBufActualPos += sizeof(signed char);
985 pBufPos += sizeof(signed char);
986 nBufFree -= sizeof(signed char);
988 else
989 Read( (char*)&r, sizeof(signed char) );
990 return *this;
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 )
1000 r = *pBufPos;
1001 nBufActualPos += sizeof(char);
1002 pBufPos += sizeof(char);
1003 nBufFree -= sizeof(char);
1005 else
1006 Read( (char*)&r, sizeof(char) );
1007 return *this;
1010 SvStream& SvStream::operator>>( unsigned char& r )
1012 if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
1013 sizeof(char) <= nBufFree )
1015 r = *pBufPos;
1016 nBufActualPos += sizeof(char);
1017 pBufPos += sizeof(char);
1018 nBufFree -= sizeof(char);
1020 else
1021 Read( (char*)&r, sizeof(char) );
1022 return *this;
1025 SvStream& SvStream::operator>>(float& r)
1027 float n = 0;
1028 READNUMBER_WITHOUT_SWAP(float, n)
1029 if (good())
1031 #if defined UNX
1032 if (bSwap)
1033 SwapFloat(n);
1034 #endif
1035 r = n;
1037 return *this;
1040 SvStream& SvStream::operator>>(double& r)
1042 double n = 0;
1043 READNUMBER_WITHOUT_SWAP(double, n)
1044 if (good())
1046 #if defined UNX
1047 if (bSwap)
1048 SwapDouble(n);
1049 #endif
1050 r = n;
1052 return *this;
1055 SvStream& SvStream::operator>> ( SvStream& rStream )
1057 const sal_uInt32 cBufLen = 0x8000;
1058 char* pBuf = new char[ cBufLen ];
1060 sal_uInt32 nCount;
1061 do {
1062 nCount = Read( pBuf, cBufLen );
1063 rStream.Write( pBuf, nCount );
1064 } while( nCount == cBufLen );
1066 delete[] pBuf;
1067 return *this;
1070 SvStream& SvStream::operator<< ( sal_uInt16 v )
1072 if( bSwap )
1073 SwapUShort(v);
1074 WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
1075 return *this;
1078 SvStream& SvStream::operator<< ( sal_uInt32 v )
1080 if( bSwap )
1081 SwapULong(v);
1082 WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
1083 return *this;
1086 SvStream& SvStream::operator<< ( sal_uInt64 v )
1088 if( bSwap )
1089 SwapUInt64(v);
1090 WRITENUMBER_WITHOUT_SWAP(sal_uInt64,v)
1091 return *this;
1094 SvStream& SvStream::operator<< ( sal_Int16 v )
1096 if( bSwap )
1097 SwapShort(v);
1098 WRITENUMBER_WITHOUT_SWAP(sal_Int16,v)
1099 return *this;
1102 SvStream& SvStream::operator<< ( sal_Int32 v )
1104 if( bSwap )
1105 SwapLongInt(v);
1106 WRITENUMBER_WITHOUT_SWAP(sal_Int32,v)
1107 return *this;
1110 SvStream& SvStream::WriteInt64 (sal_Int64 v)
1112 if( bSwap )
1113 SwapInt64(v);
1114 WRITENUMBER_WITHOUT_SWAP(sal_Int64,v)
1115 return *this;
1118 SvStream& SvStream::operator<< ( signed char v )
1120 //SDO
1121 int tmp = eIOMode;
1122 if(tmp == STREAM_IO_WRITE && sizeof(signed char) <= nBufFree )
1124 *pBufPos = v;
1125 pBufPos++; // sizeof(char);
1126 nBufActualPos++;
1127 if( nBufActualPos > nBufActualLen ) // Append ?
1128 nBufActualLen = nBufActualPos;
1129 nBufFree--; // = sizeof(char);
1130 bIsDirty = sal_True;
1132 else
1133 Write( (char*)&v, sizeof(signed char) );
1134 return *this;
1137 // Special treatment for Chars due to PutBack
1139 SvStream& SvStream::operator<< ( char v )
1141 //SDO
1142 int tmp = eIOMode;
1143 if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
1145 *pBufPos = v;
1146 pBufPos++; // sizeof(char);
1147 nBufActualPos++;
1148 if( nBufActualPos > nBufActualLen ) // Append ?
1149 nBufActualLen = nBufActualPos;
1150 nBufFree--; // = sizeof(char);
1151 bIsDirty = sal_True;
1153 else
1154 Write( (char*)&v, sizeof(char) );
1155 return *this;
1158 SvStream& SvStream::operator<< ( unsigned char v )
1160 //SDO
1161 int tmp = eIOMode;
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;
1169 nBufFree--;
1170 bIsDirty = sal_True;
1172 else
1173 Write( (char*)&v, sizeof(char) );
1174 return *this;
1177 SvStream& SvStream::operator<< ( float v )
1179 #ifdef UNX
1180 if( bSwap )
1181 SwapFloat(v);
1182 #endif
1183 WRITENUMBER_WITHOUT_SWAP(float,v)
1184 return *this;
1187 SvStream& SvStream::operator<< ( const double& r )
1189 #if defined UNX
1190 if( bSwap )
1192 double nHelp = r;
1193 SwapDouble(nHelp);
1194 WRITENUMBER_WITHOUT_SWAP(double,nHelp)
1195 return *this;
1197 else
1198 #endif
1199 WRITENUMBER_WITHOUT_SWAP(double,r)
1201 return *this;
1204 SvStream& SvStream::operator<< ( const char* pBuf )
1206 Write( pBuf, strlen( pBuf ) );
1207 return *this;
1210 SvStream& SvStream::operator<< ( const unsigned char* pBuf )
1212 Write( (char*)pBuf, strlen( (char*)pBuf ) );
1213 return *this;
1216 SvStream& SvStream::operator<< ( SvStream& rStream )
1218 const sal_uInt32 cBufLen = 0x8000;
1219 char* pBuf = new char[ cBufLen ];
1220 sal_uInt32 nCount;
1221 do {
1222 nCount = rStream.Read( pBuf, cBufLen );
1223 Write( pBuf, nCount );
1224 } while( nCount == cBufLen );
1226 delete[] pBuf;
1227 return *this;
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);
1243 else
1244 write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(*this, rStr, eDestCharSet);
1245 return *this;
1248 sal_Size SvStream::Read( void* pData, sal_Size nCount )
1250 sal_Size nSaveCount = nCount;
1251 if( !bIsConsistent )
1252 RefreshBuffer();
1254 if( !pRWBuf )
1256 nCount = GetData( (char*)pData,nCount);
1257 if( nCryptMask )
1258 EncryptBuffer(pData, nCount);
1259 nBufFilePos += nCount;
1261 else
1263 // check if block is completely within buffer
1264 eIOMode = STREAM_IO_READ;
1265 if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
1267 // => yes
1268 memcpy(pData, pBufPos, (size_t) nCount);
1269 nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1270 pBufPos += nCount;
1271 nBufFree = nBufFree - (sal_uInt16)nCount;
1273 else
1275 if( bIsDirty ) // Does stream require a flush?
1277 SeekPos( nBufFilePos );
1278 if( nCryptMask )
1279 CryptAndWriteBuffer(pRWBuf, nBufActualLen);
1280 else
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 );
1294 nBufActualLen = 0;
1295 pBufPos = pRWBuf;
1296 nCount = GetData( (char*)pData, nCount );
1297 if( nCryptMask )
1298 EncryptBuffer(pData, nCount);
1299 nBufFilePos += nCount;
1300 nBufFilePos += nBufActualPos;
1301 nBufActualPos = 0;
1303 else
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 );
1312 if( nCryptMask )
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;
1325 bIsEof = sal_False;
1326 nBufFree = nBufActualLen - nBufActualPos;
1327 if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
1328 bIsEof = sal_True;
1329 if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
1330 nError = ERRCODE_NONE;
1331 return nCount;
1334 sal_Size SvStream::Write( const void* pData, sal_Size nCount )
1336 if( !nCount )
1337 return 0;
1338 if( !bIsWritable )
1340 SetError( ERRCODE_IO_CANTWRITE );
1341 return 0;
1343 if( !bIsConsistent )
1344 RefreshBuffer(); // Remove changes in buffer through PutBack
1346 if( !pRWBuf )
1348 if( nCryptMask )
1349 nCount = CryptAndWriteBuffer( pData, nCount );
1350 else
1351 nCount = PutData( (char*)pData, nCount );
1352 nBufFilePos += nCount;
1353 return 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;
1365 pBufPos += nCount;
1366 bIsDirty = sal_True;
1368 else
1370 // Does stream require flushing?
1371 if( bIsDirty )
1373 SeekPos( nBufFilePos );
1374 if( nCryptMask )
1375 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1376 else
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;
1386 nBufActualLen = 0;
1387 nBufActualPos = 0;
1388 pBufPos = pRWBuf;
1389 SeekPos( nBufFilePos );
1390 if( nCryptMask )
1391 nCount = CryptAndWriteBuffer( pData, nCount );
1392 else
1393 nCount = PutData( (char*)pData, nCount );
1394 nBufFilePos += nCount;
1396 else
1398 // Copy block to buffer
1399 memcpy( pRWBuf, pData, (size_t)nCount );
1401 // Mind the order!
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;
1410 return nCount;
1413 sal_Size SvStream::Seek( sal_Size nFilePos )
1415 eIOMode = STREAM_IO_DONTKNOW;
1417 bIsEof = sal_False;
1418 if( !pRWBuf )
1420 nBufFilePos = SeekPos( nFilePos );
1421 DBG_ASSERT(Tell()==nBufFilePos,"Out Of Sync!");
1422 return nBufFilePos;
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;
1433 else
1435 if( bIsDirty && bIsConsistent)
1437 SeekPos( nBufFilePos );
1438 if( nCryptMask )
1439 CryptAndWriteBuffer( pRWBuf, nBufActualLen );
1440 else
1441 PutData( pRWBuf, nBufActualLen );
1442 bIsDirty = sal_False;
1444 nBufActualLen = 0;
1445 nBufActualPos = 0;
1446 pBufPos = pRWBuf;
1447 nBufFilePos = SeekPos( nFilePos );
1449 #ifdef OV_DEBUG
1451 sal_Size nDebugTemp = nBufFilePos + nBufActualPos;
1452 DBG_ASSERT(Tell()==nDebugTemp,"Sync?");
1454 #endif
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;
1466 Seek(nCurr);
1467 return nMaxAvailable;
1470 void SvStream::Flush()
1472 if( bIsDirty && bIsConsistent )
1474 SeekPos( nBufFilePos );
1475 if( nCryptMask )
1476 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1477 else
1478 if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
1479 SetError( SVSTREAM_WRITE_ERROR );
1480 bIsDirty = sal_False;
1482 if( bIsWritable )
1483 FlushData();
1486 void SvStream::RefreshBuffer()
1488 if( bIsDirty && bIsConsistent )
1490 SeekPos( nBufFilePos );
1491 if( nCryptMask )
1492 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1493 else
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;
1501 if( nCryptMask )
1502 EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
1503 bIsConsistent = sal_True;
1504 eIOMode = STREAM_IO_DONTKNOW;
1507 SvStream& SvStream::WriteNumber(sal_Int32 nInt32)
1509 char buffer[12];
1510 sal_Size nLen = sprintf(buffer, "%" SAL_PRIdINT32, nInt32);
1511 Write(buffer, nLen);
1512 return *this;
1515 SvStream& SvStream::WriteNumber(sal_uInt32 nUInt32)
1517 char buffer[11];
1518 sal_Size nLen = sprintf(buffer, "%" SAL_PRIuUINT32, nUInt32);
1519 Write(buffer, nLen);
1520 return *this;
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;
1531 sal_Size nBufCount;
1532 unsigned char nMask = nCryptMask;
1535 if( nLen >= CRYPT_BUFSIZE )
1536 nBufCount = CRYPT_BUFSIZE;
1537 else
1538 nBufCount = nLen;
1539 nLen -= nBufCount;
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];
1545 aCh ^= nMask;
1546 SWAPNIBBLES(aCh)
1547 pTemp[n] = aCh;
1549 // *************************
1550 nCount += PutData( (char*)pTemp, nBufCount );
1551 pDataPtr += nBufCount;
1553 while ( nLen );
1554 return nCount;
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;
1565 SWAPNIBBLES(aCh)
1566 aCh ^= nMask;
1567 *pTemp = aCh;
1569 return sal_True;
1572 static unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
1574 unsigned char nCryptMask = 0;
1576 if (!nLen)
1577 return nCryptMask;
1579 if( nVersion <= SOFFICE_FILEFORMAT_31 )
1581 while( nLen )
1583 nCryptMask ^= *pStr;
1584 pStr++;
1585 nLen--;
1588 else // BugFix #25888#
1590 for( sal_uInt16 i = 0; i < nLen; i++ ) {
1591 nCryptMask ^= pStr[i];
1592 if( nCryptMask & 0x80 ) {
1593 nCryptMask <<= 1;
1594 nCryptMask++;
1596 else
1597 nCryptMask <<= 1;
1601 if( !nCryptMask )
1602 nCryptMask = 67;
1604 return nCryptMask;
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 )
1616 ClearBuffer();
1617 SvStream::nBufFilePos = nNewStreamPos;
1620 void SvStream::SyncSysStream()
1622 Flush();
1623 SeekPos( Tell() );
1626 sal_Bool SvStream::SetStreamSize( sal_Size nSize )
1628 #ifdef DBG_UTIL
1629 sal_Size nFPos = Tell();
1630 #endif
1631 sal_uInt16 nBuf = nBufSize;
1632 SetBufferSize( 0 );
1633 SetSize( nSize );
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 )
1643 rStr << '\r';
1644 else if( eDelim == LINEEND_LF )
1645 rStr << '\n';
1646 else
1647 rStr << '\r' << '\n';
1648 return rStr;
1651 SvStream& endlu( SvStream& rStrm )
1653 switch ( rStrm.GetLineDelimiter() )
1655 case LINEEND_CR :
1656 rStrm << sal_Unicode('\r');
1657 break;
1658 case LINEEND_LF :
1659 rStrm << sal_Unicode('\n');
1660 break;
1661 default:
1662 rStrm << sal_Unicode('\r') << sal_Unicode('\n');
1664 return rStrm;
1667 SvStream& endlub( SvStream& rStrm )
1669 if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
1670 return endlu( rStrm );
1671 else
1672 return endl( rStrm );
1675 SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
1676 StreamMode eMode )
1678 if( eMode & STREAM_WRITE )
1679 bIsWritable = sal_True;
1680 else
1681 bIsWritable = sal_False;
1682 nEndOfData = bufSize;
1683 bOwnsData = sal_False;
1684 pBuf = (sal_uInt8 *) pBuffer;
1685 nResize = 0L;
1686 nSize = bufSize;
1687 nPos = 0L;
1688 SetBufferSize( 0 );
1691 SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
1693 bIsWritable = sal_True;
1694 bOwnsData = sal_True;
1695 nEndOfData = 0L;
1696 nResize = nResizeOffset;
1697 nPos = 0;
1698 pBuf = 0;
1699 if( nResize != 0 && nResize < 16 )
1700 nResize = 16;
1701 if( nInitSize && !AllocateMemory( nInitSize ) )
1703 SetError( SVSTREAM_OUTOFMEMORY );
1704 nSize = 0;
1706 else
1707 nSize = nInitSize;
1708 SetBufferSize( 64 );
1711 SvMemoryStream::~SvMemoryStream()
1713 if( pBuf )
1715 if( bOwnsData )
1716 FreeMemory();
1717 else
1718 Flush();
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 )
1730 void* pResult;
1731 SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
1732 Seek( 0 );
1733 if( bOwnsData )
1735 pResult = 0;
1736 if( pNewBuf != pBuf )
1737 FreeMemory();
1739 else
1740 pResult = pBuf;
1742 pBuf = (sal_uInt8 *) pNewBuf;
1743 nPos = 0;
1744 nSize = nCount;
1745 nResize = 0;
1746 bOwnsData = bOwnsDat;
1748 if( nEOF > nCount )
1749 nEOF = nCount;
1750 nEndOfData = nEOF;
1752 ResetError();
1754 DBG_ASSERT( nEndOfData<STREAM_SEEK_TO_END,"Invalid EOF");
1755 return pResult;
1758 sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
1760 sal_Size nMaxCount = nEndOfData-nPos;
1761 if( nCount > nMaxCount )
1762 nCount = nMaxCount;
1763 memcpy( pData, pBuf+nPos, (size_t)nCount );
1764 nPos += nCount;
1765 return nCount;
1768 sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
1770 if( GetError() )
1771 return 0L;
1773 sal_Size nMaxCount = nSize-nPos;
1775 // check for overflow
1776 if( nCount > nMaxCount )
1778 if( nResize == 0 )
1780 // copy as much as possible
1781 nCount = nMaxCount;
1782 SetError( SVSTREAM_OUTOFMEMORY );
1784 else
1786 long nNewResize;
1787 if( nSize && nSize > nResize )
1788 nNewResize = nSize;
1789 else
1790 nNewResize = nResize;
1792 if( (nCount-nMaxCount) < nResize )
1794 // lacking memory is smaller than nResize,
1795 // resize accordingly
1796 if( !ReAllocateMemory( nNewResize) )
1798 nCount = 0;
1799 SetError( SVSTREAM_WRITE_ERROR );
1802 else
1804 // lacking memory is larger than nResize,
1805 // resize by (nCoount-nMaxCount) + resize offset
1806 if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
1808 nCount = 0;
1809 SetError( SVSTREAM_WRITE_ERROR );
1814 DBG_ASSERT(pBuf,"Possibly Reallocate failed");
1815 memcpy( pBuf+nPos, pData, (size_t)nCount);
1817 nPos += nCount;
1818 if( nPos > nEndOfData )
1819 nEndOfData = nPos;
1820 return nCount;
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 )
1829 nPos = nNewPos;
1830 else if( nNewPos == STREAM_SEEK_TO_END )
1831 nPos = nEndOfData;
1832 else
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 );
1841 nPos = nNewPos;
1842 nEndOfData = nNewPos;
1844 else // Extension not possible, set pos to end of data
1846 // SetError( SVSTREAM_OUTOFMEMORY );
1847 nPos = nEndOfData;
1850 else // Expand buffer size
1852 nPos = nNewPos;
1853 nEndOfData = nNewPos;
1856 return nPos;
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;
1879 nTemp += nDiff;
1880 sal_Size nNewSize = (sal_Size)nTemp;
1882 if( nNewSize )
1884 sal_uInt8* pNewBuf = new sal_uInt8[nNewSize];
1886 if( pNewBuf )
1888 bRetVal = sal_True; // Success!
1889 if( nNewSize < nSize ) // Are we shrinking?
1891 memcpy( pNewBuf, pBuf, (size_t)nNewSize );
1892 if( nPos > nNewSize )
1893 nPos = 0L;
1894 if( nEndOfData >= nNewSize )
1895 nEndOfData = nNewSize-1L;
1897 else
1899 memcpy( pNewBuf, pBuf, (size_t)nSize );
1902 FreeMemory();
1904 pBuf = pNewBuf;
1905 nSize = nNewSize;
1908 else
1910 bRetVal = sal_True;
1911 FreeMemory();
1912 pBuf = 0;
1913 nSize = 0;
1914 nEndOfData = 0;
1915 nPos = 0;
1918 return bRetVal;
1921 void SvMemoryStream::FreeMemory()
1923 delete[] pBuf;
1926 void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
1928 Flush();
1929 if( !bOwnsData )
1930 return 0;
1931 Seek( STREAM_SEEK_TO_BEGIN );
1933 void* pRetVal = pBuf;
1934 pBuf = 0;
1935 nEndOfData = 0L;
1936 nResize = nResizeOffset;
1937 nPos = 0;
1939 if( nResize != 0 && nResize < 16 )
1940 nResize = 16;
1942 ResetError();
1944 if( nInitSize && !AllocateMemory(nInitSize) )
1946 SetError( SVSTREAM_OUTOFMEMORY );
1947 nSize = 0;
1949 else
1950 nSize = nInitSize;
1952 SetBufferSize( 64 );
1953 return pRetVal;
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;
1972 if (nLen)
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;
1997 if (nLen)
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();
2023 namespace
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
2034 while (i < nStrLen)
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
2042 if ( !bConvert )
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'))) )
2051 bConvert = true;
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]) )
2057 ++i;
2059 else
2060 ++nLen;
2061 ++i;
2064 if (!bConvert)
2065 return rIn;
2067 // convert linebreaks, insert string
2068 O aNewData(nLen);
2069 i = 0;
2070 while (i < nStrLen)
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');
2080 else
2082 if ( eLineEnd == LINEEND_CR )
2083 aNewData.append('\r');
2084 else
2085 aNewData.append('\n');
2088 if ( ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
2089 (rIn[i] != rIn[i+1]) )
2090 ++i;
2092 else
2094 aNewData.append(rIn[i]);
2097 ++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: */