LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xistream.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 342 539 63.5 %
Date: 2015-06-13 12:38:46 Functions: 53 82 64.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <comphelper/docpasswordhelper.hxx>
      21             : #include <comphelper/sequenceashashmap.hxx>
      22             : #include <osl/thread.h>
      23             : #include <osl/diagnose.h>
      24             : #include "xistream.hxx"
      25             : #include "xlstring.hxx"
      26             : #include "xiroot.hxx"
      27             : 
      28             : #include <vector>
      29             : #include <boost/scoped_array.hpp>
      30             : 
      31             : using namespace ::com::sun::star;
      32             : 
      33             : // Decryption
      34           0 : XclImpDecrypter::XclImpDecrypter() :
      35             :     mnError( EXC_ENCR_ERROR_UNSUPP_CRYPT ),
      36             :     mnOldPos( STREAM_SEEK_TO_END ),
      37           0 :     mnRecSize( 0 )
      38             : {
      39           0 : }
      40             : 
      41           0 : XclImpDecrypter::XclImpDecrypter( const XclImpDecrypter& rSrc ) :
      42             :     ::comphelper::IDocPasswordVerifier(),
      43             :     mnError( rSrc.mnError ),
      44             :     mnOldPos( STREAM_SEEK_TO_END ),
      45           0 :     mnRecSize( 0 )
      46             : {
      47           0 : }
      48             : 
      49           0 : XclImpDecrypter::~XclImpDecrypter()
      50             : {
      51           0 : }
      52             : 
      53           0 : XclImpDecrypterRef XclImpDecrypter::Clone() const
      54             : {
      55           0 :     XclImpDecrypterRef xNewDecr;
      56           0 :     if( IsValid() )
      57           0 :         xNewDecr.reset( OnClone() );
      58           0 :     return xNewDecr;
      59             : }
      60             : 
      61           0 : ::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
      62             : {
      63           0 :     o_rEncryptionData = OnVerifyPassword( rPassword );
      64           0 :     mnError = o_rEncryptionData.getLength() ? ERRCODE_NONE : ERRCODE_ABORT;
      65           0 :     return o_rEncryptionData.getLength() ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
      66             : }
      67             : 
      68           0 : ::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
      69             : {
      70           0 :     bool bValid = OnVerifyEncryptionData( rEncryptionData );
      71           0 :     mnError = bValid ? ERRCODE_NONE : ERRCODE_ABORT;
      72           0 :     return bValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
      73             : }
      74             : 
      75           0 : void XclImpDecrypter::Update( SvStream& rStrm, sal_uInt16 nRecSize )
      76             : {
      77           0 :     if( IsValid() )
      78             :     {
      79           0 :         sal_uInt64 const nNewPos = rStrm.Tell();
      80           0 :         if( (mnOldPos != nNewPos) || (mnRecSize != nRecSize) )
      81             :         {
      82           0 :             OnUpdate( mnOldPos, nNewPos, nRecSize );
      83           0 :             mnOldPos = nNewPos;
      84           0 :             mnRecSize = nRecSize;
      85             :         }
      86             :     }
      87           0 : }
      88             : 
      89           0 : sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes )
      90             : {
      91           0 :     sal_uInt16 nRet = 0;
      92           0 :     if( pData && nBytes )
      93             :     {
      94           0 :         if( IsValid() )
      95             :         {
      96           0 :             Update( rStrm, mnRecSize );
      97           0 :             nRet = OnRead( rStrm, static_cast< sal_uInt8* >( pData ), nBytes );
      98           0 :             mnOldPos = rStrm.Tell();
      99             :         }
     100             :         else
     101           0 :             nRet = static_cast< sal_uInt16 >( rStrm.Read( pData, nBytes ) );
     102             :     }
     103           0 :     return nRet;
     104             : }
     105             : 
     106           0 : XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) :
     107             :     mnKey( nKey ),
     108           0 :     mnHash( nHash )
     109             : {
     110           0 : }
     111             : 
     112           0 : XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc ) :
     113             :     XclImpDecrypter( rSrc ),
     114             :     maEncryptionData( rSrc.maEncryptionData ),
     115             :     mnKey( rSrc.mnKey ),
     116           0 :     mnHash( rSrc.mnHash )
     117             : {
     118           0 :     if( IsValid() )
     119           0 :         maCodec.InitCodec( maEncryptionData );
     120           0 : }
     121             : 
     122           0 : XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const
     123             : {
     124           0 :     return new XclImpBiff5Decrypter( *this );
     125             : }
     126             : 
     127           0 : uno::Sequence< beans::NamedValue > XclImpBiff5Decrypter::OnVerifyPassword( const OUString& rPassword )
     128             : {
     129           0 :     maEncryptionData.realloc( 0 );
     130             : 
     131             :     /*  Convert password to a byte string. TODO: this needs some finetuning
     132             :         according to the spec... */
     133           0 :     OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
     134           0 :     sal_Int32 nLen = aBytePassword.getLength();
     135           0 :     if( (0 < nLen) && (nLen < 16) )
     136             :     {
     137             :         // init codec
     138           0 :         maCodec.InitKey( reinterpret_cast<sal_uInt8 const *>(aBytePassword.getStr()) );
     139             : 
     140           0 :         if ( maCodec.VerifyKey( mnKey, mnHash ) )
     141             :         {
     142           0 :             maEncryptionData = maCodec.GetEncryptionData();
     143             : 
     144             :             // since the export uses Std97 encryption always we have to request it here
     145           0 :             ::std::vector< sal_uInt16 > aPassVect( 16 );
     146           0 :             ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
     147           0 :             for( sal_Int32 nInd = 0; nInd < nLen; ++nInd, ++aIt )
     148           0 :                 *aIt = static_cast< sal_uInt16 >( rPassword[nInd] );
     149             : 
     150           0 :             uno::Sequence< sal_Int8 > aDocId = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
     151             :             OSL_ENSURE( aDocId.getLength() == 16, "Unexpected length of the senquence!" );
     152             : 
     153           0 :             ::msfilter::MSCodec_Std97 aCodec97;
     154           0 :             aCodec97.InitKey( &aPassVect.front(), reinterpret_cast<sal_uInt8 const *>(aDocId.getConstArray()) );
     155             : 
     156             :             // merge the EncryptionData, there should be no conflicts
     157           0 :             ::comphelper::SequenceAsHashMap aEncryptionHash( maEncryptionData );
     158           0 :             aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) );
     159           0 :             aEncryptionHash >> maEncryptionData;
     160             :         }
     161             :     }
     162             : 
     163           0 :     return maEncryptionData;
     164             : }
     165             : 
     166           0 : bool XclImpBiff5Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
     167             : {
     168           0 :     maEncryptionData.realloc( 0 );
     169             : 
     170           0 :     if( rEncryptionData.getLength() )
     171             :     {
     172             :         // init codec
     173           0 :         maCodec.InitCodec( rEncryptionData );
     174             : 
     175           0 :         if ( maCodec.VerifyKey( mnKey, mnHash ) )
     176           0 :             maEncryptionData = rEncryptionData;
     177             :     }
     178             : 
     179           0 :     return maEncryptionData.getLength();
     180             : }
     181             : 
     182           0 : void XclImpBiff5Decrypter::OnUpdate( sal_Size /*nOldStrmPos*/, sal_Size nNewStrmPos, sal_uInt16 nRecSize )
     183             : {
     184           0 :     maCodec.InitCipher();
     185           0 :     maCodec.Skip( (nNewStrmPos + nRecSize) & 0x0F );
     186           0 : }
     187             : 
     188           0 : sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
     189             : {
     190           0 :     sal_uInt16 nRet = static_cast< sal_uInt16 >( rStrm.Read( pnData, nBytes ) );
     191           0 :     maCodec.Decode( pnData, nRet );
     192           0 :     return nRet;
     193             : }
     194             : 
     195           0 : XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
     196             :         sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
     197             :     maSalt( pnSalt, pnSalt + 16 ),
     198             :     maVerifier( pnVerifier, pnVerifier + 16 ),
     199           0 :     maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
     200             : {
     201           0 : }
     202             : 
     203           0 : XclImpBiff8Decrypter::XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ) :
     204             :     XclImpDecrypter( rSrc ),
     205             :     maEncryptionData( rSrc.maEncryptionData ),
     206             :     maSalt( rSrc.maSalt ),
     207             :     maVerifier( rSrc.maVerifier ),
     208           0 :     maVerifierHash( rSrc.maVerifierHash )
     209             : {
     210           0 :     if( IsValid() )
     211           0 :         maCodec.InitCodec( maEncryptionData );
     212           0 : }
     213             : 
     214           0 : XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const
     215             : {
     216           0 :     return new XclImpBiff8Decrypter( *this );
     217             : }
     218             : 
     219           0 : uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const OUString& rPassword )
     220             : {
     221           0 :     maEncryptionData.realloc( 0 );
     222             : 
     223           0 :     sal_Int32 nLen = rPassword.getLength();
     224           0 :     if( (0 < nLen) && (nLen < 16) )
     225             :     {
     226             :         // copy string to sal_uInt16 array
     227           0 :         ::std::vector< sal_uInt16 > aPassVect( 16 );
     228           0 :         const sal_Unicode* pcChar = rPassword.getStr();
     229           0 :         const sal_Unicode* pcCharEnd = pcChar + nLen;
     230           0 :         ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
     231           0 :         for( ; pcChar < pcCharEnd; ++pcChar, ++aIt )
     232           0 :             *aIt = static_cast< sal_uInt16 >( *pcChar );
     233             : 
     234             :         // init codec
     235           0 :         maCodec.InitKey( &aPassVect.front(), &maSalt.front() );
     236           0 :         if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
     237           0 :             maEncryptionData = maCodec.GetEncryptionData();
     238             :     }
     239             : 
     240           0 :     return maEncryptionData;
     241             : }
     242             : 
     243           0 : bool XclImpBiff8Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
     244             : {
     245           0 :     maEncryptionData.realloc( 0 );
     246             : 
     247           0 :     if( rEncryptionData.getLength() )
     248             :     {
     249             :         // init codec
     250           0 :         maCodec.InitCodec( rEncryptionData );
     251             : 
     252           0 :         if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
     253           0 :             maEncryptionData = rEncryptionData;
     254             :     }
     255             : 
     256           0 :     return maEncryptionData.getLength();
     257             : }
     258             : 
     259           0 : void XclImpBiff8Decrypter::OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 /*nRecSize*/ )
     260             : {
     261           0 :     if( nNewStrmPos != nOldStrmPos )
     262             :     {
     263           0 :         sal_uInt32 nOldBlock = GetBlock( nOldStrmPos );
     264           0 :         sal_uInt16 nOldOffset = GetOffset( nOldStrmPos );
     265             : 
     266           0 :         sal_uInt32 nNewBlock = GetBlock( nNewStrmPos );
     267           0 :         sal_uInt16 nNewOffset = GetOffset( nNewStrmPos );
     268             : 
     269             :         /*  Rekey cipher, if block changed or if previous offset in same block. */
     270           0 :         if( (nNewBlock != nOldBlock) || (nNewOffset < nOldOffset) )
     271             :         {
     272           0 :             maCodec.InitCipher( nNewBlock );
     273           0 :             nOldOffset = 0;     // reset nOldOffset for next if() statement
     274             :         }
     275             : 
     276             :         /*  Seek to correct offset. */
     277           0 :         if( nNewOffset > nOldOffset )
     278           0 :             maCodec.Skip( nNewOffset - nOldOffset );
     279             :     }
     280           0 : }
     281             : 
     282           0 : sal_uInt16 XclImpBiff8Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
     283             : {
     284           0 :     sal_uInt16 nRet = 0;
     285             : 
     286           0 :     sal_uInt8* pnCurrData = pnData;
     287           0 :     sal_uInt16 nBytesLeft = nBytes;
     288           0 :     while( nBytesLeft )
     289             :     {
     290           0 :         sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - GetOffset( rStrm.Tell() );
     291           0 :         sal_uInt16 nDecBytes = ::std::min< sal_uInt16 >( nBytesLeft, nBlockLeft );
     292             : 
     293             :         // read the block from stream
     294           0 :         nRet = nRet + static_cast< sal_uInt16 >( rStrm.Read( pnCurrData, nDecBytes ) );
     295             :         // decode the block inplace
     296           0 :         maCodec.Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
     297           0 :         if( GetOffset( rStrm.Tell() ) == 0 )
     298           0 :             maCodec.InitCipher( GetBlock( rStrm.Tell() ) );
     299             : 
     300           0 :         pnCurrData += nDecBytes;
     301           0 :         nBytesLeft = nBytesLeft - nDecBytes;
     302             :     }
     303             : 
     304           0 :     return nRet;
     305             : }
     306             : 
     307           0 : sal_uInt32 XclImpBiff8Decrypter::GetBlock( sal_Size nStrmPos )
     308             : {
     309           0 :     return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
     310             : }
     311             : 
     312           0 : sal_uInt16 XclImpBiff8Decrypter::GetOffset( sal_Size nStrmPos )
     313             : {
     314           0 :     return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
     315             : }
     316             : 
     317             : // Stream
     318       11580 : XclImpStreamPos::XclImpStreamPos() :
     319             :     mnPos( STREAM_SEEK_TO_BEGIN ),
     320             :     mnNextPos( STREAM_SEEK_TO_BEGIN ),
     321             :     mnCurrSize( 0 ),
     322             :     mnRawRecId( EXC_ID_UNKNOWN ),
     323             :     mnRawRecSize( 0 ),
     324             :     mnRawRecLeft( 0 ),
     325       11580 :     mbValid( false )
     326             : {
     327       11580 : }
     328             : 
     329     1187030 : void XclImpStreamPos::Set(
     330             :         const SvStream& rStrm, sal_Size nNextPos, sal_Size nCurrSize,
     331             :         sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
     332             :         bool bValid )
     333             : {
     334     1187030 :     mnPos = rStrm.Tell();
     335     1187030 :     mnNextPos = nNextPos;
     336     1187030 :     mnCurrSize = nCurrSize;
     337     1187030 :     mnRawRecId = nRawRecId;
     338     1187030 :     mnRawRecSize = nRawRecSize;
     339     1187030 :     mnRawRecLeft = nRawRecLeft;
     340     1187030 :     mbValid = bValid;
     341     1187030 : }
     342             : 
     343       12493 : void XclImpStreamPos::Get(
     344             :         SvStream& rStrm, sal_Size& rnNextPos, sal_Size& rnCurrSize,
     345             :         sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
     346             :         bool& rbValid ) const
     347             : {
     348       12493 :     rStrm.Seek( mnPos );
     349       12493 :     rnNextPos = mnNextPos;
     350       12493 :     rnCurrSize = mnCurrSize;
     351       12493 :     rnRawRecId = mnRawRecId;
     352       12493 :     rnRawRecSize = mnRawRecSize;
     353       12493 :     rnRawRecLeft = mnRawRecLeft;
     354       12493 :     rbValid = mbValid;
     355       12493 : }
     356             : 
     357          85 : XclBiff XclImpStream::DetectBiffVersion( SvStream& rStrm )
     358             : {
     359          85 :     XclBiff eBiff = EXC_BIFF_UNKNOWN;
     360             : 
     361          85 :     rStrm.Seek( STREAM_SEEK_TO_BEGIN );
     362             :     sal_uInt16 nBofId, nBofSize;
     363          85 :     rStrm.ReadUInt16( nBofId ).ReadUInt16( nBofSize );
     364             : 
     365          85 :     if( (4 <= nBofSize) && (nBofSize <= 16) ) switch( nBofId )
     366             :     {
     367             :         case EXC_ID2_BOF:
     368           0 :             eBiff = EXC_BIFF2;
     369           0 :         break;
     370             :         case EXC_ID3_BOF:
     371           0 :             eBiff = EXC_BIFF3;
     372           0 :         break;
     373             :         case EXC_ID4_BOF:
     374           0 :             eBiff = EXC_BIFF4;
     375           0 :         break;
     376             :         case EXC_ID5_BOF:
     377             :         {
     378             :             sal_uInt16 nVersion;
     379          84 :             rStrm.ReadUInt16( nVersion );
     380             :             // #i23425# #i44031# #i62752# there are some *really* broken documents out there...
     381          84 :             switch( nVersion & 0xFF00 )
     382             :             {
     383           0 :                 case 0:             eBiff = EXC_BIFF5;  break;  // #i44031# #i62752#
     384           0 :                 case EXC_BOF_BIFF2: eBiff = EXC_BIFF2;  break;
     385           0 :                 case EXC_BOF_BIFF3: eBiff = EXC_BIFF3;  break;
     386           0 :                 case EXC_BOF_BIFF4: eBiff = EXC_BIFF4;  break;
     387           3 :                 case EXC_BOF_BIFF5: eBiff = EXC_BIFF5;  break;
     388          81 :                 case EXC_BOF_BIFF8: eBiff = EXC_BIFF8;  break;
     389             :                 default:    OSL_TRACE( "XclImpStream::DetectBiffVersion - unknown BIFF version: 0x%04hX", nVersion );
     390             :             }
     391             :         }
     392          84 :         break;
     393             :     }
     394          85 :     return eBiff;
     395             : }
     396             : 
     397         193 : XclImpStream::XclImpStream( SvStream& rInStrm, const XclImpRoot& rRoot, bool bContLookup ) :
     398             :     mrStrm( rInStrm ),
     399             :     mrRoot( rRoot ),
     400             :     mnGlobRecId( EXC_ID_UNKNOWN ),
     401             :     mbGlobValidRec( false ),
     402             :     mbHasGlobPos( false ),
     403             :     mnNextRecPos( STREAM_SEEK_TO_BEGIN ),
     404             :     mnCurrRecSize( 0 ),
     405             :     mnComplRecSize( 0 ),
     406             :     mbHasComplRec( false ),
     407             :     mnRecId( EXC_ID_UNKNOWN ),
     408             :     mnAltContId( EXC_ID_UNKNOWN ),
     409             :     mnRawRecId( EXC_ID_UNKNOWN ),
     410             :     mnRawRecSize( 0 ),
     411             :     mnRawRecLeft( 0 ),
     412             :     mcNulSubst( '?' ),
     413             :     mbCont( bContLookup ),
     414             :     mbUseDecr( false ),
     415             :     mbValidRec( false ),
     416         193 :     mbValid( false )
     417             : {
     418         193 :     mrStrm.Seek( STREAM_SEEK_TO_END );
     419         193 :     mnStreamSize = mrStrm.Tell();
     420         193 :     mrStrm.Seek( STREAM_SEEK_TO_BEGIN );
     421         193 : }
     422             : 
     423         193 : XclImpStream::~XclImpStream()
     424             : {
     425         193 : }
     426             : 
     427     1175529 : bool XclImpStream::StartNextRecord()
     428             : {
     429     1175529 :     maPosStack.clear();
     430             : 
     431             :     /*  #i4266# Counter to ignore zero records (id==len==0) (i.e. the application
     432             :         "Crystal Report" writes zero records between other records) */
     433     1175529 :     sal_Size nZeroRecCount = 5;
     434     1175529 :     bool bIsZeroRec = false;
     435             : 
     436     1175663 :     do
     437             :     {
     438     1175663 :         mbValidRec = ReadNextRawRecHeader();
     439     1175663 :         bIsZeroRec = (mnRawRecId == 0) && (mnRawRecSize == 0);
     440     1175663 :         if( bIsZeroRec ) --nZeroRecCount;
     441     1175663 :         mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
     442             :     }
     443     1175663 :     while( mbValidRec && ((mbCont && IsContinueId( mnRawRecId )) || (bIsZeroRec && nZeroRecCount)) );
     444             : 
     445     1175529 :     mbValidRec = mbValidRec && !bIsZeroRec;
     446     1175529 :     mbValid = mbValidRec;
     447     1175529 :     SetupRecord();
     448             : 
     449     1175529 :     return mbValidRec;
     450             : }
     451             : 
     452         224 : bool XclImpStream::StartNextRecord( sal_Size nNextRecPos )
     453             : {
     454         224 :     mnNextRecPos = nNextRecPos;
     455         224 :     return StartNextRecord();
     456             : }
     457             : 
     458         551 : void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId )
     459             : {
     460         551 :     if( mbValidRec )
     461             :     {
     462         551 :         maPosStack.clear();
     463         551 :         RestorePosition( maFirstRec );
     464         551 :         mnCurrRecSize = mnComplRecSize = mnRawRecSize;
     465         551 :         mbHasComplRec = !bContLookup;
     466         551 :         mbCont = bContLookup;
     467         551 :         mnAltContId = nAltContId;
     468         551 :         EnableDecryption();
     469             :     }
     470         551 : }
     471             : 
     472           0 : void XclImpStream::RewindRecord()
     473             : {
     474           0 :     mnNextRecPos = maFirstRec.GetPos();
     475           0 :     mbValid = mbValidRec = false;
     476           0 : }
     477             : 
     478           4 : void XclImpStream::SetDecrypter( XclImpDecrypterRef xDecrypter )
     479             : {
     480           4 :     mxDecrypter = xDecrypter;
     481           4 :     EnableDecryption();
     482           4 :     SetupDecrypter();
     483           4 : }
     484             : 
     485           4 : void XclImpStream::CopyDecrypterFrom( const XclImpStream& rStrm )
     486             : {
     487           4 :     XclImpDecrypterRef xNewDecr;
     488           4 :     if( rStrm.mxDecrypter )
     489           0 :         xNewDecr = rStrm.mxDecrypter->Clone();
     490           4 :     SetDecrypter( xNewDecr );
     491           4 : }
     492             : 
     493     1176436 : bool XclImpStream::HasValidDecrypter() const
     494             : {
     495     1176436 :     return mxDecrypter && mxDecrypter->IsValid();
     496             : }
     497             : 
     498     1176976 : void XclImpStream::EnableDecryption( bool bEnable )
     499             : {
     500     1176976 :     mbUseDecr = bEnable && HasValidDecrypter();
     501     1176976 : }
     502             : 
     503       10930 : void XclImpStream::PushPosition()
     504             : {
     505       10930 :     maPosStack.push_back( XclImpStreamPos() );
     506       10930 :     StorePosition( maPosStack.back() );
     507       10930 : }
     508             : 
     509       10930 : void XclImpStream::PopPosition()
     510             : {
     511             :     OSL_ENSURE( !maPosStack.empty(), "XclImpStream::PopPosition - stack empty" );
     512       10930 :     if( !maPosStack.empty() )
     513             :     {
     514       10930 :         RestorePosition( maPosStack.back() );
     515       10930 :         maPosStack.pop_back();
     516             :     }
     517       10930 : }
     518             : 
     519         307 : void XclImpStream::StoreGlobalPosition()
     520             : {
     521         307 :     StorePosition( maGlobPos );
     522         307 :     mnGlobRecId = mnRecId;
     523         307 :     mbGlobValidRec = mbValidRec;
     524         307 :     mbHasGlobPos = true;
     525         307 : }
     526             : 
     527         307 : void XclImpStream::SeekGlobalPosition()
     528             : {
     529             :     OSL_ENSURE( mbHasGlobPos, "XclImpStream::SeekGlobalPosition - no position stored" );
     530         307 :     if( mbHasGlobPos )
     531             :     {
     532         307 :         RestorePosition( maGlobPos );
     533         307 :         mnRecId = mnGlobRecId;
     534         307 :         mnComplRecSize = mnCurrRecSize;
     535         307 :         mbHasComplRec = !mbCont;
     536         307 :         mbValidRec = mbGlobValidRec;
     537             :     }
     538         307 : }
     539             : 
     540       95066 : sal_Size XclImpStream::GetRecPos() const
     541             : {
     542       95066 :     return mbValid ? (mnCurrRecSize - mnRawRecLeft) : EXC_REC_SEEK_TO_END;
     543             : }
     544             : 
     545       61531 : sal_Size XclImpStream::GetRecSize()
     546             : {
     547       61531 :     if( !mbHasComplRec )
     548             :     {
     549        6031 :         PushPosition();
     550        6031 :         while( JumpToNextContinue() ) ;  // JumpToNextContinue() adds up mnCurrRecSize
     551        6031 :         mnComplRecSize = mnCurrRecSize;
     552        6031 :         mbHasComplRec = true;
     553        6031 :         PopPosition();
     554             :     }
     555       61531 :     return mnComplRecSize;
     556             : }
     557             : 
     558       61122 : sal_Size XclImpStream::GetRecLeft()
     559             : {
     560       61122 :     return mbValid ? (GetRecSize() - GetRecPos()) : 0;
     561             : }
     562             : 
     563        2838 : sal_uInt16 XclImpStream::GetNextRecId()
     564             : {
     565        2838 :     sal_uInt16 nRecId = EXC_ID_UNKNOWN;
     566        2838 :     if( mbValidRec )
     567             :     {
     568        2838 :         PushPosition();
     569        2838 :         while( JumpToNextContinue() ) ;  // skip following CONTINUE records
     570        2838 :         if( mnNextRecPos < mnStreamSize )
     571             :         {
     572        2838 :             mrStrm.Seek( mnNextRecPos );
     573        2838 :             mrStrm.ReadUInt16( nRecId );
     574             :         }
     575        2838 :         PopPosition();
     576             :     }
     577        2838 :     return nRecId;
     578             : }
     579             : 
     580         218 : sal_uInt16 XclImpStream::PeekRecId( sal_Size nPos )
     581             : {
     582         218 :     sal_uInt16 nRecId = EXC_ID_UNKNOWN;
     583         218 :     if (mbValidRec && nPos < mnStreamSize)
     584             :     {
     585         218 :         sal_Size nCurPos = mrStrm.Tell();
     586         218 :         mrStrm.Seek(nPos);
     587         218 :         mrStrm.ReadUInt16( nRecId );
     588         218 :         mrStrm.Seek(nCurPos);
     589             :     }
     590         218 :     return nRecId;
     591             : }
     592             : 
     593      107433 : sal_uInt8 XclImpStream::ReaduInt8()
     594             : {
     595      107433 :     sal_uInt8 nValue = 0;
     596      107433 :     if( EnsureRawReadSize( 1 ) )
     597             :     {
     598      107433 :         if( mbUseDecr )
     599           0 :             mxDecrypter->Read( mrStrm, &nValue, 1 );
     600             :         else
     601      107433 :             mrStrm.ReadUChar( nValue );
     602      107433 :         --mnRawRecLeft;
     603             :     }
     604      107433 :     return nValue;
     605             : }
     606             : 
     607        1364 : sal_Int16 XclImpStream::ReadInt16()
     608             : {
     609        1364 :     sal_Int16 nValue = 0;
     610        1364 :     if( EnsureRawReadSize( 2 ) )
     611             :     {
     612        1364 :         if( mbUseDecr )
     613             :         {
     614             :             SVBT16 pnBuffer;
     615           0 :             mxDecrypter->Read( mrStrm, pnBuffer, 2 );
     616           0 :             nValue = static_cast< sal_Int16 >( SVBT16ToShort( pnBuffer ) );
     617             :         }
     618             :         else
     619        1364 :             mrStrm.ReadInt16( nValue );
     620        1364 :         mnRawRecLeft -= 2;
     621             :     }
     622        1364 :     return nValue;
     623             : }
     624             : 
     625     2101141 : sal_uInt16 XclImpStream::ReaduInt16()
     626             : {
     627     2101141 :     sal_uInt16 nValue = 0;
     628     2101141 :     if( EnsureRawReadSize( 2 ) )
     629             :     {
     630     2101141 :         if( mbUseDecr )
     631             :         {
     632             :             SVBT16 pnBuffer;
     633           0 :             mxDecrypter->Read( mrStrm, pnBuffer, 2 );
     634           0 :             nValue = SVBT16ToShort( pnBuffer );
     635             :         }
     636             :         else
     637     2101141 :             mrStrm.ReadUInt16( nValue );
     638     2101141 :         mnRawRecLeft -= 2;
     639             :     }
     640     2101141 :     return nValue;
     641             : }
     642             : 
     643       16360 : sal_Int32 XclImpStream::ReadInt32()
     644             : {
     645       16360 :     sal_Int32 nValue = 0;
     646       16360 :     if( EnsureRawReadSize( 4 ) )
     647             :     {
     648       16360 :         if( mbUseDecr )
     649             :         {
     650             :             SVBT32 pnBuffer;
     651           0 :             mxDecrypter->Read( mrStrm, pnBuffer, 4 );
     652           0 :             nValue = static_cast< sal_Int32 >( SVBT32ToUInt32( pnBuffer ) );
     653             :         }
     654             :         else
     655       16360 :             mrStrm.ReadInt32( nValue );
     656       16360 :         mnRawRecLeft -= 4;
     657             :     }
     658       16360 :     return nValue;
     659             : }
     660             : 
     661       85519 : sal_uInt32 XclImpStream::ReaduInt32()
     662             : {
     663       85519 :     sal_uInt32 nValue = 0;
     664       85519 :     if( EnsureRawReadSize( 4 ) )
     665             :     {
     666       85519 :         if( mbUseDecr )
     667             :         {
     668             :             SVBT32 pnBuffer;
     669           0 :             mxDecrypter->Read( mrStrm, pnBuffer, 4 );
     670           0 :             nValue = SVBT32ToUInt32( pnBuffer );
     671             :         }
     672             :         else
     673       85519 :             mrStrm.ReadUInt32( nValue );
     674       85519 :         mnRawRecLeft -= 4;
     675             :     }
     676       85519 :     return nValue;
     677             : }
     678             : 
     679        7433 : double XclImpStream::ReadDouble()
     680             : {
     681        7433 :     double nValue = 0;
     682        7433 :     if( EnsureRawReadSize( 8 ) )
     683             :     {
     684        7433 :         if( mbUseDecr )
     685             :         {
     686             :             SVBT64 pnBuffer;
     687           0 :             mxDecrypter->Read( mrStrm, pnBuffer, 8 );
     688           0 :             nValue = SVBT64ToDouble( pnBuffer );
     689             :         }
     690             :         else
     691        7433 :             mrStrm.ReadDouble( nValue );
     692        7433 :         mnRawRecLeft -= 8;
     693             :     }
     694        7433 :     return nValue;
     695             : }
     696             : 
     697         607 : sal_Size XclImpStream::Read( void* pData, sal_Size nBytes )
     698             : {
     699         607 :     sal_Size nRet = 0;
     700         607 :     if( mbValid && pData && (nBytes > 0) )
     701             :     {
     702         607 :         sal_uInt8* pnBuffer = static_cast< sal_uInt8* >( pData );
     703         607 :         sal_Size nBytesLeft = nBytes;
     704             : 
     705        1862 :         while( mbValid && (nBytesLeft > 0) )
     706             :         {
     707         648 :             sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
     708         648 :             sal_uInt16 nReadRet = ReadRawData( pnBuffer, nReadSize );
     709         648 :             nRet += nReadRet;
     710         648 :             mbValid = (nReadSize == nReadRet);
     711             :             OSL_ENSURE( mbValid, "XclImpStream::Read - stream read error" );
     712         648 :             pnBuffer += nReadRet;
     713         648 :             nBytesLeft -= nReadRet;
     714         648 :             if( mbValid && (nBytesLeft > 0) )
     715          41 :                 JumpToNextContinue();
     716             :             OSL_ENSURE( mbValid, "XclImpStream::Read - record overread" );
     717             :         }
     718             :     }
     719         607 :     return nRet;
     720             : }
     721             : 
     722         401 : sal_Size XclImpStream::CopyToStream( SvStream& rOutStrm, sal_Size nBytes )
     723             : {
     724         401 :     sal_Size nRet = 0;
     725         401 :     if( mbValid && (nBytes > 0) )
     726             :     {
     727         401 :         const sal_Size nMaxBuffer = 4096;
     728         401 :         boost::scoped_array<sal_uInt8> pnBuffer(new sal_uInt8[ ::std::min( nBytes, nMaxBuffer ) ]);
     729         401 :         sal_Size nBytesLeft = nBytes;
     730             : 
     731        1288 :         while( mbValid && (nBytesLeft > 0) )
     732             :         {
     733         486 :             sal_Size nReadSize = ::std::min( nBytesLeft, nMaxBuffer );
     734         486 :             nRet += Read( pnBuffer.get(), nReadSize );
     735             :             // writing more bytes than read results in invalid memory access
     736             :             SAL_WARN_IF(nRet != nReadSize, "sc", "read less bytes than requested");
     737         486 :             rOutStrm.Write( pnBuffer.get(), nReadSize );
     738         486 :             nBytesLeft -= nReadSize;
     739         401 :         }
     740             :     }
     741         401 :     return nRet;
     742             : }
     743             : 
     744         304 : sal_Size XclImpStream::CopyRecordToStream( SvStream& rOutStrm )
     745             : {
     746         304 :     sal_Size nRet = 0;
     747         304 :     if( mbValidRec )
     748             :     {
     749         304 :         PushPosition();
     750         304 :         RestorePosition( maFirstRec );
     751         304 :         nRet = CopyToStream( rOutStrm, GetRecSize() );
     752         304 :         PopPosition();
     753             :     }
     754         304 :     return nRet;
     755             : }
     756             : 
     757        3292 : void XclImpStream::Seek( sal_Size nPos )
     758             : {
     759        3292 :     if( mbValidRec )
     760             :     {
     761        3292 :         sal_Size nCurrPos = GetRecPos();
     762        3292 :         if( !mbValid || (nPos < nCurrPos) ) // from invalid state or backward
     763             :         {
     764         137 :             RestorePosition( maFirstRec );
     765         137 :             Ignore( nPos );
     766             :         }
     767        3155 :         else if( nPos > nCurrPos )          // forward
     768             :         {
     769          59 :             Ignore( nPos - nCurrPos );
     770             :         }
     771             :     }
     772        3292 : }
     773             : 
     774      553026 : void XclImpStream::Ignore( sal_Size nBytes )
     775             : {
     776             :     // implementation similar to Read(), but without really reading anything
     777      553026 :     sal_Size nBytesLeft = nBytes;
     778     1650950 :     while( mbValid && (nBytesLeft > 0) )
     779             :     {
     780      544898 :         sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
     781      544898 :         mrStrm.SeekRel( nReadSize );
     782      544898 :         mnRawRecLeft = mnRawRecLeft - nReadSize;
     783      544898 :         nBytesLeft -= nReadSize;
     784      544898 :         if( nBytesLeft > 0 )
     785           5 :             JumpToNextContinue();
     786             :         OSL_ENSURE( mbValid, "XclImpStream::Ignore - record overread" );
     787             :     }
     788      553026 : }
     789             : 
     790        8040 : sal_Size XclImpStream::ReadUniStringExtHeader(
     791             :         bool& rb16Bit, bool& rbRich, bool& rbFareast,
     792             :         sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags )
     793             : {
     794             :     OSL_ENSURE( !::get_flag( nFlags, EXC_STRF_UNKNOWN ), "XclImpStream::ReadUniStringExt - unknown flags" );
     795        8040 :     rb16Bit = ::get_flag( nFlags, EXC_STRF_16BIT );
     796        8040 :     rbRich = ::get_flag( nFlags, EXC_STRF_RICH );
     797        8040 :     rbFareast = ::get_flag( nFlags, EXC_STRF_FAREAST );
     798        8040 :     rnFormatRuns = rbRich ? ReaduInt16() : 0;
     799        8040 :     rnExtInf = rbFareast ? ReaduInt32() : 0;
     800        8040 :     return rnExtInf + 4 * rnFormatRuns;
     801             : }
     802             : 
     803        5811 : sal_Size XclImpStream::ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags )
     804             : {
     805             :     bool bRich, bFareast;
     806             :     sal_uInt16 nCrun;
     807             :     sal_uInt32 nExtInf;
     808        5811 :     return ReadUniStringExtHeader( rb16Bit, bRich, bFareast, nCrun, nExtInf, nFlags );
     809             : }
     810             : 
     811        8048 : OUString XclImpStream::ReadRawUniString( sal_uInt16 nChars, bool b16Bit )
     812             : {
     813        8048 :     OUString aRet;
     814        8048 :     sal_uInt16 nCharsLeft = nChars;
     815             :     sal_uInt16 nReadSize;
     816             : 
     817       16096 :     boost::scoped_array<sal_Unicode> pcBuffer(new sal_Unicode[ nCharsLeft + 1 ]);
     818             : 
     819       24137 :     while( IsValid() && (nCharsLeft > 0) )
     820             :     {
     821        8041 :         if( b16Bit )
     822             :         {
     823        1582 :             nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
     824             :             OSL_ENSURE( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
     825             :                 "XclImpStream::ReadRawUniString - missing a byte" );
     826             :         }
     827             :         else
     828        6459 :             nReadSize = GetMaxRawReadSize( nCharsLeft );
     829             : 
     830        8041 :         sal_Unicode* pcUniChar = pcBuffer.get();
     831        8041 :         sal_Unicode* pcEndChar = pcBuffer.get() + nReadSize;
     832             : 
     833        8041 :         if( b16Bit )
     834             :         {
     835             :             sal_uInt16 nReadChar;
     836       33006 :             for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
     837             :             {
     838       31424 :                 nReadChar = ReaduInt16();
     839       31424 :                 (*pcUniChar) = (nReadChar == EXC_NUL) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
     840             :             }
     841             :         }
     842             :         else
     843             :         {
     844             :             sal_uInt8 nReadChar;
     845       62578 :             for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
     846             :             {
     847       56119 :                 nReadChar = ReaduInt8();
     848       56119 :                 (*pcUniChar) = (nReadChar == EXC_NUL_C) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
     849             :             }
     850             :         }
     851             : 
     852        8041 :         *pcEndChar = '\0';
     853        8041 :         aRet += OUString( pcBuffer.get() );
     854             : 
     855        8041 :         nCharsLeft = nCharsLeft - nReadSize;
     856        8041 :         if( nCharsLeft > 0 )
     857           3 :             JumpToNextStringContinue( b16Bit );
     858             :     }
     859             : 
     860       16096 :     return aRet;
     861             : }
     862             : 
     863        5811 : OUString XclImpStream::ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
     864             : {
     865             :     bool b16Bit;
     866        5811 :     sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
     867        5811 :     OUString aRet( ReadRawUniString( nChars, b16Bit ) );
     868        5811 :     Ignore( nExtSize );
     869        5811 :     return aRet;
     870             : }
     871             : 
     872        5811 : OUString XclImpStream::ReadUniString( sal_uInt16 nChars )
     873             : {
     874        5811 :     return ReadUniString( nChars, ReaduInt8() );
     875             : }
     876             : 
     877        1817 : OUString XclImpStream::ReadUniString()
     878             : {
     879        1817 :     return ReadUniString( ReaduInt16() );
     880             : }
     881             : 
     882           0 : void XclImpStream::IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit )
     883             : {
     884           0 :     sal_uInt16 nCharsLeft = nChars;
     885             :     sal_uInt16 nReadSize;
     886             : 
     887           0 :     while( IsValid() && (nCharsLeft > 0) )
     888             :     {
     889           0 :         if( b16Bit )
     890             :         {
     891           0 :             nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
     892             :             OSL_ENSURE( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
     893             :                 "XclImpStream::IgnoreRawUniString - missing a byte" );
     894           0 :             Ignore( nReadSize * 2 );
     895             :         }
     896             :         else
     897             :         {
     898           0 :             nReadSize = GetMaxRawReadSize( nCharsLeft );
     899           0 :             Ignore( nReadSize );
     900             :         }
     901             : 
     902           0 :         nCharsLeft = nCharsLeft - nReadSize;
     903           0 :         if( nCharsLeft > 0 )
     904           0 :             JumpToNextStringContinue( b16Bit );
     905             :     }
     906           0 : }
     907             : 
     908           0 : void XclImpStream::IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
     909             : {
     910             :     bool b16Bit;
     911           0 :     sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
     912           0 :     IgnoreRawUniString( nChars, b16Bit );
     913           0 :     Ignore( nExtSize );
     914           0 : }
     915             : 
     916           0 : void XclImpStream::IgnoreUniString( sal_uInt16 nChars )
     917             : {
     918           0 :     IgnoreUniString( nChars, ReaduInt8() );
     919           0 : }
     920             : 
     921         865 : OUString XclImpStream::ReadRawByteString( sal_uInt16 nChars )
     922             : {
     923         865 :     nChars = GetMaxRawReadSize(nChars);
     924         865 :     boost::scoped_array<sal_Char> pcBuffer(new sal_Char[ nChars + 1 ]);
     925         865 :     sal_uInt16 nCharsRead = ReadRawData( pcBuffer.get(), nChars );
     926         865 :     pcBuffer[ nCharsRead ] = '\0';
     927         865 :     OUString aRet( pcBuffer.get(), strlen(pcBuffer.get()), mrRoot.GetTextEncoding() );
     928         865 :     return aRet;
     929             : }
     930             : 
     931         864 : OUString XclImpStream::ReadByteString( bool b16BitLen )
     932             : {
     933         864 :     return ReadRawByteString( ReadByteStrLen( b16BitLen ) );
     934             : }
     935             : 
     936             : // private --------------------------------------------------------------------
     937             : 
     938     1187030 : void XclImpStream::StorePosition( XclImpStreamPos& rPos )
     939             : {
     940     1187030 :     rPos.Set( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
     941     1187030 : }
     942             : 
     943       12493 : void XclImpStream::RestorePosition( const XclImpStreamPos& rPos )
     944             : {
     945       12493 :     rPos.Get( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
     946       12493 :     SetupDecrypter();
     947       12493 : }
     948             : 
     949     1184049 : bool XclImpStream::ReadNextRawRecHeader()
     950             : {
     951     1184049 :     sal_Size nSeekedPos = mrStrm.Seek( mnNextRecPos );
     952     1184049 :     bool bRet = (nSeekedPos == mnNextRecPos) && (mnNextRecPos + 4 <= mnStreamSize);
     953     1184049 :     if( bRet )
     954             :     {
     955     1183943 :         mrStrm.ReadUInt16( mnRawRecId ).ReadUInt16( mnRawRecSize );
     956     1183943 :         bRet = mrStrm.good();
     957             :     }
     958     1184049 :     return bRet;
     959             : }
     960             : 
     961     1188113 : void XclImpStream::SetupDecrypter()
     962             : {
     963     1188113 :     if( mxDecrypter )
     964           0 :         mxDecrypter->Update( mrStrm, mnRawRecSize );
     965     1188113 : }
     966             : 
     967     1175616 : void XclImpStream::SetupRawRecord()
     968             : {
     969             :     // pre: mnRawRecSize contains current raw record size
     970             :     // pre: mrStrm points to start of raw record data
     971     1175616 :     mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
     972     1175616 :     mnRawRecLeft = mnRawRecSize;
     973     1175616 :     mnCurrRecSize += mnRawRecSize;
     974     1175616 :     SetupDecrypter();   // decrypter works on raw record level
     975     1175616 : }
     976             : 
     977     1175529 : void XclImpStream::SetupRecord()
     978             : {
     979     1175529 :     mnRecId = mnRawRecId;
     980     1175529 :     mnAltContId = EXC_ID_UNKNOWN;
     981     1175529 :     mnCurrRecSize = 0;
     982     1175529 :     mnComplRecSize = mnRawRecSize;
     983     1175529 :     mbHasComplRec = !mbCont;
     984     1175529 :     SetupRawRecord();
     985     1175529 :     SetNulSubstChar();
     986     1175529 :     EnableDecryption();
     987     1175529 :     StorePosition( maFirstRec );
     988     1175529 : }
     989             : 
     990     1183656 : bool XclImpStream::IsContinueId( sal_uInt16 nRecId ) const
     991             : {
     992     1183656 :     return (nRecId == EXC_ID_CONT) || (nRecId == mnAltContId);
     993             : }
     994             : 
     995        8962 : bool XclImpStream::JumpToNextContinue()
     996             : {
     997        8962 :     mbValid = mbValid && mbCont && ReadNextRawRecHeader() && IsContinueId( mnRawRecId );
     998        8962 :     if( mbValid )   // do not setup a following non-CONTINUE record
     999          87 :         SetupRawRecord();
    1000        8962 :     return mbValid;
    1001             : }
    1002             : 
    1003           3 : bool XclImpStream::JumpToNextStringContinue( bool& rb16Bit )
    1004             : {
    1005             :     OSL_ENSURE( mnRawRecLeft == 0, "XclImpStream::JumpToNextStringContinue - unexpected garbage" );
    1006             : 
    1007           3 :     if( mbCont && (GetRecLeft() > 0) )
    1008             :     {
    1009           3 :         JumpToNextContinue();
    1010             :     }
    1011           0 :     else if( mnRecId == EXC_ID_CONT )
    1012             :     {
    1013             :         // CONTINUE handling is off, but we have started reading in a CONTINUE record
    1014             :         // -> start next CONTINUE for TXO import
    1015           0 :         mbValidRec = ReadNextRawRecHeader() && ((mnRawRecId != 0) || (mnRawRecSize > 0));
    1016           0 :         mbValid = mbValidRec && (mnRawRecId == EXC_ID_CONT);
    1017             :         // we really start a new record here - no chance to return to string origin
    1018           0 :         if( mbValid )
    1019           0 :             SetupRecord();
    1020             :     }
    1021             :     else
    1022           0 :         mbValid = false;
    1023             : 
    1024           3 :     if( mbValid )
    1025           2 :         rb16Bit = ::get_flag( ReaduInt8(), EXC_STRF_16BIT );
    1026           3 :     return mbValid;
    1027             : }
    1028             : 
    1029     2319250 : bool XclImpStream::EnsureRawReadSize( sal_uInt16 nBytes )
    1030             : {
    1031     2319250 :     if( mbValid && nBytes )
    1032             :     {
    1033     2319250 :         while( mbValid && !mnRawRecLeft ) JumpToNextContinue();
    1034     2319250 :         mbValid = mbValid && (nBytes <= mnRawRecLeft);
    1035             :         OSL_ENSURE( mbValid, "XclImpStream::EnsureRawReadSize - record overread" );
    1036             :     }
    1037     2319250 :     return mbValid;
    1038             : }
    1039             : 
    1040      552870 : sal_uInt16 XclImpStream::GetMaxRawReadSize( sal_Size nBytes ) const
    1041             : {
    1042      552870 :     return static_cast< sal_uInt16 >( ::std::min< sal_Size >( nBytes, mnRawRecLeft ) );
    1043             : }
    1044             : 
    1045        1513 : sal_uInt16 XclImpStream::ReadRawData( void* pData, sal_uInt16 nBytes )
    1046             : {
    1047             :     OSL_ENSURE( (nBytes <= mnRawRecLeft), "XclImpStream::ReadRawData - record overread" );
    1048        1513 :     sal_uInt16 nRet = 0;
    1049        1513 :     if( mbUseDecr )
    1050           0 :         nRet = mxDecrypter->Read( mrStrm, pData, nBytes );
    1051             :     else
    1052        1513 :         nRet = static_cast< sal_uInt16 >( mrStrm.Read( pData, nBytes ) );
    1053        1513 :     mnRawRecLeft = mnRawRecLeft - nRet;
    1054        1513 :     return nRet;
    1055             : }
    1056             : 
    1057             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11