LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xistream.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 346 570 60.7 %
Date: 2012-08-25 Functions: 56 89 62.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 195 568 34.3 %

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

Generated by: LCOV version 1.10