@@ -1843,6 +1843,10 @@ class MoQImmutableExtensionsTest : public ::testing::TestWithParam<uint64_t> {
18431843 MoQFrameParser parser_;
18441844 MoQFrameWriter writer_;
18451845
1846+ bool deltaEncoding () const {
1847+ return getDraftMajorVersion (GetParam ()) >= 16 ;
1848+ }
1849+
18461850 // Creates the following extensions (encoded back-to-back):
18471851 // {type = 20, value = 100, immutable}
18481852 // {type = 21, value = binary(0xAB,0xCD,0xEF), immutable}
@@ -1856,7 +1860,7 @@ class MoQImmutableExtensionsTest : public ::testing::TestWithParam<uint64_t> {
18561860
18571861 // Extension type 21 (odd => length + bytes), binary value
18581862 static uint8_t testData[] = {0xAB , 0xCD , 0xEF };
1859- writeVarintTo (immutableBuf, 21 ); // type
1863+ writeVarintTo (immutableBuf, deltaEncoding () ? 21 - 20 : 21 ); // type
18601864 writeVarintTo (immutableBuf, sizeof (testData)); // length
18611865 immutableBuf.append (testData, sizeof (testData)); // data
18621866
@@ -1868,25 +1872,33 @@ class MoQImmutableExtensionsTest : public ::testing::TestWithParam<uint64_t> {
18681872 // type = kImmutableExtensionType (odd) and an arbitrary byte value. This is
18691873 // invalid when parsed as nested immutable extensions (parseImmutable=false).
18701874 std::unique_ptr<folly::IOBuf> createImmutableExtensionsBufMalformed () {
1871- // Start with the valid immutable extensions blob
1872- auto base = createImmutableExtensionsBuf ();
1873-
18741875 // Append an additional immutable-extensions container entry with arbitrary
18751876 // 1-byte payload. This makes the nested immutable blob malformed for our
18761877 // parser (immutable container found while already parsing immutable).
18771878 folly::IOBufQueue q{folly::IOBufQueue::cacheChainLength ()};
18781879
1879- if (base) {
1880- q.append (std::move (base));
1881- }
1880+ if (deltaEncoding ()) {
1881+ // Different path to support delta encoding.
1882+ writeVarintTo (q, 2 ); // type
1883+ writeVarintTo (q, 1 ); // value
1884+ writeVarintTo (q, kImmutableExtensionType - 2 ); // nested
1885+ writeVarintTo (q, 1 ); // length
1886+ static const uint8_t kArbitrary = 0xAA ;
1887+ q.append (&kArbitrary , 1 );
1888+ } else {
1889+ auto base = createImmutableExtensionsBuf ();
1890+ if (base) {
1891+ q.append (std::move (base));
1892+ }
18821893
1883- // Write type = kImmutableExtensionType (odd)
1884- writeVarintTo (q, kImmutableExtensionType );
1894+ // Write type = kImmutableExtensionType (odd)
1895+ writeVarintTo (q, kImmutableExtensionType );
18851896
1886- // Write length = 1, then one arbitrary byte value 0xAA
1887- writeVarintTo (q, 1 ); // length
1888- static const uint8_t kArbitrary = 0xAA ;
1889- q.append (&kArbitrary , 1 );
1897+ // Write length = 1, then one arbitrary byte value 0xAA
1898+ writeVarintTo (q, 1 ); // length
1899+ static const uint8_t kArbitrary = 0xAA ;
1900+ q.append (&kArbitrary , 1 );
1901+ }
18901902
18911903 return q.move ();
18921904 }
@@ -1906,14 +1918,14 @@ class MoQImmutableExtensionsTest : public ::testing::TestWithParam<uint64_t> {
19061918 // 2) type = kImmutableExtensionType (odd => length + bytes), value =
19071919 // output of createImmutableExtensionsBuf()
19081920 auto imm = createImmutableExtensionsBuf ();
1909- writeVarintTo (buf, kImmutableExtensionType ); // type
1921+ writeVarintTo (buf, deltaEncoding () ? kImmutableExtensionType - 10 : kImmutableExtensionType ); // type
19101922 writeVarintTo (buf, imm ? imm->computeChainDataLength () : 0 ); // length
19111923 if (imm) {
19121924 buf.append (std::move (imm)); // payload
19131925 }
19141926
19151927 // 3) type = 30 (even => integer value follows), value = 999
1916- writeVarintTo (buf, 30 ); // type
1928+ writeVarintTo (buf, deltaEncoding () ? 30 - kImmutableExtensionType : 30 ); // type
19171929 writeVarintTo (buf, 999 ); // value
19181930
19191931 return buf.move ();
@@ -1932,14 +1944,14 @@ class MoQImmutableExtensionsTest : public ::testing::TestWithParam<uint64_t> {
19321944 // 2) type = kImmutableExtensionType (odd => length + bytes), value =
19331945 // output of createImmutableExtensionsBufMalformed()
19341946 auto imm = createImmutableExtensionsBufMalformed ();
1935- writeVarintTo (buf, kImmutableExtensionType ); // type
1947+ writeVarintTo (buf, deltaEncoding () ? kImmutableExtensionType - 10 : kImmutableExtensionType ); // type
19361948 writeVarintTo (buf, imm ? imm->computeChainDataLength () : 0 ); // length
19371949 if (imm) {
19381950 buf.append (std::move (imm)); // payload
19391951 }
19401952
19411953 // 3) type = 30 (even => integer value follows), value = 999
1942- writeVarintTo (buf, 30 ); // type
1954+ writeVarintTo (buf, deltaEncoding () ? 30 - kImmutableExtensionType : 30 ); // type
19431955 writeVarintTo (buf, 999 ); // value
19441956
19451957 return buf.move ();
@@ -2025,9 +2037,11 @@ TEST_P(MoQImmutableExtensionsTest, WriteImmutableExtensionsDraft) {
20252037
20262038 static const uint8_t kTestBinary [] = {0xAB , 0xCD , 0xEF };
20272039 std::vector<Extension> immutableExts = {
2040+ Extension{2 , 2 },
20282041 Extension{20 , 100 },
20292042 Extension{
2030- 21 , folly::IOBuf::copyBuffer (kTestBinary , sizeof (kTestBinary ))}};
2043+ 21 , folly::IOBuf::copyBuffer (kTestBinary , sizeof (kTestBinary ))},
2044+ Extension{32 , 32 }};
20312045
20322046 Extensions extensions (mutableExts, immutableExts);
20332047
@@ -2056,8 +2070,8 @@ TEST_P(MoQImmutableExtensionsTest, WriteImmutableExtensionsDraft) {
20562070 EXPECT_TRUE (parseResult.hasValue ()) << " Parsing should succeed" ;
20572071
20582072 // Verify both mutable and immutable extensions are present
2059- EXPECT_EQ (obj.extensions .size (), 4 )
2060- << " Should have 4 total extensions (2 mutable + 2 immutable)" ;
2073+ EXPECT_EQ (obj.extensions .size (), 6 )
2074+ << " Should have 6 total extensions (2 mutable + 4 immutable)" ;
20612075 EXPECT_THAT (
20622076 obj.extensions .getMutableExtensions (), testing::ContainerEq (mutableExts));
20632077 EXPECT_THAT (
@@ -2114,7 +2128,7 @@ TEST_P(MoQImmutableExtensionsTest, WriteOnlyImmutableExtensionsDraft) {
21142128INSTANTIATE_TEST_SUITE_P (
21152129 MoQImmutableExtensionsTest,
21162130 MoQImmutableExtensionsTest,
2117- ::testing::Values (kVersionDraft14 , kVersionDraft15 ));
2131+ ::testing::Values (kVersionDraft14 , kVersionDraft15 , kVersionDraft16 ));
21182132
21192133TEST_P (MoQFramerTest, DatagramWithExtensionsAndNonNormalStatus) {
21202134 folly::IOBufQueue writeBuf{folly::IOBufQueue::cacheChainLength ()};
0 commit comments