Line data Source code
1 : #include <cstdint> 2 : #include <ios> 3 : #include <sstream> 4 : 5 : #include "Module/Stateful/Sink/User/Sink_user_binary.hpp" 6 : #include "Tools/Algo/Bit_packer/Bit_packer.hpp" 7 : #include "Tools/Exception/exception.hpp" 8 : 9 : using namespace spu; 10 : using namespace spu::module; 11 : 12 : template<typename B> 13 51 : Sink_user_binary<B>::Sink_user_binary(const int max_data_size, const std::string& filename) 14 : : Sink<B>(max_data_size) 15 51 : , filename(filename) 16 51 : , sink_file(filename.c_str(), std::ios::out | std::ios::binary) 17 51 : , chunk(max_data_size) 18 51 : , reconstructed_buffer(CHAR_BIT) 19 51 : , n_left(0) 20 : { 21 51 : const std::string name = "Sink_user_binary"; 22 51 : this->set_name(name); 23 : 24 51 : if (this->max_data_size < CHAR_BIT) 25 : { 26 0 : std::stringstream message; 27 0 : message << "'max_data_size' has to be greater or equal to 'CHAR_BIT' ('max_data_size' = " << this->max_data_size 28 0 : << ", 'CHAR_BIT' = " << CHAR_BIT << ")."; 29 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str()); 30 0 : } 31 : 32 51 : if (sink_file.fail()) 33 : { 34 0 : std::stringstream message; 35 0 : message << "'filename' file name is not valid: sink file failbit is set."; 36 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str()); 37 0 : } 38 51 : } 39 : 40 : template<typename B> 41 : void 42 0 : Sink_user_binary<B>::reset() 43 : { 44 0 : sink_file.close(); 45 0 : sink_file.open(this->filename.c_str(), std::ios::out | std::ios::binary); 46 0 : if (sink_file.fail()) 47 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, "Could not go back to the beginning of the file."); 48 0 : this->n_left = 0; 49 0 : } 50 : 51 : template<typename B> 52 : void 53 11763 : Sink_user_binary<B>::_send_count(const B* in_data, const uint32_t* in_count, const size_t frame_id) 54 : { 55 11763 : size_t n_completing = (CHAR_BIT - this->n_left) % CHAR_BIT; // number of bits that are needed to complete one byte 56 : char reconstructed_byte; // to store reconstructed byte (n_left & n_completing) 57 : 58 11763 : if (sink_file.fail()) 59 : { 60 0 : std::stringstream message; 61 0 : message << "'filename' file name is not valid: sink file failbit is set."; 62 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str()); 63 0 : } 64 : 65 11763 : if (this->n_left != 0) 66 : { 67 0 : for (size_t i = 0; i < n_completing; i++) // completing byte with n_completing first bits of in_data 68 0 : this->reconstructed_buffer[this->n_left + i] = in_data[i]; 69 : 70 0 : tools::Bit_packer::pack(this->reconstructed_buffer.data(), &reconstructed_byte, CHAR_BIT); 71 0 : sink_file.write(&reconstructed_byte, 1); 72 : } 73 : 74 11763 : size_t main_chunk_size = (*in_count - n_completing) / CHAR_BIT; // in byte 75 11763 : this->n_left = (*in_count - n_completing) % CHAR_BIT; 76 : 77 11763 : tools::Bit_packer::pack(in_data + n_completing, this->chunk.data(), main_chunk_size * CHAR_BIT); 78 11763 : sink_file.write(this->chunk.data(), main_chunk_size); 79 11763 : sink_file.flush(); 80 11763 : this->n_left = 0; 81 11763 : for (size_t i = n_completing + main_chunk_size * CHAR_BIT; i < (size_t)*in_count; i++) 82 0 : this->reconstructed_buffer[this->n_left++] = in_data[i]; 83 11763 : } 84 : 85 : // ==================================================================================== explicit template instantiation 86 : template class spu::module::Sink_user_binary<int8_t>; 87 : template class spu::module::Sink_user_binary<uint8_t>; 88 : template class spu::module::Sink_user_binary<int16_t>; 89 : template class spu::module::Sink_user_binary<uint16_t>; 90 : template class spu::module::Sink_user_binary<int32_t>; 91 : template class spu::module::Sink_user_binary<uint32_t>; 92 : template class spu::module::Sink_user_binary<int64_t>; 93 : template class spu::module::Sink_user_binary<uint64_t>; 94 : template class spu::module::Sink_user_binary<float>; 95 : template class spu::module::Sink_user_binary<double>; 96 : // ==================================================================================== explicit template instantiation