// Insert a new substring to be reassembled into a ByteStream. voidinsert( uint64_t first_index, std::string data, bool is_last_substring, Writer& output );
// How many bytes are stored in the Reassembler itself? uint64_tbytes_pending()const;
// insert valid but un-ordered data into buffer voidinsert_into_buffer( uint64_t first_index, std::string&& data, bool is_last_substring );
// pop invalid bytes and insert valid bytes into writer voidpop_from_buffer( Writer& output ); public: /* * Insert a new substring to be reassembled into a ByteStream. * `first_index`: the index of the first byte of the substring * `data`: the substring itself * `is_last_substring`: this substring represents the end of the stream * `output`: a mutable reference to the Writer * * The Reassembler's job is to reassemble the indexed substrings (possibly out-of-order * and possibly overlapping) back into the original ByteStream. As soon as the Reassembler * learns the next byte in the stream, it should write it to the output. * * If the Reassembler learns about bytes that fit within the stream's available capacity * but can't yet be written (because earlier bytes remain unknown), it should store them * internally until the gaps are filled in. * * The Reassembler should discard any bytes that lie beyond the stream's available capacity * (i.e., bytes that couldn't be written even if earlier gaps get filled in). * * The Reassembler should close the stream after writing the last byte. */ voidinsert( uint64_t first_index, std::string data, bool is_last_substring, Writer& output );
// How many bytes are stored in the Reassembler itself? uint64_tbytes_pending()const; };
// data is not in [first_unassembled_index, first_unacceptable) if ( end_index <= first_unassembled_index_ || first_index >= first_unacceptable ) { return; }
// if part of data is out of capacity, then truncate it if ( end_index > first_unacceptable ) { data = data.substr( 0, first_unacceptable - first_index ); // if truncated, it won't be last_substring is_last_substring = false; }
// unordered bytes, save it in buffer and return if ( first_index > first_unassembled_index_ ) { insert_into_buffer( first_index, std::move( data ), is_last_substring ); return; }
// remove useless prefix of data (i.e. bytes which are already assembled) if ( first_index < first_unassembled_index_ ) { data = data.substr( first_unassembled_index_ - first_index ); }
// here we have first_index == first_unassembled_index_ first_unassembled_index_ += data.size(); output.push( std::move( data ) );