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

Generated by: LCOV version 1.10