LCOV - code coverage report
Current view: top level - co - dataIStream.cpp (source / functions) Hit Total Coverage
Test: Collage Lines: 67 80 83.8 %
Date: 2018-01-09 16:37:03 Functions: 13 15 86.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2017, 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 <lunchbox/buffer.h>
      28             : #include <lunchbox/debug.h>
      29             : #include <pression/data/Compressor.h>
      30             : #include <pression/data/CompressorInfo.h>
      31             : 
      32             : #include <string.h>
      33             : 
      34             : namespace co
      35             : {
      36             : namespace detail
      37             : {
      38     2814033 : class DataIStream
      39             : {
      40             : public:
      41     2809437 :     DataIStream()
      42     2809437 :         : input(0)
      43             :         , inputSize(0)
      44     2809437 :         , position(0)
      45             :     {
      46     2802442 :     }
      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             : };
      70             : }
      71             : 
      72     2807337 : DataIStream::DataIStream()
      73     2807337 :     : _impl(new detail::DataIStream())
      74             : {
      75     2802492 : }
      76             : 
      77     5623955 : DataIStream::~DataIStream()
      78             : {
      79     2814214 :     _reset();
      80     2814078 :     delete _impl;
      81     2809741 : }
      82             : 
      83     2814202 : void DataIStream::_reset()
      84             : {
      85     2814202 :     _impl->input = 0;
      86     2814202 :     _impl->inputSize = 0;
      87     2814202 :     _impl->position = 0;
      88     2814202 : }
      89             : 
      90     3409582 : void DataIStream::_read(void* data, uint64_t size)
      91             : {
      92     3409582 :     if (!_checkBuffer())
      93             :     {
      94           0 :         LBUNREACHABLE;
      95           0 :         LBERROR << "No more input data" << std::endl;
      96           0 :         return;
      97             :     }
      98             : 
      99     3409617 :     LBASSERT(_impl->input);
     100     3409615 :     if (size > _impl->inputSize - _impl->position)
     101             :     {
     102           0 :         LBERROR << "Not enough data in input buffer: need 0x" << std::hex
     103           0 :                 << size << " bytes, 0x" << _impl->inputSize - _impl->position
     104           0 :                 << " left " << std::dec << std::endl;
     105           0 :         LBUNREACHABLE;
     106             :         // TODO: Allow reads which are asymmetric to writes by reading from
     107             :         // multiple blocks here?
     108           0 :         return;
     109             :     }
     110             : 
     111     3409615 :     memcpy(data, _impl->input + _impl->position, size);
     112     3409615 :     _impl->position += size;
     113             : }
     114             : 
     115     2302004 : const void* DataIStream::getRemainingBuffer(const uint64_t size)
     116             : {
     117     2302004 :     if (!_checkBuffer())
     118           0 :         return 0;
     119             : 
     120     2311455 :     LBASSERT(_impl->position + size <= _impl->inputSize);
     121     2311705 :     if (_impl->position + size > _impl->inputSize)
     122           0 :         return 0;
     123             : 
     124     2311705 :     _impl->position += size;
     125     2311705 :     return _impl->input + _impl->position - size;
     126             : }
     127             : 
     128     2691858 : uint64_t DataIStream::getRemainingBufferSize()
     129             : {
     130     2691858 :     if (!_checkBuffer())
     131         110 :         return 0;
     132             : 
     133     2673790 :     return _impl->inputSize - _impl->position;
     134             : }
     135             : 
     136           0 : bool DataIStream::wasUsed() const
     137             : {
     138           0 :     return _impl->input != 0;
     139             : }
     140             : 
     141    10801051 : bool DataIStream::_checkBuffer()
     142             : {
     143    13207640 :     while (_impl->position >= _impl->inputSize)
     144             :     {
     145     4831021 :         CompressorInfo info;
     146     2390673 :         uint32_t nChunks = 0;
     147     2390673 :         const void* data = 0;
     148             : 
     149     2390673 :         _impl->position = 0;
     150     2390673 :         _impl->input = 0;
     151     2390673 :         _impl->inputSize = 0;
     152             : 
     153     2390673 :         if (!getNextBuffer(info, nChunks, data, _impl->inputSize))
     154         155 :             return false;
     155             : 
     156     2392525 :         _impl->input = _decompress(data, info, nChunks, _impl->inputSize);
     157             :     }
     158     8376619 :     return true;
     159             : }
     160             : 
     161     2395333 : const uint8_t* DataIStream::_decompress(const void* data,
     162             :                                         const CompressorInfo& info,
     163             :                                         const uint32_t nChunks,
     164             :                                         const uint64_t dataSize)
     165             : {
     166     2395333 :     const uint8_t* src = reinterpret_cast<const uint8_t*>(data);
     167     2395333 :     if (info.name.empty())
     168     2395900 :         return src;
     169             : 
     170           8 :     LBASSERT(!info.name.empty());
     171             : #ifndef CO_AGGRESSIVE_CACHING
     172           8 :     _impl->data.clear();
     173             : #endif
     174           8 :     _impl->data.reset(dataSize);
     175           8 :     _impl->initCompressor(info);
     176             : 
     177          16 :     std::vector<std::pair<const uint8_t*, size_t>> inputs(nChunks);
     178          16 :     for (uint32_t i = 0; i < nChunks; ++i)
     179             :     {
     180           8 :         const uint64_t size = *reinterpret_cast<const uint64_t*>(src);
     181           8 :         src += sizeof(uint64_t);
     182             : 
     183           8 :         inputs[i] = {src, size};
     184           8 :         src += size;
     185             :     }
     186             : 
     187           8 :     _impl->compressor->decompress(inputs, _impl->data.getData(), dataSize);
     188           8 :     return _impl->data.getData();
     189             : }
     190          63 : }

Generated by: LCOV version 1.11