summaryrefslogtreecommitdiff
path: root/tools/source/stream/stream.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tools/source/stream/stream.cxx')
-rw-r--r--tools/source/stream/stream.cxx2841
1 files changed, 2841 insertions, 0 deletions
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
new file mode 100644
index 000000000000..9fdef8436f1a
--- /dev/null
+++ b/tools/source/stream/stream.cxx
@@ -0,0 +1,2841 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+// ToDo:
+// - Read->RefreshBuffer->Auf Aenderungen von nBufActualLen reagieren
+
+#include <cstddef>
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h> // isspace
+#include <stdlib.h> // strtol, _crotl
+
+#include "boost/static_assert.hpp"
+
+/*
+#if defined( DBG_UTIL ) && (OSL_DEBUG_LEVEL > 1)
+// prueft Synchronisation des Buffers nach allen Read, Write, Seek
+#define OV_DEBUG
+#endif
+*/
+
+#include <tools/solar.h>
+
+#if defined(BLC)
+#define SWAPNIBBLES(c) c=_crotl(c,4);
+#else
+#define SWAPNIBBLES(c) \
+unsigned char nSwapTmp=c; \
+nSwapTmp <<= 4; \
+c >>= 4; \
+c |= nSwapTmp;
+#endif
+
+#include <tools/debug.hxx>
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+#include <tools/stream.hxx>
+#include <osl/thread.h>
+#include <algorithm>
+
+// -----------------------------------------------------------------------
+
+DBG_NAME( Stream )
+
+// -----------------------------------------------------------------------
+
+// sprintf Param-Mode
+#define SPECIAL_PARAM_NONE 0 // Format-Str, Number
+#define SPECIAL_PARAM_WIDTH 1 // Format-Str, Width, Number
+#define SPECIAL_PARAM_PRECISION 2 // Format-Str, Precision, Number
+#define SPECIAL_PARAM_BOTH 3 // Format-Str, Width, Precision, Number
+
+// -----------------------------------------------------------------------
+
+// !!! Nicht inline, wenn Operatoren <<,>> inline sind
+inline static void SwapUShort( sal_uInt16& r )
+ { r = SWAPSHORT(r); }
+inline static void SwapShort( short& r )
+ { r = SWAPSHORT(r); }
+inline static void SwapLong( long& r )
+ { r = SWAPLONG(r); }
+inline static void SwapULong( sal_uInt32& r )
+ { r = SWAPLONG(r); }
+inline static void SwapLongInt( int& r )
+ { r = SWAPLONG(r); }
+inline static void SwapLongUInt( unsigned int& r )
+ { r = SWAPLONG(r); }
+#ifdef UNX
+inline static void SwapFloat( float& r )
+ {
+ *((sal_uInt32*)(void*)&r) = SWAPLONG( *((sal_uInt32*)(void*)&r) );
+ }
+inline static void SwapDouble( double& r )
+ {
+ if( sizeof(double) != 8 )
+ {
+ DBG_ASSERT( FALSE, "Can only swap 8-Byte-doubles\n" );
+ }
+ else
+ {
+ sal_uInt32* c = (sal_uInt32*)(void*)&r;
+ c[0] ^= c[1]; // zwei 32-Bit-Werte in situ vertauschen
+ c[1] ^= c[0];
+ c[0] ^= c[1];
+ c[0] = SWAPLONG(c[0]); // und die beiden 32-Bit-Werte selbst in situ drehen
+ c[1] = SWAPLONG(c[1]);
+ }
+ }
+#endif
+
+//SDO
+
+#define READNUMBER_WITHOUT_SWAP(datatype,value) \
+{\
+int tmp = eIOMode; \
+if( (tmp == STREAM_IO_READ) && sizeof(datatype)<=nBufFree) \
+{\
+ for (std::size_t i = 0; i < sizeof(datatype); i++)\
+ ((char *)&value)[i] = pBufPos[i];\
+ nBufActualPos += sizeof(datatype);\
+ pBufPos += sizeof(datatype);\
+ nBufFree -= sizeof(datatype);\
+}\
+else\
+ Read( (char*)&value, sizeof(datatype) );\
+}
+
+#define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
+{\
+int tmp = eIOMode; \
+if( (tmp==STREAM_IO_WRITE) && sizeof(datatype) <= nBufFree)\
+{\
+ for (std::size_t i = 0; i < sizeof(datatype); i++)\
+ pBufPos[i] = ((char *)&value)[i];\
+ nBufFree -= sizeof(datatype);\
+ nBufActualPos += sizeof(datatype);\
+ if( nBufActualPos > nBufActualLen )\
+ nBufActualLen = nBufActualPos;\
+ pBufPos += sizeof(datatype);\
+ bIsDirty = TRUE;\
+}\
+else\
+ Write( (char*)&value, sizeof(datatype) );\
+}
+
+//============================================================================
+//
+// class SvLockBytes
+//
+//============================================================================
+
+void SvLockBytes::close()
+{
+ if (m_bOwner)
+ delete m_pStream;
+ m_pStream = 0;
+}
+
+//============================================================================
+TYPEINIT0(SvLockBytes);
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
+ sal_Size * pRead) const
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::ReadAt(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->Seek(nPos);
+ sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
+ if (pRead)
+ *pRead = nTheRead;
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten)
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::WriteAt(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->Seek(nPos);
+ sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
+ if (pWritten)
+ *pWritten = nTheWritten;
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::Flush() const
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::Flush(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->Flush();
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+// virtual
+ErrCode SvLockBytes::SetSize(sal_Size nSize)
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::SetSize(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ m_pStream->SetStreamSize(nSize);
+ return m_pStream->GetErrorCode();
+}
+
+//============================================================================
+ErrCode SvLockBytes::LockRegion(sal_Size, sal_Size, LockType)
+{
+ DBG_ERROR("SvLockBytes::LockRegion(): Not implemented");
+ return ERRCODE_NONE;
+}
+
+//============================================================================
+
+ErrCode SvLockBytes::UnlockRegion(sal_Size, sal_Size, LockType)
+{
+ DBG_ERROR("SvLockBytes::UnlockRegion(): Not implemented");
+ return ERRCODE_NONE;
+}
+
+//============================================================================
+ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
+{
+ if (!m_pStream)
+ {
+ DBG_ERROR("SvLockBytes::Stat(): Bad stream");
+ return ERRCODE_NONE;
+ }
+
+ if (pStat)
+ {
+ sal_Size nPos = m_pStream->Tell();
+ pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
+ m_pStream->Seek(nPos);
+ }
+ return ERRCODE_NONE;
+}
+
+//============================================================================
+//
+// class SvOpenLockBytes
+//
+//============================================================================
+
+TYPEINIT1(SvOpenLockBytes, SvLockBytes);
+
+//============================================================================
+//
+// class SvAsyncLockBytes
+//
+//============================================================================
+
+TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
+
+//============================================================================
+// virtual
+ErrCode SvAsyncLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
+ sal_Size * pRead) const
+{
+ if (m_bTerminated)
+ return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
+ else
+ {
+ sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
+ ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
+ pRead);
+ return !nCount || nTheCount == nCount || nError ? nError :
+ ERRCODE_IO_PENDING;
+ }
+}
+
+//============================================================================
+// virtual
+ErrCode SvAsyncLockBytes::WriteAt(sal_Size nPos, const void * pBuffer,
+ sal_Size nCount, sal_Size * pWritten)
+{
+ if (m_bTerminated)
+ return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
+ else
+ {
+ sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
+ ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
+ pWritten);
+ return !nCount || nTheCount == nCount || nError ? nError :
+ ERRCODE_IO_PENDING;
+ }
+}
+
+//============================================================================
+// virtual
+ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
+ sal_Size * pWritten)
+{
+ sal_Size nTheWritten;
+ ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
+ &nTheWritten);
+ if (!nError)
+ m_nSize += nTheWritten;
+ if (pWritten)
+ *pWritten = nTheWritten;
+ return nError;
+}
+
+//============================================================================
+// virtual
+sal_Size SvAsyncLockBytes::Seek(sal_Size nPos)
+{
+ if (nPos != STREAM_SEEK_TO_END)
+ m_nSize = nPos;
+ return m_nSize;
+}
+
+//============================================================================
+//
+// class SvStream
+//
+//============================================================================
+
+sal_Size SvStream::GetData( void* pData, sal_Size nSize )
+{
+ if( !GetError() )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ sal_Size nRet;
+ nError = xLockBytes->ReadAt( nActPos, pData, nSize, &nRet );
+ nActPos += nRet;
+ return nRet;
+ }
+ else return 0;
+}
+
+ErrCode SvStream::SetLockBytes( SvLockBytesRef& rLB )
+{
+ xLockBytes = rLB;
+ RefreshBuffer();
+ return ERRCODE_NONE;
+}
+
+//========================================================================
+
+sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
+{
+ if( !GetError() )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ sal_Size nRet;
+ nError = xLockBytes->WriteAt( nActPos, pData, nSize, &nRet );
+ nActPos += nRet;
+ return nRet;
+ }
+ else return 0;
+}
+
+//========================================================================
+
+sal_Size SvStream::SeekPos( sal_Size nPos )
+{
+ if( !GetError() && nPos == STREAM_SEEK_TO_END )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ SvLockBytesStat aStat;
+ xLockBytes->Stat( &aStat, SVSTATFLAG_DEFAULT );
+ nActPos = aStat.nSize;
+ }
+ else
+ nActPos = nPos;
+ return nActPos;
+}
+
+//========================================================================
+
+void SvStream::FlushData()
+{
+ if( !GetError() )
+ {
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ nError = xLockBytes->Flush();
+ }
+}
+
+//========================================================================
+
+void SvStream::SetSize( sal_Size nSize )
+{
+ DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
+ nError = xLockBytes->SetSize( nSize );
+}
+
+void SvStream::ImpInit()
+{
+ nActPos = 0;
+ nCompressMode = COMPRESSMODE_NONE;
+ eStreamCharSet = osl_getThreadTextEncoding();
+// eTargetCharSet = osl_getThreadTextEncoding();
+ nCryptMask = 0;
+ bIsEof = FALSE;
+#if defined UNX
+ eLineDelimiter = LINEEND_LF; // UNIX-Format
+#else
+ eLineDelimiter = LINEEND_CRLF; // DOS-Format
+#endif
+
+ SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ nBufFilePos = 0;
+ nBufActualPos = 0;
+ bIsDirty = FALSE;
+ bIsConsistent = TRUE;
+ bIsWritable = TRUE;
+
+ pRWBuf = 0;
+ pBufPos = 0;
+ nBufSize = 0;
+ nBufActualLen = 0;
+ eIOMode = STREAM_IO_DONTKNOW;
+ nBufFree = 0;
+
+ nRadix = 10;
+ nPrecision = 0; // all significant digits
+ nWidth = 0; // default width
+ cFiller = ' ';
+ nJustification = JUSTIFY_RIGHT;
+ eStreamMode = 0;
+ CreateFormatString();
+
+ nVersion = 0;
+
+ ClearError();
+}
+
+/*************************************************************************
+|*
+|* Stream::Stream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream::SvStream( SvLockBytes* pLockBytesP )
+{
+ DBG_CTOR( Stream, NULL );
+
+ ImpInit();
+ xLockBytes = pLockBytesP;
+ const SvStream* pStrm;
+ if( pLockBytesP ) {
+ pStrm = pLockBytesP->GetStream();
+ if( pStrm ) {
+ SetError( pStrm->GetErrorCode() );
+ }
+ }
+ SetBufferSize( 256 );
+}
+
+SvStream::SvStream()
+{
+ DBG_CTOR( Stream, NULL );
+
+ ImpInit();
+}
+
+/*************************************************************************
+|*
+|* Stream::~Stream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream::~SvStream()
+{
+ DBG_DTOR( Stream, NULL );
+
+ if ( xLockBytes.Is() )
+ Flush();
+
+ if( pRWBuf )
+ delete[] pRWBuf;
+}
+
+/*************************************************************************
+|*
+|* Stream::IsA()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_uInt16 SvStream::IsA() const
+{
+ return (sal_uInt16)ID_STREAM;
+}
+
+/*************************************************************************
+|*
+|* Stream::ClearError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::ClearError()
+{
+ bIsEof = FALSE;
+ nError = SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::SetError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SetError( sal_uInt32 nErrorCode )
+{
+ if ( nError == SVSTREAM_OK )
+ nError = nErrorCode;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::SetNumberFormatInt()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SetNumberFormatInt( sal_uInt16 nNewFormat )
+{
+ nNumberFormatInt = nNewFormat;
+ bSwap = FALSE;
+#ifdef OSL_BIGENDIAN
+ if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN )
+ bSwap = TRUE;
+#else
+ if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN )
+ bSwap = TRUE;
+#endif
+}
+
+/*************************************************************************
+|*
+|* Stream::SetBufferSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
+{
+ sal_Size nActualFilePos = Tell();
+ sal_Bool bDontSeek = (sal_Bool)(pRWBuf == 0);
+
+ if( bIsDirty && bIsConsistent && bIsWritable ) // wg. Windows NT: Access denied
+ Flush();
+
+ if( nBufSize )
+ {
+ delete[] pRWBuf;
+ nBufFilePos += nBufActualPos;
+ }
+
+ pRWBuf = 0;
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ nBufSize = nBufferSize;
+ if( nBufSize )
+ pRWBuf = new BYTE[ nBufSize ];
+ bIsConsistent = TRUE;
+ pBufPos = pRWBuf;
+ eIOMode = STREAM_IO_DONTKNOW;
+ if( !bDontSeek )
+ SeekPos( nActualFilePos );
+}
+
+/*************************************************************************
+|*
+|* Stream::ClearBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::ClearBuffer()
+{
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ nBufFilePos = 0;
+ pBufPos = pRWBuf;
+ bIsDirty = FALSE;
+ bIsConsistent = TRUE;
+ eIOMode = STREAM_IO_DONTKNOW;
+
+ bIsEof = FALSE;
+}
+
+/*************************************************************************
+|*
+|* Stream::ResetError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::ResetError()
+{
+ ClearError();
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadLine()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::ReadByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
+{
+ sal_Bool bRet;
+ ByteString aStr;
+
+ bRet = ReadLine(aStr);
+ rStr = UniString( aStr, eSrcCharSet );
+ return bRet;
+}
+
+sal_Bool SvStream::ReadLine( ByteString& rStr )
+{
+ sal_Char buf[256+1];
+ sal_Bool bEnd = FALSE;
+ sal_Size nOldFilePos = Tell();
+ sal_Char c = 0;
+ sal_Size nTotalLen = 0;
+
+ rStr.Erase();
+ while( !bEnd && !GetError() ) // !!! nicht auf EOF testen,
+ // !!! weil wir blockweise
+ // !!! lesen
+ {
+ sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
+ if ( !nLen )
+ {
+ if ( rStr.Len() == 0 )
+ {
+ // der allererste Blockread hat fehlgeschlagen -> Abflug
+ bIsEof = TRUE;
+ return FALSE;
+ }
+ else
+ break;
+ }
+
+ sal_uInt16 j, n;
+ for( j = n = 0; j < nLen ; ++j )
+ {
+ c = buf[j];
+ if ( c == '\n' || c == '\r' )
+ {
+ bEnd = TRUE;
+ break;
+ }
+ // erAck 26.02.01: Old behavior was no special treatment of '\0'
+ // character here, but a following rStr+=c did ignore it. Is this
+ // really intended? Or should a '\0' better terminate a line?
+ // The nOldFilePos stuff wasn't correct then anyways.
+ if ( c )
+ {
+ if ( n < j )
+ buf[n] = c;
+ ++n;
+ }
+ }
+ if ( n )
+ rStr.Append( buf, n );
+ nTotalLen += j;
+ }
+
+ if ( !bEnd && !GetError() && rStr.Len() )
+ bEnd = TRUE;
+
+ nOldFilePos += nTotalLen;
+ if( Tell() > nOldFilePos )
+ nOldFilePos++;
+ Seek( nOldFilePos ); // seeken wg. obigem BlockRead!
+
+ if ( bEnd && (c=='\r' || c=='\n') ) // Sonderbehandlung DOS-Dateien
+ {
+ char cTemp;
+ sal_Size nLen = Read((char*)&cTemp , sizeof(cTemp) );
+ if ( nLen ) {
+ if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
+ Seek( nOldFilePos );
+ }
+ }
+
+ if ( bEnd )
+ bIsEof = FALSE;
+ return bEnd;
+}
+
+sal_Bool SvStream::ReadUniStringLine( String& rStr )
+{
+ sal_Unicode buf[256+1];
+ sal_Bool bEnd = FALSE;
+ sal_Size nOldFilePos = Tell();
+ sal_Unicode c = 0;
+ sal_Size nTotalLen = 0;
+
+ DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
+
+ rStr.Erase();
+ while( !bEnd && !GetError() ) // !!! nicht auf EOF testen,
+ // !!! weil wir blockweise
+ // !!! lesen
+ {
+ sal_uInt16 nLen = (sal_uInt16)Read( (char*)buf, sizeof(buf)-sizeof(sal_Unicode) );
+ nLen /= sizeof(sal_Unicode);
+ if ( !nLen )
+ {
+ if ( rStr.Len() == 0 )
+ {
+ // der allererste Blockread hat fehlgeschlagen -> Abflug
+ bIsEof = TRUE;
+ return FALSE;
+ }
+ else
+ break;
+ }
+
+ sal_uInt16 j, n;
+ for( j = n = 0; j < nLen ; ++j )
+ {
+ if ( bSwap )
+ SwapUShort( buf[n] );
+ c = buf[j];
+ if ( c == '\n' || c == '\r' )
+ {
+ bEnd = TRUE;
+ break;
+ }
+ // erAck 26.02.01: Old behavior was no special treatment of '\0'
+ // character here, but a following rStr+=c did ignore it. Is this
+ // really intended? Or should a '\0' better terminate a line?
+ // The nOldFilePos stuff wasn't correct then anyways.
+ if ( c )
+ {
+ if ( n < j )
+ buf[n] = c;
+ ++n;
+ }
+ }
+ if ( n )
+ rStr.Append( buf, n );
+ nTotalLen += j;
+ }
+
+ if ( !bEnd && !GetError() && rStr.Len() )
+ bEnd = TRUE;
+
+ nOldFilePos += nTotalLen * sizeof(sal_Unicode);
+ if( Tell() > nOldFilePos )
+ nOldFilePos += sizeof(sal_Unicode);
+ Seek( nOldFilePos ); // seeken wg. obigem BlockRead!
+
+ if ( bEnd && (c=='\r' || c=='\n') ) // Sonderbehandlung DOS-Dateien
+ {
+ sal_Unicode cTemp;
+ Read( (char*)&cTemp, sizeof(cTemp) );
+ if ( bSwap )
+ SwapUShort( cTemp );
+ if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
+ Seek( nOldFilePos );
+ }
+
+ if ( bEnd )
+ bIsEof = FALSE;
+ return bEnd;
+}
+
+sal_Bool SvStream::ReadUniOrByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
+{
+ if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
+ return ReadUniStringLine( rStr );
+ else
+ return ReadByteStringLine( rStr, eSrcCharSet );
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadCString
+|*
+*************************************************************************/
+
+sal_Bool SvStream::ReadCString( ByteString& rStr )
+{
+ if( rStr.Len() )
+ rStr.Erase();
+
+ sal_Char buf[ 256 + 1 ];
+ sal_Bool bEnd = FALSE;
+ sal_Size nFilePos = Tell();
+
+ while( !bEnd && !GetError() )
+ {
+ sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
+ sal_uInt16 nReallyRead = nLen;
+ if( !nLen )
+ break;
+
+ const sal_Char* pPtr = buf;
+ while( *pPtr && nLen )
+ ++pPtr, --nLen;
+
+ bEnd = ( nReallyRead < sizeof(buf)-1 ) // read less than attempted to read
+ || ( ( nLen > 0 ) // OR it is inside the block we read
+ && ( 0 == *pPtr ) // AND found a string terminator
+ );
+
+ rStr.Append( buf, ::sal::static_int_cast< xub_StrLen >( pPtr - buf ) );
+ }
+
+ nFilePos += rStr.Len();
+ if( Tell() > nFilePos )
+ nFilePos++;
+ Seek( nFilePos ); // seeken wg. obigem BlockRead!
+ return bEnd;
+}
+
+sal_Bool SvStream::ReadCString( String& rStr, rtl_TextEncoding eToEncode )
+{
+ ByteString sStr;
+ sal_Bool bRet = ReadCString( sStr );
+ rStr = String( sStr, eToEncode );
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::WriteUnicodeText()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteUnicodeText( const String& rStr )
+{
+ DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "WriteUnicodeText: swapping sizeof(sal_Unicode) not implemented" );
+ if ( bSwap )
+ {
+ xub_StrLen nLen = rStr.Len();
+ sal_Unicode aBuf[384];
+ sal_Unicode* const pTmp = ( nLen > 384 ? new sal_Unicode[nLen] : aBuf);
+ memcpy( pTmp, rStr.GetBuffer(), nLen * sizeof(sal_Unicode) );
+ sal_Unicode* p = pTmp;
+ const sal_Unicode* const pStop = pTmp + nLen;
+ while ( p < pStop )
+ {
+ SwapUShort( *p );
+ p++;
+ }
+ Write( (char*)pTmp, nLen * sizeof(sal_Unicode) );
+ if ( pTmp != aBuf )
+ delete [] pTmp;
+ }
+ else
+ Write( (char*)rStr.GetBuffer(), rStr.Len() * sizeof(sal_Unicode) );
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUnicodeOrByteText( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ return WriteUnicodeText( rStr );
+ else
+ {
+ ByteString aStr( rStr, eDestCharSet );
+ Write( aStr.GetBuffer(), aStr.Len() );
+ return nError == SVSTREAM_OK;
+ }
+}
+
+/*************************************************************************
+|*
+|* Stream::WriteLine()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ return WriteLine( ByteString( rStr, eDestCharSet ) );
+}
+
+sal_Bool SvStream::WriteLine( const ByteString& rStr )
+{
+ Write( rStr.GetBuffer(), rStr.Len() );
+ endl(*this);
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUniStringLine( const String& rStr )
+{
+ WriteUnicodeText( rStr );
+ endlu(*this);
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUniOrByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ return WriteUniStringLine( rStr );
+ else
+ return WriteByteStringLine( rStr, eDestCharSet );
+}
+
+/*************************************************************************
+|*
+|* Stream::WriteLines()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 17.07.95
+|* Letzte Aenderung OV 17.07.95
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ return WriteLines( ByteString( rStr, eDestCharSet ) );
+}
+
+sal_Bool SvStream::WriteLines( const ByteString& rStr )
+{
+ ByteString aStr( rStr );
+ aStr.ConvertLineEnd( eLineDelimiter );
+ Write( aStr.GetBuffer(), aStr.Len() );
+ endl( *this );
+ return (sal_Bool)(nError == SVSTREAM_OK);
+}
+
+sal_Bool SvStream::WriteUniStringLines( const String& rStr )
+{
+ String aStr( rStr );
+ aStr.ConvertLineEnd( eLineDelimiter );
+ WriteUniStringLine( aStr );
+ return nError == SVSTREAM_OK;
+}
+
+sal_Bool SvStream::WriteUniOrByteStringLines( const String& rStr, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ return WriteUniStringLines( rStr );
+ else
+ return WriteByteStringLines( rStr, eDestCharSet );
+}
+
+/*************************************************************************
+|*
+|* Stream::WriteUniOrByteChar()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
+{
+ if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
+ *this << ch;
+ else
+ {
+ ByteString aStr( ch, eDestCharSet );
+ Write( aStr.GetBuffer(), aStr.Len() );
+ }
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::StartWritingUnicodeText()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::StartWritingUnicodeText()
+{
+ SetEndianSwap( FALSE ); // write native format
+ // BOM, Byte Order Mark, U+FEFF, see
+ // http://www.unicode.org/faq/utf_bom.html#BOM
+ // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
+ *this << sal_uInt16( 0xfeff );
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::StartReadingUnicodeText()
+|*
+*************************************************************************/
+
+sal_Bool SvStream::StartReadingUnicodeText()
+{
+ sal_uInt16 nFlag;
+ *this >> nFlag;
+ switch ( nFlag )
+ {
+ case 0xfeff :
+ // native
+ break;
+ case 0xfffe :
+ SetEndianSwap( !bSwap );
+ break;
+ default:
+ SeekRel( -((sal_sSize)sizeof(nFlag)) ); // no BOM, pure data
+ }
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadCsvLine()
+|*
+*************************************************************************/
+
+// Precondition: pStr is guaranteed to be non-NULL and points to a 0-terminated
+// array.
+inline const sal_Unicode* lcl_UnicodeStrChr( const sal_Unicode* pStr,
+ sal_Unicode c )
+{
+ while (*pStr)
+ {
+ if (*pStr == c)
+ return pStr;
+ ++pStr;
+ }
+ return 0;
+}
+
+sal_Bool SvStream::ReadCsvLine( String& rStr, sal_Bool bEmbeddedLineBreak,
+ const String& rFieldSeparators, sal_Unicode cFieldQuote,
+ sal_Bool bAllowBackslashEscape)
+{
+ ReadUniOrByteStringLine( rStr);
+
+ if (bEmbeddedLineBreak)
+ {
+ const sal_Unicode* pSeps = rFieldSeparators.GetBuffer();
+ xub_StrLen nLastOffset = 0;
+ xub_StrLen nQuotes = 0;
+ while (!IsEof() && rStr.Len() < STRING_MAXLEN)
+ {
+ bool bBackslashEscaped = false;
+ const sal_Unicode *p, *pStart;
+ p = pStart = rStr.GetBuffer();
+ p += nLastOffset;
+ while (*p)
+ {
+ if (nQuotes)
+ {
+ if (*p == cFieldQuote && !bBackslashEscaped)
+ ++nQuotes;
+ else if (bAllowBackslashEscape)
+ {
+ if (*p == '\\')
+ bBackslashEscaped = !bBackslashEscaped;
+ else
+ bBackslashEscaped = false;
+ }
+ }
+ else if (*p == cFieldQuote && (p == pStart ||
+ lcl_UnicodeStrChr( pSeps, p[-1])))
+ nQuotes = 1;
+ // A quote character inside a field content does not start
+ // a quote.
+ ++p;
+ }
+
+ if (nQuotes % 2 == 0)
+ break;
+ else
+ {
+ nLastOffset = rStr.Len();
+ String aNext;
+ ReadUniOrByteStringLine( aNext);
+ rStr += sal_Unicode(_LF);
+ rStr += aNext;
+ }
+ }
+ }
+ return nError == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* Stream::SeekRel()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::SeekRel( sal_sSize nPos )
+{
+ sal_Size nActualPos = Tell();
+
+ if ( nPos >= 0 )
+ {
+ if ( SAL_MAX_SIZE - nActualPos > (sal_Size)nPos )
+ nActualPos += nPos;
+ }
+ else
+ {
+ sal_Size nAbsPos = (sal_Size)-nPos;
+ if ( nActualPos >= nAbsPos )
+ nActualPos -= nAbsPos;
+ }
+
+ pBufPos = pRWBuf + nActualPos;
+ return Seek( nActualPos );
+}
+
+/*************************************************************************
+|*
+|* Stream::operator>>()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream& SvStream::operator >> ( sal_uInt16& r )
+{
+ READNUMBER_WITHOUT_SWAP(sal_uInt16,r)
+ if( bSwap )
+ SwapUShort(r);
+ return *this;
+}
+
+SvStream& SvStream::operator>> ( sal_uInt32& r )
+{
+ READNUMBER_WITHOUT_SWAP(sal_uInt32,r)
+ if( bSwap )
+ SwapULong(r);
+ return *this;
+}
+
+SvStream& SvStream::operator >> ( long& r )
+{
+#if(SAL_TYPES_SIZEOFLONG != 4)
+ int tmp = r;
+ *this >> tmp;
+ r = tmp;
+#else
+ READNUMBER_WITHOUT_SWAP(long,r)
+ if( bSwap )
+ SwapLong(r);
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator >> ( short& r )
+{
+ READNUMBER_WITHOUT_SWAP(short,r)
+ if( bSwap )
+ SwapShort(r);
+ return *this;
+}
+
+SvStream& SvStream::operator >> ( int& r )
+{
+ READNUMBER_WITHOUT_SWAP(int,r)
+ if( bSwap )
+ SwapLongInt(r);
+ return *this;
+}
+
+SvStream& SvStream::operator>>( signed char& r )
+{
+ if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
+ sizeof(signed char) <= nBufFree )
+ {
+ r = *pBufPos;
+ nBufActualPos += sizeof(signed char);
+ pBufPos += sizeof(signed char);
+ nBufFree -= sizeof(signed char);
+ }
+ else
+ Read( (char*)&r, sizeof(signed char) );
+ return *this;
+}
+
+// Sonderbehandlung fuer Chars wegen PutBack
+
+SvStream& SvStream::operator>>( char& r )
+{
+ if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
+ sizeof(char) <= nBufFree )
+ {
+ r = *pBufPos;
+ nBufActualPos += sizeof(char);
+ pBufPos += sizeof(char);
+ nBufFree -= sizeof(char);
+ }
+ else
+ Read( (char*)&r, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator>>( unsigned char& r )
+{
+ if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
+ sizeof(char) <= nBufFree )
+ {
+ r = *pBufPos;
+ nBufActualPos += sizeof(char);
+ pBufPos += sizeof(char);
+ nBufFree -= sizeof(char);
+ }
+ else
+ Read( (char*)&r, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator>>( float& r )
+{
+ // Read( (char*)&r, sizeof(float) );
+ READNUMBER_WITHOUT_SWAP(float,r)
+#if defined UNX
+ if( bSwap )
+ SwapFloat(r);
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator>>( double& r )
+{
+ // Read( (char*)&r, sizeof(double) );
+ READNUMBER_WITHOUT_SWAP(double,r)
+#if defined UNX
+ if( bSwap )
+ SwapDouble(r);
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator>> ( SvStream& rStream )
+{
+ const sal_uInt32 cBufLen = 0x8000;
+ char* pBuf = new char[ cBufLen ];
+
+ sal_uInt32 nCount;
+ do {
+ nCount = Read( pBuf, cBufLen );
+ rStream.Write( pBuf, nCount );
+ } while( nCount == cBufLen );
+
+ delete[] pBuf;
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::operator<<()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream& SvStream::operator<< ( sal_uInt16 v )
+{
+ if( bSwap )
+ SwapUShort(v);
+ WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( sal_uInt32 v )
+{
+ if( bSwap )
+ SwapULong(v);
+ WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( long v )
+{
+#if(SAL_TYPES_SIZEOFLONG != 4)
+ int tmp = v;
+ *this << tmp;
+#else
+ if( bSwap )
+ SwapLong(v);
+ WRITENUMBER_WITHOUT_SWAP(long,v)
+#endif
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( short v )
+{
+ if( bSwap )
+ SwapShort(v);
+ WRITENUMBER_WITHOUT_SWAP(short,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<<( int v )
+{
+ if( bSwap )
+ SwapLongInt( v );
+ WRITENUMBER_WITHOUT_SWAP(int,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( signed char v )
+{
+ //SDO
+ int tmp = eIOMode;
+ if(tmp == STREAM_IO_WRITE && sizeof(signed char) <= nBufFree )
+ {
+ *pBufPos = v;
+ pBufPos++; // sizeof(char);
+ nBufActualPos++;
+ if( nBufActualPos > nBufActualLen ) // Append ?
+ nBufActualLen = nBufActualPos;
+ nBufFree--; // = sizeof(char);
+ bIsDirty = TRUE;
+ }
+ else
+ Write( (char*)&v, sizeof(signed char) );
+ return *this;
+}
+
+// Sonderbehandlung fuer chars wegen PutBack
+
+SvStream& SvStream::operator<< ( char v )
+{
+ //SDO
+ int tmp = eIOMode;
+ if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
+ {
+ *pBufPos = v;
+ pBufPos++; // sizeof(char);
+ nBufActualPos++;
+ if( nBufActualPos > nBufActualLen ) // Append ?
+ nBufActualLen = nBufActualPos;
+ nBufFree--; // = sizeof(char);
+ bIsDirty = TRUE;
+ }
+ else
+ Write( (char*)&v, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( unsigned char v )
+{
+//SDO
+ int tmp = eIOMode;
+ if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
+ {
+ *(unsigned char*)pBufPos = v;
+ pBufPos++; // = sizeof(char);
+ nBufActualPos++; // = sizeof(char);
+ if( nBufActualPos > nBufActualLen ) // Append ?
+ nBufActualLen = nBufActualPos;
+ nBufFree--;
+ bIsDirty = TRUE;
+ }
+ else
+ Write( (char*)&v, sizeof(char) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( float v )
+{
+#ifdef UNX
+ if( bSwap )
+ SwapFloat(v);
+#endif
+ WRITENUMBER_WITHOUT_SWAP(float,v)
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( const double& r )
+{
+// Write( (char*)&r, sizeof( double ) );
+#if defined UNX
+ if( bSwap )
+ {
+ double nHelp = r;
+ SwapDouble(nHelp);
+ WRITENUMBER_WITHOUT_SWAP(double,nHelp)
+ return *this;
+ }
+ else
+#endif
+ WRITENUMBER_WITHOUT_SWAP(double,r)
+
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( const char* pBuf )
+{
+ Write( pBuf, strlen( pBuf ) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( const unsigned char* pBuf )
+{
+ Write( (char*)pBuf, strlen( (char*)pBuf ) );
+ return *this;
+}
+
+SvStream& SvStream::operator<< ( SvStream& rStream )
+{
+ const sal_uInt32 cBufLen = 0x8000;
+ char* pBuf = new char[ cBufLen ];
+ sal_uInt32 nCount;
+ do {
+ nCount = rStream.Read( pBuf, cBufLen );
+ Write( pBuf, nCount );
+ } while( nCount == cBufLen );
+
+ delete[] pBuf;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::ReadByteString( UniString& rStr, rtl_TextEncoding eSrcCharSet )
+{
+ // read UTF-16 string directly from stream ?
+ if (eSrcCharSet == RTL_TEXTENCODING_UNICODE)
+ {
+ sal_uInt32 nLen;
+ operator>> (nLen);
+ if (nLen)
+ {
+ if (nLen > STRING_MAXLEN) {
+ SetError(SVSTREAM_GENERALERROR);
+ return *this;
+ }
+ sal_Unicode *pStr = rStr.AllocBuffer(
+ static_cast< xub_StrLen >(nLen));
+ BOOST_STATIC_ASSERT(STRING_MAXLEN <= SAL_MAX_SIZE / 2);
+ Read( pStr, nLen << 1 );
+
+ if (bSwap)
+ for (sal_Unicode *pEnd = pStr + nLen; pStr < pEnd; pStr++)
+ SwapUShort(*pStr);
+ }
+ else
+ rStr.Erase();
+
+ return *this;
+ }
+
+ ByteString aStr;
+ ReadByteString( aStr );
+ rStr = UniString( aStr, eSrcCharSet );
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::ReadByteString( ByteString& rStr )
+{
+ sal_uInt16 nLen = 0;
+ operator>>( nLen );
+ if( nLen )
+ {
+ char* pTmp = rStr.AllocBuffer( nLen );
+ nLen = (sal_uInt16)Read( pTmp, nLen );
+ }
+ else
+ rStr.Erase();
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::WriteByteString( const UniString& rStr, rtl_TextEncoding eDestCharSet )
+{
+ // write UTF-16 string directly into stream ?
+ if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
+ {
+ sal_uInt32 nLen = rStr.Len();
+ operator<< (nLen);
+ if (nLen)
+ {
+ if (bSwap)
+ {
+ const sal_Unicode *pStr = rStr.GetBuffer();
+ const sal_Unicode *pEnd = pStr + nLen;
+
+ for (; pStr < pEnd; pStr++)
+ {
+ sal_Unicode c = *pStr;
+ SwapUShort(c);
+ WRITENUMBER_WITHOUT_SWAP(sal_uInt16,c)
+ }
+ }
+ else
+ Write( rStr.GetBuffer(), nLen << 1 );
+ }
+
+ return *this;
+ }
+
+ return WriteByteString(ByteString( rStr, eDestCharSet ));
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& SvStream::WriteByteString( const ByteString& rStr)
+{
+ sal_uInt16 nLen = rStr.Len();
+ operator<< ( nLen );
+ if( nLen != 0 )
+ Write( rStr.GetBuffer(), nLen );
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::Read()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::Read( void* pData, sal_Size nCount )
+{
+ sal_Size nSaveCount = nCount;
+ if( !bIsConsistent )
+ RefreshBuffer();
+
+ if( !pRWBuf )
+ {
+ nCount = GetData( (char*)pData,nCount);
+ if( nCryptMask )
+ EncryptBuffer(pData, nCount);
+ nBufFilePos += nCount;
+ }
+ else
+ {
+ // ist Block komplett im Puffer
+ eIOMode = STREAM_IO_READ;
+ if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
+ {
+ // Ja!
+ memcpy(pData, pBufPos, (size_t) nCount);
+ nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
+ pBufPos += nCount;
+ nBufFree = nBufFree - (sal_uInt16)nCount;
+ }
+ else
+ {
+ if( bIsDirty ) // Flushen ?
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer(pRWBuf, nBufActualLen);
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+
+ // passt der Datenblock in den Puffer ?
+ if( nCount > nBufSize )
+ {
+ // Nein! Deshalb ohne Umweg ueber den Puffer direkt
+ // in den Zielbereich einlesen
+
+ eIOMode = STREAM_IO_DONTKNOW;
+
+ SeekPos( nBufFilePos + nBufActualPos );
+ nBufActualLen = 0;
+ pBufPos = pRWBuf;
+ nCount = GetData( (char*)pData, nCount );
+ if( nCryptMask )
+ EncryptBuffer(pData, nCount);
+ nBufFilePos += nCount;
+ nBufFilePos += nBufActualPos;
+ nBufActualPos = 0;
+ }
+ else
+ {
+ // Der Datenblock passt komplett in den Puffer. Deshalb
+ // Puffer fuellen und dann die angeforderten Daten in den
+ // Zielbereich kopieren.
+
+ nBufFilePos += nBufActualPos;
+ SeekPos( nBufFilePos );
+
+ // TODO: Typecast vor GetData, sal_uInt16 nCountTmp
+ sal_Size nCountTmp = GetData( pRWBuf, nBufSize );
+ if( nCryptMask )
+ EncryptBuffer(pRWBuf, nCountTmp);
+ nBufActualLen = (sal_uInt16)nCountTmp;
+ if( nCount > nCountTmp )
+ {
+ nCount = nCountTmp; // zurueckstutzen, Eof siehe unten
+ }
+ memcpy( pData, pRWBuf, (size_t)nCount );
+ nBufActualPos = (sal_uInt16)nCount;
+ pBufPos = pRWBuf + nCount;
+ }
+ }
+ }
+ bIsEof = FALSE;
+ nBufFree = nBufActualLen - nBufActualPos;
+ if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
+ bIsEof = TRUE;
+ if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
+ nError = ERRCODE_NONE;
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* Stream::Write()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::Write( const void* pData, sal_Size nCount )
+{
+ if( !nCount )
+ return 0;
+ if( !bIsWritable )
+ {
+ SetError( ERRCODE_IO_CANTWRITE );
+ return 0;
+ }
+ if( !bIsConsistent )
+ RefreshBuffer(); // Aenderungen des Puffers durch PutBack loeschen
+
+ if( !pRWBuf )
+ {
+ if( nCryptMask )
+ nCount = CryptAndWriteBuffer( pData, nCount );
+ else
+ nCount = PutData( (char*)pData, nCount );
+ nBufFilePos += nCount;
+ return nCount;
+ }
+
+ eIOMode = STREAM_IO_WRITE;
+ if( nCount <= (sal_Size)(nBufSize - nBufActualPos) )
+ {
+ memcpy( pBufPos, pData, (size_t)nCount );
+ nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
+ // wurde der Puffer erweitert ?
+ if( nBufActualPos > nBufActualLen )
+ nBufActualLen = nBufActualPos;
+
+ pBufPos += nCount;
+ bIsDirty = TRUE;
+ }
+ else
+ {
+ // Flushen ?
+ if( bIsDirty )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+
+ // passt der Block in den Puffer ?
+ if( nCount > nBufSize )
+ {
+ eIOMode = STREAM_IO_DONTKNOW;
+ nBufFilePos += nBufActualPos;
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ pBufPos = pRWBuf;
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ nCount = CryptAndWriteBuffer( pData, nCount );
+ else
+ nCount = PutData( (char*)pData, nCount );
+ nBufFilePos += nCount;
+ }
+ else
+ {
+ // Block in Puffer stellen
+ memcpy( pRWBuf, pData, (size_t)nCount );
+
+ // Reihenfolge!
+ nBufFilePos += nBufActualPos;
+ nBufActualPos = (sal_uInt16)nCount;
+ pBufPos = pRWBuf + nCount;
+ nBufActualLen = (sal_uInt16)nCount;
+ bIsDirty = TRUE;
+ }
+ }
+ nBufFree = nBufSize - nBufActualPos;
+ return nCount;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::Seek()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Size SvStream::Seek( sal_Size nFilePos )
+{
+ eIOMode = STREAM_IO_DONTKNOW;
+
+ bIsEof = FALSE;
+ if( !pRWBuf )
+ {
+ nBufFilePos = SeekPos( nFilePos );
+ DBG_ASSERT(Tell()==nBufFilePos,"Out Of Sync!");
+ return nBufFilePos;
+ }
+
+ // Ist Position im Puffer ?
+ if( nFilePos >= nBufFilePos && nFilePos <= (nBufFilePos + nBufActualLen))
+ {
+ nBufActualPos = (sal_uInt16)(nFilePos - nBufFilePos);
+ pBufPos = pRWBuf + nBufActualPos;
+ // nBufFree korrigieren, damit wir nicht von einem
+ // PutBack (ignoriert den StreamMode) getoetet werden
+ nBufFree = nBufActualLen - nBufActualPos;
+ }
+ else
+ {
+ if( bIsDirty && bIsConsistent)
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+ nBufActualLen = 0;
+ nBufActualPos = 0;
+ pBufPos = pRWBuf;
+ nBufFilePos = SeekPos( nFilePos );
+ }
+#ifdef OV_DEBUG
+ {
+ sal_Size nDebugTemp = nBufFilePos + nBufActualPos;
+ DBG_ASSERT(Tell()==nDebugTemp,"Sync?");
+ }
+#endif
+ return nBufFilePos + nBufActualPos;
+}
+
+/*************************************************************************
+|*
+|* Stream::Flush()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::Flush()
+{
+ if( bIsDirty && bIsConsistent )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
+ else
+ if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
+ SetError( SVSTREAM_WRITE_ERROR );
+ bIsDirty = FALSE;
+ }
+ if( bIsWritable )
+ FlushData();
+}
+
+
+/*************************************************************************
+|*
+|* Stream::PutBack()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 01.08.94
+|* Letzte Aenderung OV 01.08.94
+|*
+*************************************************************************/
+
+/*
+ 4 Faelle :
+
+ 1. Datenzeiger steht mitten im Puffer (nBufActualPos >= 1)
+ 2. Datenzeiger auf Position 0, Puffer ist voll
+ 3. Datenzeiger auf Position 0, Puffer ist teilweise gefuellt
+ 4. Datenzeiger auf Position 0, Puffer ist leer -> Fehler!
+*/
+
+SvStream& SvStream::PutBack( char aCh )
+{
+ // wenn kein Buffer oder Zurueckscrollen nicht moeglich -> Fehler
+ if( !pRWBuf || !nBufActualLen || ( !nBufActualPos && !nBufFilePos ) )
+ {
+ // 4. Fall
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+
+ // Flush() (Phys. Flushen aber nicht notwendig, deshalb selbst schreiben)
+ if( bIsConsistent && bIsDirty )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+ bIsConsistent = FALSE; // Puffer enthaelt jetzt TRASH
+ if( nBufActualPos )
+ {
+ // 1. Fall
+ nBufActualPos--;
+ pBufPos--;
+ *pBufPos = aCh;
+ nBufFree++;
+ }
+ else // Puffer muss verschoben werden
+ {
+ // Ist Puffer am Anschlag ?
+ if( nBufSize == nBufActualLen )
+ {
+ // 2. Fall
+ memmove( pRWBuf+1, pRWBuf, nBufSize-1 );
+ // nBufFree behaelt den Wert!
+ }
+ else
+ {
+ // 3. Fall -> Puffer vergroessern
+ memmove( pRWBuf+1, pRWBuf, (sal_uInt16)nBufActualLen );
+ nBufActualLen++;
+ nBufFree++;
+ }
+ nBufFilePos--;
+ *pRWBuf = aCh;
+ }
+ eIOMode = STREAM_IO_DONTKNOW;
+ bIsEof = FALSE;
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::EatWhite()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 01.08.94
+|* Letzte Aenderung OV 01.08.94
+|*
+*************************************************************************/
+
+void SvStream::EatWhite()
+{
+ char aCh;
+ Read(&aCh, sizeof(char) );
+ while( !bIsEof && isspace((int)aCh) ) //( aCh == ' ' || aCh == '\t' ) )
+ Read(&aCh, sizeof(char) );
+ if( !bIsEof ) // konnte das letzte Char gelesen werden ?
+ SeekRel( -1L );
+}
+
+/*************************************************************************
+|*
+|* Stream::RefreshBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 01.08.94
+|* Letzte Aenderung OV 01.08.94
+|*
+*************************************************************************/
+
+void SvStream::RefreshBuffer()
+{
+ if( bIsDirty && bIsConsistent )
+ {
+ SeekPos( nBufFilePos );
+ if( nCryptMask )
+ CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
+ else
+ PutData( pRWBuf, nBufActualLen );
+ bIsDirty = FALSE;
+ }
+ SeekPos( nBufFilePos );
+ nBufActualLen = (sal_uInt16)GetData( pRWBuf, nBufSize );
+ if( nBufActualLen && nError == ERRCODE_IO_PENDING )
+ nError = ERRCODE_NONE;
+ if( nCryptMask )
+ EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
+ bIsConsistent = TRUE;
+ eIOMode = STREAM_IO_DONTKNOW;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::CreateFormatString()
+|*
+|* Beschreibung Baut Formatstring zusammen
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::CreateFormatString()
+{
+ aFormatString = '%';
+ nPrintfParams = SPECIAL_PARAM_NONE;
+
+ if( nJustification )
+ {
+ aFormatString += '-';
+ }
+
+ if( nWidth )
+ {
+ if( cFiller != ' ' )
+ aFormatString += '0';
+ aFormatString += '*';
+ nPrintfParams = SPECIAL_PARAM_WIDTH;
+ }
+
+ if( nPrecision )
+ {
+ aFormatString += ".*";
+ if( nWidth )
+ nPrintfParams = SPECIAL_PARAM_BOTH;
+ else
+ nPrintfParams = SPECIAL_PARAM_PRECISION;
+ }
+}
+
+/*************************************************************************
+|*
+|* Stream::ReadNumber()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+#define BUFSIZE_LONG 21 // log( 2 hoch 64 ) + 1
+
+SvStream& SvStream::ReadNumber( long& rLong )
+{
+ EatWhite();
+ if( bIsEof || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ sal_Size nFPtr = Tell();
+ char buf[ BUFSIZE_LONG ];
+ memset( buf, 0, BUFSIZE_LONG );
+ sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
+ if( !nTemp || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ char *pEndPtr;
+ rLong = strtol( buf, &pEndPtr, (int)nRadix );
+ nFPtr += ( (sal_Size)pEndPtr - (sal_Size)(&(buf[0])) );
+ Seek( nFPtr );
+ bIsEof = FALSE;
+ return *this;
+}
+
+SvStream& SvStream::ReadNumber( sal_uInt32& rUInt32 )
+{
+ EatWhite();
+ if( bIsEof || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ sal_Size nFPtr = Tell();
+ char buf[ BUFSIZE_LONG ];
+ memset( buf, 0, BUFSIZE_LONG );
+ sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
+ if( !nTemp || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ char *pEndPtr;
+ rUInt32 = strtoul( buf, &pEndPtr, (int)nRadix );
+ nFPtr += ( (sal_uIntPtr)pEndPtr - (sal_uIntPtr)buf );
+ Seek( nFPtr );
+ bIsEof = FALSE;
+ return *this;
+}
+
+SvStream& SvStream::ReadNumber( double& rDouble )
+{
+ EatWhite();
+ if( bIsEof || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ sal_Size nFPtr = Tell();
+ char buf[ BUFSIZE_LONG ];
+ memset( buf, 0, BUFSIZE_LONG );
+ sal_Size nTemp = Read( buf, BUFSIZE_LONG-1 );
+ if( !nTemp || nError )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ return *this;
+ }
+ char *pEndPtr;
+ rDouble = strtod( buf, &pEndPtr );
+ nFPtr += ( (sal_Size)pEndPtr - (sal_Size)buf );
+ Seek( nFPtr );
+ bIsEof = FALSE;
+ return *this;
+}
+
+
+/*************************************************************************
+|*
+|* Stream::WriteNumber()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+SvStream& SvStream::WriteNumber( long nLong )
+{
+ char buffer[256+12];
+ char pType[] = "ld"; // Nicht static!
+ if( nRadix == 16 )
+ pType[1] = 'x';
+ else if( nRadix == 8 )
+ pType[1] = 'o';
+ ByteString aFStr( aFormatString);
+ aFStr += pType;
+ int nLen;
+ switch ( nPrintfParams )
+ {
+ case SPECIAL_PARAM_NONE :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nLong );
+ break;
+ case SPECIAL_PARAM_WIDTH :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, nLong );
+ break;
+ case SPECIAL_PARAM_PRECISION :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision,nLong);
+ break;
+ default:
+ nLen=sprintf(buffer, aFStr.GetBuffer(),nWidth,nPrecision,nLong);
+ }
+ Write( buffer, (long)nLen );
+ return *this;
+}
+
+SvStream& SvStream::WriteNumber( sal_uInt32 nUInt32 )
+{
+ char buffer[256+12];
+ char pType[] = "lu"; // Nicht static!
+ if( nRadix == 16 )
+ pType[1] = 'x';
+ else if( nRadix == 8 )
+ pType[1] = 'o';
+ ByteString aFStr( aFormatString);
+ aFStr += pType;
+ int nLen;
+ switch ( nPrintfParams )
+ {
+ case SPECIAL_PARAM_NONE :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nUInt32 );
+ break;
+ case SPECIAL_PARAM_WIDTH :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, nUInt32 );
+ break;
+ case SPECIAL_PARAM_PRECISION :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision, nUInt32 );
+ break;
+ default:
+ nLen=sprintf(buffer,aFStr.GetBuffer(),nWidth,nPrecision,nUInt32 );
+ }
+ Write( buffer, (long)nLen );
+ return *this;
+}
+
+
+SvStream& SvStream::WriteNumber( const double& rDouble )
+{
+ char buffer[256+24];
+ ByteString aFStr( aFormatString);
+ aFStr += "lf";
+ int nLen;
+ switch ( nPrintfParams )
+ {
+ case SPECIAL_PARAM_NONE :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), rDouble );
+ break;
+ case SPECIAL_PARAM_WIDTH :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nWidth, rDouble );
+ break;
+ case SPECIAL_PARAM_PRECISION :
+ nLen = sprintf( buffer, aFStr.GetBuffer(), nPrecision, rDouble);
+ break;
+ default:
+ nLen=sprintf(buffer, aFStr.GetBuffer(),nWidth,nPrecision,rDouble);
+ }
+ Write( buffer, (long)nLen );
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* Stream::CryptAndWriteBuffer()
+|*
+|* Beschreibung Verschluesseln und Schreiben
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+#define CRYPT_BUFSIZE 1024
+
+sal_Size SvStream::CryptAndWriteBuffer( const void* pStart, sal_Size nLen)
+{
+ unsigned char pTemp[CRYPT_BUFSIZE];
+ unsigned char* pDataPtr = (unsigned char*)pStart;
+ sal_Size nCount = 0;
+ sal_Size nBufCount;
+ unsigned char nMask = nCryptMask;
+ do
+ {
+ if( nLen >= CRYPT_BUFSIZE )
+ nBufCount = CRYPT_BUFSIZE;
+ else
+ nBufCount = nLen;
+ nLen -= nBufCount;
+ memcpy( pTemp, pDataPtr, (sal_uInt16)nBufCount );
+ // **** Verschluesseln *****
+ for ( sal_uInt16 n=0; n < CRYPT_BUFSIZE; n++ )
+ {
+ unsigned char aCh = pTemp[n];
+ aCh ^= nMask;
+ SWAPNIBBLES(aCh)
+ pTemp[n] = aCh;
+ }
+ // *************************
+ nCount += PutData( (char*)pTemp, nBufCount );
+ pDataPtr += nBufCount;
+ }
+ while ( nLen );
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* Stream::EncryptBuffer()
+|*
+|* Beschreibung Buffer entschluesseln
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::EncryptBuffer(void* pStart, sal_Size nLen)
+{
+ unsigned char* pTemp = (unsigned char*)pStart;
+ unsigned char nMask = nCryptMask;
+
+ for ( sal_Size n=0; n < nLen; n++, pTemp++ )
+ {
+ unsigned char aCh = *pTemp;
+ SWAPNIBBLES(aCh)
+ aCh ^= nMask;
+ *pTemp = aCh;
+ }
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* Stream::SetKey()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
+{
+ unsigned char nCryptMask = 0;
+
+ if (!nLen)
+ return nCryptMask;
+
+ if( nVersion <= SOFFICE_FILEFORMAT_31 )
+ {
+ while( nLen )
+ {
+ nCryptMask ^= *pStr;
+ pStr++;
+ nLen--;
+ }
+ }
+ else // BugFix #25888#
+ {
+ for( sal_uInt16 i = 0; i < nLen; i++ ) {
+ nCryptMask ^= pStr[i];
+ if( nCryptMask & 0x80 ) {
+ nCryptMask <<= 1;
+ nCryptMask++;
+ }
+ else
+ nCryptMask <<= 1;
+ }
+ }
+
+ if( !nCryptMask )
+ nCryptMask = 67;
+
+ return nCryptMask;
+}
+
+void SvStream::SetKey( const ByteString& rKey )
+{
+ aKey = rKey;
+ nCryptMask = implGetCryptMask( aKey.GetBuffer(), aKey.Len(), GetVersion() );
+}
+
+/*************************************************************************
+|*
+|* Stream::SyncSvStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SyncSvStream( sal_Size nNewStreamPos )
+{
+ ClearBuffer();
+ SvStream::nBufFilePos = nNewStreamPos;
+}
+
+/*************************************************************************
+|*
+|* Stream::SyncSysStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+void SvStream::SyncSysStream()
+{
+ Flush();
+ SeekPos( Tell() );
+}
+
+/*************************************************************************
+|*
+|* Stream::SetStreamSize()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung OV 08.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvStream::SetStreamSize( sal_Size nSize )
+{
+#ifdef DBG_UTIL
+ sal_Size nFPos = Tell();
+#endif
+ sal_uInt16 nBuf = nBufSize;
+ SetBufferSize( 0 );
+ SetSize( nSize );
+ SetBufferSize( nBuf );
+ DBG_ASSERT(Tell()==nFPos,"SetStreamSize failed");
+ return (sal_Bool)(nError == 0);
+}
+
+//============================================================================
+
+void SvStream::AddMark( sal_Size )
+{
+}
+
+//============================================================================
+
+void SvStream::RemoveMark( sal_Size )
+{
+}
+
+/*************************************************************************
+|*
+|* endl()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 08.06.94
+|* Letzte Aenderung TH 13.11.96
+|*
+*************************************************************************/
+
+SvStream& endl( SvStream& rStr )
+{
+ LineEnd eDelim = rStr.GetLineDelimiter();
+ if ( eDelim == LINEEND_CR )
+ rStr << _CR;
+ else if( eDelim == LINEEND_LF )
+ rStr << _LF;
+ else
+ rStr << _CR << _LF;
+ return rStr;
+}
+
+SvStream& endlu( SvStream& rStrm )
+{
+ switch ( rStrm.GetLineDelimiter() )
+ {
+ case LINEEND_CR :
+ rStrm << sal_Unicode(_CR);
+ break;
+ case LINEEND_LF :
+ rStrm << sal_Unicode(_LF);
+ break;
+ default:
+ rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
+ }
+ return rStrm;
+}
+
+SvStream& endlub( SvStream& rStrm )
+{
+ if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ return endlu( rStrm );
+ else
+ return endl( rStrm );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SvMemoryStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
+ StreamMode eMode )
+{
+ if( eMode & STREAM_WRITE )
+ bIsWritable = TRUE;
+ else
+ bIsWritable = FALSE;
+ nEndOfData = bufSize;
+ bOwnsData = FALSE;
+ pBuf = (BYTE *) pBuffer;
+ nResize = 0L;
+ nSize = bufSize;
+ nPos = 0L;
+ SetBufferSize( 0 );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SvMemoryStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
+{
+ bIsWritable = TRUE;
+ bOwnsData = TRUE;
+ nEndOfData = 0L;
+ nResize = nResizeOffset;
+ nPos = 0;
+ pBuf = 0;
+ if( nResize != 0 && nResize < 16 )
+ nResize = 16;
+ if( nInitSize && !AllocateMemory( nInitSize ) )
+ {
+ SetError( SVSTREAM_OUTOFMEMORY );
+ nSize = 0;
+ }
+ else
+ nSize = nInitSize;
+ SetBufferSize( 64 );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::~SvMemoryStream()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+SvMemoryStream::~SvMemoryStream()
+{
+ if( pBuf )
+ {
+ if( bOwnsData )
+ FreeMemory();
+ else
+ Flush();
+ }
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::IsA()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_uInt16 SvMemoryStream::IsA() const
+{
+ return (sal_uInt16)ID_MEMORYSTREAM;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SetBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+void* SvMemoryStream::SetBuffer( void* pNewBuf, sal_Size nCount,
+ sal_Bool bOwnsDat, sal_Size nEOF )
+{
+ void* pResult;
+ SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
+ Seek( 0 );
+ if( bOwnsData )
+ {
+ pResult = 0;
+ if( pNewBuf != pBuf )
+ FreeMemory();
+ }
+ else
+ pResult = pBuf;
+
+ pBuf = (BYTE *) pNewBuf;
+ nPos = 0;
+ nSize = nCount;
+ nResize = 0;
+ bOwnsData = bOwnsDat;
+
+ if( nEOF > nCount )
+ nEOF = nCount;
+ nEndOfData = nEOF;
+
+ ResetError();
+
+ DBG_ASSERT( nEndOfData<STREAM_SEEK_TO_END,"Invalid EOF");
+ return pResult;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::GetData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
+{
+ sal_Size nMaxCount = nEndOfData-nPos;
+ if( nCount > nMaxCount )
+ nCount = nMaxCount;
+ memcpy( pData, pBuf+nPos, (size_t)nCount );
+ nPos += nCount;
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::PutData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
+{
+ if( GetError() )
+ return 0L;
+
+ sal_Size nMaxCount = nSize-nPos;
+
+ // auf Ueberlauf testen
+ if( nCount > nMaxCount )
+ {
+ if( nResize == 0 )
+ {
+ // soviel wie moeglich rueberschaufeln
+ nCount = nMaxCount;
+ SetError( SVSTREAM_OUTOFMEMORY );
+ }
+ else
+ {
+ long nNewResize;
+ if( nSize && nSize > nResize )
+ nNewResize = nSize;
+ else
+ nNewResize = nResize;
+
+ if( (nCount-nMaxCount) < nResize )
+ {
+ // fehlender Speicher ist kleiner als Resize-Offset,
+ // deshalb um Resize-Offset vergroessern
+ if( !ReAllocateMemory( nNewResize) )
+ {
+ nCount = 0;
+ SetError( SVSTREAM_WRITE_ERROR );
+ }
+ }
+ else
+ {
+ // fehlender Speicher ist groesser als Resize-Offset
+ // deshalb um Differenz+ResizeOffset vergroessern
+ if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
+ {
+ nCount = 0;
+ SetError( SVSTREAM_WRITE_ERROR );
+ }
+ }
+ }
+ }
+ DBG_ASSERT(pBuf,"Possibly Reallocate failed");
+ memcpy( pBuf+nPos, pData, (size_t)nCount);
+
+ nPos += nCount;
+ if( nPos > nEndOfData )
+ nEndOfData = nPos;
+ return nCount;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SeekPos()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+// nEndOfData: Erste Position im Stream, die nicht gelesen werden darf
+// nSize: Groesse des allozierten Speichers
+
+sal_Size SvMemoryStream::SeekPos( sal_Size nNewPos )
+{
+ if( nNewPos < nEndOfData )
+ nPos = nNewPos;
+ else if( nNewPos == STREAM_SEEK_TO_END )
+ nPos = nEndOfData;
+ else
+ {
+ if( nNewPos >= nSize ) // muss Buffer vergroessert werden ?
+ {
+ if( nResize ) // ist vergroeseern erlaubt ?
+ {
+ long nDiff = (long)(nNewPos - nSize + 1);
+ nDiff += (long)nResize;
+ ReAllocateMemory( nDiff );
+ nPos = nNewPos;
+ nEndOfData = nNewPos;
+ }
+ else // vergroessern ist nicht erlaubt -> ans Ende setzen
+ {
+ // SetError( SVSTREAM_OUTOFMEMORY );
+ nPos = nEndOfData;
+ }
+ }
+ else // gueltigen Bereich innerhalb des Buffers vergroessern
+ {
+ nPos = nNewPos;
+ nEndOfData = nNewPos;
+ }
+ }
+ return nPos;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::FlushData()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+void SvMemoryStream::FlushData()
+{
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::ResetError()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+void SvMemoryStream::ResetError()
+{
+ SvStream::ClearError();
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::AllocateMemory()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvMemoryStream::AllocateMemory( sal_Size nNewSize )
+{
+ pBuf = new BYTE[nNewSize];
+ return( pBuf != 0 );
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::ReAllocateMemory() (Bozo-Algorithmus)
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 20.06.94
+|* Letzte Aenderung OV 20.06.94
+|*
+*************************************************************************/
+
+sal_Bool SvMemoryStream::ReAllocateMemory( long nDiff )
+{
+ sal_Bool bRetVal = FALSE;
+ long nTemp = (long)nSize;
+ nTemp += nDiff;
+ sal_Size nNewSize = (sal_Size)nTemp;
+
+ if( nNewSize )
+ {
+ BYTE* pNewBuf = new BYTE[nNewSize];
+
+ if( pNewBuf )
+ {
+ bRetVal = TRUE; // Success!
+ if( nNewSize < nSize ) // Verkleinern ?
+ {
+ memcpy( pNewBuf, pBuf, (size_t)nNewSize );
+ if( nPos > nNewSize )
+ nPos = 0L;
+ if( nEndOfData >= nNewSize )
+ nEndOfData = nNewSize-1L;
+ }
+ else
+ {
+ memcpy( pNewBuf, pBuf, (size_t)nSize );
+ }
+
+ FreeMemory();
+
+ pBuf = pNewBuf;
+ nSize = nNewSize;
+ }
+ }
+ else
+ {
+ bRetVal = TRUE;
+ FreeMemory();
+ pBuf = 0;
+ nSize = 0;
+ nEndOfData = 0;
+ nPos = 0;
+ }
+
+ return bRetVal;
+}
+
+void SvMemoryStream::FreeMemory()
+{
+ delete[] pBuf;
+}
+
+/*************************************************************************
+|*
+|* SvMemoryStream::SwitchBuffer()
+|*
+|* Beschreibung STREAM.SDW
+|* Ersterstellung OV 26.07.94
+|* Letzte Aenderung OV 26.07.94
+|*
+*************************************************************************/
+
+void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
+{
+ Flush();
+ if( !bOwnsData )
+ return 0;
+ Seek( STREAM_SEEK_TO_BEGIN );
+
+ void* pRetVal = pBuf;
+ pBuf = 0;
+ nEndOfData = 0L;
+ nResize = nResizeOffset;
+ nPos = 0;
+
+ if( nResize != 0 && nResize < 16 )
+ nResize = 16;
+
+ ResetError();
+
+ if( nInitSize && !AllocateMemory(nInitSize) )
+ {
+ SetError( SVSTREAM_OUTOFMEMORY );
+ nSize = 0;
+ }
+ else
+ nSize = nInitSize;
+
+ SetBufferSize( 64 );
+ return pRetVal;
+}
+
+void SvMemoryStream::SetSize( sal_Size nNewSize )
+{
+ long nDiff = (long)nNewSize - (long)nSize;
+ ReAllocateMemory( nDiff );
+}
+
+TYPEINIT0 ( SvDataCopyStream )
+
+void SvDataCopyStream::Assign( const SvDataCopyStream& )
+{
+}