/* * 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 #include // NOTE: this file is included from RFC.hpp and CPP_RFC_API.hpp // Yes, another template parameter would keep us away from macros. // But I prefer to kep the parameters the same as for the classes. // So we keep the macros. (NOTE: this header requires C++98 compatibility) #ifdef RQ_HEADER_ONLY #include "RaptorQ/v1/RFC.hpp" namespace RFC6330__v1 { namespace Impl { template class Encoder; template class Decoder; } } #define RQ_ENC_T Impl::Encoder #define RQ_DEC_T Impl::Decoder #else #include "RaptorQ/v1/wrapper/CPP_RFC_API_void.hpp" #define RQ_ENC_T Impl::Encoder_void #define RQ_DEC_T Impl::Decoder_void #endif /////////////////// //// Iterators /////////////////// namespace RFC6330__v1 { namespace It { namespace Encoder { template class RAPTORQ_API Symbol { public: Symbol (RQ_ENC_T *const enc, const uint32_t id) : _enc (enc), _id (id) {} Symbol() = delete; Symbol (const Symbol&) = default; Symbol& operator= (const Symbol&) = default; Symbol (Symbol&&) = default; Symbol& operator= (Symbol&&) = default; ~Symbol() = default; uint64_t operator() (Fwd_It &start, const Fwd_It end) { if (_enc == nullptr) return 0; return _enc->encode (start, end, _id); } uint32_t id() const { return _id; } uint8_t block() const { return static_cast (_id >> 24); } uint32_t esi() const { uint32_t rev_mask = static_cast (0xFF) << 24; return static_cast (_id & ~rev_mask); } private: RQ_ENC_T *const _enc; const uint32_t _id; }; template class RAPTORQ_API Symbol_Iterator : public std::iterator> { public: Symbol_Iterator (RQ_ENC_T *const enc, const uint32_t id) : _enc (enc), _id (id) {} Symbol_Iterator() = delete; Symbol_Iterator (const Symbol_Iterator&) = default; Symbol_Iterator& operator= (const Symbol_Iterator&) = default; Symbol_Iterator (Symbol_Iterator&&) = default; Symbol_Iterator& operator= (Symbol_Iterator&&) = default; ~Symbol_Iterator() = default; Symbol operator*() { return Symbol (_enc, _id); } Symbol_Iterator& operator++() { ++_id; return *this; } Symbol_Iterator operator++ (const int i) const { return Symbol_Iterator (_enc, _id + static_cast (i)); } bool operator== (const Symbol_Iterator &it) const { return it._id == _id && it._enc == _enc; } bool operator!= (const Symbol_Iterator &it) const { return it._id != _id && it._enc == _enc; } private: RQ_ENC_T *const _enc; uint32_t _id; }; template class RAPTORQ_API Block { public: Block (RQ_ENC_T *const enc, const uint8_t block) : _enc (enc), _block (block) {} Block() = delete; Block (const Block&) = default; Block& operator= (const Block&) = default; Block (Block&&) = default; Block& operator= (Block&&) = default; ~Block() = default; Symbol_Iterator begin_source() const { if (_enc == nullptr) return Symbol_Iterator (nullptr, 0); const uint32_t id = static_cast (_block) << 24; return Symbol_Iterator (_enc, id); } Symbol_Iterator end_source() const { if (_enc == nullptr) return Symbol_Iterator (nullptr, 0); const uint32_t id = static_cast (_block) << 24; return Symbol_Iterator (_enc, id + _enc->symbols (_block)); } Symbol_Iterator begin_repair() const { return end_source(); } Symbol_Iterator end_repair (uint32_t repairs) const { if (repairs > std::pow (2, 20)) repairs = static_cast (std::pow (2, 20)); if (_enc == nullptr) return Symbol_Iterator (nullptr, 0); const uint32_t id = static_cast (_block) << 24; return Symbol_Iterator (_enc, id + _enc->symbols (_block) + repairs); } uint8_t id() const { return _block; } uint32_t max_repair() const { if (_enc == nullptr) return 0; return _enc->max_repair (_block); } uint16_t symbols() const { if (_enc == nullptr) return 0; return _enc->symbols (_block); } uint32_t block_size() const { if (_enc == nullptr) return 0; return _enc->block_size (_block); } private: RQ_ENC_T *const _enc; const uint8_t _block; }; template class RAPTORQ_API Block_Iterator : public std::iterator> { public: Block_Iterator (RQ_ENC_T *const enc, const uint8_t block) : _enc (enc), _block (block) {} Block_Iterator() = delete; Block_Iterator (const Block_Iterator&) = default; Block_Iterator& operator= (const Block_Iterator&) = default; Block_Iterator (Block_Iterator&&) = default; Block_Iterator& operator= (Block_Iterator&&) = default; ~Block_Iterator() = default; Block operator*() { return Block (_enc, _block); } Block_Iterator& operator++() { ++_block; return *this; } Block_Iterator operator++ (const int i) const { return Block_Iterator (_enc, _block + static_cast (i)); } bool operator== (const Block_Iterator &it) const { return it._block == _block && it._enc == _enc; } bool operator!= (const Block_Iterator &it) const { return it._block != _block && it._enc == _enc; } private: RQ_ENC_T *const _enc; uint8_t _block; }; } // namespace Encoder ///////////////// //// Decoder ///////////////// namespace Decoder { template class RAPTORQ_API Symbol { public: Symbol (RQ_DEC_T *const dec, const uint32_t id) : _dec (dec), _id (id) {} Symbol() = delete; Symbol (const Symbol&) = default; Symbol& operator= (const Symbol&) = default; Symbol (Symbol&&) = default; Symbol& operator= (Symbol&&) = default; ~Symbol() = default; uint64_t operator() (In_It &start, const In_It end) { if (_dec == nullptr || esi (_id) > _dec->symbols (block (_id))) return 0; return _dec->decode_symbol (start, end, static_cast (esi (_id)), block (_id)); } uint32_t id() const { return _id; } uint8_t block() const { return static_cast (_id >> 24); } uint32_t esi() const { uint32_t rev_mask = static_cast (0xFF) << 24; return static_cast (_id & ~rev_mask); } private: RQ_DEC_T *const _dec; const uint32_t _id; }; template class RAPTORQ_API Symbol_Iterator : public std::iterator> { public: Symbol_Iterator (RQ_DEC_T *const dec, const uint32_t id) : _dec (dec), _id (id) {} Symbol_Iterator() = delete; Symbol_Iterator (const Symbol_Iterator&) = default; Symbol_Iterator& operator= (const Symbol_Iterator&) = default; Symbol_Iterator (Symbol_Iterator&&) = default; Symbol_Iterator& operator= (Symbol_Iterator&&) = default; ~Symbol_Iterator() = default; Symbol operator*() { return Symbol (_dec, _id); } Symbol_Iterator& operator++() { ++_id; return *this; } Symbol_Iterator operator++ (const int i) const { return Symbol_Iterator (_dec, _id + static_cast (i)); } bool operator== (const Symbol_Iterator &it) const { return it._id == _id && it._dec == _dec; } bool operator!= (const Symbol_Iterator &it) const { return it._id != _id && it._dec == _dec; } private: RQ_DEC_T *const _dec; uint32_t _id; }; template class RAPTORQ_API Block { public: Block (RQ_DEC_T *const dec, const uint8_t block) : _dec (dec), _block (block) {} Block() = delete; Block (const Block&) = default; Block& operator= (const Block&) = default; Block (Block&&) = default; Block& operator= (Block&&) = default; ~Block() = default; Symbol_Iterator begin() const { if (_dec == nullptr) return Symbol_Iterator (nullptr, 0); const uint32_t id = static_cast (_block) << 24; return Symbol_Iterator (_dec, id); } Symbol_Iterator end() const { if (_dec == nullptr) return Symbol_Iterator (nullptr, 0); const uint32_t id = static_cast (_block) << 24; return Symbol_Iterator (_dec, id + _dec->symbols (_block)); } uint8_t id() const { return _block; } uint16_t symbols() const { if (_dec == nullptr) return 0; return _dec->symbols (_block); } uint32_t block_size() const { if (_dec == nullptr) return 0; return _dec->block_size (_block); } private: RQ_DEC_T *const _dec; const uint8_t _block; }; template class RAPTORQ_API Block_Iterator : public std::iterator> { public: Block_Iterator (RQ_DEC_T *const dec, const uint8_t block) : _dec (dec), _block (block) {} Block_Iterator() = delete; Block_Iterator (const Block_Iterator&) = default; Block_Iterator& operator= (const Block_Iterator&) = default; Block_Iterator (Block_Iterator&&) = default; Block_Iterator& operator= (Block_Iterator&&) = default; ~Block_Iterator() = default; Block operator*() { return Block (_dec, _block); } Block_Iterator& operator++() { ++_block; return *this; } Block_Iterator operator++ (const int i) const { return Block_Iterator (_dec, _block + static_cast (i)); } bool operator== (const Block_Iterator &it) const { return it._block == _block && it._dec == _dec; } bool operator!= (const Block_Iterator &it) const { return it._block != _block && it._dec == _dec; } private: RQ_DEC_T *const _dec; uint8_t _block; }; } // namespace Decoder } // namespace It } // namespace Rfc6330__v1