Add a proper API to create memslices from the QUIC code.

Current API provides an (allocator, size) constructor.  However, this just creates a buffer with random data in it and no way to change it, since memslices are read-only.  Current code uses const_cast; this CL creates a proper API and updates all existing call sites to use it.

gfe-relnote: n/a (no functional change)
PiperOrigin-RevId: 287072774
Change-Id: Ie4dd2eae6db2ec91b087f5d41887ea3948ee411a
diff --git a/quic/core/frames/quic_frame.cc b/quic/core/frames/quic_frame.cc
index e640179..44d3cc8 100644
--- a/quic/core/frames/quic_frame.cc
+++ b/quic/core/frames/quic_frame.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"
 
+#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
 #include "net/third_party/quiche/src/quic/core/quic_constants.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
@@ -319,10 +320,11 @@
       copy.message_frame->data = frame.message_frame->data;
       copy.message_frame->message_length = frame.message_frame->message_length;
       for (const auto& slice : frame.message_frame->message_data) {
-        QuicMemSlice copy_slice(allocator, slice.length());
-        memcpy(const_cast<char*>(copy_slice.data()), slice.data(),
-               slice.length());
-        copy.message_frame->message_data.push_back(std::move(copy_slice));
+        QuicUniqueBufferPtr buffer =
+            MakeUniqueBuffer(allocator, slice.length());
+        memcpy(buffer.get(), slice.data(), slice.length());
+        copy.message_frame->message_data.push_back(
+            QuicMemSlice(std::move(buffer), slice.length()));
       }
       break;
     case NEW_TOKEN_FRAME:
diff --git a/quic/core/quic_buffer_allocator.h b/quic/core/quic_buffer_allocator.h
index 10df369..4b0abf4 100644
--- a/quic/core/quic_buffer_allocator.h
+++ b/quic/core/quic_buffer_allocator.h
@@ -7,6 +7,8 @@
 
 #include <stddef.h>
 
+#include <memory>
+
 #include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
 
 namespace quic {
@@ -32,6 +34,28 @@
   virtual void MarkAllocatorIdle() {}
 };
 
+// A deleter that can be used to manage ownership of buffers allocated via
+// QuicBufferAllocator through std::unique_ptr.
+class QUIC_EXPORT_PRIVATE QuicBufferDeleter {
+ public:
+  explicit QuicBufferDeleter(QuicBufferAllocator* allocator)
+      : allocator_(allocator) {}
+
+  QuicBufferAllocator* allocator() { return allocator_; }
+  void operator()(char* buffer) { allocator_->Delete(buffer); }
+
+ private:
+  QuicBufferAllocator* allocator_;
+};
+
+using QuicUniqueBufferPtr = std::unique_ptr<char[], QuicBufferDeleter>;
+
+inline QuicUniqueBufferPtr MakeUniqueBuffer(QuicBufferAllocator* allocator,
+                                            size_t size) {
+  return QuicUniqueBufferPtr(allocator->New(size),
+                             QuicBufferDeleter(allocator));
+}
+
 }  // namespace quic
 
 #endif  // QUICHE_QUIC_CORE_QUIC_BUFFER_ALLOCATOR_H_
diff --git a/quic/core/quic_stream_send_buffer.cc b/quic/core/quic_stream_send_buffer.cc
index 2008cf2..d91ceb8 100644
--- a/quic/core/quic_stream_send_buffer.cc
+++ b/quic/core/quic_stream_send_buffer.cc
@@ -67,10 +67,10 @@
       GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size);
   while (data_length > 0) {
     size_t slice_len = std::min(data_length, max_data_slice_size);
-    QuicMemSlice slice(allocator_, slice_len);
+    QuicUniqueBufferPtr buffer = MakeUniqueBuffer(allocator_, slice_len);
     QuicUtils::CopyToBuffer(iov, iov_count, iov_offset, slice_len,
-                            const_cast<char*>(slice.data()));
-    SaveMemSlice(std::move(slice));
+                            buffer.get());
+    SaveMemSlice(QuicMemSlice(std::move(buffer), slice_len));
     data_length -= slice_len;
     iov_offset += slice_len;
   }
diff --git a/quic/core/quic_stream_send_buffer_test.cc b/quic/core/quic_stream_send_buffer_test.cc
index 8f864c6..325dca0 100644
--- a/quic/core/quic_stream_send_buffer_test.cc
+++ b/quic/core/quic_stream_send_buffer_test.cc
@@ -39,10 +39,12 @@
     iov[0] = MakeIovec(quiche::QuicheStringPiece(data1));
     iov[1] = MakeIovec(quiche::QuicheStringPiece(data2));
 
-    QuicMemSlice slice1(&allocator_, 1024);
-    memset(const_cast<char*>(slice1.data()), 'c', 1024);
-    QuicMemSlice slice2(&allocator_, 768);
-    memset(const_cast<char*>(slice2.data()), 'd', 768);
+    QuicUniqueBufferPtr buffer1 = MakeUniqueBuffer(&allocator_, 1024);
+    memset(buffer1.get(), 'c', 1024);
+    QuicMemSlice slice1(std::move(buffer1), 1024);
+    QuicUniqueBufferPtr buffer2 = MakeUniqueBuffer(&allocator_, 768);
+    memset(buffer2.get(), 'd', 768);
+    QuicMemSlice slice2(std::move(buffer2), 768);
 
     if (!GetQuicReloadableFlag(quic_interval_deque)) {
       // Index starts from not pointing to any slice.
@@ -362,8 +364,9 @@
     // Last offset is end offset of last slice.
     EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
   }
-  QuicMemSlice slice(&allocator_, 60);
-  memset(const_cast<char*>(slice.data()), 'e', 60);
+  QuicUniqueBufferPtr buffer = MakeUniqueBuffer(&allocator_, 60);
+  memset(buffer.get(), 'e', 60);
+  QuicMemSlice slice(std::move(buffer), 60);
   send_buffer_.SaveMemSlice(std::move(slice));
   if (!GetQuicReloadableFlag(quic_interval_deque)) {
     // With new data, index points to the new data.