LCOV - code coverage report
Current view: top level - co - dataIStream.cpp (source / functions) Hit Total Coverage
Test: Collage Lines: 80 93 86.0 %
Date: 2016-12-14 01:26:48 Functions: 17 19 89.5 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2016, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Cedric Stalder <cedric.stalder@gmail.com>
       4             :  *
       5             :  * This file is part of Collage <https://github.com/Eyescale/Collage>
       6             :  *
       7             :  * This library is free software; you can redistribute it and/or modify it under
       8             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       9             :  * by the Free Software Foundation.
      10             :  *
      11             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      12             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      13             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      14             :  * details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public License
      17             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             :  */
      20             : 
      21             : #include "dataIStream.h"
      22             : 
      23             : #include "global.h"
      24             : #include "log.h"
      25             : #include "node.h"
      26             : 
      27             : #include <pression/data/Compressor.h>
      28             : #include <pression/data/CompressorInfo.h>
      29             : #include <lunchbox/buffer.h>
      30             : #include <lunchbox/debug.h>
      31             : 
      32             : #include <string.h>
      33             : 
      34             : namespace co
      35             : {
      36             : namespace detail
      37             : {
      38     3015942 : class DataIStream
      39             : {
      40             : public:
      41     3013371 :     explicit DataIStream( const bool swap_ )
      42     3013371 :         : input( 0 )
      43             :         , inputSize( 0 )
      44             :         , position( 0 )
      45     3013371 :         , swap( swap_ )
      46     3004702 :     {}
      47             : 
      48           8 :     void initCompressor( const CompressorInfo& info )
      49             :     {
      50           8 :         if( info == compressorInfo )
      51           0 :             return;
      52           8 :         compressorInfo = info;
      53           8 :         compressor.reset( info.create( ));
      54           8 :         LBLOG( LOG_OBJECTS ) << "Allocated " << compressorInfo.name <<std::endl;
      55             :     }
      56             : 
      57             :     /** The current input buffer */
      58             :     const uint8_t* input;
      59             : 
      60             :     /** The size of the input buffer */
      61             :     uint64_t inputSize;
      62             : 
      63             :     /** The current read position in the buffer */
      64             :     uint64_t position;
      65             : 
      66             :     CompressorPtr compressor; //!< current decompressor
      67             :     CompressorInfo compressorInfo; //!< current decompressor data
      68             :     lunchbox::Bufferb data; //!< decompressed buffer
      69             :     bool swap; //!< Invoke endian conversion
      70             : };
      71             : }
      72             : 
      73     1106353 : DataIStream::DataIStream( const bool swap_ )
      74     1106353 :         : _impl( new detail::DataIStream( swap_ ))
      75     1106116 : {}
      76             : 
      77     1910766 : DataIStream::DataIStream( const DataIStream& rhs )
      78     1910766 :         : _impl( new detail::DataIStream( rhs._impl->swap ))
      79     1910764 : {}
      80             : 
      81     6025867 : DataIStream::~DataIStream()
      82             : {
      83     3016784 :     _reset();
      84     3015903 :     delete _impl;
      85     3009083 : }
      86             : 
      87      593785 : DataIStream& DataIStream::operator = ( const DataIStream& rhs )
      88             : {
      89      593785 :     _reset();
      90      593796 :     setSwapping( rhs.isSwapping( ));
      91      593802 :     return *this;
      92             : }
      93             : 
      94      593966 : void DataIStream::setSwapping( const bool onOff )
      95             : {
      96      593966 :     _impl->swap = onOff;
      97      593966 : }
      98             : 
      99     4196299 : bool DataIStream::isSwapping() const
     100             : {
     101     4196299 :     return _impl->swap;
     102             : }
     103             : 
     104     3603551 : void DataIStream::_reset()
     105             : {
     106     3603551 :     _impl->input     = 0;
     107     3603551 :     _impl->inputSize = 0;
     108     3603551 :     _impl->position  = 0;
     109     3603551 :     _impl->swap      = false;
     110     3603551 : }
     111             : 
     112     3602349 : void DataIStream::_read( void* data, uint64_t size )
     113             : {
     114     3602349 :     if( !_checkBuffer( ))
     115             :     {
     116           0 :         LBUNREACHABLE;
     117           0 :         LBERROR << "No more input data" << std::endl;
     118           0 :         return;
     119             :     }
     120             : 
     121     3602352 :     LBASSERT( _impl->input );
     122     3602352 :     if( size > _impl->inputSize - _impl->position )
     123             :     {
     124           0 :         LBERROR << "Not enough data in input buffer: need 0x" << std::hex << size
     125           0 :                 << " bytes, 0x" << _impl->inputSize - _impl->position << " left "
     126           0 :                 << std::dec << std::endl;
     127           0 :         LBUNREACHABLE;
     128             :         // TODO: Allow reads which are asymmetric to writes by reading from
     129             :         // multiple blocks here?
     130           0 :         return;
     131             :     }
     132             : 
     133     3602352 :     memcpy( data, _impl->input + _impl->position, size );
     134     3602352 :     _impl->position += size;
     135             : }
     136             : 
     137     2484667 : const void* DataIStream::getRemainingBuffer( const uint64_t size )
     138             : {
     139     2484667 :     if( !_checkBuffer( ))
     140           0 :         return 0;
     141             : 
     142     2476868 :     LBASSERT( _impl->position + size <= _impl->inputSize );
     143     2476943 :     if( _impl->position + size > _impl->inputSize )
     144           0 :         return 0;
     145             : 
     146     2476943 :     _impl->position += size;
     147     2476943 :     return _impl->input + _impl->position - size;
     148             : }
     149             : 
     150     2889905 : uint64_t DataIStream::getRemainingBufferSize()
     151             : {
     152     2889905 :     if( !_checkBuffer( ))
     153         110 :         return 0;
     154             : 
     155     2879837 :     return _impl->inputSize - _impl->position;
     156             : }
     157             : 
     158           0 : bool DataIStream::wasUsed() const
     159             : {
     160           0 :     return _impl->input != 0;
     161             : }
     162             : 
     163    11521403 : bool DataIStream::_checkBuffer()
     164             : {
     165    14111507 :     while( _impl->position >= _impl->inputSize )
     166             :     {
     167     5191508 :         CompressorInfo info;
     168     2555357 :         uint32_t nChunks = 0;
     169     2555357 :         const void* data = 0;
     170             : 
     171     2555357 :         _impl->position = 0;
     172     2555357 :         _impl->input = 0;
     173     2555357 :         _impl->inputSize = 0;
     174             : 
     175     2555357 :         if( !getNextBuffer( info, nChunks, data, _impl->inputSize ))
     176         161 :             return false;
     177             : 
     178     2599074 :         _impl->input = _decompress( data, info, nChunks, _impl->inputSize );
     179             :     }
     180     8919999 :     return true;
     181             : }
     182             : 
     183     2599908 : const uint8_t* DataIStream::_decompress( const void* data,
     184             :                                          const CompressorInfo& info,
     185             :                                          const uint32_t nChunks,
     186             :                                          const uint64_t dataSize )
     187             : {
     188     2599908 :     const uint8_t* src = reinterpret_cast< const uint8_t* >( data );
     189     2599908 :     if( info.name.empty( ))
     190     2601173 :         return src;
     191             : 
     192           8 :     LBASSERT( !info.name.empty( ));
     193             : #ifndef CO_AGGRESSIVE_CACHING
     194           8 :     _impl->data.clear();
     195             : #endif
     196           8 :     _impl->data.reset( dataSize );
     197           8 :     _impl->initCompressor( info );
     198             : 
     199          16 :     std::vector< std::pair< const uint8_t*, size_t >> inputs( nChunks );
     200          16 :     for( uint32_t i = 0; i < nChunks; ++i )
     201             :     {
     202           8 :         const uint64_t size = *reinterpret_cast< const uint64_t* >( src );
     203           8 :         src += sizeof( uint64_t );
     204             : 
     205           8 :         inputs[ i ] = { src, size };
     206           8 :         src += size;
     207             :     }
     208             : 
     209           8 :     _impl->compressor->decompress( inputs, _impl->data.getData(), dataSize );
     210           8 :     return _impl->data.getData();
     211             : }
     212             : 
     213          66 : }

Generated by: LCOV version 1.11