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

Generated by: LCOV version 1.10