diff options
Diffstat (limited to 'tools/source/stream/stream.cxx')
-rw-r--r-- | tools/source/stream/stream.cxx | 2841 |
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& ) +{ +} |