pw_stream: Allow staging data to MemoryWriter end

Changes the memory writer to use std::memmove to allow data to be staged
to the unused portion of a MemoryWriter's buffer before it is written.
This is useful for operations that require direct access to a buffer to
build data before it is flushed to a MemoryWriter.

No-Docs-Update-Reason: Optimization that shouldn't be advertised
Change-Id: I3728e50e30031d7f87db43981827ef799fbce217
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/40244
Reviewed-by: David Rogers <davidrogers@google.com>
Commit-Queue: Armando Montanez <amontanez@google.com>
diff --git a/pw_stream/CMakeLists.txt b/pw_stream/CMakeLists.txt
index 55a9f96..c414144 100644
--- a/pw_stream/CMakeLists.txt
+++ b/pw_stream/CMakeLists.txt
@@ -37,3 +37,13 @@
     pw_stream
     pw_sys_io
 )
+
+pw_add_test(pw_stream.memory_stream_test
+  SOURCES
+    memory_stream_test.cc
+  DEPS
+    pw_stream
+  GROUPS
+    modules
+    pw_stream
+)
diff --git a/pw_stream/memory_stream.cc b/pw_stream/memory_stream.cc
index 0a44810..2faa510 100644
--- a/pw_stream/memory_stream.cc
+++ b/pw_stream/memory_stream.cc
@@ -30,7 +30,7 @@
   }
 
   size_t bytes_to_write = data.size_bytes();
-  std::memcpy(dest_.data() + bytes_written_, data.data(), bytes_to_write);
+  std::memmove(dest_.data() + bytes_written_, data.data(), bytes_to_write);
   bytes_written_ += bytes_to_write;
 
   return OkStatus();
diff --git a/pw_stream/memory_stream_test.cc b/pw_stream/memory_stream_test.cc
index b4a1395..4b47b2c 100644
--- a/pw_stream/memory_stream_test.cc
+++ b/pw_stream/memory_stream_test.cc
@@ -131,6 +131,21 @@
   EXPECT_EQ(memory_writer.data()[1], std::byte{0x7E});
 }
 
+TEST(MemoryWriter, OverlappingBuffer) {
+  constexpr std::string_view kTestString("This is staged into the same buffer");
+  // Write at a five-byte offset from the start of the destination buffer.
+  constexpr std::byte* kOverlappingStart = memory_buffer.data() + 5;
+  std::memcpy(kOverlappingStart, kTestString.data(), kTestString.size());
+  MemoryWriter memory_writer(memory_buffer);
+  EXPECT_TRUE(memory_writer.Write(kOverlappingStart, kTestString.size()).ok());
+  EXPECT_TRUE(memory_writer.Write(std::byte(0)).ok());
+  EXPECT_EQ(memory_writer.bytes_written(), kTestString.size() + 1);
+
+  EXPECT_STREQ(
+      reinterpret_cast<const char*>(memory_writer.WrittenData().data()),
+      kTestString.data());
+}
+
 #define TESTING_CHECK_FAILURES_IS_SUPPORTED 0
 #if TESTING_CHECK_FAILURES_IS_SUPPORTED