Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_data_writer_test.cc b/quic/core/quic_data_writer_test.cc
new file mode 100644
index 0000000..aed14c1
--- /dev/null
+++ b/quic/core/quic_data_writer_test.cc
@@ -0,0 +1,1102 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
+
+#include <cstdint>
+
+#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
+#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+char* AsChars(unsigned char* data) {
+  return reinterpret_cast<char*>(data);
+}
+
+struct TestParams {
+  explicit TestParams(Endianness endianness) : endianness(endianness) {}
+
+  Endianness endianness;
+};
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (Endianness endianness : {NETWORK_BYTE_ORDER, HOST_BYTE_ORDER}) {
+    params.push_back(TestParams(endianness));
+  }
+  return params;
+}
+
+class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
+
+INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests, QuicDataWriterTest,
+                         ::testing::ValuesIn(GetTestParams()));
+
+TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
+  // Check the arithmetic on the constants - otherwise the values below make
+  // no sense.
+  EXPECT_EQ(30, kUFloat16MaxExponent);
+  EXPECT_EQ(11, kUFloat16MantissaBits);
+  EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
+  EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
+}
+
+TEST_P(QuicDataWriterTest, WriteUFloat16) {
+  struct TestCase {
+    uint64_t decoded;
+    uint16_t encoded;
+  };
+  TestCase test_cases[] = {
+      // Small numbers represent themselves.
+      {0, 0},
+      {1, 1},
+      {2, 2},
+      {3, 3},
+      {4, 4},
+      {5, 5},
+      {6, 6},
+      {7, 7},
+      {15, 15},
+      {31, 31},
+      {42, 42},
+      {123, 123},
+      {1234, 1234},
+      // Check transition through 2^11.
+      {2046, 2046},
+      {2047, 2047},
+      {2048, 2048},
+      {2049, 2049},
+      // Running out of mantissa at 2^12.
+      {4094, 4094},
+      {4095, 4095},
+      {4096, 4096},
+      {4097, 4096},
+      {4098, 4097},
+      {4099, 4097},
+      {4100, 4098},
+      {4101, 4098},
+      // Check transition through 2^13.
+      {8190, 6143},
+      {8191, 6143},
+      {8192, 6144},
+      {8193, 6144},
+      {8194, 6144},
+      {8195, 6144},
+      {8196, 6145},
+      {8197, 6145},
+      // Half-way through the exponents.
+      {0x7FF8000, 0x87FF},
+      {0x7FFFFFF, 0x87FF},
+      {0x8000000, 0x8800},
+      {0xFFF0000, 0x8FFF},
+      {0xFFFFFFF, 0x8FFF},
+      {0x10000000, 0x9000},
+      // Transition into the largest exponent.
+      {0x1FFFFFFFFFE, 0xF7FF},
+      {0x1FFFFFFFFFF, 0xF7FF},
+      {0x20000000000, 0xF800},
+      {0x20000000001, 0xF800},
+      {0x2003FFFFFFE, 0xF800},
+      {0x2003FFFFFFF, 0xF800},
+      {0x20040000000, 0xF801},
+      {0x20040000001, 0xF801},
+      // Transition into the max value and clamping.
+      {0x3FF80000000, 0xFFFE},
+      {0x3FFBFFFFFFF, 0xFFFE},
+      {0x3FFC0000000, 0xFFFF},
+      {0x3FFC0000001, 0xFFFF},
+      {0x3FFFFFFFFFF, 0xFFFF},
+      {0x40000000000, 0xFFFF},
+      {0xFFFFFFFFFFFFFFFF, 0xFFFF},
+  };
+  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+
+  for (int i = 0; i < num_test_cases; ++i) {
+    char buffer[2];
+    QuicDataWriter writer(2, buffer, GetParam().endianness);
+    EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
+    uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
+    if (GetParam().endianness == NETWORK_BYTE_ORDER) {
+      result = QuicEndian::HostToNet16(result);
+    }
+    EXPECT_EQ(test_cases[i].encoded, result);
+  }
+}
+
+TEST_P(QuicDataWriterTest, ReadUFloat16) {
+  struct TestCase {
+    uint64_t decoded;
+    uint16_t encoded;
+  };
+  TestCase test_cases[] = {
+      // There are fewer decoding test cases because encoding truncates, and
+      // decoding returns the smallest expansion.
+      // Small numbers represent themselves.
+      {0, 0},
+      {1, 1},
+      {2, 2},
+      {3, 3},
+      {4, 4},
+      {5, 5},
+      {6, 6},
+      {7, 7},
+      {15, 15},
+      {31, 31},
+      {42, 42},
+      {123, 123},
+      {1234, 1234},
+      // Check transition through 2^11.
+      {2046, 2046},
+      {2047, 2047},
+      {2048, 2048},
+      {2049, 2049},
+      // Running out of mantissa at 2^12.
+      {4094, 4094},
+      {4095, 4095},
+      {4096, 4096},
+      {4098, 4097},
+      {4100, 4098},
+      // Check transition through 2^13.
+      {8190, 6143},
+      {8192, 6144},
+      {8196, 6145},
+      // Half-way through the exponents.
+      {0x7FF8000, 0x87FF},
+      {0x8000000, 0x8800},
+      {0xFFF0000, 0x8FFF},
+      {0x10000000, 0x9000},
+      // Transition into the largest exponent.
+      {0x1FFE0000000, 0xF7FF},
+      {0x20000000000, 0xF800},
+      {0x20040000000, 0xF801},
+      // Transition into the max value.
+      {0x3FF80000000, 0xFFFE},
+      {0x3FFC0000000, 0xFFFF},
+  };
+  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+
+  for (int i = 0; i < num_test_cases; ++i) {
+    uint16_t encoded_ufloat = test_cases[i].encoded;
+    if (GetParam().endianness == NETWORK_BYTE_ORDER) {
+      encoded_ufloat = QuicEndian::HostToNet16(encoded_ufloat);
+    }
+    QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
+                          GetParam().endianness);
+    uint64_t value;
+    EXPECT_TRUE(reader.ReadUFloat16(&value));
+    EXPECT_EQ(test_cases[i].decoded, value);
+  }
+}
+
+TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
+  // Just test all 16-bit encoded values. 0 and max already tested above.
+  uint64_t previous_value = 0;
+  for (uint16_t i = 1; i < 0xFFFF; ++i) {
+    // Read the two bytes.
+    uint16_t read_number = i;
+    if (GetParam().endianness == NETWORK_BYTE_ORDER) {
+      read_number = QuicEndian::HostToNet16(read_number);
+    }
+    QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
+                          GetParam().endianness);
+    uint64_t value;
+    // All values must be decodable.
+    EXPECT_TRUE(reader.ReadUFloat16(&value));
+    // Check that small numbers represent themselves
+    if (i < 4097) {
+      EXPECT_EQ(i, value);
+    }
+    // Check there's monotonic growth.
+    EXPECT_LT(previous_value, value);
+    // Check that precision is within 0.5% away from the denormals.
+    if (i > 2000) {
+      EXPECT_GT(previous_value * 1005, value * 1000);
+    }
+    // Check we're always within the promised range.
+    EXPECT_LT(value, UINT64_C(0x3FFC0000000));
+    previous_value = value;
+    char buffer[6];
+    QuicDataWriter writer(6, buffer, GetParam().endianness);
+    EXPECT_TRUE(writer.WriteUFloat16(value - 1));
+    EXPECT_TRUE(writer.WriteUFloat16(value));
+    EXPECT_TRUE(writer.WriteUFloat16(value + 1));
+    // Check minimal decoding (previous decoding has previous encoding).
+    uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
+    uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
+    uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
+    if (GetParam().endianness == NETWORK_BYTE_ORDER) {
+      encoded1 = QuicEndian::NetToHost16(encoded1);
+      encoded2 = QuicEndian::NetToHost16(encoded2);
+      encoded3 = QuicEndian::NetToHost16(encoded3);
+    }
+    EXPECT_EQ(i - 1, encoded1);
+    // Check roundtrip.
+    EXPECT_EQ(i, encoded2);
+    // Check next decoding.
+    EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
+  }
+}
+
+TEST_P(QuicDataWriterTest, WriteConnectionId) {
+  QuicConnectionId connection_id =
+      TestConnectionId(UINT64_C(0x0011223344556677));
+  char big_endian[] = {
+      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+  };
+  EXPECT_EQ(connection_id.length(), QUIC_ARRAYSIZE(big_endian));
+  ASSERT_LE(connection_id.length(), kQuicMaxConnectionIdLength);
+  char buffer[kQuicMaxConnectionIdLength];
+  QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteConnectionId(connection_id));
+  test::CompareCharArraysWithHexError("connection_id", buffer,
+                                      connection_id.length(), big_endian,
+                                      connection_id.length());
+
+  QuicConnectionId read_connection_id;
+  QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
+  EXPECT_TRUE(
+      reader.ReadConnectionId(&read_connection_id, QUIC_ARRAYSIZE(big_endian)));
+  EXPECT_EQ(connection_id, read_connection_id);
+}
+
+TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
+  QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
+  char buffer[2];
+  QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_TRUE(writer.WriteUInt8(1));
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_TRUE(writer.WriteUInt8(2));
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_FALSE(writer.WriteUInt8(3));
+
+  EXPECT_EQ(buffer[0], 1);
+  EXPECT_EQ(buffer[1], 2);
+
+  QuicConnectionId read_connection_id = TestConnectionId();
+  uint8_t read_byte;
+  QuicDataReader reader(buffer, QUIC_ARRAYSIZE(buffer), GetParam().endianness);
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
+  EXPECT_EQ(read_byte, 1);
+  // Reset read_connection_id to something else to verify that
+  // ReadConnectionId properly sets it back to empty.
+  read_connection_id = TestConnectionId();
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
+  EXPECT_EQ(read_byte, 2);
+  read_connection_id = TestConnectionId();
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_FALSE(reader.ReadUInt8(&read_byte));
+}
+
+TEST_P(QuicDataWriterTest, WriteTag) {
+  char CHLO[] = {
+      'C',
+      'H',
+      'L',
+      'O',
+  };
+  const int kBufferLength = sizeof(QuicTag);
+  char buffer[kBufferLength];
+  QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
+  writer.WriteTag(kCHLO);
+  test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength, CHLO,
+                                      kBufferLength);
+
+  QuicTag read_chlo;
+  QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
+  reader.ReadTag(&read_chlo);
+  EXPECT_EQ(kCHLO, read_chlo);
+}
+
+TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
+  char little_endian16[] = {0x22, 0x11};
+  char big_endian16[] = {0x11, 0x22};
+  char buffer16[2];
+  {
+    uint16_t in_memory16 = 0x1122;
+    QuicDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteUInt16(in_memory16);
+    test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian16
+                                                    : little_endian16,
+        2);
+
+    uint16_t read_number16;
+    QuicDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadUInt16(&read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+
+  {
+    uint64_t in_memory16 = 0x0000000000001122;
+    QuicDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteBytesToUInt64(2, in_memory16);
+    test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian16
+                                                    : little_endian16,
+        2);
+
+    uint64_t read_number16;
+    QuicDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadBytesToUInt64(2, &read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+}
+
+TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
+  char little_endian24[] = {0x33, 0x22, 0x11};
+  char big_endian24[] = {0x11, 0x22, 0x33};
+  char buffer24[3];
+  uint64_t in_memory24 = 0x0000000000112233;
+  QuicDataWriter writer(3, buffer24, GetParam().endianness);
+  writer.WriteBytesToUInt64(3, in_memory24);
+  test::CompareCharArraysWithHexError(
+      "uint24", buffer24, 3,
+      GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian24
+                                                  : little_endian24,
+      3);
+
+  uint64_t read_number24;
+  QuicDataReader reader(buffer24, 3, GetParam().endianness);
+  reader.ReadBytesToUInt64(3, &read_number24);
+  EXPECT_EQ(in_memory24, read_number24);
+}
+
+TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
+  char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
+  char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
+  char buffer32[4];
+  {
+    uint32_t in_memory32 = 0x11223344;
+    QuicDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteUInt32(in_memory32);
+    test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian32
+                                                    : little_endian32,
+        4);
+
+    uint32_t read_number32;
+    QuicDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadUInt32(&read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+
+  {
+    uint64_t in_memory32 = 0x11223344;
+    QuicDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteBytesToUInt64(4, in_memory32);
+    test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian32
+                                                    : little_endian32,
+        4);
+
+    uint64_t read_number32;
+    QuicDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadBytesToUInt64(4, &read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+}
+
+TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
+  uint64_t in_memory40 = 0x0000001122334455;
+  char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
+  char buffer40[5];
+  QuicDataWriter writer(5, buffer40, GetParam().endianness);
+  writer.WriteBytesToUInt64(5, in_memory40);
+  test::CompareCharArraysWithHexError(
+      "uint40", buffer40, 5,
+      GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian40
+                                                  : little_endian40,
+      5);
+
+  uint64_t read_number40;
+  QuicDataReader reader(buffer40, 5, GetParam().endianness);
+  reader.ReadBytesToUInt64(5, &read_number40);
+  EXPECT_EQ(in_memory40, read_number40);
+}
+
+TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
+  uint64_t in_memory48 = 0x0000112233445566;
+  char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+  char buffer48[6];
+  QuicDataWriter writer(6, buffer48, GetParam().endianness);
+  writer.WriteBytesToUInt64(6, in_memory48);
+  test::CompareCharArraysWithHexError(
+      "uint48", buffer48, 6,
+      GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian48
+                                                  : little_endian48,
+      6);
+
+  uint64_t read_number48;
+  QuicDataReader reader(buffer48, 6, GetParam().endianness);
+  reader.ReadBytesToUInt64(6., &read_number48);
+  EXPECT_EQ(in_memory48, read_number48);
+}
+
+TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
+  uint64_t in_memory56 = 0x0011223344556677;
+  char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+  char buffer56[7];
+  QuicDataWriter writer(7, buffer56, GetParam().endianness);
+  writer.WriteBytesToUInt64(7, in_memory56);
+  test::CompareCharArraysWithHexError(
+      "uint56", buffer56, 7,
+      GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian56
+                                                  : little_endian56,
+      7);
+
+  uint64_t read_number56;
+  QuicDataReader reader(buffer56, 7, GetParam().endianness);
+  reader.ReadBytesToUInt64(7, &read_number56);
+  EXPECT_EQ(in_memory56, read_number56);
+}
+
+TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
+  uint64_t in_memory64 = 0x1122334455667788;
+  unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11};
+  unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
+                                  0x55, 0x66, 0x77, 0x88};
+  char buffer64[8];
+  QuicDataWriter writer(8, buffer64, GetParam().endianness);
+  writer.WriteBytesToUInt64(8, in_memory64);
+  test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == NETWORK_BYTE_ORDER ? AsChars(big_endian64)
+                                                  : AsChars(little_endian64),
+      8);
+
+  uint64_t read_number64;
+  QuicDataReader reader(buffer64, 8, GetParam().endianness);
+  reader.ReadBytesToUInt64(8, &read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+
+  QuicDataWriter writer2(8, buffer64, GetParam().endianness);
+  writer2.WriteUInt64(in_memory64);
+  test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == NETWORK_BYTE_ORDER ? AsChars(big_endian64)
+                                                  : AsChars(little_endian64),
+      8);
+  read_number64 = 0u;
+  QuicDataReader reader2(buffer64, 8, GetParam().endianness);
+  reader2.ReadUInt64(&read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+}
+
+TEST_P(QuicDataWriterTest, WriteIntegers) {
+  char buf[43];
+  uint8_t i8 = 0x01;
+  uint16_t i16 = 0x0123;
+  uint32_t i32 = 0x01234567;
+  uint64_t i64 = 0x0123456789ABCDEF;
+  QuicDataWriter writer(46, buf, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 1u:
+        EXPECT_TRUE(writer.WriteUInt8(i8));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 2u:
+        EXPECT_TRUE(writer.WriteUInt16(i16));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 3u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 4u:
+        EXPECT_TRUE(writer.WriteUInt32(i32));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 5u:
+      case 6u:
+      case 7u:
+      case 8u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      default:
+        EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
+    }
+  }
+
+  QuicDataReader reader(buf, 46, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    uint8_t read8;
+    uint16_t read16;
+    uint32_t read32;
+    uint64_t read64;
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0u, read64);
+        break;
+      case 1u:
+        EXPECT_TRUE(reader.ReadUInt8(&read8));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i8, read8);
+        EXPECT_EQ(0xEFu, read64);
+        break;
+      case 2u:
+        EXPECT_TRUE(reader.ReadUInt16(&read16));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i16, read16);
+        EXPECT_EQ(0xCDEFu, read64);
+        break;
+      case 3u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0xABCDEFu, read64);
+        break;
+      case 4u:
+        EXPECT_TRUE(reader.ReadUInt32(&read32));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i32, read32);
+        EXPECT_EQ(0x89ABCDEFu, read64);
+        break;
+      case 5u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x6789ABCDEFu, read64);
+        break;
+      case 6u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x456789ABCDEFu, read64);
+        break;
+      case 7u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x23456789ABCDEFu, read64);
+        break;
+      case 8u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x0123456789ABCDEFu, read64);
+        break;
+      default:
+        EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
+    }
+  }
+}
+
+TEST_P(QuicDataWriterTest, WriteBytes) {
+  char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+  char buf[QUIC_ARRAYSIZE(bytes)];
+  QuicDataWriter writer(QUIC_ARRAYSIZE(buf), buf, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteBytes(bytes, QUIC_ARRAYSIZE(bytes)));
+  for (unsigned int i = 0; i < QUIC_ARRAYSIZE(bytes); ++i) {
+    EXPECT_EQ(bytes[i], buf[i]);
+  }
+}
+
+const int kVarIntBufferLength = 1024;
+
+// Encodes and then decodes a specified value, checks that the
+// value that was encoded is the same as the decoded value, the length
+// is correct, and that after decoding, all data in the buffer has
+// been consumed..
+// Returns true if everything works, false if not.
+bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
+  // Init the buffer to all 0, just for cleanliness. Makes for better
+  // output if, in debugging, we need to dump out the buffer.
+  memset(buffer, 0, size_of_buffer);
+  // make a writer. Note that for IETF encoding
+  // we do not care about endianness... It's always big-endian,
+  // but the c'tor expects to be told what endianness is in force...
+  QuicDataWriter writer(size_of_buffer, buffer, Endianness::NETWORK_BYTE_ORDER);
+
+  // Try to write the value.
+  if (writer.WriteVarInt62(value_in) != true) {
+    return false;
+  }
+  // Look at the value we encoded. Determine how much should have been
+  // used based on the value, and then check the state of the writer
+  // to see that it matches.
+  size_t expected_length = 0;
+  if (value_in <= 0x3f) {
+    expected_length = 1;
+  } else if (value_in <= 0x3fff) {
+    expected_length = 2;
+  } else if (value_in <= 0x3fffffff) {
+    expected_length = 4;
+  } else {
+    expected_length = 8;
+  }
+  if (writer.length() != expected_length) {
+    return false;
+  }
+
+  // set up a reader, just the length we've used, no more, no less.
+  QuicDataReader reader(buffer, expected_length,
+                        Endianness::NETWORK_BYTE_ORDER);
+  uint64_t value_out;
+
+  if (reader.ReadVarInt62(&value_out) == false) {
+    return false;
+  }
+  if (value_in != value_out) {
+    return false;
+  }
+  // We only write one value so there had better be nothing left to read
+  return reader.IsDoneReading();
+}
+
+// Test that 8-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt8Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x31 + 0xc0));  // 0xc0 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
+}
+
+// Test that 4-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt4Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x32 + 0x80));  // 0x80 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
+}
+
+// Test that 2-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt2Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3647));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x36 + 0x40));  // 0x40 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
+}
+
+// Test that 1-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt1Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer
+  // is correct. Bytes are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3f));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
+}
+
+// Test certain, targeted, values that are expected to succeed:
+// 0, 1,
+// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
+// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
+// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
+//                          transition)
+// 0x3ffffffffffffffe, 0x3fffffffffffffff,  (the highest valid values)
+// 0xfe, 0xff, 0x100, 0x101,
+// 0xfffe, 0xffff, 0x10000, 0x10001,
+// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
+// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
+// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
+// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
+// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
+TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t passing_values[] = {
+      0,
+      1,
+      0x3e,
+      0x3f,
+      0x40,
+      0x41,
+      0x3ffe,
+      0x3fff,
+      0x4000,
+      0x4001,
+      0x3ffffffe,
+      0x3fffffff,
+      0x40000000,
+      0x40000001,
+      0x3ffffffffffffffe,
+      0x3fffffffffffffff,
+      0xfe,
+      0xff,
+      0x100,
+      0x101,
+      0xfffe,
+      0xffff,
+      0x10000,
+      0x10001,
+      0xfffffe,
+      0xffffff,
+      0x1000000,
+      0x1000001,
+      0xfffffffe,
+      0xffffffff,
+      0x100000000,
+      0x100000001,
+      0xfffffffffe,
+      0xffffffffff,
+      0x10000000000,
+      0x10000000001,
+      0xfffffffffffe,
+      0xffffffffffff,
+      0x1000000000000,
+      0x1000000000001,
+      0xfffffffffffffe,
+      0xffffffffffffff,
+      0x100000000000000,
+      0x100000000000001,
+  };
+  for (uint64_t test_val : passing_values) {
+    EXPECT_TRUE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " failed";
+  }
+}
+//
+// Test certain, targeted, values where failure is expected (the
+// values are invalid w.r.t. IETF VarInt encoding):
+// 0x4000000000000000, 0x4000000000000001,  ( Just above max allowed value)
+// 0xfffffffffffffffe, 0xffffffffffffffff,  (should fail)
+TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t failing_values[] = {
+      0x4000000000000000,
+      0x4000000000000001,
+      0xfffffffffffffffe,
+      0xffffffffffffffff,
+  };
+  for (uint64_t test_val : failing_values) {
+    EXPECT_FALSE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " succeeded, but was an "
+        << "invalid value";
+  }
+}
+
+// Following tests all try to fill the buffer with multiple values,
+// go one value more than the buffer can accommodate, then read
+// the successfully encoded values, and try to read the unsuccessfully
+// encoded value. The following is the number of values to encode.
+const int kMultiVarCount = 1000;
+
+// Test writing & reading multiple 8-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt8) {
+  uint64_t test_val;
+  char buffer[8 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer), Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 4-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt4) {
+  uint64_t test_val;
+  char buffer[4 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
+  }
+  EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer), Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 2-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt2) {
+  uint64_t test_val;
+  char buffer[2 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
+  }
+  EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer), Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 1-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt1) {
+  uint64_t test_val;
+  char buffer[1 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over. &0xf ensures we do not
+  // overflow the max value for single-byte encoding.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
+  }
+  EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer), Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing varints with a forced length.
+TEST_P(QuicDataWriterTest, VarIntFixedLength) {
+  char buffer[90];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  QuicDataReader reader(buffer, sizeof(buffer), Endianness::NETWORK_BYTE_ORDER);
+
+  uint64_t test_val = 0;
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1u);
+  }
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 63u);
+  }
+
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 64u);
+  }
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16383u);
+  }
+
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16384u);
+  }
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1073741823u);
+  }
+
+  EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+  EXPECT_EQ(test_val, 1073741824u);
+
+  // We are at the end of the buffer so this should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test encoding/decoding stream-id values.
+void EncodeDecodeStreamId(uint64_t value_in, bool expected_decode_result) {
+  char buffer[1 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+
+  // Encode the given Stream ID.
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(value_in));
+
+  QuicDataReader reader(buffer, sizeof(buffer), Endianness::NETWORK_BYTE_ORDER);
+  QuicStreamId received_stream_id;
+  bool read_result = reader.ReadVarIntStreamId(&received_stream_id);
+  EXPECT_EQ(expected_decode_result, read_result);
+  if (read_result) {
+    EXPECT_EQ(value_in, received_stream_id);
+  }
+}
+
+// Test writing & reading stream-ids of various value.
+TEST_P(QuicDataWriterTest, StreamId1) {
+  // Check a 1-byte QuicStreamId, should work
+  EncodeDecodeStreamId(UINT64_C(0x15), true);
+
+  // Check a 2-byte QuicStream ID. It should work.
+  EncodeDecodeStreamId(UINT64_C(0x1567), true);
+
+  // Check a QuicStreamId that requires 4 bytes of encoding
+  // This should work.
+  EncodeDecodeStreamId(UINT64_C(0x34567890), true);
+
+  // Check a QuicStreamId that requires 8 bytes of encoding
+  // but whose value is in the acceptable range.
+  // This should work.
+  EncodeDecodeStreamId(UINT64_C(0xf4567890), true);
+
+  // Check QuicStreamIds that require 8 bytes of encoding
+  // and whose value is not acceptable.
+  // This should fail.
+  EncodeDecodeStreamId(UINT64_C(0x100000000), false);
+  EncodeDecodeStreamId(UINT64_C(0x3fffffffffffffff), false);
+}
+
+TEST_P(QuicDataWriterTest, WriteRandomBytes) {
+  char buffer[20];
+  char expected[20];
+  for (size_t i = 0; i < 20; ++i) {
+    expected[i] = 'r';
+  }
+  MockRandom random;
+  QuicDataWriter writer(20, buffer, GetParam().endianness);
+  EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
+
+  EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
+  test::CompareCharArraysWithHexError("random", buffer, 20, expected, 20);
+}
+
+TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
+  // In range [0, 63], variable length should be 1 byte.
+  char buffer[20];
+  QuicDataWriter writer(20, buffer, NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(50));
+  QuicDataReader reader(buffer, 20, NETWORK_BYTE_ORDER);
+  EXPECT_EQ(1, reader.PeekVarInt62Length());
+  // In range (63-16383], variable length should be 2 byte2.
+  char buffer2[20];
+  QuicDataWriter writer2(20, buffer2, NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer2.WriteVarInt62(100));
+  QuicDataReader reader2(buffer2, 20, NETWORK_BYTE_ORDER);
+  EXPECT_EQ(2, reader2.PeekVarInt62Length());
+  // In range (16383, 1073741823], variable length should be 4 bytes.
+  char buffer3[20];
+  QuicDataWriter writer3(20, buffer3, NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer3.WriteVarInt62(20000));
+  QuicDataReader reader3(buffer3, 20, NETWORK_BYTE_ORDER);
+  EXPECT_EQ(4, reader3.PeekVarInt62Length());
+  // In range (1073741823, 4611686018427387903], variable length should be 8
+  // bytes.
+  char buffer4[20];
+  QuicDataWriter writer4(20, buffer4, NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
+  QuicDataReader reader4(buffer4, 20, NETWORK_BYTE_ORDER);
+  EXPECT_EQ(8, reader4.PeekVarInt62Length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic