fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / tools / source / stream / stream.cxx
blobbb6d21e1a92a9fce81752e12a1f7af0385d89816
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>
27 #include <stdlib.h>
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; \
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 // !!! 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 )
58 union
60 sal_uInt64 n;
61 sal_uInt32 c[2];
62 } s;
64 s.n = r;
65 s.c[0] ^= s.c[1]; // swap the 32 bit words
66 s.c[1] ^= s.c[0];
67 s.c[0] ^= s.c[1];
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]);
71 r = s.n;
73 inline static void SwapInt64( sal_Int64& r )
75 union
77 sal_Int64 n;
78 sal_Int32 c[2];
79 } s;
81 s.n = r;
82 s.c[0] ^= s.c[1]; // swap the 32 bit words
83 s.c[1] ^= s.c[0];
84 s.c[0] ^= s.c[1];
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]);
88 r = s.n;
91 #ifdef UNX
92 inline static void SwapFloat( float& r )
94 union
96 float f;
97 sal_uInt32 c;
98 } s;
100 s.f = r;
101 s.c = OSL_SWAPDWORD( s.c );
102 r = s.f;
105 inline static void SwapDouble( double& r )
107 if( sizeof(double) != 8 )
109 DBG_ASSERT( false, "Can only swap 8-Byte-doubles\n" );
111 else
113 union
115 double d;
116 sal_uInt32 c[2];
117 } s;
119 s.d = r;
120 s.c[0] ^= s.c[1]; // swap 32-bit values in situ
121 s.c[1] ^= s.c[0];
122 s.c[0] ^= s.c[1];
123 s.c[0] = OSL_SWAPDWORD(s.c[0]); // swap dword itself in situ
124 s.c[1] = OSL_SWAPDWORD(s.c[1]);
125 r = s.d;
128 #endif
130 //SDO
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); \
141 else \
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); \
157 bIsDirty = true; \
159 else \
161 Write( &value, sizeof(datatype) ); \
164 // class SvLockBytes
166 void SvLockBytes::close()
168 if (m_bOwner)
169 delete m_pStream;
170 m_pStream = 0;
173 TYPEINIT0(SvLockBytes);
175 // virtual
176 ErrCode SvLockBytes::ReadAt(sal_uInt64 const nPos, void * pBuffer, sal_Size nCount,
177 sal_Size * pRead) const
179 if (!m_pStream)
181 OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
182 return ERRCODE_NONE;
185 m_pStream->Seek(nPos);
186 sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
187 if (pRead)
188 *pRead = nTheRead;
189 return m_pStream->GetErrorCode();
192 // virtual
193 ErrCode SvLockBytes::WriteAt(sal_uInt64 const nPos, const void * pBuffer, sal_Size nCount,
194 sal_Size * pWritten)
196 if (!m_pStream)
198 OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
199 return ERRCODE_NONE;
202 m_pStream->Seek(nPos);
203 sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
204 if (pWritten)
205 *pWritten = nTheWritten;
206 return m_pStream->GetErrorCode();
209 // virtual
210 ErrCode SvLockBytes::Flush() const
212 if (!m_pStream)
214 OSL_FAIL("SvLockBytes::Flush(): Bad stream");
215 return ERRCODE_NONE;
218 m_pStream->Flush();
219 return m_pStream->GetErrorCode();
222 // virtual
223 ErrCode SvLockBytes::SetSize(sal_uInt64 const nSize)
225 if (!m_pStream)
227 OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
228 return ERRCODE_NONE;
231 m_pStream->SetStreamSize(nSize);
232 return m_pStream->GetErrorCode();
235 ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
237 if (!m_pStream)
239 OSL_FAIL("SvLockBytes::Stat(): Bad stream");
240 return ERRCODE_NONE;
243 if (pStat)
245 sal_uInt64 const nPos = m_pStream->Tell();
246 pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
247 m_pStream->Seek(nPos);
249 return ERRCODE_NONE;
252 // class SvOpenLockBytes
254 TYPEINIT1(SvOpenLockBytes, SvLockBytes);
256 // class SvAsyncLockBytes
258 TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
260 // virtual
261 ErrCode SvAsyncLockBytes::ReadAt(sal_uInt64 const nPos, void * pBuffer, sal_Size nCount,
262 sal_Size * pRead) const
264 if (m_bTerminated)
265 return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
266 else
268 sal_Size nTheCount =
269 std::min<sal_Size>(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
270 ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
271 pRead);
272 return !nCount || nTheCount == nCount || nError ? nError :
273 ERRCODE_IO_PENDING;
277 // virtual
278 ErrCode SvAsyncLockBytes::WriteAt(sal_uInt64 const nPos, const void * pBuffer,
279 sal_Size nCount, sal_Size * pWritten)
281 if (m_bTerminated)
282 return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
283 else
285 sal_Size nTheCount =
286 std::min<sal_Size>(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
287 ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
288 pWritten);
289 return !nCount || nTheCount == nCount || nError ? nError :
290 ERRCODE_IO_PENDING;
294 // virtual
295 ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
296 sal_Size * pWritten)
298 sal_Size nTheWritten(0);
299 ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
300 &nTheWritten);
301 if (!nError)
302 m_nSize += nTheWritten;
303 if (pWritten)
304 *pWritten = nTheWritten;
305 return nError;
308 // virtual
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)
314 m_nSize = nPos;
315 return m_nSize;
318 // class SvStream
320 sal_Size SvStream::GetData( void* pData, sal_Size nSize )
322 if( !GetError() )
324 DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
325 sal_Size nRet(0);
326 nError = xLockBytes->ReadAt(m_nActPos, pData, nSize, &nRet);
327 m_nActPos += nRet;
328 return nRet;
330 else return 0;
333 sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
335 if( !GetError() )
337 DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
338 sal_Size nRet(0);
339 nError = xLockBytes->WriteAt(m_nActPos, pData, nSize, &nRet);
340 m_nActPos += nRet;
341 return nRet;
343 else return 0;
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;
357 else
358 m_nActPos = nPos;
359 return m_nActPos;
362 void SvStream::FlushData()
364 if( !GetError() )
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()
379 m_nActPos = 0;
380 nCompressMode = SvStreamCompressFlags::NONE;
381 eStreamCharSet = osl_getThreadTextEncoding();
382 nCryptMask = 0;
383 bIsEof = false;
384 #if defined UNX
385 eLineDelimiter = LINEEND_LF; // UNIX-Format
386 #else
387 eLineDelimiter = LINEEND_CRLF; // DOS-Format
388 #endif
390 SetEndian( SvStreamEndian::LITTLE );
392 m_nBufFilePos = 0;
393 nBufActualPos = 0;
394 bIsDirty = false;
395 bIsConsistent = true;
396 bIsWritable = true;
398 pRWBuf = 0;
399 pBufPos = 0;
400 nBufSize = 0;
401 nBufActualLen = 0;
402 bIoRead = false;
403 bIoWrite = false;
404 nBufFree = 0;
406 eStreamMode = StreamMode::NONE;
408 nVersion = 0;
410 ClearError();
413 SvStream::SvStream( SvLockBytes* pLockBytesP )
415 ImpInit();
416 xLockBytes = pLockBytesP;
417 if( pLockBytesP ) {
418 const SvStream* pStrm = pLockBytesP->GetStream();
419 if( pStrm ) {
420 SetError( pStrm->GetErrorCode() );
423 SetBufferSize( 256 );
426 SvStream::SvStream()
428 ImpInit();
431 SvStream::~SvStream()
433 if ( xLockBytes.Is() )
434 Flush();
436 if( pRWBuf )
437 delete[] pRWBuf;
440 void SvStream::ClearError()
442 bIsEof = false;
443 nError = SVSTREAM_OK;
446 void SvStream::SetError( sal_uInt32 nErrorCode )
448 if ( nError == SVSTREAM_OK )
449 nError = nErrorCode;
452 void SvStream::SetEndian( SvStreamEndian nNewFormat )
454 nEndian = nNewFormat;
455 bSwap = false;
456 #ifdef OSL_BIGENDIAN
457 if( nEndian == SvStreamEndian::LITTLE )
458 bSwap = true;
459 #else
460 if( nEndian == SvStreamEndian::BIG )
461 bSwap = true;
462 #endif
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
471 Flush();
473 if( nBufSize )
475 delete[] pRWBuf;
476 m_nBufFilePos += nBufActualPos;
479 pRWBuf = 0;
480 nBufActualLen = 0;
481 nBufActualPos = 0;
482 nBufSize = nBufferSize;
483 if( nBufSize )
484 pRWBuf = new sal_uInt8[ nBufSize ];
485 bIsConsistent = true;
486 pBufPos = pRWBuf;
487 bIoRead = bIoWrite = false;
488 if( !bDontSeek )
489 SeekPos( nActualFilePos );
492 void SvStream::ClearBuffer()
494 nBufActualLen = 0;
495 nBufActualPos = 0;
496 m_nBufFilePos = 0;
497 pBufPos = pRWBuf;
498 bIsDirty = false;
499 bIsConsistent = true;
500 bIoRead = bIoWrite = false;
502 bIsEof = false;
505 void SvStream::ResetError()
507 ClearError();
510 bool SvStream::ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
511 sal_Int32 nMaxBytesToRead )
513 OString aStr;
514 bool bRet = ReadLine( aStr, nMaxBytesToRead);
515 rStr = OStringToOUString(aStr, eSrcCharSet);
516 return bRet;
519 bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
521 sal_Char buf[256+1];
522 bool bEnd = false;
523 sal_uInt64 nOldFilePos = Tell();
524 sal_Char c = 0;
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 );
532 if ( !nLen )
534 if ( aBuf.isEmpty() )
536 // Exit on first block-read error
537 bIsEof = true;
538 rStr.clear();
539 return false;
541 else
542 break;
545 sal_uInt16 j, n;
546 for( j = n = 0; j < nLen ; ++j )
548 c = buf[j];
549 if ( c == '\n' || c == '\r' )
551 bEnd = true;
552 break;
554 if ( n < j )
555 buf[n] = c;
556 ++n;
558 nTotalLen += j;
559 if (nTotalLen > static_cast<sal_Size>(nMaxBytesToRead))
561 n -= nTotalLen - nMaxBytesToRead;
562 nTotalLen = nMaxBytesToRead;
563 bEnd = true;
565 if ( n )
566 aBuf.append(buf, n);
569 if ( !bEnd && !GetError() && !aBuf.isEmpty() )
570 bEnd = true;
572 nOldFilePos += nTotalLen;
573 if( Tell() > nOldFilePos )
574 nOldFilePos++;
575 Seek( nOldFilePos ); // Seek pointer due to BlockRead above
577 if ( bEnd && (c=='\r' || c=='\n') ) // Special treatment for DOS files
579 char cTemp;
580 sal_Size nLen = Read(&cTemp , sizeof(cTemp) );
581 if ( nLen ) {
582 if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
583 Seek( nOldFilePos );
587 if ( bEnd )
588 bIsEof = false;
589 rStr = aBuf.makeStringAndClear();
590 return bEnd;
593 bool SvStream::ReadUniStringLine( OUString& rStr, sal_Int32 nMaxCodepointsToRead )
595 sal_Unicode buf[256+1];
596 bool bEnd = false;
597 sal_uInt64 nOldFilePos = Tell();
598 sal_Unicode c = 0;
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);
609 if ( !nLen )
611 if ( aBuf.isEmpty() )
613 // exit on first BlockRead error
614 bIsEof = true;
615 rStr.clear();
616 return false;
618 else
619 break;
622 sal_uInt16 j, n;
623 for( j = n = 0; j < nLen ; ++j )
625 if ( bSwap )
626 SwapUShort( buf[n] );
627 c = buf[j];
628 if ( c == '\n' || c == '\r' )
630 bEnd = true;
631 break;
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.
637 if ( c )
639 if ( n < j )
640 buf[n] = c;
641 ++n;
644 nTotalLen += j;
645 if (nTotalLen > static_cast<sal_Size>(nMaxCodepointsToRead))
647 n -= nTotalLen - nMaxCodepointsToRead;
648 nTotalLen = nMaxCodepointsToRead;
649 bEnd = true;
651 if ( n )
652 aBuf.append( buf, n );
655 if ( !bEnd && !GetError() && !aBuf.isEmpty() )
656 bEnd = true;
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
665 sal_Unicode cTemp;
666 Read( &cTemp, sizeof(cTemp) );
667 if ( bSwap )
668 SwapUShort( cTemp );
669 if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
670 Seek( nOldFilePos );
673 if ( bEnd )
674 bIsEof = false;
675 rStr = aBuf.makeStringAndClear();
676 return bEnd;
679 bool SvStream::ReadUniOrByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
680 sal_Int32 nMaxCodepointsToRead )
682 if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
683 return ReadUniStringLine( rStr, nMaxCodepointsToRead );
684 else
685 return ReadByteStringLine( rStr, eSrcCharSet, nMaxCodepointsToRead );
688 OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStream)
690 OStringBuffer aOutput(256);
692 sal_Char buf[ 256 + 1 ];
693 bool bEnd = false;
694 sal_uInt64 nFilePos = rStream.Tell();
696 while( !bEnd && !rStream.GetError() )
698 sal_Size nLen = rStream.Read(buf, sizeof(buf)-1);
699 if (!nLen)
700 break;
702 sal_Size nReallyRead = nLen;
703 const sal_Char* pPtr = buf;
704 while (nLen && *pPtr)
705 ++pPtr, --nLen;
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,
730 sal_Size nUnits)
732 DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
733 sal_Size nWritten;
734 if (!rStrm.IsEndianSwap())
735 nWritten = rStrm.Write( rStr.getStr(), nUnits * sizeof(sal_Unicode) );
736 else
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;
744 while ( p < pStop )
746 SwapUShort( *p );
747 p++;
749 nWritten = rStrm.Write( pTmp, nLen * sizeof(sal_Unicode) );
750 if ( pTmp != aBuf )
751 delete [] pTmp;
753 return nWritten;
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;
763 else
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());
779 endl(*this);
780 return nError == SVSTREAM_OK;
783 bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
785 if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
786 WriteUnicode(ch);
787 else
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;
813 sal_uInt16 nFlag(0);
814 sal_sSize nBack = sizeof(nFlag);
815 this->ReadUInt16( nFlag );
816 switch ( nFlag )
818 case 0xfeff :
819 // native UTF-16
820 if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
821 eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
822 nBack = 0;
823 break;
824 case 0xfffe :
825 // swapped UTF-16
826 if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
827 eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
829 SetEndian( nEndian == SvStreamEndian::BIG ? SvStreamEndian::LITTLE : SvStreamEndian::BIG );
830 nBack = 0;
832 break;
833 case 0xefbb :
834 if (nEndian == SvStreamEndian::BIG &&
835 (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
836 eReadBomCharSet == RTL_TEXTENCODING_UTF8))
837 bTryUtf8 = true;
838 break;
839 case 0xbbef :
840 if (nEndian == SvStreamEndian::LITTLE &&
841 (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
842 eReadBomCharSet == RTL_TEXTENCODING_UTF8))
843 bTryUtf8 = true;
844 break;
845 default:
846 ; // nothing
848 if (bTryUtf8)
850 unsigned char nChar(0);
851 nBack += sizeof(nChar);
852 this->ReadUChar( nChar );
853 if (nChar == 0xbf)
854 nBack = 0; // it is UTF-8
856 if (nBack)
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();
865 if ( nPos >= 0 )
867 if (SAL_MAX_UINT64 - nActualPos > static_cast<sal_uInt64>(nPos))
868 nActualPos += nPos;
870 else
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)
883 sal_uInt16 n = 0;
884 READNUMBER_WITHOUT_SWAP(sal_uInt16, n)
885 if (good())
887 if (bSwap)
888 SwapUShort(n);
889 r = n;
891 return *this;
894 SvStream& SvStream::ReadUInt32(sal_uInt32& r)
896 sal_uInt32 n = 0;
897 READNUMBER_WITHOUT_SWAP(sal_uInt32, n)
898 if (good())
900 if (bSwap)
901 SwapULong(n);
902 r = n;
904 return *this;
907 SvStream& SvStream::ReadUInt64(sal_uInt64& r)
909 sal_uInt64 n = 0;
910 READNUMBER_WITHOUT_SWAP(sal_uInt64, n)
911 if (good())
913 if (bSwap)
914 SwapUInt64(n);
915 r = n;
917 return *this;
920 SvStream& SvStream::ReadInt16(sal_Int16& r)
922 sal_Int16 n = 0;
923 READNUMBER_WITHOUT_SWAP(sal_Int16, n)
924 if (good())
926 if (bSwap)
927 SwapShort(n);
928 r = n;
930 return *this;
933 SvStream& SvStream::ReadInt32(sal_Int32& r)
935 sal_Int32 n = 0;
936 READNUMBER_WITHOUT_SWAP(sal_Int32, n)
937 if (good())
939 if (bSwap)
940 SwapLongInt(n);
941 r = n;
943 return *this;
946 SvStream& SvStream::ReadInt64(sal_Int64& r)
948 sal_Int64 n = 0;
949 READNUMBER_WITHOUT_SWAP(sal_Int64, n)
950 if (good())
952 if (bSwap)
953 SwapInt64(n);
954 r = n;
956 return *this;
959 SvStream& SvStream::ReadSChar( signed char& r )
961 if( (bIoRead || !bIsConsistent) &&
962 sizeof(signed char) <= nBufFree )
964 r = *pBufPos;
965 nBufActualPos += sizeof(signed char);
966 pBufPos += sizeof(signed char);
967 nBufFree -= sizeof(signed char);
969 else
970 Read( &r, sizeof(signed char) );
971 return *this;
974 // Special treatment for Chars due to PutBack
976 SvStream& SvStream::ReadChar( char& r )
978 if( (bIoRead || !bIsConsistent) &&
979 sizeof(char) <= nBufFree )
981 r = *pBufPos;
982 nBufActualPos += sizeof(char);
983 pBufPos += sizeof(char);
984 nBufFree -= sizeof(char);
986 else
987 Read( &r, sizeof(char) );
988 return *this;
991 SvStream& SvStream::ReadUChar( unsigned char& r )
993 if( (bIoRead || !bIsConsistent) &&
994 sizeof(char) <= nBufFree )
996 r = *pBufPos;
997 nBufActualPos += sizeof(char);
998 pBufPos += sizeof(char);
999 nBufFree -= sizeof(char);
1001 else
1002 Read( &r, sizeof(char) );
1003 return *this;
1006 SvStream& SvStream::ReadCharAsBool( bool& r )
1008 if( (bIoRead || !bIsConsistent) &&
1009 sizeof(char) <= nBufFree )
1011 SAL_WARN_IF(
1012 *pBufPos > 1, "tools.stream", unsigned(*pBufPos) << " not 0/1");
1013 r = *pBufPos != 0;
1014 nBufActualPos += sizeof(char);
1015 pBufPos += sizeof(char);
1016 nBufFree -= sizeof(char);
1018 else
1020 unsigned char c;
1021 if (Read(&c, 1) == 1)
1023 SAL_WARN_IF(c > 1, "tools.stream", unsigned(c) << " not 0/1");
1024 r = c != 0;
1027 return *this;
1030 SvStream& SvStream::ReadFloat(float& r)
1032 float n = 0;
1033 READNUMBER_WITHOUT_SWAP(float, n)
1034 if (good())
1036 #if defined UNX
1037 if (bSwap)
1038 SwapFloat(n);
1039 #endif
1040 r = n;
1042 return *this;
1045 SvStream& SvStream::ReadDouble(double& r)
1047 double n = 0;
1048 READNUMBER_WITHOUT_SWAP(double, n)
1049 if (good())
1051 #if defined UNX
1052 if (bSwap)
1053 SwapDouble(n);
1054 #endif
1055 r = n;
1057 return *this;
1060 SvStream& SvStream::ReadStream( SvStream& rStream )
1062 const sal_uInt32 cBufLen = 0x8000;
1063 char* pBuf = new char[ cBufLen ];
1065 sal_uInt32 nCount;
1066 do {
1067 nCount = Read( pBuf, cBufLen );
1068 rStream.Write( pBuf, nCount );
1069 } while( nCount == cBufLen );
1071 delete[] pBuf;
1072 return *this;
1075 SvStream& SvStream::WriteUInt16( sal_uInt16 v )
1077 if( bSwap )
1078 SwapUShort(v);
1079 WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
1080 return *this;
1083 SvStream& SvStream::WriteUInt32( sal_uInt32 v )
1085 if( bSwap )
1086 SwapULong(v);
1087 WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
1088 return *this;
1091 SvStream& SvStream::WriteUInt64( sal_uInt64 v )
1093 if( bSwap )
1094 SwapUInt64(v);
1095 WRITENUMBER_WITHOUT_SWAP(sal_uInt64,v)
1096 return *this;
1099 SvStream& SvStream::WriteInt16( sal_Int16 v )
1101 if( bSwap )
1102 SwapShort(v);
1103 WRITENUMBER_WITHOUT_SWAP(sal_Int16,v)
1104 return *this;
1107 SvStream& SvStream::WriteInt32( sal_Int32 v )
1109 if( bSwap )
1110 SwapLongInt(v);
1111 WRITENUMBER_WITHOUT_SWAP(sal_Int32,v)
1112 return *this;
1115 SvStream& SvStream::WriteInt64 (sal_Int64 v)
1117 if( bSwap )
1118 SwapInt64(v);
1119 WRITENUMBER_WITHOUT_SWAP(sal_Int64,v)
1120 return *this;
1123 SvStream& SvStream::WriteSChar( signed char v )
1125 //SDO
1126 if(bIoWrite && sizeof(signed char) <= nBufFree )
1128 *pBufPos = v;
1129 pBufPos++; // sizeof(char);
1130 nBufActualPos++;
1131 if( nBufActualPos > nBufActualLen ) // Append ?
1132 nBufActualLen = nBufActualPos;
1133 nBufFree--; // = sizeof(char);
1134 bIsDirty = true;
1136 else
1137 Write( &v, sizeof(signed char) );
1138 return *this;
1141 // Special treatment for Chars due to PutBack
1143 SvStream& SvStream::WriteChar( char v )
1145 //SDO
1146 if(bIoWrite && sizeof(char) <= nBufFree )
1148 *pBufPos = v;
1149 pBufPos++; // sizeof(char);
1150 nBufActualPos++;
1151 if( nBufActualPos > nBufActualLen ) // Append ?
1152 nBufActualLen = nBufActualPos;
1153 nBufFree--; // = sizeof(char);
1154 bIsDirty = true;
1156 else
1157 Write( &v, sizeof(char) );
1158 return *this;
1161 SvStream& SvStream::WriteUChar( unsigned char v )
1163 //SDO
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;
1171 nBufFree--;
1172 bIsDirty = true;
1174 else
1175 Write( &v, sizeof(char) );
1176 return *this;
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 )
1191 #ifdef UNX
1192 if( bSwap )
1193 SwapFloat(v);
1194 #endif
1195 WRITENUMBER_WITHOUT_SWAP(float,v)
1196 return *this;
1199 SvStream& SvStream::WriteDouble ( const double& r )
1201 #if defined UNX
1202 if( bSwap )
1204 double nHelp = r;
1205 SwapDouble(nHelp);
1206 WRITENUMBER_WITHOUT_SWAP(double,nHelp)
1207 return *this;
1209 else
1210 #endif
1212 WRITENUMBER_WITHOUT_SWAP(double,r);
1214 return *this;
1217 SvStream& SvStream::WriteCharPtr( const char* pBuf )
1219 Write( pBuf, strlen( pBuf ) );
1220 return *this;
1223 SvStream& SvStream::WriteStream( SvStream& rStream )
1225 const sal_uInt32 cBufLen = 0x8000;
1226 char* pBuf = new char[ cBufLen ];
1227 sal_uInt32 nCount;
1228 do {
1229 nCount = rStream.Read( pBuf, cBufLen );
1230 Write( pBuf, nCount );
1231 } while( nCount == cBufLen );
1233 delete[] pBuf;
1234 return *this;
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);
1250 else
1251 write_uInt16_lenPrefixed_uInt8s_FromOUString(*this, rStr, eDestCharSet);
1252 return *this;
1255 sal_Size SvStream::Read( void* pData, sal_Size nCount )
1257 sal_Size nSaveCount = nCount;
1258 if( !bIsConsistent )
1259 RefreshBuffer();
1261 if( !pRWBuf )
1263 nCount = GetData( pData,nCount);
1264 if( nCryptMask )
1265 EncryptBuffer(pData, nCount);
1266 m_nBufFilePos += nCount;
1268 else
1270 // check if block is completely within buffer
1271 bIoRead = true;
1272 bIoWrite = false;
1273 if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
1275 // => yes
1276 memcpy(pData, pBufPos, (size_t) nCount);
1277 nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
1278 pBufPos += nCount;
1279 nBufFree = nBufFree - (sal_uInt16)nCount;
1281 else
1283 if( bIsDirty ) // Does stream require a flush?
1285 SeekPos(m_nBufFilePos);
1286 if( nCryptMask )
1287 CryptAndWriteBuffer(pRWBuf, nBufActualLen);
1288 else
1289 PutData( pRWBuf, nBufActualLen );
1290 bIsDirty = false;
1293 // Does data block fit into buffer?
1294 if( nCount > nBufSize )
1296 // => No! Thus read directly
1297 // into target area without using the buffer
1299 bIoRead = false;
1301 SeekPos(m_nBufFilePos + nBufActualPos);
1302 nBufActualLen = 0;
1303 pBufPos = pRWBuf;
1304 nCount = GetData( pData, nCount );
1305 if( nCryptMask )
1306 EncryptBuffer(pData, nCount);
1307 m_nBufFilePos += nCount;
1308 m_nBufFilePos += nBufActualPos;
1309 nBufActualPos = 0;
1311 else
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 );
1320 if( nCryptMask )
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;
1333 bIsEof = false;
1334 nBufFree = nBufActualLen - nBufActualPos;
1335 if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
1336 bIsEof = true;
1337 if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
1338 nError = ERRCODE_NONE;
1339 return nCount;
1342 sal_Size SvStream::Write( const void* pData, sal_Size nCount )
1344 if( !nCount )
1345 return 0;
1346 if( !bIsWritable )
1348 SetError( ERRCODE_IO_CANTWRITE );
1349 return 0;
1351 if( !bIsConsistent )
1352 RefreshBuffer(); // Remove changes in buffer through PutBack
1354 if( !pRWBuf )
1356 if( nCryptMask )
1357 nCount = CryptAndWriteBuffer( pData, nCount );
1358 else
1359 nCount = PutData( pData, nCount );
1360 m_nBufFilePos += nCount;
1361 return nCount;
1364 bIoRead = false;
1365 bIoWrite = true;
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;
1374 pBufPos += nCount;
1375 bIsDirty = true;
1377 else
1379 // Does stream require flushing?
1380 if( bIsDirty )
1382 SeekPos(m_nBufFilePos);
1383 if( nCryptMask )
1384 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1385 else
1386 PutData( pRWBuf, nBufActualLen );
1387 bIsDirty = false;
1390 // Does data block fit into buffer?
1391 if( nCount > nBufSize )
1393 bIoWrite = false;
1394 m_nBufFilePos += nBufActualPos;
1395 nBufActualLen = 0;
1396 nBufActualPos = 0;
1397 pBufPos = pRWBuf;
1398 SeekPos(m_nBufFilePos);
1399 if( nCryptMask )
1400 nCount = CryptAndWriteBuffer( pData, nCount );
1401 else
1402 nCount = PutData( pData, nCount );
1403 m_nBufFilePos += nCount;
1405 else
1407 // Copy block to buffer
1408 memcpy( pRWBuf, pData, (size_t)nCount );
1410 // Mind the order!
1411 m_nBufFilePos += nBufActualPos;
1412 nBufActualPos = (sal_uInt16)nCount;
1413 pBufPos = pRWBuf + nCount;
1414 nBufActualLen = (sal_uInt16)nCount;
1415 bIsDirty = true;
1418 nBufFree = nBufSize - nBufActualPos;
1419 return nCount;
1422 sal_uInt64 SvStream::Seek(sal_uInt64 const nFilePos)
1424 bIoRead = bIoWrite = false;
1425 bIsEof = false;
1426 if( !pRWBuf )
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;
1441 else
1443 if( bIsDirty && bIsConsistent)
1445 SeekPos(m_nBufFilePos);
1446 if( nCryptMask )
1447 CryptAndWriteBuffer( pRWBuf, nBufActualLen );
1448 else
1449 PutData( pRWBuf, nBufActualLen );
1450 bIsDirty = false;
1452 nBufActualLen = 0;
1453 nBufActualPos = 0;
1454 pBufPos = pRWBuf;
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;
1468 Seek(nCurr);
1469 return nMaxAvailable;
1472 void SvStream::Flush()
1474 if( bIsDirty && bIsConsistent )
1476 SeekPos(m_nBufFilePos);
1477 if( nCryptMask )
1478 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1479 else
1480 if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
1481 SetError( SVSTREAM_WRITE_ERROR );
1482 bIsDirty = false;
1484 if( bIsWritable )
1485 FlushData();
1488 void SvStream::RefreshBuffer()
1490 if( bIsDirty && bIsConsistent )
1492 SeekPos(m_nBufFilePos);
1493 if( nCryptMask )
1494 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
1495 else
1496 PutData( pRWBuf, nBufActualLen );
1497 bIsDirty = false;
1499 SeekPos(m_nBufFilePos);
1500 nBufActualLen = (sal_uInt16)GetData( pRWBuf, nBufSize );
1501 if( nBufActualLen && nError == ERRCODE_IO_PENDING )
1502 nError = ERRCODE_NONE;
1503 if( nCryptMask )
1504 EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
1505 bIsConsistent = true;
1506 bIoRead = bIoWrite = false;
1509 SvStream& SvStream::WriteInt32AsString(sal_Int32 nInt32)
1511 char buffer[12];
1512 sal_Size nLen = sprintf(buffer, "%" SAL_PRIdINT32, nInt32);
1513 Write(buffer, nLen);
1514 return *this;
1517 SvStream& SvStream::WriteUInt32AsString(sal_uInt32 nUInt32)
1519 char buffer[11];
1520 sal_Size nLen = sprintf(buffer, "%" SAL_PRIuUINT32, nUInt32);
1521 Write(buffer, nLen);
1522 return *this;
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;
1533 sal_Size nBufCount;
1534 unsigned char nMask = nCryptMask;
1537 if( nLen >= CRYPT_BUFSIZE )
1538 nBufCount = CRYPT_BUFSIZE;
1539 else
1540 nBufCount = nLen;
1541 nLen -= nBufCount;
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];
1547 aCh ^= nMask;
1548 SWAPNIBBLES(aCh)
1549 pTemp[n] = aCh;
1551 // *************************
1552 nCount += PutData( pTemp, nBufCount );
1553 pDataPtr += nBufCount;
1555 while ( nLen );
1556 return nCount;
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;
1567 SWAPNIBBLES(aCh)
1568 aCh ^= nMask;
1569 *pTemp = aCh;
1571 return true;
1574 static unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
1576 unsigned char nCryptMask = 0;
1578 if (!nLen)
1579 return nCryptMask;
1581 if( nVersion <= SOFFICE_FILEFORMAT_31 )
1583 while( nLen )
1585 nCryptMask ^= *pStr;
1586 pStr++;
1587 nLen--;
1590 else // BugFix #25888#
1592 for( sal_uInt16 i = 0; i < nLen; i++ ) {
1593 nCryptMask ^= pStr[i];
1594 if( nCryptMask & 0x80 ) {
1595 nCryptMask <<= 1;
1596 nCryptMask++;
1598 else
1599 nCryptMask <<= 1;
1603 if( !nCryptMask )
1604 nCryptMask = 67;
1606 return nCryptMask;
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 )
1618 ClearBuffer();
1619 SvStream::m_nBufFilePos = nNewStreamPos;
1622 void SvStream::SyncSysStream()
1624 Flush();
1625 SeekPos( Tell() );
1628 bool SvStream::SetStreamSize(sal_uInt64 const nSize)
1630 #ifdef DBG_UTIL
1631 sal_uInt64 nFPos = Tell();
1632 #endif
1633 sal_uInt16 nBuf = nBufSize;
1634 SetBufferSize( 0 );
1635 SetSize( nSize );
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');
1648 else
1649 rStr.WriteChar('\r').WriteChar('\n');
1650 return rStr;
1653 SvStream& endlu( SvStream& rStrm )
1655 switch ( rStrm.GetLineDelimiter() )
1657 case LINEEND_CR :
1658 rStrm.WriteUnicode('\r');
1659 break;
1660 case LINEEND_LF :
1661 rStrm.WriteUnicode('\n');
1662 break;
1663 default:
1664 rStrm.WriteUnicode('\r').WriteUnicode('\n');
1666 return rStrm;
1669 SvStream& endlub( SvStream& rStrm )
1671 if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
1672 return endlu( rStrm );
1673 else
1674 return endl( rStrm );
1677 SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
1678 StreamMode eMode )
1680 if( eMode & StreamMode::WRITE )
1681 bIsWritable = true;
1682 else
1683 bIsWritable = false;
1684 nEndOfData = bufSize;
1685 bOwnsData = false;
1686 pBuf = static_cast<sal_uInt8 *>(pBuffer);
1687 nResize = 0L;
1688 nSize = bufSize;
1689 nPos = 0L;
1690 SetBufferSize( 0 );
1693 SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
1695 bIsWritable = true;
1696 bOwnsData = true;
1697 nEndOfData = 0L;
1698 nResize = nResizeOffset;
1699 nPos = 0;
1700 pBuf = 0;
1701 if( nResize != 0 && nResize < 16 )
1702 nResize = 16;
1703 if( nInitSize && !AllocateMemory( nInitSize ) )
1705 SetError( SVSTREAM_OUTOFMEMORY );
1706 nSize = 0;
1708 else
1709 nSize = nInitSize;
1710 SetBufferSize( 64 );
1713 SvMemoryStream::~SvMemoryStream()
1715 if( pBuf )
1717 if( bOwnsData )
1718 FreeMemory();
1719 else
1720 Flush();
1724 const void* SvMemoryStream::GetBuffer()
1726 Flush();
1727 return GetData();
1730 sal_uIntPtr SvMemoryStream::GetSize()
1732 Flush();
1733 sal_uInt64 const nTemp = Tell();
1734 sal_uInt64 const nLength = Seek( STREAM_SEEK_TO_END );
1735 Seek( nTemp );
1736 return nLength;
1739 void* SvMemoryStream::SetBuffer( void* pNewBuf, sal_Size nCount,
1740 bool bOwnsDat, sal_Size nEOF )
1742 void* pResult;
1743 SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
1744 Seek( 0 );
1745 if( bOwnsData )
1747 pResult = 0;
1748 if( pNewBuf != pBuf )
1749 FreeMemory();
1751 else
1752 pResult = pBuf;
1754 pBuf = static_cast<sal_uInt8 *>(pNewBuf);
1755 nPos = 0;
1756 nSize = nCount;
1757 nResize = 0;
1758 bOwnsData = bOwnsDat;
1760 if( nEOF > nCount )
1761 nEOF = nCount;
1762 nEndOfData = nEOF;
1764 ResetError();
1766 return pResult;
1769 sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
1771 sal_Size nMaxCount = nEndOfData-nPos;
1772 if( nCount > nMaxCount )
1773 nCount = nMaxCount;
1774 memcpy( pData, pBuf+nPos, (size_t)nCount );
1775 nPos += nCount;
1776 return nCount;
1779 sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
1781 if( GetError() )
1782 return 0L;
1784 sal_Size nMaxCount = nSize-nPos;
1786 // check for overflow
1787 if( nCount > nMaxCount )
1789 if( nResize == 0 )
1791 // copy as much as possible
1792 nCount = nMaxCount;
1793 SetError( SVSTREAM_OUTOFMEMORY );
1795 else
1797 long nNewResize;
1798 if( nSize && nSize > nResize )
1799 nNewResize = nSize;
1800 else
1801 nNewResize = nResize;
1803 if( (nCount-nMaxCount) < nResize )
1805 // lacking memory is smaller than nResize,
1806 // resize accordingly
1807 if( !ReAllocateMemory( nNewResize) )
1809 nCount = 0;
1810 SetError( SVSTREAM_WRITE_ERROR );
1813 else
1815 // lacking memory is larger than nResize,
1816 // resize by (nCoount-nMaxCount) + resize offset
1817 if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
1819 nCount = 0;
1820 SetError( SVSTREAM_WRITE_ERROR );
1825 assert(pBuf && "Possibly Reallocate failed");
1826 memcpy( pBuf+nPos, pData, (size_t)nCount);
1828 nPos += nCount;
1829 if( nPos > nEndOfData )
1830 nEndOfData = nPos;
1831 return nCount;
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 )
1842 nPos = nNewPos;
1843 else if( nNewPos == STREAM_SEEK_TO_END )
1844 nPos = nEndOfData;
1845 else
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 );
1854 nPos = nNewPos;
1855 nEndOfData = nNewPos;
1857 else // Extension not possible, set pos to end of data
1859 // SetError( SVSTREAM_OUTOFMEMORY );
1860 nPos = nEndOfData;
1863 else // Expand buffer size
1865 nPos = nNewPos;
1866 nEndOfData = nNewPos;
1869 return nPos;
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;
1892 nTemp += nDiff;
1893 sal_Size nNewSize = (sal_Size)nTemp;
1895 if( nNewSize )
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 )
1904 nPos = 0L;
1905 if( nEndOfData >= nNewSize )
1906 nEndOfData = nNewSize-1L;
1908 else
1910 memcpy( pNewBuf, pBuf, (size_t)nSize );
1913 FreeMemory();
1915 pBuf = pNewBuf;
1916 nSize = nNewSize;
1918 else
1920 bRetVal = true;
1921 FreeMemory();
1922 pBuf = 0;
1923 nSize = 0;
1924 nEndOfData = 0;
1925 nPos = 0;
1928 return bRetVal;
1931 void SvMemoryStream::FreeMemory()
1933 delete[] pBuf;
1936 void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
1938 Flush();
1939 if( !bOwnsData )
1940 return 0;
1941 Seek( STREAM_SEEK_TO_BEGIN );
1943 void* pRetVal = pBuf;
1944 pBuf = 0;
1945 nEndOfData = 0L;
1946 nResize = nResizeOffset;
1947 nPos = 0;
1949 if( nResize != 0 && nResize < 16 )
1950 nResize = 16;
1952 ResetError();
1954 if( nInitSize && !AllocateMemory(nInitSize) )
1956 SetError( SVSTREAM_OUTOFMEMORY );
1957 nSize = 0;
1959 else
1960 nSize = nInitSize;
1962 SetBufferSize( 64 );
1963 return pRetVal;
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)
1975 oslProcessError rc;
1976 rc = osl_executeProcess_WithRedirectedIO(
1977 rUrl.pData,
1978 NULL, 0,
1979 osl_Process_HIDDEN,
1980 NULL,
1981 NULL,
1982 NULL, 0,
1983 &mpProcess,
1984 NULL, &mpHandle, NULL);
1985 if (osl_Process_E_None != rc)
1987 mpProcess = NULL;
1988 mpHandle = NULL;
1992 SvScriptStream::~SvScriptStream()
1994 if (mpProcess)
1996 osl_terminateProcess(mpProcess);
1997 osl_freeProcessHandle(mpProcess);
1999 if (mpHandle)
2000 osl_closeFile(mpHandle);
2003 bool SvScriptStream::ReadLine(OString &rStr, sal_Int32)
2005 rStr.clear();
2006 if (!good())
2007 return false;
2009 OStringBuffer sBuf;
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())
2019 return true;
2021 return false;
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;
2039 if (nLen)
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");
2046 if (pStr)
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;
2068 if (nLen)
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");
2075 if (pStr)
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();
2098 namespace
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
2109 while (i < nStrLen)
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
2117 if ( !bConvert )
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'))) )
2126 bConvert = true;
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]) )
2132 ++i;
2134 else
2135 ++nLen;
2136 ++i;
2139 if (!bConvert)
2140 return rIn;
2142 // convert linebreaks, insert string
2143 O aNewData(nLen);
2144 i = 0;
2145 while (i < nStrLen)
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');
2155 else
2157 if ( eLineEnd == LINEEND_CR )
2158 aNewData.append('\r');
2159 else
2160 aNewData.append('\n');
2163 if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
2164 (rIn[i] != rIn[i+1]) )
2165 ++i;
2167 else
2169 aNewData.append(rIn[i]);
2172 ++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()),
2195 "tools.stream",
2196 "string too long for prefix count to fit in output type");
2197 rStrm.WriteUInt32(nUnits);
2198 if (rStrm.good())
2200 nWritten += sizeof(sal_uInt32);
2201 nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
2203 return nWritten;
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(),
2212 "tools.stream",
2213 "string too long for prefix count to fit in output type");
2214 rStrm.WriteUInt16(nUnits);
2215 if (rStrm.good())
2217 nWritten += sizeof(nUnits);
2218 nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
2220 return nWritten;
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()),
2229 "tools.stream",
2230 "string too long for sal_uInt16 count to fit in output type");
2231 rStrm.WriteUInt16( nUnits );
2232 if (rStrm.good())
2234 nWritten += sizeof(sal_uInt16);
2235 nWritten += write_uInt8s_FromOString(rStrm, rStr, nUnits);
2237 return nWritten;
2240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */