| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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( sal_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 = sal_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 = sal_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 = sal_False; |
| bIsConsistent = sal_True; |
| bIsWritable = sal_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 = sal_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 = sal_False; |
| #ifdef OSL_BIGENDIAN |
| if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN ) |
| bSwap = sal_True; |
| #else |
| if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN ) |
| bSwap = sal_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 sal_uInt8[ nBufSize ]; |
| bIsConsistent = sal_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 = sal_False; |
| bIsConsistent = sal_True; |
| eIOMode = STREAM_IO_DONTKNOW; |
| |
| bIsEof = sal_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 = sal_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 = sal_True; |
| return sal_False; |
| } |
| else |
| break; |
| } |
| |
| sal_uInt16 j, n; |
| for( j = n = 0; j < nLen ; ++j ) |
| { |
| c = buf[j]; |
| if ( c == '\n' || c == '\r' ) |
| { |
| bEnd = sal_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 = sal_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 = sal_False; |
| return bEnd; |
| } |
| |
| sal_Bool SvStream::ReadUniStringLine( String& rStr ) |
| { |
| sal_Unicode buf[256+1]; |
| sal_Bool bEnd = sal_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 = sal_True; |
| return sal_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 = sal_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 = sal_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 = sal_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 = sal_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( sal_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( rtl_TextEncoding eReadBomCharSet ) |
| { |
| if (!( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW || |
| eReadBomCharSet == RTL_TEXTENCODING_UNICODE || |
| eReadBomCharSet == RTL_TEXTENCODING_UTF8)) |
| return sal_True; // nothing to read |
| |
| bool bTryUtf8 = false; |
| sal_uInt16 nFlag; |
| sal_sSize nBack = sizeof(nFlag); |
| *this >> nFlag; |
| switch ( nFlag ) |
| { |
| case 0xfeff : |
| // native UTF-16 |
| if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW || |
| eReadBomCharSet == RTL_TEXTENCODING_UNICODE) |
| nBack = 0; |
| break; |
| case 0xfffe : |
| // swapped UTF-16 |
| if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW || |
| eReadBomCharSet == RTL_TEXTENCODING_UNICODE) |
| { |
| SetEndianSwap( !bSwap ); |
| nBack = 0; |
| } |
| break; |
| case 0xefbb : |
| if (nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN && |
| (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW || |
| eReadBomCharSet == RTL_TEXTENCODING_UTF8)) |
| bTryUtf8 = true; |
| break; |
| case 0xbbef : |
| if (nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN && |
| (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW || |
| eReadBomCharSet == RTL_TEXTENCODING_UTF8)) |
| bTryUtf8 = true; |
| break; |
| default: |
| ; // nothing |
| } |
| if (bTryUtf8) |
| { |
| sal_uChar nChar; |
| nBack += sizeof(nChar); |
| *this >> nChar; |
| if (nChar == 0xbf) |
| nBack = 0; // it is UTF-8 |
| } |
| if (nBack) |
| SeekRel( -nBack ); // 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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_False; |
| nBufFree = nBufActualLen - nBufActualPos; |
| if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING ) |
| bIsEof = sal_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 = sal_True; |
| } |
| else |
| { |
| // Flushen ? |
| if( bIsDirty ) |
| { |
| SeekPos( nBufFilePos ); |
| if( nCryptMask ) |
| CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen ); |
| else |
| PutData( pRWBuf, nBufActualLen ); |
| bIsDirty = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_False; |
| } |
| bIsConsistent = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 = sal_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 sal_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 = sal_True; |
| else |
| bIsWritable = sal_False; |
| nEndOfData = bufSize; |
| bOwnsData = sal_False; |
| pBuf = (sal_uInt8 *) 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 = sal_True; |
| bOwnsData = sal_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 = (sal_uInt8 *) 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 sal_uInt8[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 = sal_False; |
| long nTemp = (long)nSize; |
| nTemp += nDiff; |
| sal_Size nNewSize = (sal_Size)nTemp; |
| |
| if( nNewSize ) |
| { |
| sal_uInt8* pNewBuf = new sal_uInt8[nNewSize]; |
| |
| if( pNewBuf ) |
| { |
| bRetVal = sal_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 = sal_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& ) |
| { |
| } |