LCOV - code coverage report
Current view: top level - src/Module/Stateful/Source/User - Source_user_binary.cpp (source / functions) Hit Total Coverage
Test: streampu_clean.info Lines: 40 66 60.6 %
Date: 2025-01-11 12:25:42 Functions: 3 40 7.5 %

          Line data    Source code
       1             : #include "Module/Stateful/Source/User/Source_user_binary.hpp"
       2             : #include "Tools/Algo/Bit_packer/Bit_packer.hpp"
       3             : #include "Tools/Exception/exception.hpp"
       4             : 
       5             : using namespace spu;
       6             : using namespace spu::module;
       7             : 
       8             : template<typename B>
       9          51 : Source_user_binary<B>::Source_user_binary(const int max_data_size,
      10             :                                           const std::string& filename,
      11             :                                           const bool auto_reset,
      12             :                                           const bool fifo_mode)
      13             :   : Source<B>(max_data_size)
      14          51 :   , source_file(filename.c_str(), std::ios::in | std::ios::binary)
      15          51 :   , auto_reset(fifo_mode ? true : auto_reset)
      16          51 :   , fifo_mode(fifo_mode)
      17          51 :   , done(false)
      18          51 :   , n_left(0)
      19          51 :   , memblk(max_data_size)
      20         102 :   , left_bits(CHAR_BIT)
      21             : {
      22          51 :     const std::string name = "Source_user_binary";
      23          51 :     this->set_name(name);
      24             : 
      25          51 :     if (source_file.fail())
      26             :     {
      27           0 :         std::stringstream message;
      28           0 :         message << "'filename' file name is not valid: sink file failbit is set.";
      29           0 :         throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
      30           0 :     }
      31          51 : }
      32             : 
      33             : template<typename B>
      34             : void
      35           0 : Source_user_binary<B>::reset()
      36             : {
      37           0 :     source_file.clear();
      38           0 :     if (!this->fifo_mode) source_file.seekg(0, std::ios::beg);
      39           0 :     if (source_file.fail())
      40           0 :         throw tools::runtime_error(__FILE__, __LINE__, __func__, "Could not go back to the beginning of the file.");
      41           0 :     this->done = false;
      42           0 :     this->n_left = 0;
      43           0 : }
      44             : 
      45             : template<typename B>
      46             : bool
      47       23476 : Source_user_binary<B>::is_done() const
      48             : {
      49       23476 :     return this->done;
      50             : }
      51             : 
      52             : template<typename B>
      53             : void
      54       11768 : Source_user_binary<B>::_generate(B* out_data, uint32_t* out_count, const size_t frame_id)
      55             : {
      56       11768 :     if (this->is_done())
      57             :     {
      58          14 :         std::fill(out_data, out_data + this->max_data_size, (B)0);
      59          14 :         *out_count = 0;
      60             :     }
      61             :     else
      62             :     {
      63       11754 :         size_t n_bytes_read = 0;
      64       11754 :         const size_t n_bytes_needed =
      65       11754 :           (size_t)(this->max_data_size - this->n_left + CHAR_BIT - 1) / CHAR_BIT; // number of bytes needed
      66             : 
      67       11754 :         for (size_t i = 0; i < this->n_left; i++)
      68           0 :             out_data[i] = this->left_bits[i];
      69             : 
      70       23457 :         while (n_bytes_read < n_bytes_needed)
      71             :         {
      72       11754 :             source_file.read(this->memblk.data() + n_bytes_read, n_bytes_needed - n_bytes_read);
      73       11754 :             n_bytes_read += source_file.gcount();
      74             : 
      75       11754 :             if (source_file.fail())
      76             :             {
      77          51 :                 if (source_file.eof())
      78             :                 {
      79          51 :                     if (this->auto_reset)
      80           0 :                         this->reset();
      81             :                     else
      82          51 :                         break;
      83             :                 }
      84             :                 else
      85           0 :                     throw tools::runtime_error(__FILE__, __LINE__, __func__, "Unknown error during file reading.");
      86             :             }
      87             :         }
      88             : 
      89       11754 :         if (this->n_left + n_bytes_read * CHAR_BIT <= (size_t)this->max_data_size)
      90             :         {
      91       11754 :             *out_count = this->n_left + n_bytes_read * CHAR_BIT;
      92             : 
      93       11754 :             if (!this->auto_reset && source_file.eof())
      94             :             {
      95          51 :                 this->done = true;
      96          51 :                 if (this->n_left + n_bytes_read * CHAR_BIT == 0)
      97             :                 {
      98           5 :                     if (frame_id == 0)
      99           5 :                         throw tools::processing_aborted(__FILE__, __LINE__, __func__);
     100             :                     else
     101             :                     {
     102           0 :                         std::fill(out_data, out_data + this->max_data_size, (B)0);
     103           0 :                         *out_count = 0;
     104           0 :                         return;
     105             :                     }
     106             :                 }
     107             :             }
     108             : 
     109       11749 :             tools::Bit_packer::unpack(this->memblk.data(), out_data + this->n_left, n_bytes_read * CHAR_BIT);
     110       11749 :             std::fill(out_data + this->n_left + n_bytes_read * CHAR_BIT, out_data + this->max_data_size, (B)0);
     111             : 
     112       11749 :             int tmp_n_left = ((int)n_bytes_read * (int)CHAR_BIT) - (this->max_data_size - (int)this->n_left);
     113       11749 :             this->n_left = tmp_n_left < 0 ? (size_t)0 : (size_t)tmp_n_left;
     114             :         }
     115             :         else
     116             :         {
     117           0 :             *out_count = this->max_data_size;
     118             : 
     119           0 :             tools::Bit_packer::unpack(this->memblk.data(), out_data + this->n_left, this->max_data_size - this->n_left);
     120             : 
     121           0 :             int tmp_n_left = ((int)n_bytes_read * (int)CHAR_BIT) - (this->max_data_size - (int)this->n_left);
     122           0 :             this->n_left = tmp_n_left < 0 ? (size_t)0 : (size_t)tmp_n_left;
     123             : 
     124           0 :             if (this->n_left)
     125             :             {
     126             :                 // re-unpack last byte && store into left_bits
     127           0 :                 tools::Bit_packer::unpack(this->memblk.data() + n_bytes_needed - 1, this->left_bits.data(), 8);
     128             : 
     129             :                 // shift the left bits to the beginning of the array
     130           0 :                 for (size_t i = 0; i < this->n_left; i++)
     131           0 :                     this->left_bits[i] = this->left_bits[i + CHAR_BIT - this->n_left];
     132             :             }
     133             :         }
     134             :     }
     135             : }
     136             : 
     137             : // ==================================================================================== explicit template instantiation
     138             : template class spu::module::Source_user_binary<int8_t>;
     139             : template class spu::module::Source_user_binary<uint8_t>;
     140             : template class spu::module::Source_user_binary<int16_t>;
     141             : template class spu::module::Source_user_binary<uint16_t>;
     142             : template class spu::module::Source_user_binary<int32_t>;
     143             : template class spu::module::Source_user_binary<uint32_t>;
     144             : template class spu::module::Source_user_binary<int64_t>;
     145             : template class spu::module::Source_user_binary<uint64_t>;
     146             : template class spu::module::Source_user_binary<float>;
     147             : template class spu::module::Source_user_binary<double>;
     148             : // ==================================================================================== explicit template instantiation

Generated by: LCOV version 1.14