/* (**************************************************************************) (* *) (* Schifra *) (* Reed-Solomon Error Correcting Code Library *) (* *) (* Release Version 0.0.1 *) (* http://www.schifra.com *) (* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) (* *) (* The Schifra Reed-Solomon error correcting code library and all its *) (* components are supplied under the terms of the General Schifra License *) (* agreement. The contents of the Schifra Reed-Solomon error correcting *) (* code library and all its components may not be copied or disclosed *) (* except in accordance with the terms of that agreement. *) (* *) (* URL: http://www.schifra.com/license.html *) (* *) (**************************************************************************) */ #ifndef INCLUDE_SCHIFRA_REED_GENERAL_CODEC_HPP #define INCLUDE_SCHIFRA_REED_GENERAL_CODEC_HPP #include "schifra_galois_field.hpp" #include "schifra_galois_field_polynomial.hpp" #include "schifra_sequential_root_generator_polynomial_creator.hpp" #include "schifra_reed_solomon_block.hpp" #include "schifra_reed_solomon_encoder.hpp" #include "schifra_reed_solomon_decoder.hpp" #include "schifra_ecc_traits.hpp" namespace schifra { namespace reed_solomon { template void* create_encoder(const galois::field& field, const std::size_t& gen_poly_index) { const std::size_t data_length = code_length - fec_length; traits::validate_reed_solomon_code_parameters(); galois::field_polynomial gen_polynomial(field); if ( !make_sequential_root_generator_polynomial(field, gen_poly_index, fec_length, gen_polynomial) ) { return reinterpret_cast(0); } return new encoder(field,gen_polynomial); } template void* create_decoder(const galois::field& field, const std::size_t& gen_poly_index) { const std::size_t data_length = code_length - fec_length; traits::validate_reed_solomon_code_parameters(); return new decoder(field,static_cast(gen_poly_index)); } template class general_codec { public: general_codec(const galois::field& field, const std::size_t& gen_poly_index) { for (std::size_t i = 0; i < max_fec_length; ++i) { encoder_[i] = 0; decoder_[i] = 0; } encoder_[ 2] = create_encoder(field, gen_poly_index); encoder_[ 4] = create_encoder(field, gen_poly_index); encoder_[ 6] = create_encoder(field, gen_poly_index); encoder_[ 8] = create_encoder(field, gen_poly_index); encoder_[ 10] = create_encoder(field, gen_poly_index); encoder_[ 12] = create_encoder(field, gen_poly_index); encoder_[ 14] = create_encoder(field, gen_poly_index); encoder_[ 16] = create_encoder(field, gen_poly_index); encoder_[ 18] = create_encoder(field, gen_poly_index); encoder_[ 20] = create_encoder(field, gen_poly_index); encoder_[ 22] = create_encoder(field, gen_poly_index); encoder_[ 24] = create_encoder(field, gen_poly_index); encoder_[ 26] = create_encoder(field, gen_poly_index); encoder_[ 28] = create_encoder(field, gen_poly_index); encoder_[ 30] = create_encoder(field, gen_poly_index); encoder_[ 32] = create_encoder(field, gen_poly_index); encoder_[ 64] = create_encoder(field, gen_poly_index); encoder_[ 80] = create_encoder(field, gen_poly_index); encoder_[ 96] = create_encoder(field, gen_poly_index); encoder_[128] = create_encoder(field, gen_poly_index); decoder_[ 2] = create_decoder(field, gen_poly_index); decoder_[ 4] = create_decoder(field, gen_poly_index); decoder_[ 6] = create_decoder(field, gen_poly_index); decoder_[ 8] = create_decoder(field, gen_poly_index); decoder_[ 10] = create_decoder(field, gen_poly_index); decoder_[ 12] = create_decoder(field, gen_poly_index); decoder_[ 14] = create_decoder(field, gen_poly_index); decoder_[ 16] = create_decoder(field, gen_poly_index); decoder_[ 18] = create_decoder(field, gen_poly_index); decoder_[ 20] = create_decoder(field, gen_poly_index); decoder_[ 22] = create_decoder(field, gen_poly_index); decoder_[ 24] = create_decoder(field, gen_poly_index); decoder_[ 26] = create_decoder(field, gen_poly_index); decoder_[ 28] = create_decoder(field, gen_poly_index); decoder_[ 30] = create_decoder(field, gen_poly_index); decoder_[ 32] = create_decoder(field, gen_poly_index); decoder_[ 64] = create_decoder(field, gen_poly_index); decoder_[ 80] = create_decoder(field, gen_poly_index); decoder_[ 96] = create_decoder(field, gen_poly_index); decoder_[128] = create_decoder(field, gen_poly_index); } ~general_codec() { delete static_cast*>(encoder_[ 2]); delete static_cast*>(encoder_[ 4]); delete static_cast*>(encoder_[ 6]); delete static_cast*>(encoder_[ 8]); delete static_cast*>(encoder_[ 10]); delete static_cast*>(encoder_[ 12]); delete static_cast*>(encoder_[ 14]); delete static_cast*>(encoder_[ 16]); delete static_cast*>(encoder_[ 18]); delete static_cast*>(encoder_[ 20]); delete static_cast*>(encoder_[ 22]); delete static_cast*>(encoder_[ 24]); delete static_cast*>(encoder_[ 26]); delete static_cast*>(encoder_[ 28]); delete static_cast*>(encoder_[ 30]); delete static_cast*>(encoder_[ 32]); delete static_cast*>(encoder_[ 64]); delete static_cast*>(encoder_[ 80]); delete static_cast*>(encoder_[ 96]); delete static_cast*>(encoder_[128]); delete static_cast*>(decoder_[ 2]); delete static_cast*>(decoder_[ 4]); delete static_cast*>(decoder_[ 6]); delete static_cast*>(decoder_[ 8]); delete static_cast*>(decoder_[ 10]); delete static_cast*>(decoder_[ 12]); delete static_cast*>(decoder_[ 14]); delete static_cast*>(decoder_[ 16]); delete static_cast*>(decoder_[ 18]); delete static_cast*>(decoder_[ 20]); delete static_cast*>(decoder_[ 22]); delete static_cast*>(decoder_[ 24]); delete static_cast*>(decoder_[ 26]); delete static_cast*>(decoder_[ 28]); delete static_cast*>(decoder_[ 30]); delete static_cast*>(decoder_[ 32]); delete static_cast*>(decoder_[ 64]); delete static_cast*>(decoder_[ 80]); delete static_cast*>(decoder_[ 96]); delete static_cast*>(decoder_[128]); } template bool encode(Block& block) const { /* cl : code length fl : fec length */ typedef reed_solomon::encoder encoder_type; traits::__static_assert__<(Block::trait::fec_length <= max_fec_length)>(); if (encoder_[Block::trait::fec_length] == 0) return false; else return static_cast(encoder_[Block::trait::fec_length])->encode(block); } template bool decode(Block& block) const { typedef reed_solomon::decoder decoder_type; traits::__static_assert__<(Block::trait::fec_length <= max_fec_length)>(); if (decoder_[Block::trait::fec_length] == 0) return false; else return static_cast(decoder_[Block::trait::fec_length])->decode(block); } private: void* encoder_[max_fec_length + 1]; void* decoder_[max_fec_length + 1]; }; } // namespace reed_solomon } // namespace schifra #endif