bool read_pkt(buf_ptr &buf_out) { buf_ptr buf_in = super::buffer(); if (!is_done() && is_partial_complete()) { get_pkt(buf_out); return true; } else if (is_done()) { increment(); return false; } while (true) { super::rlnc_hdr_reserve(buf_in); if (!super::read_pkt(buf_in)) break; if (!validate_type(buf_in)) continue; put_pkt(buf_in); process_rank(); buf_in->reset(); if (is_complete()) { send_ack(super::rlnc_hdr_block(), base::m_coder->rank()); break; } } if (!is_partial_complete()) return false; get_pkt(buf_out); return true; }
inline void run_test_systematic_packets_decode() { uint32_t symbols = 5; uint32_t symbol_size = 1400; // Common setting typename Encoder::factory encoder_factory(symbols, symbol_size); auto encoder = encoder_factory.build(); typename Decoder::factory decoder_factory(symbols, symbol_size); auto decoder = decoder_factory.build(); std::vector<uint8_t> payload(encoder->payload_size()); std::vector<uint8_t> data_in = random_vector(encoder->block_size()); auto symbol_sequence = sak::split_storage( sak::storage(data_in), symbol_size); // Lets start by specifying the first three symbols encoder->set_symbol(0, symbol_sequence[0]); encoder->set_symbol(1, symbol_sequence[1]); encoder->set_symbol(2, symbol_sequence[2]); // Make sure the encoder is systematic if(kodo::has_systematic_encoder<Encoder>::value) kodo::set_systematic_on(encoder); encoder->encode( &payload[0] ); decoder->decode( &payload[0] ); EXPECT_TRUE(decoder->is_partial_complete()); EXPECT_TRUE(decoder->is_symbol_uncoded(0)); encoder->encode( &payload[0] ); // Simulate a packet loss encoder->encode( &payload[0] ); decoder->decode( &payload[0] ); EXPECT_TRUE(decoder->is_partial_complete()); EXPECT_TRUE(decoder->is_symbol_uncoded(0)); EXPECT_TRUE(decoder->is_symbol_uncoded(2)); // We now have to loop since we are producing coded packets // and we might generate linear dependent packets uint32_t loop = 0; while(decoder->symbols_uncoded() != 3) { encoder->encode( &payload[0] ); decoder->decode( &payload[0] ); ++loop; // std::cout << "Loop " << loop << std::endl; } EXPECT_TRUE(decoder->is_partial_complete()); EXPECT_TRUE(decoder->is_symbol_uncoded(0)); EXPECT_TRUE(decoder->is_symbol_uncoded(1)); EXPECT_TRUE(decoder->is_symbol_uncoded(2)); encoder->set_symbol(3, symbol_sequence[3]); encoder->encode( &payload[0] ); decoder->decode( &payload[0] ); EXPECT_TRUE(decoder->is_partial_complete()); EXPECT_TRUE(decoder->is_symbol_uncoded(3)); // Nothing should happen now since the encoder contains no // new symbols encoder->encode( &payload[0] ); decoder->decode( &payload[0] ); EXPECT_FALSE(decoder->is_partial_complete()); encoder->encode( &payload[0] ); decoder->decode( &payload[0] ); EXPECT_FALSE(decoder->is_partial_complete()); encoder->set_symbol(4, symbol_sequence[4]); encoder->encode( &payload[0] ); // Packet loss while(decoder->symbols_uncoded() != 5) { encoder->encode( &payload[0] ); decoder->decode( &payload[0] ); ++loop; // std::cout << "Loop " << loop << std::endl; } }
inline bool is_partial_complete(const boost::shared_ptr<T>& t) { return is_partial_complete(*t); }