LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xistream.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 574 0.0 %
Date: 2014-04-14 Functions: 0 90 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10