/* * Copyright (c) 2015-2016, Luca Fulchir, All rights reserved. * * This file is part of "libRaptorQ". * * libRaptorQ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * libRaptorQ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * and a copy of the GNU Lesser General Public License * along with libRaptorQ. If not, see . */ #pragma once #include "RaptorQ/v1/common.hpp" #include "RaptorQ/v1/wrapper/CPP_RFC_API_void.hpp" #include "RaptorQ/v1/RFC_Iterators.hpp" #include #if __cplusplus >= 201103L || _MSC_VER > 1900 #include #endif ///////////////////// // // These templates are just a wrapper around the // functionalities offered by the RaptorQ__v1::Impl namespace // So if you want to see what the algorithm looks like, // you are in the wrong place // ///////////////////// namespace RFC6330__v1 { //////////////////// //// Encoder //////////////////// template class RAPTORQ_API Encoder { public: Encoder (const Rnd_It data_from, const Rnd_It data_to, const uint16_t min_subsymbol_size, const uint16_t symbol_size, const size_t max_sub_block); Encoder() = delete; Encoder (const Encoder&) = delete; Encoder& operator= (const Encoder&) = delete; Encoder (Encoder&&) = default; Encoder& operator= (Encoder&&) = default; ~Encoder(); It::Encoder::Block_Iterator begin(); const It::Encoder::Block_Iterator end(); operator bool() const; RFC6330_OTI_Common_Data OTI_Common() const; RFC6330_OTI_Scheme_Specific_Data OTI_Scheme_Specific() const; #if __cplusplus >= 201103L || _MSC_VER > 1900 std::future> compute (const Compute flags); #endif size_t precompute_max_memory (); size_t encode (Fwd_It &output, const Fwd_It end, const uint32_t esi, const uint8_t sbn); size_t encode (Fwd_It &output, const Fwd_It end, const uint32_t &id); void free (const uint8_t sbn); uint8_t blocks() const; uint32_t block_size (const uint8_t sbn) const; uint16_t symbol_size() const; uint16_t symbols (const uint8_t sbn) const; uint32_t max_repair (const uint8_t sbn) const; private: Impl::Encoder_void *_encoder; }; //////////////////// //// Decoder //////////////////// template class RAPTORQ_API Decoder { public: Decoder (const RFC6330_OTI_Common_Data common, const RFC6330_OTI_Scheme_Specific_Data scheme); Decoder (const uint64_t size, const uint16_t symbol_size, const uint16_t sub_blocks, const uint8_t blocks, const uint8_t alignment); Decoder() = delete; Decoder (const Decoder&) = delete; Decoder& operator= (const Decoder&) = delete; Decoder (Decoder&&) = default; Decoder& operator= (Decoder&&) = default; ~Decoder(); It::Decoder::Block_Iterator begin (); const It::Decoder::Block_Iterator end (); operator bool() const; #if __cplusplus >= 201103L || _MSC_VER > 1900 std::future> compute (const Compute flags); #endif void end_of_input (const uint8_t block); void end_of_input(); uint64_t decode_bytes (Fwd_It &start, const Fwd_It end, const uint8_t skip); size_t decode_block_bytes (Fwd_It &start, const Fwd_It end, const uint8_t skip, const uint8_t sbn); struct aligned_res { uint64_t written; uint8_t offset; }; aligned_res decode_aligned (Fwd_It &start,const Fwd_It end, const uint8_t skip); aligned_res decode_block_aligned (Fwd_It &start, const Fwd_It end, const uint8_t skip, const uint8_t sbn); Error add_symbol (In_It &start, const In_It end, const uint32_t id); Error add_symbol (In_It &start, const In_It end, const uint32_t esi, const uint8_t sbn); void free (const uint8_t sbn); uint64_t bytes() const; uint8_t blocks() const; uint32_t block_size (const uint8_t sbn) const; uint16_t symbol_size() const; uint16_t symbols (const uint8_t sbn) const; private: Impl::Decoder_void *_decoder; }; /////////////////// //// Encoder /////////////////// template <> Encoder::Encoder (uint8_t* const data_from, uint8_t* const data_to, const uint16_t min_subsymbol_size, const uint16_t symbol_size, const size_t max_sub_block) { _encoder = new Impl::Encoder_void (RaptorQ_type::RQ_ENC_8, data_from, data_to, min_subsymbol_size, symbol_size, max_sub_block); } template <> Encoder::Encoder (uint16_t* const data_from, uint16_t* const data_to, const uint16_t min_subsymbol_size, const uint16_t symbol_size, const size_t max_sub_block) { _encoder = new Impl::Encoder_void (RaptorQ_type::RQ_ENC_16, data_from, data_to, min_subsymbol_size, symbol_size, max_sub_block); } template <> Encoder::Encoder (uint32_t* const data_from, uint32_t* const data_to, const uint16_t min_subsymbol_size, const uint16_t symbol_size, const size_t max_sub_block) { _encoder = new Impl::Encoder_void (RaptorQ_type::RQ_ENC_32, data_from, data_to, min_subsymbol_size, symbol_size, max_sub_block); } template <> Encoder::Encoder (uint64_t* const data_from, uint64_t* const data_to, const uint16_t min_subsymbol_size, const uint16_t symbol_size, const size_t max_sub_block) { _encoder = new Impl::Encoder_void (RaptorQ_type::RQ_ENC_64, data_from, data_to, min_subsymbol_size, symbol_size, max_sub_block); } template Encoder::Encoder (const Rnd_It data_from, const Rnd_It data_to, const uint16_t min_subsymbol_size, const uint16_t symbol_size, const size_t max_sub_block) { RQ_UNUSED (data_from); RQ_UNUSED (data_to); RQ_UNUSED (min_subsymbol_size); RQ_UNUSED (symbol_size); RQ_UNUSED (max_sub_block); static_assert (false, "RaptorQ: sorry, only uint8_t*, uint16_t*, uint32_t*, uint64_t*, " "supported for the linked library. For more please use the " "header-only version"); } template Encoder::~Encoder() { delete _encoder; } template It::Encoder::Block_Iterator Encoder::begin() { return It::Encoder::Block_Iterator (_encoder, 0); } template const It::Encoder::Block_Iterator Encoder::end() { if (_encoder == nullptr) return It::Encoder::Block_Iterator (nullptr, 0); return It::Encoder::Block_Iterator (_encoder, blocks()); } template Encoder::operator bool() const { if (_encoder == nullptr) return false; return static_cast (*_encoder); } template RFC6330_OTI_Common_Data Encoder::OTI_Common() const { if (_encoder == nullptr) return 0; return _encoder->OTI_Common(); } template RFC6330_OTI_Scheme_Specific_Data Encoder::OTI_Scheme_Specific() const { if (_encoder == nullptr) return 0; return _encoder->OTI_Common(); } #if __cplusplus >= 201103L template std::future> Encoder::compute ( const Compute flags) { if (_encoder != nullptr) return _encoder->compute (flags); std::promise> ret; ret.set_value ({Error::INITIALIZATION, 0}); return ret.get_future(); } #endif template size_t Encoder::precompute_max_memory () { if (_encoder == nullptr) return 0; return _encoder->precompute_max_memory(); } template size_t Encoder::encode (Fwd_It &output, const Fwd_It end, const uint32_t esi, const uint8_t sbn) { if (_encoder == nullptr) return 0; return _encoder->encode (output, end, esi, sbn); } template size_t Encoder::encode (Fwd_It &output, const Fwd_It end, const uint32_t &id) { if (_encoder == nullptr) return 0; return _encoder->encode (output, end, id); } template void Encoder::free (const uint8_t sbn) { if (_encoder == nullptr) return; return _encoder->free (sbn); } template uint8_t Encoder::blocks() const { if (_encoder == nullptr) return 0; return _encoder->blocks(); } template uint32_t Encoder::block_size (const uint8_t sbn) const { if (_encoder == nullptr) return 0; return _encoder->block_size (sbn); } template uint16_t Encoder::symbol_size() const { if (_encoder == nullptr) return 0; return _encoder->symbol_size(); } template uint16_t Encoder::symbols (const uint8_t sbn) const { if (_encoder == nullptr) return 0; return _encoder->symbols (sbn); } template uint32_t Encoder::max_repair (const uint8_t sbn) const { if (_encoder == nullptr) return 0; return _encoder->max_repair (sbn); } //////////////////// //// Decoder //////////////////// template <> Decoder::Decoder (const RFC6330_OTI_Common_Data common, const RFC6330_OTI_Scheme_Specific_Data scheme) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_8, common, scheme); } template <> Decoder::Decoder (const RFC6330_OTI_Common_Data common, const RFC6330_OTI_Scheme_Specific_Data scheme) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_16, common, scheme); } template <> Decoder::Decoder (const RFC6330_OTI_Common_Data common, const RFC6330_OTI_Scheme_Specific_Data scheme) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_32, common, scheme); } template <> Decoder::Decoder (const RFC6330_OTI_Common_Data common, const RFC6330_OTI_Scheme_Specific_Data scheme) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_64, common, scheme); } template Decoder::Decoder (const RFC6330_OTI_Common_Data common, const RFC6330_OTI_Scheme_Specific_Data scheme) { RQ_UNUSED (common); RQ_UNUSED (scheme);; static_assert (false, "RaptorQ: sorry, only uint8_t*, uint16_t*, uint32_t*, uint64_t*, " "supported for the linked library. For more please use the " "header-only version"); } template <> Decoder::Decoder (const uint64_t size,const uint16_t symbol_size, const uint16_t sub_blocks, const uint8_t blocks, const uint8_t alignment) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_8, size, symbol_size, sub_blocks, blocks, alignment); } template <> Decoder::Decoder (const uint64_t size,const uint16_t symbol_size, const uint16_t sub_blocks, const uint8_t blocks, const uint8_t alignment) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_16, size, symbol_size, sub_blocks, blocks, alignment); } template <> Decoder::Decoder (const uint64_t size,const uint16_t symbol_size, const uint16_t sub_blocks, const uint8_t blocks, const uint8_t alignment) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_32, size, symbol_size, sub_blocks, blocks, alignment); } template <> Decoder::Decoder (const uint64_t size,const uint16_t symbol_size, const uint16_t sub_blocks, const uint8_t blocks, const uint8_t alignment) { _decoder = new Impl::Decoder_void (RaptorQ_type::RQ_DEC_64, size, symbol_size, sub_blocks, blocks, alignment); } template Decoder::Decoder (const uint64_t size, const uint16_t symbol_size, const uint16_t sub_blocks, const uint8_t blocks, const uint8_t alignment) { RQ_UNUSED (size); RQ_UNUSED (symbol_size); RQ_UNUSED (sub_blocks); RQ_UNUSED (blocks); RQ_UNUSED (alignment); static_assert (false, "RaptorQ: sorry, only uint8_t*, uint16_t*, uint32_t*, uint64_t*, " "supported for the linked library. For more please use the " "header-only version"); } template Decoder::~Decoder() { delete _decoder; } template It::Decoder::Block_Iterator Decoder::begin() { return It::Encoder::Block_Iterator (_decoder, 0); } template const It::Decoder::Block_Iterator Decoder::end() { if (_decoder == nullptr) return It::Encoder::Block_Iterator (nullptr, 0); return It::Encoder::Block_Iterator (_decoder, blocks()); } template Decoder::operator bool() const { if (_decoder == nullptr) return false; return static_cast (*_decoder); } #if __cplusplus >= 201103L template std::future> Decoder::compute ( const Compute flags) { if (_decoder != nullptr) return _decoder->compute(flags); std::promise> p; p.set_value ({Error::INITIALIZATION, 0}); return p.get_future(); } #endif template void Decoder::end_of_input (const uint8_t block) { if (_decoder != nullptr) return _decoder->end_of_input (block); } template void Decoder::end_of_input() { if (_decoder != nullptr) return _decoder->end_of_input(); } template uint64_t Decoder::decode_bytes (Fwd_It &start, const Fwd_It end, const uint8_t skip) { if (_decoder == nullptr) return 0; return _decoder->decode_bytes (start, end, skip); } template size_t Decoder::decode_block_bytes (Fwd_It &start, const Fwd_It end, const uint8_t skip, const uint8_t sbn) { if (_decoder == nullptr) return 0; return _decoder->decode_block_bytes (start, end, skip, sbn); } template typename Decoder::aligned_res Decoder::decode_aligned ( Fwd_It &start, const Fwd_It end, const uint8_t skip) { if (_decoder == nullptr) return {0, 0}; return _decoder->decode_aligned (start, end, skip); } template typename Decoder::aligned_res Decoder::decode_block_aligned ( Fwd_It &start, const Fwd_It end, const uint8_t skip, const uint8_t sbn) { if (_decoder == nullptr) return {0, 0}; return _decoder->decode_block_aligned (start, end, skip, sbn); } template Error Decoder::add_symbol (In_It &start, const In_It end, const uint32_t id) { if (_decoder == nullptr) return Error::INITIALIZATION; return _decoder->add_symbol (start, end, id); } template Error Decoder::add_symbol (In_It &start, const In_It end, const uint32_t esi, const uint8_t sbn) { if (_decoder == nullptr) return Error::INITIALIZATION; return _decoder->add_symbol (start, end, esi, sbn); } template void Decoder::free (const uint8_t sbn) { if (_decoder != nullptr) return _decoder->free (sbn); } template uint64_t Decoder::bytes() const { if (_decoder == nullptr) return 0; return _decoder->bytes(); } template uint8_t Decoder::blocks() const { if (_decoder == nullptr) return 0; return _decoder->blocks(); } template uint32_t Decoder::block_size (const uint8_t sbn) const { if (_decoder == nullptr) return 0; return _decoder->block_size (sbn); } template uint16_t Decoder::symbol_size() const { if (_decoder == nullptr) return 0; return _decoder->symbol_size(); } template uint16_t Decoder::symbols (const uint8_t sbn) const { if (_decoder == nullptr) return 0; return _decoder->symbols (sbn); } } // namespace RFC6330__v1