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

Generated by: LCOV version 1.10