LCOV - code coverage report
Current view: top level - libreoffice/sc/source/filter/oox - biffinputstream.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 252 0.4 %
Date: 2012-12-27 Functions: 2 46 4.3 %
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 "biffinputstream.hxx"
      21             : 
      22             : #include <algorithm>
      23             : #include <rtl/ustrbuf.hxx>
      24             : 
      25             : namespace oox {
      26             : namespace xls {
      27             : 
      28             : // ============================================================================
      29             : 
      30             : using ::rtl::OString;
      31             : using ::rtl::OStringToOUString;
      32             : using ::rtl::OUString;
      33             : using ::rtl::OUStringBuffer;
      34             : 
      35             : // ============================================================================
      36             : 
      37             : namespace prv {
      38             : 
      39           0 : BiffInputRecordBuffer::BiffInputRecordBuffer( BinaryInputStream& rInStrm ) :
      40             :     mrInStrm( rInStrm ),
      41             :     mpCurrentData( 0 ),
      42             :     mnHeaderPos( -1 ),
      43             :     mnBodyPos( 0 ),
      44             :     mnBufferBodyPos( 0 ),
      45             :     mnNextHeaderPos( 0 ),
      46             :     mnRecId( BIFF_ID_UNKNOWN ),
      47             :     mnRecSize( 0 ),
      48             :     mnRecPos( 0 ),
      49           0 :     mbValidHeader( false )
      50             : {
      51             :     OSL_ENSURE( mrInStrm.isSeekable(), "BiffInputRecordBuffer::BiffInputRecordBuffer - stream must be seekable" );
      52           0 :     mrInStrm.seekToStart();
      53           0 :     maOriginalData.reserve( SAL_MAX_UINT16 );
      54           0 :     maDecodedData.reserve( SAL_MAX_UINT16 );
      55           0 :     enableDecoder( false );     // updates mpCurrentData
      56           0 : }
      57             : 
      58           0 : void BiffInputRecordBuffer::restartAt( sal_Int64 nPos )
      59             : {
      60           0 :     mnHeaderPos = -1;
      61           0 :     mnBodyPos = mnBufferBodyPos = 0;
      62           0 :     mnNextHeaderPos = nPos;
      63           0 :     mnRecId = BIFF_ID_UNKNOWN;
      64           0 :     mnRecSize = mnRecPos = 0;
      65           0 :     mbValidHeader = false;
      66           0 : }
      67             : 
      68           0 : void BiffInputRecordBuffer::setDecoder( const BiffDecoderRef& rxDecoder )
      69             : {
      70           0 :     mxDecoder = rxDecoder;
      71           0 :     enableDecoder( true );
      72           0 :     updateDecoded();
      73           0 : }
      74             : 
      75           0 : void BiffInputRecordBuffer::enableDecoder( bool bEnable )
      76             : {
      77           0 :     mpCurrentData = (bEnable && mxDecoder.get() && mxDecoder->isValid()) ? &maDecodedData : &maOriginalData;
      78           0 : }
      79             : 
      80           0 : bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos )
      81             : {
      82           0 :     mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.size());
      83           0 :     if( mbValidHeader )
      84             :     {
      85           0 :         mnHeaderPos = nHeaderPos;
      86           0 :         mrInStrm.seek( nHeaderPos );
      87           0 :         mrInStrm >> mnRecId >> mnRecSize;
      88           0 :         mnBodyPos = mrInStrm.tell();
      89           0 :         mnNextHeaderPos = mnBodyPos + mnRecSize;
      90           0 :         mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.size());
      91             :     }
      92           0 :     if( !mbValidHeader )
      93             :     {
      94           0 :         mnHeaderPos = mnBodyPos = -1;
      95           0 :         mnNextHeaderPos = 0;
      96           0 :         mnRecId = BIFF_ID_UNKNOWN;
      97           0 :         mnRecSize = 0;
      98             :     }
      99           0 :     mnRecPos = 0;
     100           0 :     return mbValidHeader;
     101             : }
     102             : 
     103           0 : bool BiffInputRecordBuffer::startNextRecord()
     104             : {
     105           0 :     return startRecord( mnNextHeaderPos );
     106             : }
     107             : 
     108           0 : sal_uInt16 BiffInputRecordBuffer::getNextRecId()
     109             : {
     110           0 :     sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
     111           0 :     if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.size()) )
     112             :     {
     113           0 :         mrInStrm.seek( mnNextHeaderPos );
     114           0 :         mrInStrm >> nRecId;
     115             :     }
     116           0 :     return nRecId;
     117             : }
     118             : 
     119           0 : void BiffInputRecordBuffer::read( void* opData, sal_uInt16 nBytes )
     120             : {
     121           0 :     updateBuffer();
     122             :     OSL_ENSURE( nBytes > 0, "BiffInputRecordBuffer::read - nothing to read" );
     123             :     OSL_ENSURE( nBytes <= getRecLeft(), "BiffInputRecordBuffer::read - buffer overflow" );
     124           0 :     memcpy( opData, &(*mpCurrentData)[ mnRecPos ], nBytes );
     125           0 :     mnRecPos = mnRecPos + nBytes;
     126           0 : }
     127             : 
     128           0 : void BiffInputRecordBuffer::skip( sal_uInt16 nBytes )
     129             : {
     130             :     OSL_ENSURE( nBytes > 0, "BiffInputRecordBuffer::skip - nothing to skip" );
     131             :     OSL_ENSURE( nBytes <= getRecLeft(), "BiffInputRecordBuffer::skip - buffer overflow" );
     132           0 :     mnRecPos = mnRecPos + nBytes;
     133           0 : }
     134             : 
     135           0 : void BiffInputRecordBuffer::updateBuffer()
     136             : {
     137             :     OSL_ENSURE( mbValidHeader, "BiffInputRecordBuffer::updateBuffer - invalid access" );
     138           0 :     if( mnBodyPos != mnBufferBodyPos )
     139             :     {
     140           0 :         mrInStrm.seek( mnBodyPos );
     141           0 :         maOriginalData.resize( mnRecSize );
     142           0 :         if( mnRecSize > 0 )
     143           0 :             mrInStrm.readMemory( &maOriginalData.front(), static_cast< sal_Int32 >( mnRecSize ) );
     144           0 :         mnBufferBodyPos = mnBodyPos;
     145           0 :         updateDecoded();
     146             :     }
     147           0 : }
     148             : 
     149           0 : void BiffInputRecordBuffer::updateDecoded()
     150             : {
     151           0 :     if( mxDecoder.get() && mxDecoder->isValid() )
     152             :     {
     153           0 :         maDecodedData.resize( mnRecSize );
     154           0 :         if( mnRecSize > 0 )
     155           0 :             mxDecoder->decode( &maDecodedData.front(), &maOriginalData.front(), mnBodyPos, mnRecSize );
     156             :     }
     157           0 : }
     158             : 
     159             : } // namespace prv
     160             : 
     161             : // ============================================================================
     162             : 
     163           0 : BiffInputStream::BiffInputStream( BinaryInputStream& rInStream, bool bContLookup ) :
     164             :     BinaryStreamBase( true ),
     165             :     maRecBuffer( rInStream ),
     166             :     mnRecHandle( -1 ),
     167             :     mnRecId( BIFF_ID_UNKNOWN ),
     168             :     mnAltContId( BIFF_ID_UNKNOWN ),
     169             :     mnCurrRecSize( 0 ),
     170             :     mnComplRecSize( 0 ),
     171             :     mbHasComplRec( false ),
     172           0 :     mbCont( bContLookup )
     173             : {
     174           0 :     mbEof = true;   // EOF will be true if stream is not inside a record
     175           0 : }
     176             : 
     177             : // record control -------------------------------------------------------------
     178             : 
     179           0 : bool BiffInputStream::startNextRecord()
     180             : {
     181           0 :     bool bValidRec = false;
     182             :     /*  #i4266# ignore zero records (id==len==0) (e.g. the application
     183             :         "Crystal Report" writes zero records between other records) */
     184           0 :     bool bIsZeroRec = false;
     185           0 :     do
     186             :     {
     187             :         // record header is never encrypted
     188           0 :         maRecBuffer.enableDecoder( false );
     189             :         // read header of next raw record, returns false at end of stream
     190           0 :         bValidRec = maRecBuffer.startNextRecord();
     191             :         // ignore record, if identifier and size are zero
     192           0 :         bIsZeroRec = (maRecBuffer.getRecId() == 0) && (maRecBuffer.getRecSize() == 0);
     193             :     }
     194           0 :     while( bValidRec && ((mbCont && isContinueId( maRecBuffer.getRecId() )) || bIsZeroRec) );
     195             : 
     196             :     // setup other class members
     197           0 :     setupRecord();
     198           0 :     return isInRecord();
     199             : }
     200             : 
     201           0 : bool BiffInputStream::startRecordByHandle( sal_Int64 nRecHandle )
     202             : {
     203           0 :     rewindToRecord( nRecHandle );
     204           0 :     return startNextRecord();
     205             : }
     206             : 
     207           0 : void BiffInputStream::rewindRecord()
     208             : {
     209           0 :     rewindToRecord( mnRecHandle );
     210           0 : }
     211             : 
     212             : // decoder --------------------------------------------------------------------
     213             : 
     214           0 : void BiffInputStream::setDecoder( const BiffDecoderRef& rxDecoder )
     215             : {
     216           0 :     maRecBuffer.setDecoder( rxDecoder );
     217           0 : }
     218             : 
     219           0 : void BiffInputStream::enableDecoder( bool bEnable )
     220             : {
     221           0 :     maRecBuffer.enableDecoder( bEnable );
     222           0 : }
     223             : 
     224             : // stream/record state and info -----------------------------------------------
     225             : 
     226           0 : sal_uInt16 BiffInputStream::getNextRecId()
     227             : {
     228           0 :     sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
     229           0 :     if( isInRecord() )
     230             :     {
     231           0 :         sal_Int64 nCurrPos = tell();            // save current position in record
     232           0 :         while( jumpToNextContinue() ) {}        // skip following CONTINUE records
     233           0 :         if( maRecBuffer.startNextRecord() )     // read header of next record
     234           0 :             nRecId = maRecBuffer.getRecId();
     235           0 :         seek( nCurrPos );                       // restore position, seek() resets old mbValid state
     236             :     }
     237           0 :     return nRecId;
     238             : }
     239             : 
     240             : // BinaryStreamBase interface (seeking) ---------------------------------------
     241             : 
     242           0 : sal_Int64 BiffInputStream::size() const
     243             : {
     244           0 :     if( !mbHasComplRec )
     245           0 :         const_cast< BiffInputStream* >( this )->calcRecordLength();
     246           0 :     return mnComplRecSize;
     247             : }
     248             : 
     249           0 : sal_Int64 BiffInputStream::tell() const
     250             : {
     251           0 :     return mbEof ? -1 : (mnCurrRecSize - maRecBuffer.getRecLeft());
     252             : }
     253             : 
     254           0 : void BiffInputStream::seek( sal_Int64 nRecPos )
     255             : {
     256           0 :     if( isInRecord() )
     257             :     {
     258           0 :         if( mbEof || (nRecPos < tell()) )
     259           0 :             restartRecord( false );
     260           0 :         if( !mbEof && (nRecPos > tell()) )
     261           0 :             skip( static_cast< sal_Int32 >( nRecPos - tell() ) );
     262             :     }
     263           0 : }
     264             : 
     265           0 : void BiffInputStream::close()
     266             : {
     267           0 : }
     268             : 
     269             : // BinaryInputStream interface (stream read access) ---------------------------
     270             : 
     271           0 : sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
     272             : {
     273           0 :     sal_Int32 nRet = 0;
     274           0 :     if( !mbEof )
     275             :     {
     276           0 :         orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) );
     277           0 :         if( nBytes > 0 )
     278           0 :             nRet = readMemory( orData.getArray(), nBytes, nAtomSize );
     279             :     }
     280           0 :     return nRet;
     281             : }
     282             : 
     283           0 : sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
     284             : {
     285           0 :     sal_Int32 nRet = 0;
     286           0 :     if( !mbEof && opMem && (nBytes > 0) )
     287             :     {
     288           0 :         sal_uInt8* pnBuffer = reinterpret_cast< sal_uInt8* >( opMem );
     289           0 :         sal_Int32 nBytesLeft = nBytes;
     290             : 
     291           0 :         while( !mbEof && (nBytesLeft > 0) )
     292             :         {
     293           0 :             sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft, nAtomSize );
     294             :             // check nReadSize, stream may already be located at end of a raw record
     295           0 :             if( nReadSize > 0 )
     296             :             {
     297           0 :                 maRecBuffer.read( pnBuffer, nReadSize );
     298           0 :                 nRet += nReadSize;
     299           0 :                 pnBuffer += nReadSize;
     300           0 :                 nBytesLeft -= nReadSize;
     301             :             }
     302           0 :             if( nBytesLeft > 0 )
     303           0 :                 jumpToNextContinue();
     304             :             OSL_ENSURE( !mbEof, "BiffInputStream::readMemory - record overread" );
     305             :         }
     306             :     }
     307           0 :     return nRet;
     308             : }
     309             : 
     310           0 : void BiffInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
     311             : {
     312           0 :     sal_Int32 nBytesLeft = nBytes;
     313           0 :     while( !mbEof && (nBytesLeft > 0) )
     314             :     {
     315           0 :         sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft, nAtomSize );
     316             :         // check nSkipSize, stream may already be located at end of a raw record
     317           0 :         if( nSkipSize > 0 )
     318             :         {
     319           0 :             maRecBuffer.skip( nSkipSize );
     320           0 :             nBytesLeft -= nSkipSize;
     321             :         }
     322           0 :         if( nBytesLeft > 0 )
     323           0 :             jumpToNextContinue();
     324             :         OSL_ENSURE( !mbEof, "BiffInputStream::skip - record overread" );
     325             :     }
     326           0 : }
     327             : 
     328             : // byte strings ---------------------------------------------------------------
     329             : 
     330           0 : OString BiffInputStream::readByteString( bool b16BitLen, bool bAllowNulChars )
     331             : {
     332           0 :     sal_Int32 nStrLen = b16BitLen ? readuInt16() : readuInt8();
     333           0 :     return readCharArray( nStrLen, bAllowNulChars );
     334             : }
     335             : 
     336           0 : OUString BiffInputStream::readByteStringUC( bool b16BitLen, rtl_TextEncoding eTextEnc, bool bAllowNulChars )
     337             : {
     338           0 :     return OStringToOUString( readByteString( b16BitLen, bAllowNulChars ), eTextEnc );
     339             : }
     340             : 
     341             : // Unicode strings ------------------------------------------------------------
     342             : 
     343           0 : OUString BiffInputStream::readUniStringChars( sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars )
     344             : {
     345           0 :     OUStringBuffer aBuffer;
     346           0 :     aBuffer.ensureCapacity( nChars );
     347             : 
     348             :     /*  This function has to react on CONTINUE records which repeat the flags
     349             :         field in their first byte and may change the 8bit/16bit character mode,
     350             :         thus a plain call to readCompressedUnicodeArray() cannot be used here. */
     351           0 :     sal_Int32 nCharsLeft = nChars;
     352           0 :     while( !mbEof && (nCharsLeft > 0) )
     353             :     {
     354             :         /*  Read the character array from the remaining part of the current raw
     355             :             record. First, calculate the maximum number of characters that can
     356             :             be read without triggering to start a following CONTINUE record. */
     357           0 :         sal_Int32 nRawChars = b16BitChars ? (getMaxRawReadSize( nCharsLeft * 2, 2 ) / 2) : getMaxRawReadSize( nCharsLeft, 1 );
     358           0 :         aBuffer.append( readCompressedUnicodeArray( nRawChars, !b16BitChars, bAllowNulChars ) );
     359             : 
     360             :         /*  Prepare for next CONTINUE record. Calling jumpToNextStringContinue()
     361             :             reads the leading byte in the following CONTINUE record and updates
     362             :             the b16BitChars flag. */
     363           0 :         nCharsLeft -= nRawChars;
     364           0 :         if( nCharsLeft > 0 )
     365           0 :             jumpToNextStringContinue( b16BitChars );
     366             :     }
     367             : 
     368           0 :     return aBuffer.makeStringAndClear();
     369             : }
     370             : 
     371           0 : OUString BiffInputStream::readUniStringBody( sal_uInt16 nChars, bool bAllowNulChars )
     372             : {
     373             :     bool b16BitChars;
     374             :     sal_Int32 nAddSize;
     375           0 :     readUniStringHeader( b16BitChars, nAddSize );
     376           0 :     OUString aString = readUniStringChars( nChars, b16BitChars, bAllowNulChars );
     377           0 :     skip( nAddSize );
     378           0 :     return aString;
     379             : }
     380             : 
     381           0 : OUString BiffInputStream::readUniString( bool bAllowNulChars )
     382             : {
     383           0 :     return readUniStringBody( readuInt16(), bAllowNulChars );
     384             : }
     385             : 
     386             : // private --------------------------------------------------------------------
     387             : 
     388           0 : void BiffInputStream::setupRecord()
     389             : {
     390             :     // initialize class members
     391           0 :     mnRecHandle = maRecBuffer.getRecHeaderPos();
     392           0 :     mnRecId = maRecBuffer.getRecId();
     393           0 :     mnAltContId = BIFF_ID_UNKNOWN;
     394           0 :     mnCurrRecSize = mnComplRecSize = maRecBuffer.getRecSize();
     395           0 :     mbHasComplRec = !mbCont;
     396           0 :     mbEof = !isInRecord();
     397             :     // enable decoder in new record
     398           0 :     enableDecoder( true );
     399           0 : }
     400             : 
     401           0 : void BiffInputStream::restartRecord( bool bInvalidateRecSize )
     402             : {
     403           0 :     if( isInRecord() )
     404             :     {
     405           0 :         maRecBuffer.startRecord( getRecHandle() );
     406           0 :         mnCurrRecSize = maRecBuffer.getRecSize();
     407           0 :         if( bInvalidateRecSize )
     408             :         {
     409           0 :             mnComplRecSize = mnCurrRecSize;
     410           0 :             mbHasComplRec = !mbCont;
     411             :         }
     412           0 :         mbEof = false;
     413             :     }
     414           0 : }
     415             : 
     416           0 : void BiffInputStream::rewindToRecord( sal_Int64 nRecHandle )
     417             : {
     418           0 :     if( nRecHandle >= 0 )
     419             :     {
     420           0 :         maRecBuffer.restartAt( nRecHandle );
     421           0 :         mnRecHandle = -1;
     422           0 :         mbEof = true;   // as long as the record is not started
     423             :     }
     424           0 : }
     425             : 
     426           0 : bool BiffInputStream::isContinueId( sal_uInt16 nRecId ) const
     427             : {
     428           0 :     return (nRecId == BIFF_ID_CONT) || (nRecId == mnAltContId);
     429             : }
     430             : 
     431           0 : bool BiffInputStream::jumpToNextContinue()
     432             : {
     433           0 :     mbEof = mbEof || !mbCont || !isContinueId( maRecBuffer.getNextRecId() ) || !maRecBuffer.startNextRecord();
     434           0 :     if( !mbEof )
     435           0 :         mnCurrRecSize += maRecBuffer.getRecSize();
     436           0 :     return !mbEof;
     437             : }
     438             : 
     439           0 : bool BiffInputStream::jumpToNextStringContinue( bool& rb16BitChars )
     440             : {
     441             :     OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - alignment error" );
     442             : 
     443           0 :     if( mbCont && (getRemaining() > 0) )
     444             :     {
     445           0 :         jumpToNextContinue();
     446             :     }
     447           0 :     else if( mnRecId == BIFF_ID_CONT )
     448             :     {
     449             :         /*  CONTINUE handling is off, but we have started reading in a CONTINUE
     450             :             record -> start next CONTINUE for TXO import. We really start a new
     451             :             record here - no chance to return to string origin. */
     452           0 :         mbEof = mbEof || (maRecBuffer.getNextRecId() != BIFF_ID_CONT) || !maRecBuffer.startNextRecord();
     453           0 :         if( !mbEof )
     454           0 :             setupRecord();
     455             :     }
     456             : 
     457             :     // trying to read the flags invalidates stream, if no CONTINUE record has been found
     458             :     sal_uInt8 nFlags;
     459           0 :     readValue( nFlags );
     460           0 :     rb16BitChars = getFlag( nFlags, BIFF_STRF_16BIT );
     461           0 :     return !mbEof;
     462             : }
     463             : 
     464           0 : void BiffInputStream::calcRecordLength()
     465             : {
     466           0 :     sal_Int64 nCurrPos = tell();            // save current position in record
     467           0 :     while( jumpToNextContinue() ) {}        // jumpToNextContinue() adds up mnCurrRecSize
     468           0 :     mnComplRecSize = mnCurrRecSize;
     469           0 :     mbHasComplRec = true;
     470           0 :     seek( nCurrPos );                       // restore position, seek() resets old mbValid state
     471           0 : }
     472             : 
     473           0 : sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes, size_t nAtomSize ) const
     474             : {
     475           0 :     sal_uInt16 nMaxSize = getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() );
     476           0 :     if( (0 < nMaxSize) && (nMaxSize < nBytes) && (nAtomSize > 1) )
     477             :     {
     478             :         // check that remaining data in record buffer is a multiple of the passed atom size
     479           0 :         sal_uInt16 nPadding = static_cast< sal_uInt16 >( nMaxSize % nAtomSize );
     480             :         OSL_ENSURE( nPadding == 0, "BiffInputStream::getMaxRawReadSize - alignment error" );
     481           0 :         nMaxSize = nMaxSize - nPadding;
     482             :     }
     483           0 :     return nMaxSize;
     484             : }
     485             : 
     486           0 : void BiffInputStream::readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize )
     487             : {
     488           0 :     sal_uInt8 nFlags = readuInt8();
     489             :     OSL_ENSURE( !getFlag( nFlags, BIFF_STRF_UNKNOWN ), "BiffInputStream::readUniStringHeader - unknown flags" );
     490           0 :     orb16BitChars = getFlag( nFlags, BIFF_STRF_16BIT );
     491           0 :     sal_uInt16 nFontCount = getFlag( nFlags, BIFF_STRF_RICH ) ? readuInt16() : 0;
     492           0 :     sal_Int32 nPhoneticSize = getFlag( nFlags, BIFF_STRF_PHONETIC ) ? readInt32() : 0;
     493           0 :     ornAddSize = 4 * nFontCount + ::std::max< sal_Int32 >( 0, nPhoneticSize );
     494           0 : }
     495             : 
     496             : // ============================================================================
     497             : 
     498           0 : BiffInputStreamPos::BiffInputStreamPos( BiffInputStream& rStrm ) :
     499             :     mrStrm( rStrm ),
     500           0 :     mnRecHandle( rStrm.getRecHandle() ),
     501           0 :     mnRecPos( rStrm.tell() )
     502             : {
     503           0 : }
     504             : 
     505           0 : bool BiffInputStreamPos::restorePosition()
     506             : {
     507           0 :     bool bValidRec = mrStrm.startRecordByHandle( mnRecHandle );
     508           0 :     if( bValidRec )
     509           0 :         mrStrm.seek( mnRecPos );
     510           0 :     return bValidRec && !mrStrm.isEof();
     511             : }
     512             : 
     513             : // ============================================================================
     514             : 
     515           0 : BiffInputStreamPosGuard::BiffInputStreamPosGuard( BiffInputStream& rStrm ) :
     516           0 :     BiffInputStreamPos( rStrm )
     517             : {
     518           0 : }
     519             : 
     520           0 : BiffInputStreamPosGuard::~BiffInputStreamPosGuard()
     521             : {
     522           0 :     restorePosition();
     523           0 : }
     524             : 
     525             : // ============================================================================
     526             : 
     527             : } // namespace xls
     528           9 : } // namespace oox
     529             : 
     530             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10