Fix content reader for partial input

When there is partial message in reader, popping out the
characters lead to parse errors on the subsequent attempt
to parse. To avoid this, the last matched characters'
index is stored during parsing and reset on error.
diff --git a/src/content_stream.cpp b/src/content_stream.cpp
index e7c6628..05d7f47 100644
--- a/src/content_stream.cpp
+++ b/src/content_stream.cpp
@@ -44,13 +44,17 @@
 }
 
 std::string ContentReader::read() {
+  matched_idx = 0;
+
   // Find Content-Length header prefix
   if (!scan("Content-Length:")) {
     return "";
   }
+
   // Skip whitespace and tabs
   while (matchAny(" \t")) {
   }
+
   // Parse length
   size_t len = 0;
   while (true) {
@@ -68,10 +72,16 @@
   if (!match("\r\n\r\n")) {
     return "";
   }
+
   // Read message
-  if (!buffer(len)) {
+  if (!buffer(len + matched_idx)) {
     return "";
   }
+
+  for (size_t i = 0; i < matched_idx; i++) {
+    buf.pop_front();
+  }
+
   std::string out;
   out.reserve(len);
   for (size_t i = 0; i < len; i++) {
@@ -97,18 +107,17 @@
 }
 
 bool ContentReader::match(const uint8_t* seq, size_t len) {
-  if (!buffer(len)) {
+  if (!buffer(len + matched_idx)) {
     return false;
   }
-  auto it = buf.begin();
+  auto it = matched_idx;
   for (size_t i = 0; i < len; i++, it++) {
-    if (*it != seq[i]) {
+    if (buf[it] != seq[i]) {
       return false;
     }
   }
-  for (size_t i = 0; i < len; i++) {
-    buf.pop_front();
-  }
+
+  matched_idx += len;
   return true;
 }
 
@@ -118,12 +127,12 @@
 }
 
 char ContentReader::matchAny(const char* chars) {
-  if (!buffer(1)) {
+  if (!buffer(1 + matched_idx)) {
     return false;
   }
-  int c = buf.front();
+  int c = buf[matched_idx];
   if (auto p = strchr(chars, c)) {
-    buf.pop_front();
+    matched_idx++;
     return *p;
   }
   return 0;
@@ -177,4 +186,4 @@
          writer->write(msg.data(), msg.size());
 }
 
-}  // namespace dap
\ No newline at end of file
+}  // namespace dap
diff --git a/src/content_stream.h b/src/content_stream.h
index f01fef7..1fd0849 100644
--- a/src/content_stream.h
+++ b/src/content_stream.h
@@ -47,6 +47,7 @@
 
   std::shared_ptr<Reader> reader;
   std::deque<uint8_t> buf;
+  uint32_t matched_idx = 0;
 };
 
 class ContentWriter {
diff --git a/src/content_stream_test.cpp b/src/content_stream_test.cpp
index 8742333..80939a8 100644
--- a/src/content_stream_test.cpp
+++ b/src/content_stream_test.cpp
@@ -81,3 +81,19 @@
   ASSERT_EQ(cs.read(), "Content payload number three");
   ASSERT_EQ(cs.read(), "");
 }
+
+TEST(ContentStreamTest, PartialReadAndParse) {
+  auto sb = std::make_shared<dap::StringBuffer>();
+  dap::ContentReader cs(sb);
+  sb->write("Content");
+  ASSERT_EQ(cs.read(), "");
+  sb->write("-Length: ");
+  ASSERT_EQ(cs.read(), "");
+  sb->write("26");
+  ASSERT_EQ(cs.read(), "");
+  sb->write("\r\n\r\n");
+  ASSERT_EQ(cs.read(), "");
+  sb->write("Content payload number one");
+  ASSERT_EQ(cs.read(), "Content payload number one");
+  ASSERT_EQ(cs.read(), "");
+}