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

Generated by: LCOV version 1.10