LCOV - code coverage report
Current view: top level - oox/source/ole - axbinaryreader.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 91 138 65.9 %
Date: 2015-06-13 12:38:46 Functions: 21 32 65.6 %
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 "oox/ole/axbinaryreader.hxx"
      21             : 
      22             : #include "oox/ole/olehelper.hxx"
      23             : 
      24             : #include <osl/diagnose.h>
      25             : 
      26             : namespace oox {
      27             : namespace ole {
      28             : 
      29             : namespace {
      30             : 
      31             : const sal_uInt32 AX_STRING_SIZEMASK         = 0x7FFFFFFF;
      32             : const sal_uInt32 AX_STRING_COMPRESSED       = 0x80000000;
      33             : 
      34             : } // namespace
      35             : 
      36          88 : AxAlignedInputStream::AxAlignedInputStream( BinaryInputStream& rInStrm ) :
      37             :     BinaryStreamBase( false ),
      38             :     mpInStrm( &rInStrm ),
      39             :     mnStrmPos( 0 ),
      40          88 :     mnStrmSize( rInStrm.getRemaining() )
      41             : {
      42          88 :     mbEof = mbEof || rInStrm.isEof();
      43          88 : }
      44             : 
      45           0 : sal_Int64 AxAlignedInputStream::size() const
      46             : {
      47           0 :     return mpInStrm ? mnStrmSize : -1;
      48             : }
      49             : 
      50         177 : sal_Int64 AxAlignedInputStream::tell() const
      51             : {
      52         177 :     return mpInStrm ? mnStrmPos : -1;
      53             : }
      54             : 
      55         177 : void AxAlignedInputStream::seek( sal_Int64 nPos )
      56             : {
      57         177 :     mbEof = mbEof || (nPos < mnStrmPos);
      58         177 :     if( !mbEof )
      59         177 :         skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) );
      60         177 : }
      61             : 
      62           0 : void AxAlignedInputStream::close()
      63             : {
      64           0 :     mpInStrm = 0;
      65           0 :     mbEof = true;
      66           0 : }
      67             : 
      68           0 : sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
      69             : {
      70           0 :     sal_Int32 nReadSize = 0;
      71           0 :     if( !mbEof )
      72             :     {
      73           0 :         nReadSize = mpInStrm->readData( orData, nBytes, nAtomSize );
      74           0 :         mnStrmPos += nReadSize;
      75           0 :         mbEof = mpInStrm->isEof();
      76             :     }
      77           0 :     return nReadSize;
      78             : }
      79             : 
      80         634 : sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
      81             : {
      82         634 :     sal_Int32 nReadSize = 0;
      83         634 :     if( !mbEof )
      84             :     {
      85         634 :         nReadSize = mpInStrm->readMemory( opMem, nBytes, nAtomSize );
      86         634 :         mnStrmPos += nReadSize;
      87         634 :         mbEof = mpInStrm->isEof();
      88             :     }
      89         634 :     return nReadSize;
      90             : }
      91             : 
      92         857 : void AxAlignedInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
      93             : {
      94         857 :     if( !mbEof )
      95             :     {
      96         857 :         mpInStrm->skip( nBytes, nAtomSize );
      97         857 :         mnStrmPos += nBytes;
      98         857 :         mbEof = mpInStrm->isEof();
      99             :     }
     100         857 : }
     101             : 
     102         544 : void AxAlignedInputStream::align( size_t nSize )
     103             : {
     104         544 :     skip( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) );
     105         544 : }
     106             : 
     107             : namespace {
     108             : 
     109          89 : bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString )
     110             : {
     111          89 :     bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
     112          89 :     sal_uInt32 nBufSize = nSize & AX_STRING_SIZEMASK;
     113             :     // Unicode: simple strings store byte count, array strings store char count
     114          89 :     sal_Int32 nChars = static_cast< sal_Int32 >( nBufSize / ((bCompressed || bArrayString) ? 1 : 2) );
     115          89 :     bool bValidChars = nChars <= 65536;
     116             :     OSL_ENSURE( bValidChars, "lclReadString - string too long" );
     117          89 :     sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2);
     118          89 :     nChars = ::std::min< sal_Int32 >( nChars, 65536 );
     119          89 :     rValue = rInStrm.readCompressedUnicodeArray( nChars, bCompressed );
     120          89 :     rInStrm.seek( nEndPos );
     121          89 :     return bValidChars;
     122             : }
     123             : 
     124             : } // namespace
     125             : 
     126         139 : AxBinaryPropertyReader::ComplexProperty::~ComplexProperty()
     127             : {
     128         139 : }
     129             : 
     130          50 : bool AxBinaryPropertyReader::PairProperty::readProperty( AxAlignedInputStream& rInStrm )
     131             : {
     132          50 :     mrPairData.first = rInStrm.readInt32();
     133          50 :     mrPairData.second = rInStrm.readInt32();
     134          50 :     return true;
     135             : }
     136             : 
     137          89 : bool AxBinaryPropertyReader::StringProperty::readProperty( AxAlignedInputStream& rInStrm )
     138             : {
     139          89 :     return lclReadString( rInStrm, mrValue, mnSize, false );
     140             : }
     141             : 
     142           0 : bool AxBinaryPropertyReader::ArrayStringProperty::readProperty( AxAlignedInputStream& rInStrm )
     143             : {
     144           0 :     sal_Int64 nEndPos = rInStrm.tell() + mnSize;
     145           0 :     while( rInStrm.tell() < nEndPos )
     146             :     {
     147           0 :         OUString aString;
     148           0 :         if( !lclReadString( rInStrm, aString, rInStrm.readuInt32(), true ) )
     149           0 :             return false;
     150           0 :         mrArray.push_back( aString );
     151             :         // every array string is aligned on 4 byte boundries
     152           0 :         rInStrm.align( 4 );
     153           0 :     }
     154           0 :     return true;
     155             : }
     156             : 
     157           0 : bool AxBinaryPropertyReader::GuidProperty::readProperty( AxAlignedInputStream& rInStrm )
     158             : {
     159           0 :     mrGuid = OleHelper::importGuid( rInStrm );
     160           0 :     return true;
     161             : }
     162             : 
     163           0 : bool AxBinaryPropertyReader::FontProperty::readProperty( AxAlignedInputStream& rInStrm )
     164             : {
     165           0 :     return mrFontData.importGuidAndFont( rInStrm );
     166             : }
     167             : 
     168           0 : bool AxBinaryPropertyReader::PictureProperty::readProperty( AxAlignedInputStream& rInStrm )
     169             : {
     170           0 :     return OleHelper::importStdPic( mrPicData, rInStrm, true );
     171             : }
     172             : 
     173          88 : AxBinaryPropertyReader::AxBinaryPropertyReader( BinaryInputStream& rInStrm, bool b64BitPropFlags ) :
     174             :     maInStrm( rInStrm ),
     175          88 :     mbValid( true )
     176             : {
     177             :     // version and size of property block
     178          88 :     maInStrm.skip( 2 );
     179          88 :     sal_uInt16 nBlockSize = maInStrm.readuInt16();
     180          88 :     mnPropsEnd = maInStrm.tell() + nBlockSize;
     181             :     // flagfield containing existing properties
     182          88 :     if( b64BitPropFlags )
     183          18 :         mnPropFlags = maInStrm.readInt64();
     184             :     else
     185          70 :         mnPropFlags = maInStrm.readuInt32();
     186          88 :     mnNextProp = 1;
     187          88 : }
     188             : 
     189          23 : void AxBinaryPropertyReader::readBoolProperty( bool& orbValue, bool bReverse )
     190             : {
     191             :     // there is no data, the boolean value is equivalent to the property flag itself
     192          23 :     orbValue = startNextProperty() != bReverse;
     193          23 : }
     194             : 
     195          52 : void AxBinaryPropertyReader::readPairProperty( AxPairData& orPairData )
     196             : {
     197          52 :     if( startNextProperty() )
     198          50 :         maLargeProps.push_back( ComplexPropVector::value_type( new PairProperty( orPairData ) ) );
     199          52 : }
     200             : 
     201         154 : void AxBinaryPropertyReader::readStringProperty( OUString& orValue )
     202             : {
     203         154 :     if( startNextProperty() )
     204             :     {
     205          89 :         sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
     206          89 :         maLargeProps.push_back( ComplexPropVector::value_type( new StringProperty( orValue, nSize ) ) );
     207             :     }
     208         154 : }
     209             : 
     210           0 : void AxBinaryPropertyReader::readArrayStringProperty( std::vector<OUString>& orValue )
     211             : {
     212           0 :     if( startNextProperty() )
     213             :     {
     214           0 :         sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
     215           0 :         maLargeProps.push_back( ComplexPropVector::value_type( new ArrayStringProperty( orValue, nSize ) ) );
     216             :     }
     217           0 : }
     218             : 
     219           0 : void AxBinaryPropertyReader::readGuidProperty( OUString& orGuid )
     220             : {
     221           0 :     if( startNextProperty() )
     222           0 :         maLargeProps.push_back( ComplexPropVector::value_type( new GuidProperty( orGuid ) ) );
     223           0 : }
     224             : 
     225           2 : void AxBinaryPropertyReader::readFontProperty( AxFontData& orFontData )
     226             : {
     227           2 :     if( startNextProperty() )
     228             :     {
     229           0 :         sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
     230           0 :         if( ensureValid( nData == -1 ) )
     231           0 :             maStreamProps.push_back( ComplexPropVector::value_type( new FontProperty( orFontData ) ) );
     232             :     }
     233           2 : }
     234             : 
     235          84 : void AxBinaryPropertyReader::readPictureProperty( StreamDataSequence& orPicData )
     236             : {
     237          84 :     if( startNextProperty() )
     238             :     {
     239           0 :         sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
     240           0 :         if( ensureValid( nData == -1 ) )
     241           0 :             maStreamProps.push_back( ComplexPropVector::value_type( new PictureProperty( orPicData ) ) );
     242             :     }
     243          84 : }
     244             : 
     245          88 : bool AxBinaryPropertyReader::finalizeImport()
     246             : {
     247             :     // read large properties
     248          88 :     maInStrm.align( 4 );
     249          88 :     if( ensureValid( mnPropFlags == 0 ) && !maLargeProps.empty() )
     250             :     {
     251         224 :         for( ComplexPropVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
     252             :         {
     253         139 :             ensureValid( (*aIt)->readProperty( maInStrm ) );
     254         139 :             maInStrm.align( 4 );
     255             :         }
     256             :     }
     257          88 :     maInStrm.seek( mnPropsEnd );
     258             : 
     259             :     // read stream properties (no stream alignment between properties!)
     260          88 :     if( ensureValid() && !maStreamProps.empty() )
     261           0 :         for( ComplexPropVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
     262           0 :             ensureValid( (*aIt)->readProperty( maInStrm ) );
     263             : 
     264          88 :     return mbValid;
     265             : }
     266             : 
     267        1893 : bool AxBinaryPropertyReader::ensureValid( bool bCondition )
     268             : {
     269        1893 :     mbValid = mbValid && bCondition && !maInStrm.isEof();
     270        1893 :     return mbValid;
     271             : }
     272             : 
     273        1304 : bool AxBinaryPropertyReader::startNextProperty()
     274             : {
     275        1304 :     bool bHasProp = getFlag( mnPropFlags, mnNextProp );
     276        1304 :     setFlag( mnPropFlags, mnNextProp, false );
     277        1304 :     mnNextProp <<= 1;
     278        1304 :     return ensureValid() && bHasProp;
     279             : }
     280             : 
     281             : } // namespace ole
     282         246 : } // namespace oox
     283             : 
     284             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11