Add LengthPrefixedConnectionId support to QuicDataReader and Writer

This is currently only used in v99 NEW_CONNECTION_ID frames but will soon be used to parse the new connection ID invariants

gfe-relnote: n/a, protected by disabled v99 flag
PiperOrigin-RevId: 258684056
Change-Id: I666d150b9392e195a073272d2c5e79bd970d5862
diff --git a/quic/core/quic_data_writer_test.cc b/quic/core/quic_data_writer_test.cc
index 07f0313..727c813 100644
--- a/quic/core/quic_data_writer_test.cc
+++ b/quic/core/quic_data_writer_test.cc
@@ -5,6 +5,7 @@
 #include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
 
 #include <cstdint>
+#include <cstring>
 
 #include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
 #include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
@@ -26,6 +27,12 @@
 struct TestParams {
   explicit TestParams(Endianness endianness) : endianness(endianness) {}
 
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "{ " << (p.endianness == NETWORK_BYTE_ORDER ? "network" : "host")
+       << " byte order }";
+    return os;
+  }
+
   Endianness endianness;
 };
 
@@ -270,6 +277,48 @@
   EXPECT_EQ(connection_id, read_connection_id);
 }
 
+TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
+  QuicConnectionId connection_id =
+      TestConnectionId(UINT64_C(0x0011223344556677));
+  char length_prefixed_connection_id[] = {
+      0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+  };
+  EXPECT_EQ(QUIC_ARRAYSIZE(length_prefixed_connection_id),
+            kConnectionIdLengthSize + connection_id.length());
+  char buffer[kConnectionIdLengthSize + kQuicMaxConnectionIdLength] = {};
+  QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer);
+  EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
+  test::CompareCharArraysWithHexError(
+      "WriteLengthPrefixedConnectionId", buffer, writer.length(),
+      length_prefixed_connection_id,
+      QUIC_ARRAYSIZE(length_prefixed_connection_id));
+
+  // Verify that writing length then connection ID produces the same output.
+  memset(buffer, 0, QUIC_ARRAYSIZE(buffer));
+  QuicDataWriter writer2(QUIC_ARRAYSIZE(buffer), buffer);
+  EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
+  EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
+  test::CompareCharArraysWithHexError(
+      "Write length then ConnectionId", buffer, writer2.length(),
+      length_prefixed_connection_id,
+      QUIC_ARRAYSIZE(length_prefixed_connection_id));
+
+  QuicConnectionId read_connection_id;
+  QuicDataReader reader(buffer, QUIC_ARRAYSIZE(buffer));
+  EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
+  EXPECT_EQ(connection_id, read_connection_id);
+
+  // Verify that reading length then connection ID produces the same output.
+  uint8_t read_connection_id_length2 = 33;
+  QuicConnectionId read_connection_id2;
+  QuicDataReader reader2(buffer, QUIC_ARRAYSIZE(buffer));
+  ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
+  EXPECT_EQ(connection_id.length(), read_connection_id_length2);
+  EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
+                                       read_connection_id_length2));
+  EXPECT_EQ(connection_id, read_connection_id2);
+}
+
 TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
   QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
   char buffer[2];