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.
diff --git a/quic/masque/masque_compression_engine.cc b/quic/masque/masque_compression_engine.cc
index 804a8cf..dbc4580 100644
--- a/quic/masque/masque_compression_engine.cc
+++ b/quic/masque/masque_compression_engine.cc
@@ -6,6 +6,7 @@
 
 #include <cstdint>
 
+#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
 #include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
 #include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
 #include "net/third_party/quiche/src/quic/core/quic_framer.h"
@@ -102,33 +103,32 @@
     uint8_t first_byte,
     bool long_header,
     QuicDataReader* reader,
-    QuicMemSlice* slice) {
-  QuicDataWriter writer(slice->length(), const_cast<char*>(slice->data()));
+    QuicDataWriter* writer) {
   if (validated) {
     QUIC_DVLOG(1) << "Compressing using validated flow_id " << flow_id;
-    if (!writer.WriteVarInt62(flow_id)) {
+    if (!writer->WriteVarInt62(flow_id)) {
       QUIC_BUG << "Failed to write flow_id";
       return false;
     }
   } else {
     QUIC_DVLOG(1) << "Compressing using unvalidated flow_id " << flow_id;
-    if (!writer.WriteVarInt62(kFlowId0)) {
+    if (!writer->WriteVarInt62(kFlowId0)) {
       QUIC_BUG << "Failed to write kFlowId0";
       return false;
     }
-    if (!writer.WriteVarInt62(flow_id)) {
+    if (!writer->WriteVarInt62(flow_id)) {
       QUIC_BUG << "Failed to write flow_id";
       return false;
     }
-    if (!writer.WriteLengthPrefixedConnectionId(client_connection_id)) {
+    if (!writer->WriteLengthPrefixedConnectionId(client_connection_id)) {
       QUIC_BUG << "Failed to write client_connection_id";
       return false;
     }
-    if (!writer.WriteLengthPrefixedConnectionId(server_connection_id)) {
+    if (!writer->WriteLengthPrefixedConnectionId(server_connection_id)) {
       QUIC_BUG << "Failed to write server_connection_id";
       return false;
     }
-    if (!writer.WriteUInt16(server_address.port())) {
+    if (!writer->WriteUInt16(server_address.port())) {
       QUIC_BUG << "Failed to write port";
       return false;
     }
@@ -153,16 +153,16 @@
       QUIC_BUG << "Unexpected server_address " << server_address;
       return false;
     }
-    if (!writer.WriteUInt8(address_id)) {
+    if (!writer->WriteUInt8(address_id)) {
       QUIC_BUG << "Failed to write address_id";
       return false;
     }
-    if (!writer.WriteStringPiece(peer_ip_bytes)) {
+    if (!writer->WriteStringPiece(peer_ip_bytes)) {
       QUIC_BUG << "Failed to write IP address";
       return false;
     }
   }
-  if (!writer.WriteUInt8(first_byte)) {
+  if (!writer->WriteUInt8(first_byte)) {
     QUIC_BUG << "Failed to write first_byte";
     return false;
   }
@@ -172,7 +172,7 @@
       QUIC_DLOG(ERROR) << "Failed to read version";
       return false;
     }
-    if (!writer.WriteUInt32(version_label)) {
+    if (!writer->WriteUInt32(version_label)) {
       QUIC_BUG << "Failed to write version";
       return false;
     }
@@ -214,7 +214,7 @@
     }
   }
   quiche::QuicheStringPiece packet_payload = reader->ReadRemainingPayload();
-  if (!writer.WriteStringPiece(packet_payload)) {
+  if (!writer->WriteStringPiece(packet_payload)) {
     QUIC_BUG << "Failed to write packet_payload";
     return false;
   }
@@ -276,17 +276,19 @@
                     sizeof(server_address.port()) + sizeof(uint8_t) +
                     server_address.host().ToPackedString().length();
   }
-  QuicMemSlice slice(
+  QuicUniqueBufferPtr buffer = MakeUniqueBuffer(
       masque_session_->connection()->helper()->GetStreamSendBufferAllocator(),
       slice_length);
+  QuicDataWriter writer(slice_length, buffer.get());
 
-  if (!WriteCompressedPacketToSlice(client_connection_id, server_connection_id,
-                                    server_address, destination_connection_id,
-                                    source_connection_id, flow_id, validated,
-                                    first_byte, long_header, &reader, &slice)) {
+  if (!WriteCompressedPacketToSlice(
+          client_connection_id, server_connection_id, server_address,
+          destination_connection_id, source_connection_id, flow_id, validated,
+          first_byte, long_header, &reader, &writer)) {
     return;
   }
 
+  QuicMemSlice slice(std::move(buffer), slice_length);
   MessageResult message_result =
       masque_session_->SendMessage(QuicMemSliceSpan(&slice));
 
diff --git a/quic/masque/masque_compression_engine.h b/quic/masque/masque_compression_engine.h
index 32ffc9d..95328df 100644
--- a/quic/masque/masque_compression_engine.h
+++ b/quic/masque/masque_compression_engine.h
@@ -104,7 +104,7 @@
                                     uint8_t first_byte,
                                     bool long_header,
                                     QuicDataReader* reader,
-                                    QuicMemSlice* slice);
+                                    QuicDataWriter* writer);
 
   // Parses compression context from flow ID 0 during decompression.
   bool ParseCompressionContext(QuicDataReader* reader,
diff --git a/quic/platform/api/quic_mem_slice.h b/quic/platform/api/quic_mem_slice.h
index a40d638..2d44085 100644
--- a/quic/platform/api/quic_mem_slice.h
+++ b/quic/platform/api/quic_mem_slice.h
@@ -26,14 +26,12 @@
   // Constructs a empty QuicMemSlice with no underlying data and 0 reference
   // count.
   QuicMemSlice() = default;
-  // Let |allocator| allocate a data buffer of |length|, then construct
-  // QuicMemSlice with reference count 1 from the allocated data buffer.
-  // Once all of the references to the allocated data buffer are released,
-  // |allocator| is responsible to free the memory. |allocator| must
-  // not be null, and |length| must not be 0. To construct an empty
-  // QuicMemSlice, use the zero-argument constructor instead.
-  QuicMemSlice(QuicBufferAllocator* allocator, size_t length)
-      : impl_(allocator, length) {}
+
+  // Constructs a QuicMemSlice that takes ownership of |buffer|.  |length| must
+  // not be zero.  To construct an empty QuicMemSlice, use the zero-argument
+  // constructor instead.
+  QuicMemSlice(QuicUniqueBufferPtr buffer, size_t length)
+      : impl_(std::move(buffer), length) {}
 
   // Constructs QuicMemSlice from |impl|. It takes the reference away from
   // |impl|.
diff --git a/quic/platform/api/quic_mem_slice_test.cc b/quic/platform/api/quic_mem_slice_test.cc
index 185f536..d441afa 100644
--- a/quic/platform/api/quic_mem_slice_test.cc
+++ b/quic/platform/api/quic_mem_slice_test.cc
@@ -15,7 +15,7 @@
  public:
   QuicMemSliceTest() {
     size_t length = 1024;
-    slice_ = QuicMemSlice(&allocator_, length);
+    slice_ = QuicMemSlice(MakeUniqueBuffer(&allocator_, length), length);
     orig_data_ = slice_.data();
     orig_length_ = slice_.length();
   }
diff --git a/quic/qbone/qbone_session_base.cc b/quic/qbone/qbone_session_base.cc
index e3fbb6e..c59f412 100644
--- a/quic/qbone/qbone_session_base.cc
+++ b/quic/qbone/qbone_session_base.cc
@@ -9,6 +9,7 @@
 
 #include <utility>
 
+#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
 #include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
 #include "net/third_party/quiche/src/quic/core/quic_types.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h"
@@ -139,9 +140,10 @@
   }
 
   if (send_packets_as_messages_) {
-    QuicMemSlice slice(connection()->helper()->GetStreamSendBufferAllocator(),
-                       packet.size());
-    memcpy(const_cast<char*>(slice.data()), packet.data(), packet.size());
+    QuicUniqueBufferPtr buffer = MakeUniqueBuffer(
+        connection()->helper()->GetStreamSendBufferAllocator(), packet.size());
+    memcpy(buffer.get(), packet.data(), packet.size());
+    QuicMemSlice slice(std::move(buffer), packet.size());
     switch (SendMessage(QuicMemSliceSpan(&slice), /*flush=*/true).status) {
       case MESSAGE_STATUS_SUCCESS:
         break;
diff --git a/quic/quartc/quartc_multiplexer.cc b/quic/quartc/quartc_multiplexer.cc
index 3abc3cd..376fac0 100644
--- a/quic/quartc/quartc_multiplexer.cc
+++ b/quic/quartc/quartc_multiplexer.cc
@@ -7,6 +7,7 @@
 #include <cstdint>
 #include <utility>
 
+#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
 #include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h"
@@ -95,10 +96,10 @@
 }
 
 QuicMemSlice QuartcSendChannel::EncodeChannelId() {
-  QuicMemSlice id_slice(allocator_, encoded_length_);
-  QuicDataWriter writer(encoded_length_, const_cast<char*>(id_slice.data()));
+  QuicUniqueBufferPtr buffer = MakeUniqueBuffer(allocator_, encoded_length_);
+  QuicDataWriter writer(encoded_length_, buffer.get());
   writer.WriteVarInt62(id_);
-  return id_slice;
+  return QuicMemSlice(std::move(buffer), encoded_length_);
 }
 
 QuartcMultiplexer::QuartcMultiplexer(