LCOV - code coverage report
Current view: top level - libreoffice/tools/source/stream - stream.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 680 1090 62.4 %
Date: 2012-12-27 Functions: 80 139 57.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : // TODO: Read->RefreshBuffer-> React to changes from nBufActualLen
      21             : 
      22             : #include <cstddef>
      23             : 
      24             : #include <string.h>
      25             : #include <stdio.h>
      26             : #include <ctype.h>  // isspace
      27             : #include <stdlib.h> // strtol, _crotl
      28             : 
      29             : #include "boost/static_assert.hpp"
      30             : 
      31             : #include <tools/solar.h>
      32             : #include <osl/endian.h>
      33             : 
      34             : #include <comphelper/string.hxx>
      35             : 
      36             : #define SWAPNIBBLES(c)      \
      37             : unsigned char nSwapTmp=c;   \
      38             : nSwapTmp <<= 4;             \
      39             : c >>= 4;                    \
      40             : c |= nSwapTmp;
      41             : 
      42             : #include <tools/debug.hxx>
      43             : #include <tools/stream.hxx>
      44             : #include <osl/thread.h>
      45             : #include <algorithm>
      46             : 
      47             : DBG_NAME( Stream )
      48             : 
      49             : // !!! Do not inline if already the operators <<,>> are inline
      50        1838 : inline static void SwapUShort( sal_uInt16& r )
      51        1838 :     {   r = OSL_SWAPWORD(r);   }
      52        2836 : inline static void SwapShort( short& r )
      53        2836 :     {   r = OSL_SWAPWORD(r);   }
      54             : inline static void SwapLong( long& r )
      55             :     {   r = OSL_SWAPDWORD(r);   }
      56        1422 : inline static void SwapULong( sal_uInt32& r )
      57        1422 :     {   r = OSL_SWAPDWORD(r);   }
      58         130 : inline static void SwapLongInt( sal_Int32& r )
      59         130 :     {   r = OSL_SWAPDWORD(r);   }
      60             : inline static void SwapLongUInt( unsigned int& r )
      61             :     {   r = OSL_SWAPDWORD(r);   }
      62             : 
      63           0 : inline static void SwapUInt64( sal_uInt64& r )
      64             :     {
      65             :         union
      66             :         {
      67             :             sal_uInt64 n;
      68             :             sal_uInt32 c[2];
      69             :         } s;
      70             : 
      71           0 :         s.n = r;
      72           0 :         s.c[0] ^= s.c[1]; // swap the 32 bit words
      73           0 :         s.c[1] ^= s.c[0];
      74           0 :         s.c[0] ^= s.c[1];
      75             :         // swap the bytes in the words
      76           0 :         s.c[0] = OSL_SWAPDWORD(s.c[0]);
      77           0 :         s.c[1] = OSL_SWAPDWORD(s.c[1]);
      78           0 :         r = s.n;
      79           0 :     }
      80           0 : inline static void SwapInt64( sal_Int64& r )
      81             :     {
      82             :         union
      83             :         {
      84             :             sal_Int64 n;
      85             :             sal_Int32 c[2];
      86             :         } s;
      87             : 
      88           0 :         s.n = r;
      89           0 :         s.c[0] ^= s.c[1]; // swap the 32 bit words
      90           0 :         s.c[1] ^= s.c[0];
      91           0 :         s.c[0] ^= s.c[1];
      92             :         // swap the bytes in the words
      93           0 :         s.c[0] = OSL_SWAPDWORD(s.c[0]);
      94           0 :         s.c[1] = OSL_SWAPDWORD(s.c[1]);
      95           0 :         r = s.n;
      96           0 :     }
      97             : 
      98             : #ifdef UNX
      99           0 : inline static void SwapFloat( float& r )
     100             :     {
     101             :         union
     102             :         {
     103             :             float f;
     104             :             sal_uInt32 c;
     105             :         } s;
     106             : 
     107           0 :         s.f = r;
     108           0 :         s.c = OSL_SWAPDWORD( s.c );
     109           0 :         r = s.f;
     110           0 :     }
     111             : 
     112           0 : inline static void SwapDouble( double& r )
     113             :     {
     114             :         if( sizeof(double) != 8 )
     115             :         {
     116             :           DBG_ASSERT( sal_False, "Can only swap 8-Byte-doubles\n" );
     117             :         }
     118             :         else
     119             :         {
     120             :             union
     121             :             {
     122             :                 double d;
     123             :                 sal_uInt32 c[2];
     124             :             } s;
     125             : 
     126           0 :             s.d = r;
     127           0 :             s.c[0] ^= s.c[1]; // swap 32-bit values in situ
     128           0 :             s.c[1] ^= s.c[0];
     129           0 :             s.c[0] ^= s.c[1];
     130           0 :             s.c[0] = OSL_SWAPDWORD(s.c[0]); // swap dword itself in situ
     131           0 :             s.c[1] = OSL_SWAPDWORD(s.c[1]);
     132           0 :             r = s.d;
     133             :         }
     134           0 :     }
     135             : #endif
     136             : 
     137             : //SDO
     138             : 
     139             : #define READNUMBER_WITHOUT_SWAP(datatype,value) \
     140             : {\
     141             : int tmp = eIOMode; \
     142             : if( (tmp == STREAM_IO_READ) && sizeof(datatype)<=nBufFree) \
     143             : {\
     144             :     for (std::size_t i = 0; i < sizeof(datatype); i++)\
     145             :         ((char *)&value)[i] = pBufPos[i];\
     146             :     nBufActualPos += sizeof(datatype);\
     147             :     pBufPos += sizeof(datatype);\
     148             :     nBufFree -= sizeof(datatype);\
     149             : }\
     150             : else\
     151             :     Read( (char*)&value, sizeof(datatype) );\
     152             : }
     153             : 
     154             : #define WRITENUMBER_WITHOUT_SWAP(datatype,value) \
     155             : {\
     156             : int tmp = eIOMode; \
     157             : if( (tmp==STREAM_IO_WRITE) && sizeof(datatype) <= nBufFree)\
     158             : {\
     159             :     for (std::size_t i = 0; i < sizeof(datatype); i++)\
     160             :         pBufPos[i] = ((char *)&value)[i];\
     161             :     nBufFree -= sizeof(datatype);\
     162             :     nBufActualPos += sizeof(datatype);\
     163             :     if( nBufActualPos > nBufActualLen )\
     164             :         nBufActualLen = nBufActualPos;\
     165             :     pBufPos += sizeof(datatype);\
     166             :     bIsDirty = sal_True;\
     167             : }\
     168             : else\
     169             :     Write( (char*)&value, sizeof(datatype) );\
     170             : }
     171             : 
     172             : //  class SvLockBytes
     173             : 
     174        4925 : void SvLockBytes::close()
     175             : {
     176        4925 :     if (m_bOwner)
     177           0 :         delete m_pStream;
     178        4925 :     m_pStream = 0;
     179        4925 : }
     180             : 
     181           0 : TYPEINIT0(SvLockBytes);
     182             : 
     183             : // virtual
     184           0 : ErrCode SvLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
     185             :                             sal_Size * pRead) const
     186             : {
     187           0 :     if (!m_pStream)
     188             :     {
     189             :         OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
     190           0 :         return ERRCODE_NONE;
     191             :     }
     192             : 
     193           0 :     m_pStream->Seek(nPos);
     194           0 :     sal_Size nTheRead = m_pStream->Read(pBuffer, nCount);
     195           0 :     if (pRead)
     196           0 :         *pRead = nTheRead;
     197           0 :     return m_pStream->GetErrorCode();
     198             : }
     199             : 
     200             : // virtual
     201           0 : ErrCode SvLockBytes::WriteAt(sal_Size nPos, const void * pBuffer, sal_Size nCount,
     202             :                              sal_Size * pWritten)
     203             : {
     204           0 :     if (!m_pStream)
     205             :     {
     206             :         OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
     207           0 :         return ERRCODE_NONE;
     208             :     }
     209             : 
     210           0 :     m_pStream->Seek(nPos);
     211           0 :     sal_Size nTheWritten = m_pStream->Write(pBuffer, nCount);
     212           0 :     if (pWritten)
     213           0 :         *pWritten = nTheWritten;
     214           0 :     return m_pStream->GetErrorCode();
     215             : }
     216             : 
     217             : // virtual
     218           0 : ErrCode SvLockBytes::Flush() const
     219             : {
     220           0 :     if (!m_pStream)
     221             :     {
     222             :         OSL_FAIL("SvLockBytes::Flush(): Bad stream");
     223           0 :         return ERRCODE_NONE;
     224             :     }
     225             : 
     226           0 :     m_pStream->Flush();
     227           0 :     return m_pStream->GetErrorCode();
     228             : }
     229             : 
     230             : // virtual
     231           0 : ErrCode SvLockBytes::SetSize(sal_Size nSize)
     232             : {
     233           0 :     if (!m_pStream)
     234             :     {
     235             :         OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
     236           0 :         return ERRCODE_NONE;
     237             :     }
     238             : 
     239           0 :     m_pStream->SetStreamSize(nSize);
     240           0 :     return m_pStream->GetErrorCode();
     241             : }
     242             : 
     243           0 : ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const
     244             : {
     245           0 :     if (!m_pStream)
     246             :     {
     247             :         OSL_FAIL("SvLockBytes::Stat(): Bad stream");
     248           0 :         return ERRCODE_NONE;
     249             :     }
     250             : 
     251           0 :     if (pStat)
     252             :     {
     253           0 :         sal_Size nPos = m_pStream->Tell();
     254           0 :         pStat->nSize = m_pStream->Seek(STREAM_SEEK_TO_END);
     255           0 :         m_pStream->Seek(nPos);
     256             :     }
     257           0 :     return ERRCODE_NONE;
     258             : }
     259             : 
     260             : //  class SvOpenLockBytes
     261             : 
     262           0 : TYPEINIT1(SvOpenLockBytes, SvLockBytes);
     263             : 
     264             : //  class SvAsyncLockBytes
     265             : 
     266           0 : TYPEINIT1(SvAsyncLockBytes, SvOpenLockBytes);
     267             : 
     268             : // virtual
     269           0 : ErrCode SvAsyncLockBytes::ReadAt(sal_Size nPos, void * pBuffer, sal_Size nCount,
     270             :                                  sal_Size * pRead) const
     271             : {
     272           0 :     if (m_bTerminated)
     273           0 :         return SvOpenLockBytes::ReadAt(nPos, pBuffer, nCount, pRead);
     274             :     else
     275             :     {
     276           0 :         sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
     277             :         ErrCode nError = SvOpenLockBytes::ReadAt(nPos, pBuffer, nTheCount,
     278           0 :                                                  pRead);
     279           0 :         return !nCount || nTheCount == nCount || nError ? nError :
     280           0 :                                                           ERRCODE_IO_PENDING;
     281             :     }
     282             : }
     283             : 
     284             : // virtual
     285           0 : ErrCode SvAsyncLockBytes::WriteAt(sal_Size nPos, const void * pBuffer,
     286             :                                   sal_Size nCount, sal_Size * pWritten)
     287             : {
     288           0 :     if (m_bTerminated)
     289           0 :         return SvOpenLockBytes::WriteAt(nPos, pBuffer, nCount, pWritten);
     290             :     else
     291             :     {
     292           0 :         sal_Size nTheCount = std::min(nPos < m_nSize ? m_nSize - nPos : 0, nCount);
     293             :         ErrCode nError = SvOpenLockBytes::WriteAt(nPos, pBuffer, nTheCount,
     294           0 :                                                   pWritten);
     295           0 :         return !nCount || nTheCount == nCount || nError ? nError :
     296           0 :                                                           ERRCODE_IO_PENDING;
     297             :     }
     298             : }
     299             : 
     300             : // virtual
     301           0 : ErrCode SvAsyncLockBytes::FillAppend(const void * pBuffer, sal_Size nCount,
     302             :                                      sal_Size * pWritten)
     303             : {
     304             :     sal_Size nTheWritten;
     305             :     ErrCode nError = SvOpenLockBytes::WriteAt(m_nSize, pBuffer, nCount,
     306           0 :                                               &nTheWritten);
     307           0 :     if (!nError)
     308           0 :         m_nSize += nTheWritten;
     309           0 :     if (pWritten)
     310           0 :         *pWritten = nTheWritten;
     311           0 :     return nError;
     312             : }
     313             : 
     314             : // virtual
     315           0 : sal_Size SvAsyncLockBytes::Seek(sal_Size nPos)
     316             : {
     317           0 :     if (nPos != STREAM_SEEK_TO_END)
     318           0 :         m_nSize = nPos;
     319           0 :     return m_nSize;
     320             : }
     321             : 
     322             : //  class SvStream
     323             : 
     324       20165 : sal_Size SvStream::GetData( void* pData, sal_Size nSize )
     325             : {
     326       20165 :     if( !GetError() )
     327             :     {
     328             :         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
     329             :         sal_Size nRet;
     330       20162 :         nError = xLockBytes->ReadAt( nActPos, pData, nSize, &nRet );
     331       20162 :         nActPos += nRet;
     332       20162 :         return nRet;
     333             :     }
     334           3 :     else return 0;
     335             : }
     336             : 
     337        1387 : sal_Size SvStream::PutData( const void* pData, sal_Size nSize )
     338             : {
     339        1387 :     if( !GetError() )
     340             :     {
     341             :         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
     342             :         sal_Size nRet;
     343        1387 :         nError = xLockBytes->WriteAt( nActPos, pData, nSize, &nRet );
     344        1387 :         nActPos += nRet;
     345        1387 :         return nRet;
     346             :     }
     347           0 :     else return 0;
     348             : }
     349             : 
     350       41181 : sal_Size SvStream::SeekPos( sal_Size nPos )
     351             : {
     352       41181 :     if( !GetError() && nPos == STREAM_SEEK_TO_END )
     353             :     {
     354             :         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
     355        6332 :         SvLockBytesStat aStat;
     356        6332 :         xLockBytes->Stat( &aStat, SVSTATFLAG_DEFAULT );
     357        6332 :         nActPos = aStat.nSize;
     358             :     }
     359             :     else
     360       34849 :         nActPos = nPos;
     361       41181 :     return nActPos;
     362             : }
     363             : 
     364        5219 : void SvStream::FlushData()
     365             : {
     366        5219 :     if( !GetError() )
     367             :     {
     368             :         DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
     369        4782 :         nError = xLockBytes->Flush();
     370             :     }
     371        5219 : }
     372             : 
     373         488 : void SvStream::SetSize( sal_Size nSize )
     374             : {
     375             :     DBG_ASSERT( xLockBytes.Is(), "pure virtual function" );
     376         488 :     nError = xLockBytes->SetSize( nSize );
     377         488 : }
     378             : 
     379       13998 : void SvStream::ImpInit()
     380             : {
     381       13998 :     nActPos             = 0;
     382       13998 :     nCompressMode       = COMPRESSMODE_NONE;
     383       13998 :     eStreamCharSet      = osl_getThreadTextEncoding();
     384       13998 :     nCryptMask          = 0;
     385       13998 :     bIsEof              = sal_False;
     386             : #if defined UNX
     387       13998 :     eLineDelimiter      = LINEEND_LF;   // UNIX-Format
     388             : #else
     389             :     eLineDelimiter      = LINEEND_CRLF; // DOS-Format
     390             : #endif
     391             : 
     392       13998 :     SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     393             : 
     394       13998 :     nBufFilePos         = 0;
     395       13998 :     nBufActualPos       = 0;
     396       13998 :     bIsDirty            = sal_False;
     397       13998 :     bIsConsistent       = sal_True;
     398       13998 :     bIsWritable         = sal_True;
     399             : 
     400       13998 :     pRWBuf              = 0;
     401       13998 :     pBufPos             = 0;
     402       13998 :     nBufSize            = 0;
     403       13998 :     nBufActualLen       = 0;
     404       13998 :     eIOMode             = STREAM_IO_DONTKNOW;
     405       13998 :     nBufFree            = 0;
     406             : 
     407       13998 :     eStreamMode         = 0;
     408             : 
     409       13998 :     nVersion           = 0;
     410             : 
     411       13998 :     ClearError();
     412       13998 : }
     413             : 
     414        5278 : SvStream::SvStream( SvLockBytes* pLockBytesP )
     415             : {
     416             :     DBG_CTOR( Stream, NULL );
     417             : 
     418        5278 :     ImpInit();
     419        5278 :     xLockBytes = pLockBytesP;
     420             :     const SvStream* pStrm;
     421        5278 :     if( pLockBytesP ) {
     422        5278 :         pStrm = pLockBytesP->GetStream();
     423        5278 :         if( pStrm ) {
     424           0 :             SetError( pStrm->GetErrorCode() );
     425             :         }
     426             :     }
     427        5278 :     SetBufferSize( 256 );
     428        5278 : }
     429             : 
     430        8720 : SvStream::SvStream()
     431             : {
     432             :     DBG_CTOR( Stream, NULL );
     433             : 
     434        8720 :     ImpInit();
     435        8720 : }
     436             : 
     437       31871 : SvStream::~SvStream()
     438             : {
     439             :     DBG_DTOR( Stream, NULL );
     440             : 
     441       13473 :     if ( xLockBytes.Is() )
     442        4925 :         Flush();
     443             : 
     444       13473 :     if( pRWBuf )
     445       11282 :         delete[] pRWBuf;
     446       18398 : }
     447             : 
     448           0 : sal_uInt16 SvStream::IsA() const
     449             : {
     450           0 :     return (sal_uInt16)ID_STREAM;
     451             : }
     452             : 
     453       21831 : void SvStream::ClearError()
     454             : {
     455       21831 :     bIsEof = sal_False;
     456       21831 :     nError = SVSTREAM_OK;
     457       21831 : }
     458             : 
     459     2456913 : void SvStream::SetError( sal_uInt32 nErrorCode )
     460             : {
     461     2456913 :     if ( nError == SVSTREAM_OK )
     462     2456837 :         nError = nErrorCode;
     463     2456913 : }
     464             : 
     465       33399 : void SvStream::SetNumberFormatInt( sal_uInt16 nNewFormat )
     466             : {
     467       33399 :     nNumberFormatInt = nNewFormat;
     468       33399 :     bSwap = sal_False;
     469             : #ifdef OSL_BIGENDIAN
     470             :     if( nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN )
     471             :         bSwap = sal_True;
     472             : #else
     473       33399 :     if( nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN )
     474          75 :         bSwap = sal_True;
     475             : #endif
     476       33399 : }
     477             : 
     478       20084 : void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
     479             : {
     480       20084 :     sal_Size nActualFilePos = Tell();
     481       20084 :     sal_Bool bDontSeek = (sal_Bool)(pRWBuf == 0);
     482             : 
     483       20084 :     if( bIsDirty && bIsConsistent && bIsWritable )  // due to Windows NT: Access denied
     484           0 :         Flush();
     485             : 
     486       20084 :     if( nBufSize )
     487             :     {
     488        6123 :         delete[] pRWBuf;
     489        6123 :         nBufFilePos += nBufActualPos;
     490             :     }
     491             : 
     492       20084 :     pRWBuf          = 0;
     493       20084 :     nBufActualLen   = 0;
     494       20084 :     nBufActualPos   = 0;
     495       20084 :     nBufSize        = nBufferSize;
     496       20084 :     if( nBufSize )
     497       17930 :         pRWBuf = new sal_uInt8[ nBufSize ];
     498       20084 :     bIsConsistent   = sal_True;
     499       20084 :     pBufPos         = pRWBuf;
     500       20084 :     eIOMode = STREAM_IO_DONTKNOW;
     501       20084 :     if( !bDontSeek )
     502        6123 :         SeekPos( nActualFilePos );
     503       20084 : }
     504             : 
     505        5086 : void SvStream::ClearBuffer()
     506             : {
     507        5086 :     nBufActualLen   = 0;
     508        5086 :     nBufActualPos   = 0;
     509        5086 :     nBufFilePos     = 0;
     510        5086 :     pBufPos         = pRWBuf;
     511        5086 :     bIsDirty        = sal_False;
     512        5086 :     bIsConsistent   = sal_True;
     513        5086 :     eIOMode         = STREAM_IO_DONTKNOW;
     514             : 
     515        5086 :     bIsEof          = sal_False;
     516        5086 : }
     517             : 
     518        2834 : void SvStream::ResetError()
     519             : {
     520        2834 :     ClearError();
     521        2834 : }
     522             : 
     523         190 : sal_Bool SvStream::ReadByteStringLine( rtl::OUString& rStr, rtl_TextEncoding eSrcCharSet,
     524             :                                        sal_Int32 nMaxBytesToRead )
     525             : {
     526         190 :     rtl::OString aStr;
     527         190 :     sal_Bool bRet = ReadLine( aStr, nMaxBytesToRead);
     528         190 :     rStr = rtl::OStringToOUString(aStr, eSrcCharSet);
     529         190 :     return bRet;
     530             : }
     531             : 
     532           0 : sal_Bool SvStream::ReadByteStringLine( String& rStr, rtl_TextEncoding eSrcCharSet )
     533             : {
     534           0 :     rtl::OString aStr;
     535           0 :     sal_Bool bRet = ReadLine(aStr);
     536           0 :     rStr = rtl::OStringToOUString(aStr, eSrcCharSet);
     537           0 :     return bRet;
     538             : }
     539             : 
     540      476820 : sal_Bool SvStream::ReadLine( rtl::OString& rStr, sal_Int32 nMaxBytesToRead )
     541             : {
     542             :     sal_Char    buf[256+1];
     543      476820 :     sal_Bool        bEnd        = sal_False;
     544      476820 :     sal_Size       nOldFilePos = Tell();
     545      476820 :     sal_Char    c           = 0;
     546      476820 :     sal_Size       nTotalLen   = 0;
     547             : 
     548      476820 :     rtl::OStringBuffer aBuf(4096);
     549     1430179 :     while( !bEnd && !GetError() )   // Don't test for EOF as we
     550             :                                     // are reading block-wise!
     551             :     {
     552      476874 :         sal_uInt16 nLen = (sal_uInt16)Read( buf, sizeof(buf)-1 );
     553      476874 :         if ( !nLen )
     554             :         {
     555         335 :             if ( aBuf.getLength() == 0 )
     556             :             {
     557             :                 // Exit on first block-read error
     558         332 :                 bIsEof = sal_True;
     559         332 :                 rStr = rtl::OString();
     560         332 :                 return sal_False;
     561             :             }
     562             :             else
     563           3 :                 break;
     564             :         }
     565             : 
     566             :         sal_uInt16 j, n;
     567    10728050 :         for( j = n = 0; j < nLen ; ++j )
     568             :         {
     569    10727996 :             c = buf[j];
     570    10727996 :             if ( c == '\n' || c == '\r' )
     571             :             {
     572      476485 :                 bEnd = sal_True;
     573      476485 :                 break;
     574             :             }
     575    10251511 :             if ( n < j )
     576           0 :                 buf[n] = c;
     577    10251511 :             ++n;
     578             :         }
     579      476539 :         nTotalLen += j;
     580      476539 :         if (nTotalLen > static_cast<sal_Size>(nMaxBytesToRead))
     581             :         {
     582           0 :             n -= nTotalLen - nMaxBytesToRead;
     583           0 :             nTotalLen = nMaxBytesToRead;
     584           0 :             bEnd = sal_True;
     585             :         }
     586      476539 :         if ( n )
     587      444588 :             aBuf.append(buf, n);
     588             :     }
     589             : 
     590      476488 :     if ( !bEnd && !GetError() && aBuf.getLength() )
     591           3 :         bEnd = sal_True;
     592             : 
     593      476488 :     nOldFilePos += nTotalLen;
     594      476488 :     if( Tell() > nOldFilePos )
     595      476485 :         nOldFilePos++;
     596      476488 :     Seek( nOldFilePos );  // Seek pointer due to BlockRead above
     597             : 
     598      476488 :     if ( bEnd && (c=='\r' || c=='\n') )  // Special treatment for DOS files
     599             :     {
     600             :         char cTemp;
     601      476485 :         sal_Size nLen = Read((char*)&cTemp , sizeof(cTemp) );
     602      476485 :         if ( nLen ) {
     603      476149 :             if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
     604      476149 :                 Seek( nOldFilePos );
     605             :         }
     606             :     }
     607             : 
     608      476488 :     if ( bEnd )
     609      476488 :         bIsEof = sal_False;
     610      476488 :     rStr = aBuf.makeStringAndClear();
     611      476488 :     return bEnd;
     612             : }
     613             : 
     614           0 : sal_Bool SvStream::ReadUniStringLine( rtl::OUString& rStr, sal_Int32 nMaxCodepointsToRead )
     615             : {
     616             :     sal_Unicode buf[256+1];
     617           0 :     sal_Bool        bEnd        = sal_False;
     618           0 :     sal_Size       nOldFilePos = Tell();
     619           0 :     sal_Unicode c           = 0;
     620           0 :     sal_Size       nTotalLen   = 0;
     621             : 
     622             :     DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "ReadUniStringLine: swapping sizeof(sal_Unicode) not implemented" );
     623             : 
     624           0 :     rtl::OUStringBuffer aBuf(4096);
     625           0 :     while( !bEnd && !GetError() )   // Don't test for EOF as we
     626             :                                     // are reading block-wise!
     627             :     {
     628           0 :         sal_uInt16 nLen = (sal_uInt16)Read( (char*)buf, sizeof(buf)-sizeof(sal_Unicode) );
     629           0 :         nLen /= sizeof(sal_Unicode);
     630           0 :         if ( !nLen )
     631             :         {
     632           0 :             if ( aBuf.getLength() == 0 )
     633             :             {
     634             :                 // exit on first BlockRead error
     635           0 :                 bIsEof = sal_True;
     636           0 :                 rStr = rtl::OUString();
     637           0 :                 return sal_False;
     638             :             }
     639             :             else
     640           0 :                 break;
     641             :         }
     642             : 
     643             :         sal_uInt16 j, n;
     644           0 :         for( j = n = 0; j < nLen ; ++j )
     645             :         {
     646           0 :             if ( bSwap )
     647           0 :                 SwapUShort( buf[n] );
     648           0 :             c = buf[j];
     649           0 :             if ( c == '\n' || c == '\r' )
     650             :             {
     651           0 :                 bEnd = sal_True;
     652           0 :                 break;
     653             :             }
     654             :             // erAck 26.02.01: Old behavior was no special treatment of '\0'
     655             :             // character here, but a following rStr+=c did ignore it. Is this
     656             :             // really intended? Or should a '\0' better terminate a line?
     657             :             // The nOldFilePos stuff wasn't correct then anyways.
     658           0 :             if ( c )
     659             :             {
     660           0 :                 if ( n < j )
     661           0 :                     buf[n] = c;
     662           0 :                 ++n;
     663             :             }
     664             :         }
     665           0 :         nTotalLen += j;
     666           0 :         if (nTotalLen > static_cast<sal_Size>(nMaxCodepointsToRead))
     667             :         {
     668           0 :             n -= nTotalLen - nMaxCodepointsToRead;
     669           0 :             nTotalLen = nMaxCodepointsToRead;
     670           0 :             bEnd = sal_True;
     671             :         }
     672           0 :         if ( n )
     673           0 :             aBuf.append( buf, n );
     674             :     }
     675             : 
     676           0 :     if ( !bEnd && !GetError() && aBuf.getLength() )
     677           0 :         bEnd = sal_True;
     678             : 
     679           0 :     nOldFilePos += nTotalLen * sizeof(sal_Unicode);
     680           0 :     if( Tell() > nOldFilePos )
     681           0 :         nOldFilePos += sizeof(sal_Unicode);
     682           0 :     Seek( nOldFilePos );  // seek due to BlockRead above
     683             : 
     684           0 :     if ( bEnd && (c=='\r' || c=='\n') )  // special treatment for DOS files
     685             :     {
     686             :         sal_Unicode cTemp;
     687           0 :         Read( (char*)&cTemp, sizeof(cTemp) );
     688           0 :         if ( bSwap )
     689           0 :             SwapUShort( cTemp );
     690           0 :         if( cTemp == c || (cTemp != '\n' && cTemp != '\r') )
     691           0 :             Seek( nOldFilePos );
     692             :     }
     693             : 
     694           0 :     if ( bEnd )
     695           0 :         bIsEof = sal_False;
     696           0 :     rStr = aBuf.makeStringAndClear();
     697           0 :     return bEnd;
     698             : }
     699             : 
     700         190 : sal_Bool SvStream::ReadUniOrByteStringLine( rtl::OUString& rStr, rtl_TextEncoding eSrcCharSet,
     701             :                                             sal_Int32 nMaxCodepointsToRead )
     702             : {
     703         190 :     if ( eSrcCharSet == RTL_TEXTENCODING_UNICODE )
     704           0 :         return ReadUniStringLine( rStr, nMaxCodepointsToRead );
     705             :     else
     706         190 :         return ReadByteStringLine( rStr, eSrcCharSet, nMaxCodepointsToRead );
     707             : }
     708             : 
     709           2 : rtl::OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStream)
     710             : {
     711           2 :     rtl::OStringBuffer aOutput(256);
     712             : 
     713             :     sal_Char buf[ 256 + 1 ];
     714           2 :     sal_Bool bEnd = sal_False;
     715           2 :     sal_Size nFilePos = rStream.Tell();
     716             : 
     717           6 :     while( !bEnd && !rStream.GetError() )
     718             :     {
     719           2 :         sal_Size nLen = rStream.Read(buf, sizeof(buf)-1);
     720           2 :         if (!nLen)
     721           0 :             break;
     722             : 
     723           2 :         sal_Size nReallyRead = nLen;
     724           2 :         const sal_Char* pPtr = buf;
     725          13 :         while (nLen && *pPtr)
     726           9 :             ++pPtr, --nLen;
     727             : 
     728             :         bEnd =  ( nReallyRead < sizeof(buf)-1 )         // read less than attempted to read
     729             :                 ||  (  ( nLen > 0 )                    // OR it is inside the block we read
     730             :                     &&  ( 0 == *pPtr )                  //    AND found a string terminator
     731           2 :                     );
     732             : 
     733           2 :         aOutput.append(buf, pPtr - buf);
     734             :     }
     735             : 
     736           2 :     nFilePos += aOutput.getLength();
     737           2 :     if (rStream.Tell() > nFilePos)
     738           1 :         rStream.Seek(nFilePos+1);  // seek due to FileRead above
     739           2 :     return aOutput.makeStringAndClear();
     740             : }
     741             : 
     742           0 : rtl::OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStream, rtl_TextEncoding eEnc)
     743             : {
     744             :     return rtl::OStringToOUString(
     745           0 :         read_zeroTerminated_uInt8s_ToOString(rStream), eEnc);
     746             : }
     747             : 
     748             : /** Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
     749             :     returned value is number of bytes written */
     750       29928 : sal_Size write_uInt16s_FromOUString(SvStream& rStrm, const rtl::OUString& rStr,
     751             :     sal_Size nUnits)
     752             : {
     753             :     DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
     754             :     sal_Size nWritten;
     755       29928 :     if (!rStrm.IsEndianSwap())
     756       29928 :         nWritten = rStrm.Write( (char*)rStr.getStr(), nUnits * sizeof(sal_Unicode) );
     757             :     else
     758             :     {
     759           0 :         sal_Size nLen = nUnits;
     760             :         sal_Unicode aBuf[384];
     761           0 :         sal_Unicode* const pTmp = ( nLen > 384 ? new sal_Unicode[nLen] : aBuf);
     762           0 :         memcpy( pTmp, rStr.getStr(), nLen * sizeof(sal_Unicode) );
     763           0 :         sal_Unicode* p = pTmp;
     764           0 :         const sal_Unicode* const pStop = pTmp + nLen;
     765           0 :         while ( p < pStop )
     766             :         {
     767           0 :             SwapUShort( *p );
     768           0 :             p++;
     769             :         }
     770           0 :         nWritten = rStrm.Write( (char*)pTmp, nLen * sizeof(sal_Unicode) );
     771           0 :         if ( pTmp != aBuf )
     772           0 :             delete [] pTmp;
     773             :     }
     774       29928 :     return nWritten;
     775             : }
     776             : 
     777          22 : sal_Bool SvStream::WriteUnicodeOrByteText( const String& rStr, rtl_TextEncoding eDestCharSet )
     778             : {
     779          22 :     if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
     780             :     {
     781          20 :         write_uInt16s_FromOUString(*this, rStr, rStr.Len());
     782          20 :         return nError == SVSTREAM_OK;
     783             :     }
     784             :     else
     785             :     {
     786           2 :         rtl::OString aStr(rtl::OUStringToOString(rStr, eDestCharSet));
     787           2 :         write_uInt8s_FromOString(*this, aStr, aStr.getLength());
     788           2 :         return nError == SVSTREAM_OK;
     789             :     }
     790             : }
     791             : 
     792           0 : sal_Bool SvStream::WriteByteStringLine( const String& rStr, rtl_TextEncoding eDestCharSet )
     793             : {
     794           0 :     return WriteLine(rtl::OUStringToOString(rStr, eDestCharSet));
     795             : }
     796             : 
     797      190516 : sal_Bool SvStream::WriteLine(const rtl::OString& rStr)
     798             : {
     799      190516 :     Write(rStr.getStr(), rStr.getLength());
     800      190516 :     endl(*this);
     801      190516 :     return nError == SVSTREAM_OK;
     802             : }
     803             : 
     804           0 : sal_Bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
     805             : {
     806           0 :     if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
     807           0 :         *this << ch;
     808             :     else
     809             :     {
     810           0 :         rtl::OString aStr(&ch, 1, eDestCharSet);
     811           0 :         Write(aStr.getStr(), aStr.getLength());
     812             :     }
     813           0 :     return nError == SVSTREAM_OK;
     814             : }
     815             : 
     816           0 : sal_Bool SvStream::StartWritingUnicodeText()
     817             : {
     818           0 :     SetEndianSwap( sal_False );     // write native format
     819             :     // BOM, Byte Order Mark, U+FEFF, see
     820             :     // http://www.unicode.org/faq/utf_bom.html#BOM
     821             :     // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
     822           0 :     *this << sal_uInt16( 0xfeff );
     823           0 :     return nError == SVSTREAM_OK;
     824             : }
     825             : 
     826           2 : sal_Bool SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet )
     827             : {
     828           2 :     if (!(  eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
     829             :             eReadBomCharSet == RTL_TEXTENCODING_UNICODE ||
     830           2 :             eReadBomCharSet == RTL_TEXTENCODING_UTF8))
     831           2 :         return sal_True;    // nothing to read
     832             : 
     833           0 :     bool bTryUtf8 = false;
     834             :     sal_uInt16 nFlag;
     835           0 :     sal_sSize nBack = sizeof(nFlag);
     836           0 :     *this >> nFlag;
     837           0 :     switch ( nFlag )
     838             :     {
     839             :         case 0xfeff :
     840             :             // native UTF-16
     841           0 :             if (    eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
     842             :                     eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
     843           0 :                 nBack = 0;
     844           0 :         break;
     845             :         case 0xfffe :
     846             :             // swapped UTF-16
     847           0 :             if (    eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
     848             :                     eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
     849             :             {
     850           0 :                 SetEndianSwap( !bSwap );
     851           0 :                 nBack = 0;
     852             :             }
     853           0 :         break;
     854             :         case 0xefbb :
     855           0 :             if (nNumberFormatInt == NUMBERFORMAT_INT_BIGENDIAN &&
     856             :                     (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
     857             :                      eReadBomCharSet == RTL_TEXTENCODING_UTF8))
     858           0 :                 bTryUtf8 = true;
     859           0 :         break;
     860             :         case 0xbbef :
     861           0 :             if (nNumberFormatInt == NUMBERFORMAT_INT_LITTLEENDIAN &&
     862             :                     (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
     863             :                      eReadBomCharSet == RTL_TEXTENCODING_UTF8))
     864           0 :                 bTryUtf8 = true;
     865           0 :         break;
     866             :         default:
     867             :             ;   // nothing
     868             :     }
     869           0 :     if (bTryUtf8)
     870             :     {
     871             :         sal_uChar nChar;
     872           0 :         nBack += sizeof(nChar);
     873           0 :         *this >> nChar;
     874           0 :         if (nChar == 0xbf)
     875           0 :             nBack = 0;      // it is UTF-8
     876             :     }
     877           0 :     if (nBack)
     878           0 :         SeekRel( -nBack );      // no BOM, pure data
     879           0 :     return nError == SVSTREAM_OK;
     880             : }
     881             : 
     882      299614 : sal_Size SvStream::SeekRel( sal_sSize nPos )
     883             : {
     884      299614 :     sal_Size nActualPos = Tell();
     885             : 
     886      299614 :     if ( nPos >= 0 )
     887             :     {
     888      266125 :         if ( SAL_MAX_SIZE - nActualPos > (sal_Size)nPos )
     889      266125 :             nActualPos += nPos;
     890             :     }
     891             :     else
     892             :     {
     893       33489 :         sal_Size nAbsPos = (sal_Size)-nPos;
     894       33489 :         if ( nActualPos >= nAbsPos )
     895       33489 :             nActualPos -= nAbsPos;
     896             :     }
     897             : 
     898      299614 :     pBufPos = pRWBuf + nActualPos;
     899      299614 :     return Seek( nActualPos );
     900             : }
     901             : 
     902     1483948 : SvStream& SvStream::operator>>(sal_uInt16& r)
     903             : {
     904     1483948 :     sal_uInt16 n = 0;
     905     1483948 :     READNUMBER_WITHOUT_SWAP(sal_uInt16, n)
     906     1483948 :     if (good())
     907             :     {
     908     1482029 :         if (bSwap)
     909        1838 :             SwapUShort(n);
     910     1482029 :         r = n;
     911             :     }
     912     1483948 :     return *this;
     913             : }
     914             : 
     915      397026 : SvStream& SvStream::operator>>(sal_uInt32& r)
     916             : {
     917      397026 :     sal_uInt32 n = 0;
     918      397026 :     READNUMBER_WITHOUT_SWAP(sal_uInt32, n)
     919      397026 :     if (good())
     920             :     {
     921      396717 :         if (bSwap)
     922        1070 :             SwapULong(n);
     923      396717 :         r = n;
     924             :     }
     925      397026 :     return *this;
     926             : }
     927             : 
     928           0 : SvStream& SvStream::operator>>(sal_uInt64& r)
     929             : {
     930           0 :     sal_uInt64 n = 0;
     931           0 :     READNUMBER_WITHOUT_SWAP(sal_uInt64, n)
     932           0 :     if (good())
     933             :     {
     934           0 :         if (bSwap)
     935           0 :             SwapUInt64(n);
     936           0 :         r = n;
     937             :     }
     938           0 :     return *this;
     939             : }
     940             : 
     941      182397 : SvStream& SvStream::operator>>(sal_Int16& r)
     942             : {
     943      182397 :     sal_Int16 n = 0;
     944      182397 :     READNUMBER_WITHOUT_SWAP(sal_Int16, n)
     945      182397 :     if (good())
     946             :     {
     947       60583 :         if (bSwap)
     948        2836 :             SwapShort(n);
     949       60583 :         r = n;
     950             :     }
     951      182397 :     return *this;
     952             : }
     953             : 
     954      227514 : SvStream& SvStream::operator>>(sal_Int32& r)
     955             : {
     956      227514 :     sal_Int32 n = 0;
     957      227514 :     READNUMBER_WITHOUT_SWAP(sal_Int32, n)
     958      227514 :     if (good())
     959             :     {
     960      215521 :         if (bSwap)
     961         130 :             SwapLongInt(n);
     962      215521 :         r = n;
     963             :     }
     964      227514 :     return *this;
     965             : }
     966             : 
     967           0 : SvStream& SvStream::operator>>(sal_Int64& r)
     968             : {
     969           0 :     sal_Int64 n = 0;
     970           0 :     READNUMBER_WITHOUT_SWAP(sal_Int64, n)
     971           0 :     if (good())
     972             :     {
     973           0 :         if (bSwap)
     974           0 :             SwapInt64(n);
     975           0 :         r = n;
     976             :     }
     977           0 :     return *this;
     978             : }
     979             : 
     980          80 : SvStream& SvStream::operator>>( signed char& r )
     981             : {
     982          80 :     if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
     983             :         sizeof(signed char) <= nBufFree )
     984             :     {
     985           0 :         r = *pBufPos;
     986           0 :         nBufActualPos += sizeof(signed char);
     987           0 :         pBufPos += sizeof(signed char);
     988           0 :         nBufFree -= sizeof(signed char);
     989             :     }
     990             :     else
     991          80 :         Read( (char*)&r, sizeof(signed char) );
     992          80 :     return *this;
     993             : }
     994             : 
     995             : // Special treatment for Chars due to PutBack
     996             : 
     997     1358542 : SvStream& SvStream::operator>>( char& r )
     998             : {
     999     1358542 :     if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
    1000             :         sizeof(char) <= nBufFree )
    1001             :     {
    1002     1298788 :         r = *pBufPos;
    1003     1298788 :         nBufActualPos += sizeof(char);
    1004     1298788 :         pBufPos += sizeof(char);
    1005     1298788 :         nBufFree -= sizeof(char);
    1006             :     }
    1007             :     else
    1008       59754 :         Read( (char*)&r, sizeof(char) );
    1009     1358542 :     return *this;
    1010             : }
    1011             : 
    1012     2086515 : SvStream& SvStream::operator>>( unsigned char& r )
    1013             : {
    1014     2086515 :     if( (eIOMode == STREAM_IO_READ || !bIsConsistent) &&
    1015             :         sizeof(char) <= nBufFree )
    1016             :     {
    1017     1960594 :         r = *pBufPos;
    1018     1960594 :         nBufActualPos += sizeof(char);
    1019     1960594 :         pBufPos += sizeof(char);
    1020     1960594 :         nBufFree -= sizeof(char);
    1021             :     }
    1022             :     else
    1023      125921 :         Read( (char*)&r, sizeof(char) );
    1024     2086515 :     return *this;
    1025             : }
    1026             : 
    1027         198 : SvStream& SvStream::operator>>(float& r)
    1028             : {
    1029         198 :     float n = 0;
    1030         198 :     READNUMBER_WITHOUT_SWAP(float, n)
    1031         198 :     if (good())
    1032             :     {
    1033             : #if defined UNX
    1034         198 :         if (bSwap)
    1035           0 :           SwapFloat(n);
    1036             : #endif
    1037         198 :         r = n;
    1038             :     }
    1039         198 :     return *this;
    1040             : }
    1041             : 
    1042        5310 : SvStream& SvStream::operator>>(double& r)
    1043             : {
    1044        5310 :     double n = 0;
    1045        5310 :     READNUMBER_WITHOUT_SWAP(double, n)
    1046        5310 :     if (good())
    1047             :     {
    1048             : #if defined UNX
    1049        5310 :         if (bSwap)
    1050           0 :           SwapDouble(n);
    1051             : #endif
    1052        5310 :         r = n;
    1053             :     }
    1054        5310 :     return *this;
    1055             : }
    1056             : 
    1057           4 : SvStream& SvStream::operator>> ( SvStream& rStream )
    1058             : {
    1059           4 :     const sal_uInt32 cBufLen = 0x8000;
    1060           4 :     char* pBuf = new char[ cBufLen ];
    1061             : 
    1062             :     sal_uInt32 nCount;
    1063           4 :     do {
    1064           4 :         nCount = Read( pBuf, cBufLen );
    1065           4 :         rStream.Write( pBuf, nCount );
    1066             :     } while( nCount == cBufLen );
    1067             : 
    1068           4 :     delete[] pBuf;
    1069           4 :     return *this;
    1070             : }
    1071             : 
    1072     1249571 : SvStream& SvStream::operator<< ( sal_uInt16 v )
    1073             : {
    1074     1249571 :     if( bSwap )
    1075           0 :         SwapUShort(v);
    1076     1249571 :     WRITENUMBER_WITHOUT_SWAP(sal_uInt16,v)
    1077     1249571 :     return *this;
    1078             : }
    1079             : 
    1080      435973 : SvStream& SvStream::operator<<  ( sal_uInt32 v )
    1081             : {
    1082      435973 :     if( bSwap )
    1083         352 :         SwapULong(v);
    1084      435973 :     WRITENUMBER_WITHOUT_SWAP(sal_uInt32,v)
    1085      435973 :     return *this;
    1086             : }
    1087             : 
    1088           0 : SvStream& SvStream::operator<<  ( sal_uInt64 v )
    1089             : {
    1090           0 :     if( bSwap )
    1091           0 :         SwapUInt64(v);
    1092           0 :     WRITENUMBER_WITHOUT_SWAP(sal_uInt64,v)
    1093           0 :     return *this;
    1094             : }
    1095             : 
    1096       44518 : SvStream& SvStream::operator<< ( sal_Int16 v )
    1097             : {
    1098       44518 :     if( bSwap )
    1099           0 :         SwapShort(v);
    1100       44518 :     WRITENUMBER_WITHOUT_SWAP(sal_Int16,v)
    1101       44518 :     return *this;
    1102             : }
    1103             : 
    1104      144243 : SvStream& SvStream::operator<<  ( sal_Int32 v )
    1105             : {
    1106      144243 :     if( bSwap )
    1107           0 :         SwapLongInt(v);
    1108      144243 :     WRITENUMBER_WITHOUT_SWAP(sal_Int32,v)
    1109      144243 :     return *this;
    1110             : }
    1111             : 
    1112           0 : SvStream& SvStream::operator<<  ( sal_Int64 v )
    1113             : {
    1114           0 :     if( bSwap )
    1115           0 :         SwapInt64(v);
    1116           0 :     WRITENUMBER_WITHOUT_SWAP(sal_Int64,v)
    1117           0 :     return *this;
    1118             : }
    1119             : 
    1120           0 : SvStream& SvStream::operator<<  ( signed char v )
    1121             : {
    1122             :     //SDO
    1123           0 :     int tmp = eIOMode;
    1124           0 :     if(tmp == STREAM_IO_WRITE && sizeof(signed char) <= nBufFree )
    1125             :     {
    1126           0 :         *pBufPos = v;
    1127           0 :         pBufPos++; // sizeof(char);
    1128           0 :         nBufActualPos++;
    1129           0 :         if( nBufActualPos > nBufActualLen )  // Append ?
    1130           0 :             nBufActualLen = nBufActualPos;
    1131           0 :         nBufFree--; // = sizeof(char);
    1132           0 :         bIsDirty = sal_True;
    1133             :     }
    1134             :     else
    1135           0 :         Write( (char*)&v, sizeof(signed char) );
    1136           0 :     return *this;
    1137             : }
    1138             : 
    1139             : // Special treatment for Chars due to PutBack
    1140             : 
    1141      748109 : SvStream& SvStream::operator<<  ( char v )
    1142             : {
    1143             :     //SDO
    1144      748109 :     int tmp = eIOMode;
    1145      748109 :     if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
    1146             :     {
    1147      730558 :         *pBufPos = v;
    1148      730558 :         pBufPos++; // sizeof(char);
    1149      730558 :         nBufActualPos++;
    1150      730558 :         if( nBufActualPos > nBufActualLen )  // Append ?
    1151      700710 :             nBufActualLen = nBufActualPos;
    1152      730558 :         nBufFree--; // = sizeof(char);
    1153      730558 :         bIsDirty = sal_True;
    1154             :     }
    1155             :     else
    1156       17551 :         Write( (char*)&v, sizeof(char) );
    1157      748109 :     return *this;
    1158             : }
    1159             : 
    1160      662362 : SvStream& SvStream::operator<<  ( unsigned char v )
    1161             : {
    1162             : //SDO
    1163      662362 :     int tmp = eIOMode;
    1164      662362 :     if(tmp == STREAM_IO_WRITE && sizeof(char) <= nBufFree )
    1165             :     {
    1166      189778 :         *(unsigned char*)pBufPos = v;
    1167      189778 :         pBufPos++; // = sizeof(char);
    1168      189778 :         nBufActualPos++; // = sizeof(char);
    1169      189778 :         if( nBufActualPos > nBufActualLen )  // Append ?
    1170      189778 :             nBufActualLen = nBufActualPos;
    1171      189778 :         nBufFree--;
    1172      189778 :         bIsDirty = sal_True;
    1173             :     }
    1174             :     else
    1175      472584 :         Write( (char*)&v, sizeof(char) );
    1176      662362 :     return *this;
    1177             : }
    1178             : 
    1179          30 : SvStream& SvStream::operator<< ( float v )
    1180             : {
    1181             : #ifdef UNX
    1182          30 :     if( bSwap )
    1183           0 :       SwapFloat(v);
    1184             : #endif
    1185          30 :     WRITENUMBER_WITHOUT_SWAP(float,v)
    1186          30 :     return *this;
    1187             : }
    1188             : 
    1189         151 : SvStream& SvStream::operator<< ( const double& r )
    1190             : {
    1191             : #if defined UNX
    1192         151 :     if( bSwap )
    1193             :     {
    1194           0 :       double nHelp = r;
    1195           0 :       SwapDouble(nHelp);
    1196           0 :       WRITENUMBER_WITHOUT_SWAP(double,nHelp)
    1197           0 :       return *this;
    1198             :     }
    1199             :     else
    1200             : #endif
    1201         151 :     WRITENUMBER_WITHOUT_SWAP(double,r)
    1202             : 
    1203         151 :     return *this;
    1204             : }
    1205             : 
    1206      768688 : SvStream& SvStream::operator<<  ( const char* pBuf )
    1207             : {
    1208      768688 :     Write( pBuf, strlen( pBuf ) );
    1209      768688 :     return *this;
    1210             : }
    1211             : 
    1212           0 : SvStream& SvStream::operator<<  ( const unsigned char* pBuf )
    1213             : {
    1214           0 :     Write( (char*)pBuf, strlen( (char*)pBuf ) );
    1215           0 :     return *this;
    1216             : }
    1217             : 
    1218           8 : SvStream& SvStream::operator<< ( SvStream& rStream )
    1219             : {
    1220           8 :     const sal_uInt32 cBufLen = 0x8000;
    1221           8 :     char* pBuf = new char[ cBufLen ];
    1222             :     sal_uInt32 nCount;
    1223         105 :     do {
    1224         105 :         nCount = rStream.Read( pBuf, cBufLen );
    1225         105 :         Write( pBuf, nCount );
    1226             :     } while( nCount == cBufLen );
    1227             : 
    1228           8 :     delete[] pBuf;
    1229           8 :     return *this;
    1230             : }
    1231             : 
    1232       64740 : rtl::OUString SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet )
    1233             : {
    1234             :     // read UTF-16 string directly from stream ?
    1235       64740 :     if (eSrcCharSet == RTL_TEXTENCODING_UNICODE)
    1236        7248 :         return read_lenPrefixed_uInt16s_ToOUString<sal_uInt32>(*this);
    1237       57492 :     return read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*this, eSrcCharSet);
    1238             : }
    1239             : 
    1240       71107 : SvStream& SvStream::WriteUniOrByteString( const rtl::OUString& rStr, rtl_TextEncoding eDestCharSet )
    1241             : {
    1242             :     // write UTF-16 string directly into stream ?
    1243       71107 :     if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
    1244        7701 :         write_lenPrefixed_uInt16s_FromOUString<sal_uInt32>(*this, rStr);
    1245             :     else
    1246       63406 :         write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(*this, rStr, eDestCharSet);
    1247       71107 :     return *this;
    1248             : }
    1249             : 
    1250     2484021 : sal_Size SvStream::Read( void* pData, sal_Size nCount )
    1251             : {
    1252     2484021 :     sal_Size nSaveCount = nCount;
    1253     2484021 :     if( !bIsConsistent )
    1254           0 :         RefreshBuffer();
    1255             : 
    1256     2484021 :     if( !pRWBuf )
    1257             :     {
    1258     1003126 :         nCount = GetData( (char*)pData,nCount);
    1259     1003126 :         if( nCryptMask )
    1260           0 :             EncryptBuffer(pData, nCount);
    1261     1003126 :         nBufFilePos += nCount;
    1262             :     }
    1263             :     else
    1264             :     {
    1265             :         // check if block is completely within buffer
    1266     1480895 :         eIOMode = STREAM_IO_READ;
    1267     1480895 :         if( nCount <= (sal_Size)(nBufActualLen - nBufActualPos ) )
    1268             :         {
    1269             :             // => yes
    1270     1236662 :             memcpy(pData, pBufPos, (size_t) nCount);
    1271     1236662 :             nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
    1272     1236662 :             pBufPos += nCount;
    1273     1236662 :             nBufFree = nBufFree - (sal_uInt16)nCount;
    1274             :         }
    1275             :         else
    1276             :         {
    1277      244233 :             if( bIsDirty ) // Does stream require a flush?
    1278             :             {
    1279          21 :                 SeekPos( nBufFilePos );
    1280          21 :                 if( nCryptMask )
    1281           0 :                     CryptAndWriteBuffer(pRWBuf, nBufActualLen);
    1282             :                 else
    1283          21 :                     PutData( pRWBuf, nBufActualLen );
    1284          21 :                 bIsDirty = sal_False;
    1285             :             }
    1286             : 
    1287             :             // Does data block fit into buffer?
    1288      244233 :             if( nCount > nBufSize )
    1289             :             {
    1290             :                 // => No! Thus read directly
    1291             :                 // into target area without using the buffer
    1292             : 
    1293        4880 :                 eIOMode = STREAM_IO_DONTKNOW;
    1294             : 
    1295        4880 :                 SeekPos( nBufFilePos + nBufActualPos );
    1296        4880 :                 nBufActualLen = 0;
    1297        4880 :                 pBufPos       = pRWBuf;
    1298        4880 :                 nCount = GetData( (char*)pData, nCount );
    1299        4880 :                 if( nCryptMask )
    1300           0 :                     EncryptBuffer(pData, nCount);
    1301        4880 :                 nBufFilePos += nCount;
    1302        4880 :                 nBufFilePos += nBufActualPos;
    1303        4880 :                 nBufActualPos = 0;
    1304             :             }
    1305             :             else
    1306             :             {
    1307             :                 // => Yes. Fill buffer first, then copy to target area
    1308             : 
    1309      239353 :                 nBufFilePos += nBufActualPos;
    1310      239353 :                 SeekPos( nBufFilePos );
    1311             : 
    1312             :                 // TODO: Typecast before GetData, sal_uInt16 nCountTmp
    1313      239353 :                 sal_Size nCountTmp = GetData( pRWBuf, nBufSize );
    1314      239353 :                 if( nCryptMask )
    1315           0 :                     EncryptBuffer(pRWBuf, nCountTmp);
    1316      239353 :                 nBufActualLen = (sal_uInt16)nCountTmp;
    1317      239353 :                 if( nCount > nCountTmp )
    1318             :                 {
    1319      199446 :                     nCount = nCountTmp;  // trim count back, EOF see below
    1320             :                 }
    1321      239353 :                 memcpy( pData, pRWBuf, (size_t)nCount );
    1322      239353 :                 nBufActualPos = (sal_uInt16)nCount;
    1323      239353 :                 pBufPos = pRWBuf + nCount;
    1324             :             }
    1325             :         }
    1326             :     }
    1327     2484021 :     bIsEof = sal_False;
    1328     2484021 :     nBufFree = nBufActualLen - nBufActualPos;
    1329     2484021 :     if( nCount != nSaveCount && nError != ERRCODE_IO_PENDING )
    1330      224982 :         bIsEof = sal_True;
    1331     2484021 :     if( nCount == nSaveCount && nError == ERRCODE_IO_PENDING )
    1332           0 :         nError = ERRCODE_NONE;
    1333     2484021 :     return nCount;
    1334             : }
    1335             : 
    1336     3154640 : sal_Size SvStream::Write( const void* pData, sal_Size nCount )
    1337             : {
    1338     3154640 :     if( !nCount )
    1339       25994 :         return 0;
    1340     3128646 :     if( !bIsWritable )
    1341             :     {
    1342           0 :         SetError( ERRCODE_IO_CANTWRITE );
    1343           0 :         return 0;
    1344             :     }
    1345     3128646 :     if( !bIsConsistent )
    1346           0 :         RefreshBuffer();   // Remove changes in buffer through PutBack
    1347             : 
    1348     3128646 :     if( !pRWBuf )
    1349             :     {
    1350      715881 :         if( nCryptMask )
    1351           0 :             nCount = CryptAndWriteBuffer( pData, nCount );
    1352             :         else
    1353      715881 :             nCount = PutData( (char*)pData, nCount );
    1354      715881 :         nBufFilePos += nCount;
    1355      715881 :         return nCount;
    1356             :     }
    1357             : 
    1358     2412765 :     eIOMode = STREAM_IO_WRITE;
    1359     2412765 :     if( nCount <= (sal_Size)(nBufSize - nBufActualPos) )
    1360             :     {
    1361     2337543 :         memcpy( pBufPos, pData, (size_t)nCount );
    1362     2337543 :         nBufActualPos = nBufActualPos + (sal_uInt16)nCount;
    1363             :         // Update length if buffer was updated
    1364     2337543 :         if( nBufActualPos > nBufActualLen )
    1365     2254884 :             nBufActualLen = nBufActualPos;
    1366             : 
    1367     2337543 :         pBufPos += nCount;
    1368     2337543 :         bIsDirty = sal_True;
    1369             :     }
    1370             :     else
    1371             :     {
    1372             :         // Does stream require flushing?
    1373       75222 :         if( bIsDirty )
    1374             :         {
    1375       73705 :             SeekPos( nBufFilePos );
    1376       73705 :             if( nCryptMask )
    1377           0 :                 CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
    1378             :             else
    1379       73705 :                 PutData( pRWBuf, nBufActualLen );
    1380       73705 :             bIsDirty = sal_False;
    1381             :         }
    1382             : 
    1383             :         // Does data block fit into buffer?
    1384       75222 :         if( nCount > nBufSize )
    1385             :         {
    1386        1800 :             eIOMode = STREAM_IO_DONTKNOW;
    1387        1800 :             nBufFilePos += nBufActualPos;
    1388        1800 :             nBufActualLen = 0;
    1389        1800 :             nBufActualPos = 0;
    1390        1800 :             pBufPos       = pRWBuf;
    1391        1800 :             SeekPos( nBufFilePos );
    1392        1800 :             if( nCryptMask )
    1393           0 :                 nCount = CryptAndWriteBuffer( pData, nCount );
    1394             :             else
    1395        1800 :                 nCount = PutData( (char*)pData, nCount );
    1396        1800 :             nBufFilePos += nCount;
    1397             :         }
    1398             :         else
    1399             :         {
    1400             :             // Copy block to buffer
    1401       73422 :             memcpy( pRWBuf, pData, (size_t)nCount );
    1402             : 
    1403             :             // Mind the order!
    1404       73422 :             nBufFilePos += nBufActualPos;
    1405       73422 :             nBufActualPos = (sal_uInt16)nCount;
    1406       73422 :             pBufPos = pRWBuf + nCount;
    1407       73422 :             nBufActualLen = (sal_uInt16)nCount;
    1408       73422 :             bIsDirty = sal_True;
    1409             :         }
    1410             :     }
    1411     2412765 :     nBufFree = nBufSize - nBufActualPos;
    1412     2412765 :     return nCount;
    1413             : }
    1414             : 
    1415     2931584 : sal_Size SvStream::Seek( sal_Size nFilePos )
    1416             : {
    1417     2931584 :     eIOMode = STREAM_IO_DONTKNOW;
    1418             : 
    1419     2931584 :     bIsEof = sal_False;
    1420     2931584 :     if( !pRWBuf )
    1421             :     {
    1422      801975 :         nBufFilePos = SeekPos( nFilePos );
    1423             :         DBG_ASSERT(Tell()==nBufFilePos,"Out Of Sync!");
    1424      801975 :         return nBufFilePos;
    1425             :     }
    1426             : 
    1427             :     // Is seek position within buffer?
    1428     2129609 :     if( nFilePos >= nBufFilePos && nFilePos <= (nBufFilePos + nBufActualLen))
    1429             :     {
    1430     1415977 :         nBufActualPos = (sal_uInt16)(nFilePos - nBufFilePos);
    1431     1415977 :         pBufPos = pRWBuf + nBufActualPos;
    1432             :         // Update nBufFree to avoid crash upon PutBack
    1433     1415977 :         nBufFree = nBufActualLen - nBufActualPos;
    1434             :     }
    1435             :     else
    1436             :     {
    1437      713632 :         if( bIsDirty && bIsConsistent)
    1438             :         {
    1439      633810 :             SeekPos( nBufFilePos );
    1440      633810 :             if( nCryptMask )
    1441           0 :                 CryptAndWriteBuffer( pRWBuf, nBufActualLen );
    1442             :             else
    1443      633810 :                 PutData( pRWBuf, nBufActualLen );
    1444      633810 :             bIsDirty = sal_False;
    1445             :         }
    1446      713632 :         nBufActualLen = 0;
    1447      713632 :         nBufActualPos = 0;
    1448      713632 :         pBufPos       = pRWBuf;
    1449      713632 :         nBufFilePos = SeekPos( nFilePos );
    1450             :     }
    1451             : #ifdef OV_DEBUG
    1452             :     {
    1453             :         sal_Size nDebugTemp = nBufFilePos + nBufActualPos;
    1454             :         DBG_ASSERT(Tell()==nDebugTemp,"Sync?");
    1455             :     }
    1456             : #endif
    1457     2129609 :     return nBufFilePos + nBufActualPos;
    1458             : }
    1459             : 
    1460             : //STREAM_SEEK_TO_END in the some of the Seek backends is special cased to be
    1461             : //efficient, in others e.g. SotStorageStream it's really horribly slow, and in
    1462             : //those this should be overridden
    1463           0 : sal_Size SvStream::remainingSize()
    1464             : {
    1465           0 :     sal_Size nCurr = Tell();
    1466           0 :     sal_Size nEnd = Seek(STREAM_SEEK_TO_END);
    1467           0 :     sal_Size nMaxAvailable = nEnd-nCurr;
    1468           0 :     Seek(nCurr);
    1469           0 :     return nMaxAvailable;
    1470             : }
    1471             : 
    1472       14661 : void SvStream::Flush()
    1473             : {
    1474       14661 :     if( bIsDirty && bIsConsistent )
    1475             :     {
    1476         998 :         SeekPos( nBufFilePos );
    1477         998 :         if( nCryptMask )
    1478           0 :             CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
    1479             :         else
    1480         998 :             if( PutData( pRWBuf, nBufActualLen ) != nBufActualLen )
    1481           3 :                 SetError( SVSTREAM_WRITE_ERROR );
    1482         998 :         bIsDirty = sal_False;
    1483             :     }
    1484       14661 :     if( bIsWritable )
    1485       12302 :         FlushData();
    1486       14661 : }
    1487             : 
    1488           0 : void SvStream::RefreshBuffer()
    1489             : {
    1490           0 :     if( bIsDirty && bIsConsistent )
    1491             :     {
    1492           0 :         SeekPos( nBufFilePos );
    1493           0 :         if( nCryptMask )
    1494           0 :             CryptAndWriteBuffer( pRWBuf, (sal_Size)nBufActualLen );
    1495             :         else
    1496           0 :             PutData( pRWBuf, nBufActualLen );
    1497           0 :         bIsDirty = sal_False;
    1498             :     }
    1499           0 :     SeekPos( nBufFilePos );
    1500           0 :     nBufActualLen = (sal_uInt16)GetData( pRWBuf, nBufSize );
    1501           0 :     if( nBufActualLen && nError == ERRCODE_IO_PENDING )
    1502           0 :         nError = ERRCODE_NONE;
    1503           0 :     if( nCryptMask )
    1504           0 :         EncryptBuffer(pRWBuf, (sal_Size)nBufActualLen);
    1505           0 :     bIsConsistent = sal_True;
    1506           0 :     eIOMode = STREAM_IO_DONTKNOW;
    1507           0 : }
    1508             : 
    1509           0 : SvStream& SvStream::WriteNumber(sal_Int32 nInt32)
    1510             : {
    1511             :     char buffer[12];
    1512           0 :     sal_Size nLen = sprintf(buffer, "%" SAL_PRIdINT32, nInt32);
    1513           0 :     Write(buffer, nLen);
    1514           0 :     return *this;
    1515             : }
    1516             : 
    1517           0 : SvStream& SvStream::WriteNumber(sal_uInt32 nUInt32)
    1518             : {
    1519             :     char buffer[11];
    1520           0 :     sal_Size nLen = sprintf(buffer, "%" SAL_PRIuUINT32, nUInt32);
    1521           0 :     Write(buffer, nLen);
    1522           0 :     return *this;
    1523             : }
    1524             : 
    1525             : #define CRYPT_BUFSIZE 1024
    1526             : 
    1527             : /// Encrypt and write
    1528           0 : sal_Size SvStream::CryptAndWriteBuffer( const void* pStart, sal_Size nLen)
    1529             : {
    1530             :     unsigned char  pTemp[CRYPT_BUFSIZE];
    1531           0 :     unsigned char* pDataPtr = (unsigned char*)pStart;
    1532           0 :     sal_Size nCount = 0;
    1533             :     sal_Size nBufCount;
    1534           0 :     unsigned char nMask = nCryptMask;
    1535           0 :     do
    1536             :     {
    1537           0 :         if( nLen >= CRYPT_BUFSIZE )
    1538           0 :             nBufCount = CRYPT_BUFSIZE;
    1539             :         else
    1540           0 :             nBufCount = nLen;
    1541           0 :         nLen -= nBufCount;
    1542           0 :         memcpy( pTemp, pDataPtr, (sal_uInt16)nBufCount );
    1543             :         // **** Verschluesseln *****
    1544           0 :         for ( sal_uInt16 n=0; n < CRYPT_BUFSIZE; n++ )
    1545             :         {
    1546           0 :             unsigned char aCh = pTemp[n];
    1547           0 :             aCh ^= nMask;
    1548           0 :             SWAPNIBBLES(aCh)
    1549           0 :             pTemp[n] = aCh;
    1550             :         }
    1551             :         // *************************
    1552           0 :         nCount += PutData( (char*)pTemp, nBufCount );
    1553           0 :         pDataPtr += nBufCount;
    1554             :     }
    1555             :     while ( nLen );
    1556           0 :     return nCount;
    1557             : }
    1558             : 
    1559           0 : sal_Bool SvStream::EncryptBuffer(void* pStart, sal_Size nLen)
    1560             : {
    1561           0 :     unsigned char* pTemp = (unsigned char*)pStart;
    1562           0 :     unsigned char nMask = nCryptMask;
    1563             : 
    1564           0 :     for ( sal_Size n=0; n < nLen; n++, pTemp++ )
    1565             :     {
    1566           0 :         unsigned char aCh = *pTemp;
    1567           0 :         SWAPNIBBLES(aCh)
    1568           0 :         aCh ^= nMask;
    1569           0 :         *pTemp = aCh;
    1570             :     }
    1571           0 :     return sal_True;
    1572             : }
    1573             : 
    1574           6 : unsigned char implGetCryptMask(const sal_Char* pStr, sal_Int32 nLen, long nVersion)
    1575             : {
    1576           6 :     unsigned char nCryptMask = 0;
    1577             : 
    1578           6 :     if (!nLen)
    1579           6 :         return nCryptMask;
    1580             : 
    1581           0 :     if( nVersion <= SOFFICE_FILEFORMAT_31 )
    1582             :     {
    1583           0 :         while( nLen )
    1584             :         {
    1585           0 :             nCryptMask ^= *pStr;
    1586           0 :             pStr++;
    1587           0 :             nLen--;
    1588             :         }
    1589             :     }
    1590             :     else // BugFix #25888#
    1591             :     {
    1592           0 :         for( sal_uInt16 i = 0; i < nLen; i++ ) {
    1593           0 :             nCryptMask ^= pStr[i];
    1594           0 :             if( nCryptMask & 0x80 ) {
    1595           0 :                 nCryptMask <<= 1;
    1596           0 :                 nCryptMask++;
    1597             :             }
    1598             :             else
    1599           0 :                 nCryptMask <<= 1;
    1600             :         }
    1601             :     }
    1602             : 
    1603           0 :     if( !nCryptMask )
    1604           0 :         nCryptMask = 67;
    1605             : 
    1606           0 :     return nCryptMask;
    1607             : }
    1608             : 
    1609           6 : void SvStream::SetCryptMaskKey(const rtl::OString& rCryptMaskKey)
    1610             : {
    1611           6 :     m_aCryptMaskKey = rCryptMaskKey;
    1612             :     nCryptMask = implGetCryptMask(m_aCryptMaskKey.getStr(),
    1613           6 :         m_aCryptMaskKey.getLength(), GetVersion());
    1614           6 : }
    1615             : 
    1616         196 : void SvStream::SyncSvStream( sal_Size nNewStreamPos )
    1617             : {
    1618         196 :     ClearBuffer();
    1619         196 :     SvStream::nBufFilePos = nNewStreamPos;
    1620         196 : }
    1621             : 
    1622         196 : void SvStream::SyncSysStream()
    1623             : {
    1624         196 :     Flush();
    1625         196 :     SeekPos( Tell() );
    1626         196 : }
    1627             : 
    1628         488 : sal_Bool SvStream::SetStreamSize( sal_Size nSize )
    1629             : {
    1630             : #ifdef DBG_UTIL
    1631             :     sal_Size nFPos = Tell();
    1632             : #endif
    1633         488 :     sal_uInt16 nBuf = nBufSize;
    1634         488 :     SetBufferSize( 0 );
    1635         488 :     SetSize( nSize );
    1636         488 :     SetBufferSize( nBuf );
    1637             :     DBG_ASSERT(Tell()==nFPos,"SetStreamSize failed");
    1638         488 :     return (sal_Bool)(nError == 0);
    1639             : }
    1640             : 
    1641      386997 : SvStream& endl( SvStream& rStr )
    1642             : {
    1643      386997 :     LineEnd eDelim = rStr.GetLineDelimiter();
    1644      386997 :     if ( eDelim == LINEEND_CR )
    1645           0 :         rStr << _CR;
    1646      386997 :     else if( eDelim == LINEEND_LF )
    1647      386997 :         rStr << _LF;
    1648             :     else
    1649           0 :         rStr << _CR << _LF;
    1650      386997 :     return rStr;
    1651             : }
    1652             : 
    1653           0 : SvStream& endlu( SvStream& rStrm )
    1654             : {
    1655           0 :     switch ( rStrm.GetLineDelimiter() )
    1656             :     {
    1657             :         case LINEEND_CR :
    1658           0 :             rStrm << sal_Unicode(_CR);
    1659           0 :         break;
    1660             :         case LINEEND_LF :
    1661           0 :             rStrm << sal_Unicode(_LF);
    1662           0 :         break;
    1663             :         default:
    1664           0 :             rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
    1665             :     }
    1666           0 :     return rStrm;
    1667             : }
    1668             : 
    1669           0 : SvStream& endlub( SvStream& rStrm )
    1670             : {
    1671           0 :     if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
    1672           0 :         return endlu( rStrm );
    1673             :     else
    1674           0 :         return endl( rStrm );
    1675             : }
    1676             : 
    1677        1333 : SvMemoryStream::SvMemoryStream( void* pBuffer, sal_Size bufSize,
    1678        1333 :                                 StreamMode eMode )
    1679             : {
    1680        1333 :     if( eMode & STREAM_WRITE )
    1681         392 :         bIsWritable = sal_True;
    1682             :     else
    1683         941 :         bIsWritable = sal_False;
    1684        1333 :     nEndOfData  = bufSize;
    1685        1333 :     bOwnsData   = sal_False;
    1686        1333 :     pBuf        = (sal_uInt8 *) pBuffer;
    1687        1333 :     nResize     = 0L;
    1688        1333 :     nSize       = bufSize;
    1689        1333 :     nPos        = 0L;
    1690        1333 :     SetBufferSize( 0 );
    1691        1333 : }
    1692             : 
    1693        4433 : SvMemoryStream::SvMemoryStream( sal_Size nInitSize, sal_Size nResizeOffset )
    1694             : {
    1695        4433 :     bIsWritable = sal_True;
    1696        4433 :     bOwnsData   = sal_True;
    1697        4433 :     nEndOfData  = 0L;
    1698        4433 :     nResize     = nResizeOffset;
    1699        4433 :     nPos        = 0;
    1700        4433 :     pBuf        = 0;
    1701        4433 :     if( nResize != 0 && nResize < 16 )
    1702           0 :         nResize = 16;
    1703        4433 :     if( nInitSize && !AllocateMemory( nInitSize ) )
    1704             :     {
    1705           0 :         SetError( SVSTREAM_OUTOFMEMORY );
    1706           0 :         nSize = 0;
    1707             :     }
    1708             :     else
    1709        4433 :         nSize = nInitSize;
    1710        4433 :     SetBufferSize( 64 );
    1711        4433 : }
    1712             : 
    1713       11666 : SvMemoryStream::~SvMemoryStream()
    1714             : {
    1715        5763 :     if( pBuf )
    1716             :     {
    1717        5703 :         if( bOwnsData )
    1718        4335 :             FreeMemory();
    1719             :         else
    1720        1368 :             Flush();
    1721             :     }
    1722        5903 : }
    1723             : 
    1724           0 : sal_uInt16 SvMemoryStream::IsA() const
    1725             : {
    1726           0 :     return (sal_uInt16)ID_MEMORYSTREAM;
    1727             : }
    1728             : 
    1729          67 : void* SvMemoryStream::SetBuffer( void* pNewBuf, sal_Size nCount,
    1730             :                                  sal_Bool bOwnsDat, sal_Size nEOF )
    1731             : {
    1732             :     void* pResult;
    1733          67 :     SetBufferSize( 0 ); // Buffering in der Basisklasse initialisieren
    1734          67 :     Seek( 0 );
    1735          67 :     if( bOwnsData )
    1736             :     {
    1737          67 :         pResult = 0;
    1738          67 :         if( pNewBuf != pBuf )
    1739          67 :             FreeMemory();
    1740             :     }
    1741             :     else
    1742           0 :         pResult = pBuf;
    1743             : 
    1744          67 :     pBuf        = (sal_uInt8 *) pNewBuf;
    1745          67 :     nPos        = 0;
    1746          67 :     nSize       = nCount;
    1747          67 :     nResize     = 0;
    1748          67 :     bOwnsData   = bOwnsDat;
    1749             : 
    1750          67 :     if( nEOF > nCount )
    1751           0 :         nEOF = nCount;
    1752          67 :     nEndOfData = nEOF;
    1753             : 
    1754          67 :     ResetError();
    1755             : 
    1756             :     DBG_ASSERT( nEndOfData<STREAM_SEEK_TO_END,"Invalid EOF");
    1757          67 :     return pResult;
    1758             : }
    1759             : 
    1760      173063 : sal_Size SvMemoryStream::GetData( void* pData, sal_Size nCount )
    1761             : {
    1762      173063 :     sal_Size nMaxCount = nEndOfData-nPos;
    1763      173063 :     if( nCount > nMaxCount )
    1764      115265 :         nCount = nMaxCount;
    1765      173063 :     memcpy( pData, pBuf+nPos, (size_t)nCount );
    1766      173063 :     nPos += nCount;
    1767      173063 :     return nCount;
    1768             : }
    1769             : 
    1770      713215 : sal_Size SvMemoryStream::PutData( const void* pData, sal_Size nCount )
    1771             : {
    1772      713215 :     if( GetError() )
    1773           0 :         return 0L;
    1774             : 
    1775      713215 :     sal_Size nMaxCount = nSize-nPos;
    1776             : 
    1777             :     // check for overflow
    1778      713215 :     if( nCount > nMaxCount )
    1779             :     {
    1780        1067 :         if( nResize == 0 )
    1781             :         {
    1782             :             // copy as much as possible
    1783           0 :             nCount = nMaxCount;
    1784           0 :             SetError( SVSTREAM_OUTOFMEMORY );
    1785             :         }
    1786             :         else
    1787             :         {
    1788             :             long nNewResize;
    1789        1067 :             if( nSize && nSize > nResize )
    1790         837 :                 nNewResize = nSize;
    1791             :             else
    1792         230 :                 nNewResize = nResize;
    1793             : 
    1794        1067 :             if( (nCount-nMaxCount) < nResize )
    1795             :             {
    1796             :                 // lacking memory is smaller than nResize,
    1797             :                 // resize accordingly
    1798         962 :                 if( !ReAllocateMemory( nNewResize) )
    1799             :                 {
    1800           0 :                     nCount = 0;
    1801           0 :                     SetError( SVSTREAM_WRITE_ERROR );
    1802             :                 }
    1803             :             }
    1804             :             else
    1805             :             {
    1806             :                 // lacking memory is larger than nResize,
    1807             :                 // resize by (nCoount-nMaxCount) + resize offset
    1808         105 :                 if( !ReAllocateMemory( nCount-nMaxCount+nNewResize ) )
    1809             :                 {
    1810           0 :                     nCount = 0;
    1811           0 :                     SetError( SVSTREAM_WRITE_ERROR );
    1812             :                 }
    1813             :             }
    1814             :         }
    1815             :     }
    1816             :     DBG_ASSERT(pBuf,"Possibly Reallocate failed");
    1817      713215 :     memcpy( pBuf+nPos, pData, (size_t)nCount);
    1818             : 
    1819      713215 :     nPos += nCount;
    1820      713215 :     if( nPos > nEndOfData )
    1821      473727 :         nEndOfData = nPos;
    1822      713215 :     return nCount;
    1823             : }
    1824             : 
    1825     1499408 : sal_Size SvMemoryStream::SeekPos( sal_Size nNewPos )
    1826             : {
    1827             :     // nEndOfData: First position in stream not allowed to read from
    1828             :     // nSize: Size of allocated buffer
    1829             : 
    1830     1499408 :     if( nNewPos < nEndOfData )
    1831      496406 :         nPos = nNewPos;
    1832     1003002 :     else if( nNewPos == STREAM_SEEK_TO_END )
    1833        2816 :         nPos = nEndOfData;
    1834             :     else
    1835             :     {
    1836     1000186 :         if( nNewPos >= nSize ) // Does buffer need extension?
    1837             :         {
    1838         221 :             if( nResize )  // Is extension possible?
    1839             :             {
    1840         209 :                 long nDiff = (long)(nNewPos - nSize + 1);
    1841         209 :                 nDiff += (long)nResize;
    1842         209 :                 ReAllocateMemory( nDiff );
    1843         209 :                 nPos = nNewPos;
    1844         209 :                 nEndOfData = nNewPos;
    1845             :             }
    1846             :             else  // Extension not possible, set pos to end of data
    1847             :             {
    1848             :                 // SetError( SVSTREAM_OUTOFMEMORY );
    1849          12 :                 nPos = nEndOfData;
    1850             :             }
    1851             :         }
    1852             :         else  // Expand buffer size
    1853             :         {
    1854      999965 :             nPos = nNewPos;
    1855      999965 :             nEndOfData = nNewPos;
    1856             :         }
    1857             :     }
    1858     1499408 :     return nPos;
    1859             : }
    1860             : 
    1861        5805 : void SvMemoryStream::FlushData()
    1862             : {
    1863        5805 : }
    1864             : 
    1865          77 : void SvMemoryStream::ResetError()
    1866             : {
    1867          77 :     SvStream::ClearError();
    1868          77 : }
    1869             : 
    1870        4382 : sal_Bool SvMemoryStream::AllocateMemory( sal_Size nNewSize )
    1871             : {
    1872        4382 :     pBuf = new sal_uInt8[nNewSize];
    1873        4382 :     return( pBuf != 0 );
    1874             : }
    1875             : 
    1876             : // (using Bozo algorithm)
    1877        1276 : sal_Bool SvMemoryStream::ReAllocateMemory( long nDiff )
    1878             : {
    1879        1276 :     sal_Bool bRetVal    = sal_False;
    1880        1276 :     long nTemp      = (long)nSize;
    1881        1276 :     nTemp           += nDiff;
    1882        1276 :     sal_Size nNewSize  = (sal_Size)nTemp;
    1883             : 
    1884        1276 :     if( nNewSize )
    1885             :     {
    1886        1276 :         sal_uInt8* pNewBuf   = new sal_uInt8[nNewSize];
    1887             : 
    1888        1276 :         if( pNewBuf )
    1889             :         {
    1890        1276 :             bRetVal = sal_True; // Success!
    1891        1276 :             if( nNewSize < nSize )      // Are we shrinking?
    1892             :             {
    1893           0 :                 memcpy( pNewBuf, pBuf, (size_t)nNewSize );
    1894           0 :                 if( nPos > nNewSize )
    1895           0 :                     nPos = 0L;
    1896           0 :                 if( nEndOfData >= nNewSize )
    1897           0 :                     nEndOfData = nNewSize-1L;
    1898             :             }
    1899             :             else
    1900             :             {
    1901        1276 :                 memcpy( pNewBuf, pBuf, (size_t)nSize );
    1902             :             }
    1903             : 
    1904        1276 :             FreeMemory();
    1905             : 
    1906        1276 :             pBuf  = pNewBuf;
    1907        1276 :             nSize = nNewSize;
    1908             :         }
    1909             :     }
    1910             :     else
    1911             :     {
    1912           0 :         bRetVal = sal_True;
    1913           0 :         FreeMemory();
    1914           0 :         pBuf = 0;
    1915           0 :         nSize = 0;
    1916           0 :         nEndOfData = 0;
    1917           0 :         nPos = 0;
    1918             :     }
    1919             : 
    1920        1276 :     return bRetVal;
    1921             : }
    1922             : 
    1923        5678 : void SvMemoryStream::FreeMemory()
    1924             : {
    1925        5678 :     delete[] pBuf;
    1926        5678 : }
    1927             : 
    1928           9 : void* SvMemoryStream::SwitchBuffer( sal_Size nInitSize, sal_Size nResizeOffset)
    1929             : {
    1930           9 :     Flush();
    1931           9 :     if( !bOwnsData )
    1932           0 :         return 0;
    1933           9 :     Seek( STREAM_SEEK_TO_BEGIN );
    1934             : 
    1935           9 :     void* pRetVal = pBuf;
    1936           9 :     pBuf          = 0;
    1937           9 :     nEndOfData    = 0L;
    1938           9 :     nResize       = nResizeOffset;
    1939           9 :     nPos          = 0;
    1940             : 
    1941           9 :     if( nResize != 0 && nResize < 16 )
    1942           0 :         nResize = 16;
    1943             : 
    1944           9 :     ResetError();
    1945             : 
    1946           9 :     if( nInitSize && !AllocateMemory(nInitSize) )
    1947             :     {
    1948           0 :         SetError( SVSTREAM_OUTOFMEMORY );
    1949           0 :         nSize = 0;
    1950             :     }
    1951             :     else
    1952           9 :         nSize = nInitSize;
    1953             : 
    1954           9 :     SetBufferSize( 64 );
    1955           9 :     return pRetVal;
    1956             : }
    1957             : 
    1958           0 : void SvMemoryStream::SetSize( sal_Size nNewSize )
    1959             : {
    1960           0 :     long nDiff = (long)nNewSize - (long)nSize;
    1961           0 :     ReAllocateMemory( nDiff );
    1962           0 : }
    1963             : 
    1964           0 : TYPEINIT0 ( SvDataCopyStream )
    1965             : 
    1966           0 : void SvDataCopyStream::Assign( const SvDataCopyStream& )
    1967             : {
    1968           0 : }
    1969             : 
    1970             : //Create a OString of nLen bytes from rStream
    1971       74211 : rtl::OString read_uInt8s_ToOString(SvStream& rStrm, sal_Size nLen)
    1972             : {
    1973       74211 :     rtl_String *pStr = NULL;
    1974       74211 :     if (nLen)
    1975             :     {
    1976       35602 :         nLen = std::min(nLen, static_cast<sal_Size>(SAL_MAX_INT32));
    1977             :         //alloc a (ref-count 1) rtl_String of the desired length.
    1978             :         //rtl_String's buffer is uninitialized, except for null termination
    1979       35602 :         pStr = rtl_string_alloc(sal::static_int_cast<sal_Int32>(nLen));
    1980       35602 :         sal_Size nWasRead = rStrm.Read(pStr->buffer, nLen);
    1981       35602 :         if (nWasRead != nLen)
    1982             :         {
    1983             :             //on (typically unlikely) short read set length to what we could
    1984             :             //read, and null terminate. Excess buffer capacity remains of
    1985             :             //course, could create a (true) replacement OString if it matters.
    1986           4 :             pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
    1987           4 :             pStr->buffer[pStr->length] = 0;
    1988             :         }
    1989             :     }
    1990             : 
    1991             :     //take ownership of buffer and return, otherwise return empty string
    1992       74211 :     return pStr ? rtl::OString(pStr, SAL_NO_ACQUIRE) : rtl::OString();
    1993             : }
    1994             : 
    1995             : //Create a OUString of nLen sal_Unicodes from rStream
    1996       31022 : rtl::OUString read_uInt16s_ToOUString(SvStream& rStrm, sal_Size nLen)
    1997             : {
    1998       31022 :     rtl_uString *pStr = NULL;
    1999       31022 :     if (nLen)
    2000             :     {
    2001       30188 :         nLen = std::min(nLen, static_cast<sal_Size>(SAL_MAX_INT32));
    2002             :         //alloc a (ref-count 1) rtl_uString of the desired length.
    2003             :         //rtl_String's buffer is uninitialized, except for null termination
    2004       30188 :         pStr = rtl_uString_alloc(sal::static_int_cast<sal_Int32>(nLen));
    2005       30188 :         sal_Size nWasRead = rStrm.Read(pStr->buffer, nLen*2)/2;
    2006       30188 :         if (nWasRead != nLen)
    2007             :         {
    2008             :             //on (typically unlikely) short read set length to what we could
    2009             :             //read, and null terminate. Excess buffer capacity remains of
    2010             :             //course, could create a (true) replacement OUString if it matters.
    2011           4 :             pStr->length = sal::static_int_cast<sal_Int32>(nWasRead);
    2012           4 :             pStr->buffer[pStr->length] = 0;
    2013             :         }
    2014       30188 :         if (rStrm.IsEndianSwap())
    2015             :         {
    2016           0 :             for (sal_Int32 i = 0; i < pStr->length; ++i)
    2017           0 :                 pStr->buffer[i] = OSL_SWAPWORD(pStr->buffer[i]);
    2018             :         }
    2019             :     }
    2020             : 
    2021             :     //take ownership of buffer and return, otherwise return empty string
    2022       31022 :     return pStr ? rtl::OUString(pStr, SAL_NO_ACQUIRE) : rtl::OUString();
    2023             : }
    2024             : 
    2025             : namespace
    2026             : {
    2027        8096 :     template <typename T, typename O> T tmpl_convertLineEnd(const T &rIn, LineEnd eLineEnd)
    2028             :     {
    2029             :         // Determine linebreaks and compute length
    2030        8096 :         bool            bConvert    = false;    // Needs conversion
    2031        8096 :         sal_Int32       nStrLen     = rIn.getLength();
    2032        8096 :         sal_Int32       nLineEndLen = (eLineEnd == LINEEND_CRLF) ? 2 : 1;
    2033        8096 :         sal_Int32       nLen        = 0;        // Target length
    2034        8096 :         sal_Int32       i           = 0;        // Source counter
    2035             : 
    2036       79817 :         while (i < nStrLen)
    2037             :         {
    2038             :             // \r or \n causes linebreak
    2039       63625 :             if ( (rIn[i] == _CR) || (rIn[i] == _LF) )
    2040             :             {
    2041         630 :                 nLen = nLen + nLineEndLen;
    2042             : 
    2043             :                 // If set already, skip expensive test
    2044         630 :                 if ( !bConvert )
    2045             :                 {
    2046             :                     // Muessen wir Konvertieren
    2047         630 :                     if ( ((eLineEnd != LINEEND_LF) && (rIn[i] == _LF)) ||
    2048             :                          ((eLineEnd == LINEEND_CRLF) && (rIn[i+1] != _LF)) ||
    2049             :                          ((eLineEnd == LINEEND_LF) &&
    2050             :                           ((rIn[i] == _CR) || (rIn[i+1] == _CR))) ||
    2051             :                          ((eLineEnd == LINEEND_CR) &&
    2052             :                           ((rIn[i] == _LF) || (rIn[i+1] == _LF))) )
    2053         248 :                         bConvert = true;
    2054             :                 }
    2055             : 
    2056             :                 // skip char if \r\n oder \n\r
    2057         630 :                 if ( ((rIn[i+1] == _CR) || (rIn[i+1] == _LF)) &&
    2058             :                      (rIn[i] != rIn[i+1]) )
    2059           0 :                     ++i;
    2060             :             }
    2061             :             else
    2062       62995 :                 ++nLen;
    2063       63625 :             ++i;
    2064             :         }
    2065             : 
    2066        8096 :         if (!bConvert)
    2067        7848 :             return rIn;
    2068             : 
    2069             :         // convert linebreaks, insert string
    2070         248 :         O aNewData(nLen);
    2071         248 :         i = 0;
    2072         744 :         while (i < nStrLen)
    2073             :         {
    2074             :             // \r or \n causes linebreak
    2075         248 :             if ( (rIn[i] == _CR) || (rIn[i] == _LF) )
    2076             :             {
    2077         248 :                 if ( eLineEnd == LINEEND_CRLF )
    2078             :                 {
    2079           0 :                     aNewData.append(_CR);
    2080           0 :                     aNewData.append(_LF);
    2081             :                 }
    2082             :                 else
    2083             :                 {
    2084         248 :                     if ( eLineEnd == LINEEND_CR )
    2085           0 :                         aNewData.append(_CR);
    2086             :                     else
    2087         248 :                         aNewData.append(_LF);
    2088             :                 }
    2089             : 
    2090         248 :                 if ( ((rIn[i+1] == _CR) || (rIn[i+1] == _LF)) &&
    2091             :                      (rIn[i] != rIn[i+1]) )
    2092           0 :                     ++i;
    2093             :             }
    2094             :             else
    2095             :             {
    2096           0 :                 aNewData.append(rIn[i]);
    2097             :             }
    2098             : 
    2099         248 :             ++i;
    2100             :         }
    2101             : 
    2102         248 :         return aNewData.makeStringAndClear();
    2103             :     }
    2104             : }
    2105             : 
    2106           0 : rtl::OString convertLineEnd(const rtl::OString &rIn, LineEnd eLineEnd)
    2107             : {
    2108           0 :     return tmpl_convertLineEnd<rtl::OString, rtl::OStringBuffer>(rIn, eLineEnd);
    2109             : }
    2110             : 
    2111        8096 : rtl::OUString convertLineEnd(const rtl::OUString &rIn, LineEnd eLineEnd)
    2112             : {
    2113        8096 :     return tmpl_convertLineEnd<rtl::OUString, rtl::OUStringBuffer>(rIn, eLineEnd);
    2114             : }
    2115             : 
    2116             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10