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

Generated by: LCOV version 1.10