Skip to content
CPP_RFC_API.hpp 9.77 KiB
Newer Older
/*
 * Copyright (c) 2015-2016, Luca Fulchir<luca@fulchir.it>, 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 <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "RaptorQ/v1/common.hpp"
Luker's avatar
Luker committed
#include "RaptorQ/v1/API_Iterators.hpp"
#include "RaptorQ/v1/RFC.hpp"
#include <cmath>
#include <future>
#include <memory>
#include <utility>

/////////////////////
//
Luker's avatar
Luker committed
//  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 <typename Rnd_It, typename Fwd_It>
class RAPTORQ_API Encoder
{
public:
Luker's avatar
Luker committed
    ~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_memory)
    {
        rfc_encoder = std::unique_ptr<Impl::Encoder<Rnd_It, Fwd_It>> (
Luker's avatar
Luker committed
                                   new Impl::Encoder<Rnd_It, Fwd_It> (
                                        data_from, data_to, min_subsymbol_size,
                                                    symbol_size, max_memory));
Luker's avatar
Luker committed
    }
Luker's avatar
Luker committed
    Block_Iterator<Rnd_It, Fwd_It> begin ()
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->begin();
        return end();
Luker's avatar
Luker committed
    }
    const Block_Iterator<Rnd_It, Fwd_It> end ()
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->end();
        return Block_Iterator<Rnd_It, Fwd_It> (nullptr, Impl::Partition(), 1);
Luker's avatar
Luker committed
    }
Luker's avatar
Luker committed
    operator bool() const { return rfc_encoder != nullptr && (*rfc_encoder); }
    RQ_OTI_Common_Data OTI_Common() const
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->OTI_Common();
        return 0;
    }
Luker's avatar
Luker committed
    RQ_OTI_Scheme_Specific_Data OTI_Scheme_Specific() const
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->OTI_Scheme_Specific();
        return 0;
    }

Luker's avatar
Luker committed
    std::future<std::pair<Error, uint8_t>> compute (const Compute flags)
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->compute (flags);
        std::promise<std::pair<Error, uint8_t>> p;
Luker's avatar
Luker committed
        p.set_value ({Error::INITIALIZATION, 0});
        return p.get_future();
    }

Luker's avatar
Luker committed
    size_t precompute_max_memory ()
Luker's avatar
Luker committed
        if (rfc_encoder != nullptr)
            return rfc_encoder->precompute_max_memory ();
        return 0;
    }
Luker's avatar
Luker committed
    size_t encode (Fwd_It &output, const Fwd_It end, const uint32_t esi,
                                                            const uint8_t sbn)
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->encode (output, end, esi, sbn);
        return 0;
    }
Luker's avatar
Luker committed
    // id: 8-bit sbn + 24 bit esi
    size_t encode (Fwd_It &output, const Fwd_It end, const uint32_t &id)
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->encode (output, end, id);
        return 0;
    }
Luker's avatar
Luker committed
    void free (const uint8_t sbn)
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->free (sbn);
    }
Luker's avatar
Luker committed
    uint8_t blocks() const
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->blocks();
        return 0;
    }
Luker's avatar
Luker committed
    uint32_t block_size (const uint8_t sbn) const
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->block_size (sbn);
        return 0;
    }
Luker's avatar
Luker committed
    uint16_t symbol_size() const
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->symbol_size();
        return 0;
    }
Luker's avatar
Luker committed
    uint16_t symbols (const uint8_t sbn) const
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->symbols (sbn);
        return 0;
    }
Luker's avatar
Luker committed
    uint32_t max_repair (const uint8_t sbn) const
    {
        if (rfc_encoder != nullptr)
            return rfc_encoder->max_repair (sbn);
        return 0;
    }
private:
    std::unique_ptr<Impl::Encoder<Rnd_It, Fwd_It>> rfc_encoder;
};

////////////////////
//// Decoder
////////////////////

template <typename In_It, typename Fwd_It>
class RAPTORQ_API Decoder
{
public:

Luker's avatar
Luker committed
    // rfc 6330, pg 6
    // easy explanation for OTI_* comes next.
    // we do NOT use bitfields as compilators are not actually forced to put
    // them in any particular order. meaning tey're useless.
    //
    //union OTI_Common_Data {
    //  uint64_t raw;
    //  struct {
    //      uint64_t size:40;
    //      uint8_t reserved:8;
    //      uint16_t symbol_size:16;
    //  };
    //};
Luker's avatar
Luker committed
    //union OTI_Scheme_Specific_Data {
    //  uint32_t raw;
    //  struct {
    //      uint8_t source_blocks;
    //      uint16_t sub_blocks;
    //      uint8_t alignment;
    //  };
    //};
    Decoder (const RQ_OTI_Common_Data common,
                            const RQ_OTI_Scheme_Specific_Data scheme)
Luker's avatar
Luker committed
    {
        rfc_decoder = std::unique_ptr<Impl::Decoder<In_It, Fwd_It>> (
Luker's avatar
Luker committed
                                    new Impl::Decoder<In_It, Fwd_It> (
                                                            common, scheme));
    }
Luker's avatar
Luker committed
    Decoder (const uint64_t size, const uint16_t symbol_size,
                                                    const uint16_t sub_blocks,
                                                    const uint8_t blocks,
                                                    const uint8_t alignment)
    {
        rfc_decoder = std::unique_ptr<Impl::Decoder<In_It, Fwd_It>> (
                                new Impl::Decoder<In_It, Fwd_It> (
Luker's avatar
Luker committed
                                                size, symbol_size, sub_blocks,
                                                blocks, alignment));
    }
Luker's avatar
Luker committed
    std::future<std::pair<Error, uint8_t>> compute (const Compute flags)
    {
        if (rfc_decoder != nullptr)
            return rfc_decoder->compute (flags);
        std::promise<std::pair<Error, uint8_t>> p;
Luker's avatar
Luker committed
        p.set_value ({Error::INITIALIZATION, 0});
        return p.get_future();
    }

    void end_of_input (const uint8_t block)
    {
        if (rfc_decoder != nullptr)
            return rfc_decoder->end_of_input (block);
    }

    void end_of_input()
    {
        if (rfc_decoder != nullptr)
            return rfc_decoder->end_of_input();
    }

Luker's avatar
Luker committed
    // result in BYTES
    uint64_t decode_bytes (Fwd_It &start, const Fwd_It end, const uint8_t skip)
    {
        if (rfc_decoder == nullptr)
            return 0;
        return rfc_decoder->decode_bytes (start, end, skip);
    }
Luker's avatar
Luker committed
    size_t decode_block_bytes (Fwd_It &start, const Fwd_It end,
                                                            const uint8_t skip,
                                                            const uint8_t sbn)
    {
        if (rfc_decoder == nullptr)
            return 0;
        return rfc_decoder->decode_block_bytes (start, end, skip, sbn);
    }
Luker's avatar
Luker committed
    // result in ITERATORS
    // last *might* be half written depending on data alignments
    std::pair<uint64_t, uint8_t> decode_aligned (Fwd_It &start,const Fwd_It end,
                                                            const uint8_t skip)
    {
        if (rfc_decoder == nullptr)
Luker's avatar
Luker committed
            return {0, 0};
        return rfc_decoder->decode_aligned (start, end, skip);
    }
Luker's avatar
Luker committed
    std::pair<size_t, uint8_t> decode_block_aligned (Fwd_It &start,
                                                            const Fwd_It end,
                                                            const uint8_t skip,
                                                            const uint8_t sbn)
    {
        if (rfc_decoder == nullptr)
Luker's avatar
Luker committed
            return {0, 0};
        return rfc_decoder->decode_block_aligned (start, end, skip, sbn);
    }
Luker's avatar
Luker committed
    // id: 8-bit sbn + 24 bit esi
    Error add_symbol (In_It &start, const In_It end, const uint32_t id)
    {
        if (rfc_decoder == nullptr)
            return Error::INITIALIZATION;
        return rfc_decoder->add_symbol (start, end, id);
    }
Luker's avatar
Luker committed
    Error add_symbol (In_It &start, const In_It end, const uint32_t esi,
                                                            const uint8_t sbn)
    {
        if (rfc_decoder == nullptr)
            return Error::INITIALIZATION;
        return rfc_decoder->add_symbol (start, end, esi, sbn);
    }
Luker's avatar
Luker committed
    void free (const uint8_t sbn)
    {
        if (rfc_decoder != nullptr)
            return rfc_decoder->free (sbn);
    }
Luker's avatar
Luker committed
    uint64_t bytes() const
    {
        if (rfc_decoder == nullptr)
            return 0;
        return rfc_decoder->bytes();
    }
Luker's avatar
Luker committed
    uint8_t blocks() const
    {
        if (rfc_decoder == nullptr)
            return 0;
        return rfc_decoder->blocks();
    }
Luker's avatar
Luker committed
    uint32_t block_size (const uint8_t sbn) const
    {
        if (rfc_decoder == nullptr)
            return 0;
        return rfc_decoder->block_size (sbn);
    }
Luker's avatar
Luker committed
    uint16_t symbol_size() const
    {
        if (rfc_decoder == nullptr)
            return 0;
        return rfc_decoder->symbol_size();
    }
Luker's avatar
Luker committed
    uint16_t symbols (const uint8_t sbn) const
    {
        if (rfc_decoder == nullptr)
            return 0;
        return rfc_decoder->symbols (sbn);
    }
private:
    std::unique_ptr<Impl::Decoder<In_It, Fwd_It>> rfc_decoder;
};

}   // namespace RFC6330__v1