From b7319c61489acce6c8b09fe9e0af1a0c9ea68091 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Wed, 15 Feb 2023 13:23:26 +0000 Subject: [PATCH] lab1 ok(simple ver) --- libsponge/stream_reassembler.cc | 41 +++++++++++++++++++++++++++++---- libsponge/stream_reassembler.hh | 9 +++++++- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/libsponge/stream_reassembler.cc b/libsponge/stream_reassembler.cc index 988df9f..76c9a08 100644 --- a/libsponge/stream_reassembler.cc +++ b/libsponge/stream_reassembler.cc @@ -1,5 +1,6 @@ #include "stream_reassembler.hh" +#include // Dummy implementation of a stream reassembler. // For Lab 1, please replace with a real implementation that passes the @@ -8,19 +9,51 @@ // You will need to add private members to the class declaration in `stream_reassembler.hh` template -void DUMMY_CODE(Targs &&... /* unused */) {} +void DUMMY_CODE(Targs &&.../* unused */) {} using namespace std; -StreamReassembler::StreamReassembler(const size_t capacity) : _output(capacity), _capacity(capacity) {} +StreamReassembler::StreamReassembler(const size_t capacity) + : _output(capacity), _capacity(capacity), _aux_buffer(capacity, '\0'), _aux_buffer_valid(capacity, false) {} +// pre-allocate is working //! \details This function accepts a substring (aka a segment) of bytes, //! possibly out-of-order, from the logical stream, and assembles any newly //! contiguous substrings and writes them into the output stream in order. void StreamReassembler::push_substring(const string &data, const size_t index, const bool eof) { DUMMY_CODE(data, index, eof); + _unread = _unassem - _output.buffer_size(); + _aux_buffer.resize(_capacity - _output.buffer_size(), '\0'); + _aux_buffer_valid.resize(_aux_buffer.size(), false); + + if (eof) { + _eof = index + data.size(); + } + auto start = std::max(index, _unassem); + auto end = std::min(index + data.size(), _unread + _capacity); + for (auto i = start; i < end; ++i) { + _aux_buffer[i - _unassem] = data[i - index]; + if (!_aux_buffer_valid[i - _unassem]) { + _aux_buffer_valid[i - _unassem] = true; + _unassem_count++; + } + } + std::string wr_data; + while (!_aux_buffer_valid.empty() && _aux_buffer_valid.front()) { + wr_data.push_back(_aux_buffer.front()); + _aux_buffer.pop_front(); + _aux_buffer_valid.pop_front(); + ++_unassem; + --_unassem_count; + } + if (_unassem == _eof) { + _output.end_input(); + } + if (wr_data.size()) { + _output.write(wr_data); + } } -size_t StreamReassembler::unassembled_bytes() const { return {}; } +size_t StreamReassembler::unassembled_bytes() const { return _unassem_count; } -bool StreamReassembler::empty() const { return {}; } +bool StreamReassembler::empty() const { return (_unassem_count == 0); } diff --git a/libsponge/stream_reassembler.hh b/libsponge/stream_reassembler.hh index a14c1e2..a1a3dfd 100644 --- a/libsponge/stream_reassembler.hh +++ b/libsponge/stream_reassembler.hh @@ -4,6 +4,7 @@ #include "byte_stream.hh" #include +#include #include //! \brief A class that assembles a series of excerpts from a byte stream (possibly out of order, @@ -13,7 +14,13 @@ class StreamReassembler { // Your code here -- add private members as necessary. ByteStream _output; //!< The reassembled in-order byte stream - size_t _capacity; //!< The maximum number of bytes + size_t _capacity{}; //!< The maximum number of bytes + size_t _unread{}; //!< The index (in the stream) of the first unread byte + size_t _unassem{}; //!< The index (in the stream) of the first unassembled byte + size_t _unassem_count{}; + std::deque _aux_buffer; //!< auxiliary storage, initially allocated _capacity bytes + std::deque _aux_buffer_valid; //!< indicate whether the bit in _aux_buffer is filled with a valid byte + size_t _eof{static_cast(-1)}; public: //! \brief Construct a `StreamReassembler` that will store up to `capacity` bytes.