LCOV - code coverage report
Current view: top level - source/lib/file/archive - stream.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 1 50 2.0 %
Date: 2023-01-19 00:18:29 Functions: 2 12 16.7 %

          Line data    Source code
       1             : /* Copyright (C) 2010 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : #include "precompiled.h"
      24             : #include "lib/file/archive/stream.h"
      25             : 
      26             : #include "lib/allocators/page_aligned.h"
      27             : #include "lib/allocators/shared_ptr.h"
      28             : #include "lib/file/archive/codec.h"
      29             : //#include "lib/timer.h"
      30             : 
      31             : //TIMER_ADD_CLIENT(tc_stream);
      32             : 
      33             : 
      34           0 : OutputBufferManager::OutputBufferManager()
      35             : {
      36           0 :     Reset();
      37           0 : }
      38             : 
      39           0 : void OutputBufferManager::Reset()
      40             : {
      41           0 :     m_buffer = 0;
      42           0 :     m_size = 0;
      43           0 :     m_capacity = 0;
      44           0 : }
      45             : 
      46           0 : void OutputBufferManager::SetBuffer(u8* buffer, size_t size)
      47             : {
      48           0 :     ENSURE(IsAllowableBuffer(buffer, size));
      49             : 
      50           0 :     m_buffer = buffer;
      51           0 :     m_size = size;
      52           0 : }
      53             : 
      54           0 : void OutputBufferManager::AllocateBuffer(size_t size)
      55             : {
      56             :     // notes:
      57             :     // - this implementation allows reusing previous buffers if they
      58             :     //   are big enough, which reduces the number of allocations.
      59             :     // - no further attempts to reduce allocations (e.g. by doubling
      60             :     //   the current size) are made; this strategy is enough.
      61             :     // - Pool etc. cannot be used because files may be huge (larger
      62             :     //   than the address space of 32-bit systems).
      63             : 
      64             :     // no buffer or the previous one wasn't big enough: reallocate
      65           0 :     if(!m_mem || m_capacity < size)
      66             :     {
      67           0 :         AllocateAligned(m_mem, size);
      68           0 :         m_capacity = size;
      69             :     }
      70             : 
      71           0 :     SetBuffer(m_mem.get(), size);
      72           0 : }
      73             : 
      74           0 : bool OutputBufferManager::IsAllowableBuffer(u8* buffer, size_t size)
      75             : {
      76             :     // none yet established
      77           0 :     if(m_buffer == 0 && m_size == 0)
      78           0 :         return true;
      79             : 
      80             :     // same as last time (happens with temp buffers)
      81           0 :     if(m_buffer == buffer && m_size == size)
      82           0 :         return true;
      83             : 
      84             :     // located after the last buffer (note: not necessarily after
      85             :     // the entire buffer; a lack of input can cause the output buffer
      86             :     // to only partially be used before the next call.)
      87           0 :     if((unsigned)(buffer - m_buffer) <= m_size)
      88           0 :         return true;
      89             : 
      90           0 :     return false;
      91             : }
      92             : 
      93             : 
      94             : //-----------------------------------------------------------------------------
      95             : 
      96             : 
      97           0 : Stream::Stream(const PICodec& codec)
      98             :     : m_codec(codec)
      99           0 :     , m_inConsumed(0), m_outProduced(0)
     100             : {
     101           0 : }
     102             : 
     103             : 
     104           0 : void Stream::AllocateOutputBuffer(size_t outSizeMax)
     105             : {
     106           0 :     m_outputBufferManager.AllocateBuffer(outSizeMax);
     107           0 : }
     108             : 
     109             : 
     110           0 : void Stream::SetOutputBuffer(u8* out, size_t outSize)
     111             : {
     112           0 :     m_outputBufferManager.SetBuffer(out, outSize);
     113           0 : }
     114             : 
     115             : 
     116           0 : Status Stream::Feed(const u8* in, size_t inSize)
     117             : {
     118           0 :     if(m_outProduced == m_outputBufferManager.Size())   // output buffer full; must not call Process
     119           0 :         return INFO::ALL_COMPLETE;
     120             : 
     121             :     size_t inConsumed, outProduced;
     122           0 :     u8* const out = m_outputBufferManager.Buffer() + m_outProduced;
     123           0 :     const size_t outSize = m_outputBufferManager.Size() - m_outProduced;
     124           0 :     RETURN_STATUS_IF_ERR(m_codec->Process(in, inSize, out, outSize, inConsumed, outProduced));
     125             : 
     126           0 :     m_inConsumed += inConsumed;
     127           0 :     m_outProduced += outProduced;
     128           0 :     return INFO::OK;
     129             : }
     130             : 
     131             : 
     132           0 : Status Stream::Finish()
     133             : {
     134             :     size_t outProduced;
     135           0 :     RETURN_STATUS_IF_ERR(m_codec->Finish(m_checksum, outProduced));
     136           0 :     m_outProduced += outProduced;
     137           0 :     return INFO::OK;
     138           3 : }

Generated by: LCOV version 1.13