In this example we show how to encode/decode files with Kodo. In Kodo
this is example is nearly identical to the example
Encoding and decoding large objects. For this reason we will mainly
highlight the differences.

// Copyright Steinwurf ApS 2011.// Distributed under the "STEINWURF EVALUATION LICENSE 1.0".// See accompanying file LICENSE.rst or// http://www.steinwurf.com/licensing//! [0]#include<kodo_core/object/file_encoder.hpp>#include<kodo_core/object/file_decoder.hpp>#include<kodo_rlnc/full_vector_codes.hpp>//! [1]#include<cassert>#include<cstdint>#include<fstream>#include<iostream>#include<vector>/// @example encode_decode_file.cpp////// Often we want to encode / decode data that exceed a single/// encoding/decoding block. In this case we need to "chop" up/// the data into manageable chunks and then encode and decode/// each chuck separately. This example shows how to use the/// file encoder in Kodo. The file encoder operates directly on/// a file in the file-system. For decoding we use an object decoder/// which decodes data to memory, but which is compatible with/// file encoder.intmain(){//! [2]// Set the number of symbols (i.e. the generation size in RLNC// terminology) and the size of a symbol in bytesuint32_tsymbols=42;uint32_tsymbol_size=64;fifi::api::fieldfield=fifi::api::field::binary;uint32_tfile_size=23456;std::stringencode_filename="encode-file.bin";std::stringdecode_filename="decode-file.bin";usingfile_encoder=kodo_core::object::file_encoder<kodo_rlnc::full_vector_encoder>;usingfile_decoder=kodo_core::object::file_decoder<kodo_rlnc::full_vector_decoder>;//! [3]//! [4]// Create a test file for encoding.std::ofstreamencode_file;encode_file.open(encode_filename,std::ios::binary);std::vector<char>data_in(file_size,'x');encode_file.write(data_in.data(),data_in.size());encode_file.close();//! [5]//! [6]// Actual encoding/decoding of the filefile_encoder::factoryencoder_factory(field,symbols,symbol_size);file_decoder::factorydecoder_factory(field,symbols,symbol_size);encoder_factory.set_filename(encode_filename);decoder_factory.set_filename(decode_filename);decoder_factory.set_file_size(file_size);autoencoder=encoder_factory.build();autodecoder=decoder_factory.build();std::cout<<"encoder blocks = "<<encoder->blocks()<<std::endl;std::cout<<"decoder blocks = "<<decoder->blocks()<<std::endl;//! [7]//! [8]for(uint32_ti=0;i<encoder->blocks();++i){file_encoder::stack_pointere=encoder->build(i);file_decoder::stack_pointerd=decoder->build(i);std::vector<uint8_t>payload(e->payload_size());while(!d->is_complete()){// Comment in the following function to turn systematic off// e->set_systematic_off();e->write_payload(payload.data());// Here we would send and receive the payload over a// network. Lets throw away some packet to simulate.if(rand()%2){continue;}d->read_payload(payload.data());}}//! [9]}

For the file encoder/decoder case three options are new. The first is
the file name of the file we want to encode, the seconds is the file
name of the file we want to decode data into and finally the size of
file.

Note

In a real application we would most likely not use different
file names for the encoder and decoder.

Note

The file size is only needed by the file decoder. The file
encoder knows the file size after opening the file.

// Set the number of symbols (i.e. the generation size in RLNC// terminology) and the size of a symbol in bytesuint32_tsymbols=42;uint32_tsymbol_size=64;fifi::api::fieldfield=fifi::api::field::binary;uint32_tfile_size=23456;std::stringencode_filename="encode-file.bin";std::stringdecode_filename="decode-file.bin";usingfile_encoder=kodo_core::object::file_encoder<kodo_rlnc::full_vector_encoder>;usingfile_decoder=kodo_core::object::file_decoder<kodo_rlnc::full_vector_decoder>;