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

Generated by: LCOV version 1.10