diff --git a/src/content_stream_test.cpp b/src/content_stream_test.cpp index 8742333..0cd2edb 100644 --- a/src/content_stream_test.cpp +++ b/src/content_stream_test.cpp @@ -81,3 +81,16 @@ TEST(ContentStreamTest, ShortRead) { ASSERT_EQ(cs.read(), "Content payload number three"); ASSERT_EQ(cs.read(), ""); } + +TEST(ContentStreamTest, PartialReadAndParse) { + auto sb = std::make_shared(); + sb->write("Content"); + sb->write("-Length: "); + sb->write("26"); + sb->write("\r\n\r\n"); + sb->write("Content payload number one"); + + dap::ContentReader cs(sb); + ASSERT_EQ(cs.read(), "Content payload number one"); + ASSERT_EQ(cs.read(), ""); +} diff --git a/src/string_buffer.h b/src/string_buffer.h index cdd6c41..1c38197 100644 --- a/src/string_buffer.h +++ b/src/string_buffer.h @@ -19,7 +19,8 @@ #include // std::min #include // memcpy -#include // std::unique_ptr +#include +#include // std::unique_ptr #include namespace dap { @@ -39,6 +40,7 @@ class StringBuffer : public virtual Reader, public virtual Writer { private: std::string str; + std::deque chunk_lengths; bool closed = false; }; @@ -62,12 +64,19 @@ std::string StringBuffer::string() const { } size_t StringBuffer::read(void* buffer, size_t bytes) { - if (closed || bytes == 0 || str.size() == 0) { + if (closed || bytes == 0 || str.size() == 0 || chunk_lengths.size() == 0) { return 0; } - auto len = std::min(bytes, str.size()); + size_t& chunk_length = chunk_lengths.front(); + + auto len = std::min(bytes, chunk_length); memcpy(buffer, str.data(), len); str = std::string(str.begin() + len, str.end()); + if (bytes < chunk_length) { + chunk_length -= bytes; + } else { + chunk_lengths.pop_front(); + } return len; } @@ -77,6 +86,7 @@ bool StringBuffer::write(const void* buffer, size_t bytes) { } auto chars = reinterpret_cast(buffer); str.append(chars, chars + bytes); + chunk_lengths.push_back(bytes); return true; }