diff --git a/protocols/shared/src/main/scala-2/fs2/protocols/pcapng/Block.scala b/protocols/shared/src/main/scala-2/fs2/protocols/pcapng/BlockCodec.scala similarity index 67% rename from protocols/shared/src/main/scala-2/fs2/protocols/pcapng/Block.scala rename to protocols/shared/src/main/scala-2/fs2/protocols/pcapng/BlockCodec.scala index 9a6bb2aaaf..0b3e2d8793 100644 --- a/protocols/shared/src/main/scala-2/fs2/protocols/pcapng/Block.scala +++ b/protocols/shared/src/main/scala-2/fs2/protocols/pcapng/BlockCodec.scala @@ -28,12 +28,10 @@ import scodec.codecs._ import shapeless.ops.hlist.{Init, Last, Prepend} import shapeless.{::, HList, HNil} -trait Block - -object Block { +object BlockCodec { // format: off - private def codec[A, L <: HList, LB <: HList](blockType: Codec[A])(f: Length => Codec[L])( + private def commonStructure[A, L <: HList, LB <: HList](blockType: Codec[A])(f: Length => Codec[L])( implicit prepend: Prepend.Aux[L, Unit :: HNil, LB], init: Init.Aux[LB, L], @@ -45,32 +43,35 @@ object Block { ("Block Total Length" | constant(length.bv) )} // format: on - def codecByHex[L <: HList, LB <: HList](hexConstant: ByteVector)(f: Length => Codec[L])( - implicit - prepend: Prepend.Aux[L, Unit :: HNil, LB], - init: Init.Aux[LB, L], - last: Last.Aux[LB, Unit] - ): Codec[Unit :: Length :: LB] = codec(constant(hexConstant))(f) + def unknownByteOrder[L <: HList, LB <: HList](hexConstant: ByteVector)(f: Length => Codec[L])( + implicit + prepend: Prepend.Aux[L, Unit :: HNil, LB], + init: Init.Aux[LB, L], + last: Last.Aux[LB, Unit] + ): Codec[Unit :: Length :: LB] = commonStructure(constant(hexConstant))(f) - def codecByLength[L <: HList, LB <: HList](hexConstant: ByteVector, c: Codec[L])( - implicit - prepend: Prepend.Aux[L, Unit :: HNil, LB], - init: Init.Aux[LB, L], - last: Last.Aux[LB, Unit], - ord: ByteOrdering, - ): Codec[Unit :: Length :: LB] = codecByHex(hexConstant)(length => fixedSizeBytes(length.toLong - 12, c)) + def byBlockBytesCodec[L <: HList, LB <: HList]( + hexConstant: ByteVector, + blockBytesCodec: Codec[L] + )(implicit + prepend: Prepend.Aux[L, Unit :: HNil, LB], + init: Init.Aux[LB, L], + last: Last.Aux[LB, Unit], + ord: ByteOrdering + ): Codec[Unit :: Length :: LB] = + unknownByteOrder(hexConstant)(length => fixedSizeBytes(length.toLong - 12, blockBytesCodec)) - def codecIgnored( - hexConstant: ByteVector + def ignored( + hexConstant: ByteVector )(implicit ord: ByteOrdering): Codec[Length :: ByteVector :: HNil] = - codecByHex(hexConstant) { length => + unknownByteOrder(hexConstant) { length => fixedSizeBytes(length.toLong - 12, bytes) :: Codec.deriveHNil }.dropUnits - def codecUnrecognized( - implicit ord: ByteOrdering + def unrecognizedBlockType(implicit + ord: ByteOrdering ): Codec[ByteVector :: Length :: ByteVector :: HNil] = - codec(bytes(4)) { length => + commonStructure(bytes(4)) { length => fixedSizeBytes(length.toLong - 12, bytes) :: Codec.deriveHNil }.dropUnits } diff --git a/protocols/shared/src/main/scala-3/Block.scala b/protocols/shared/src/main/scala-3/BlockCodec.scala similarity index 77% rename from protocols/shared/src/main/scala-3/Block.scala rename to protocols/shared/src/main/scala-3/BlockCodec.scala index c7a3a3309a..80e636e18a 100644 --- a/protocols/shared/src/main/scala-3/Block.scala +++ b/protocols/shared/src/main/scala-3/BlockCodec.scala @@ -26,12 +26,10 @@ import scodec.Codec import scodec.bits._ import scodec.codecs._ -trait Block - -object Block { +object BlockCodec { // format: off - inline def codec[A, L <: Tuple]( + private inline def commonStructure[A, L <: Tuple]( blockType: Codec[A] )(f: Length => Codec[L]): Codec[Tuple.Concat[A *: Length *: L, Unit *: EmptyTuple]] = ("Block Type" | blockType ) :: @@ -40,27 +38,27 @@ object Block { ("Block Total Length" | constant(length.bv) )} // format: on - inline def codecByHex[L <: Tuple]( - hexConstant: ByteVector + inline def unknownByteOrder[L <: Tuple]( + hexConstant: ByteVector )(f: Length => Codec[L]): Codec[Tuple.Concat[Unit *: Length *: L, Unit *: EmptyTuple]] = - codec(constant(hexConstant))(f) + commonStructure(constant(hexConstant))(f) - inline def codecByLength[L <: Tuple](hexConstant: ByteVector, c: Codec[L])( - implicit ord: ByteOrdering, + inline def byBlockBytesCodec[L <: Tuple](hexConstant: ByteVector, blockBytesCodec: Codec[L])( + implicit ord: ByteOrdering ): Codec[Tuple.Concat[Unit *: Length *: L, Unit *: EmptyTuple]] = - codecByHex(hexConstant)(length => fixedSizeBytes(length.toLong - 12, c)) + unknownByteOrder(hexConstant)(length => fixedSizeBytes(length.toLong - 12, blockBytesCodec)) - def codecIgnored( - hexConstant: ByteVector + def ignored( + hexConstant: ByteVector )(implicit ord: ByteOrdering): Codec[Length *: ByteVector *: EmptyTuple] = - codecByHex(hexConstant) { length => + unknownByteOrder(hexConstant) { length => fixedSizeBytes(length.toLong - 12, bytes).tuple }.dropUnits - def codecUnrecognized( - implicit ord: ByteOrdering + def unrecognizedBlockType(implicit + ord: ByteOrdering ): Codec[ByteVector *: Length *: ByteVector *: EmptyTuple] = - codec(bytes(4)) { length => + commonStructure(bytes(4)) { length => fixedSizeBytes(length.toLong - 12, bytes).tuple }.dropUnits } diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcap/LinkType.scala b/protocols/shared/src/main/scala/fs2/protocols/pcap/LinkType.scala index 9897e31307..7fb4f9128a 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcap/LinkType.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcap/LinkType.scala @@ -42,7 +42,7 @@ object LinkType { case class Unknown(value: Long) extends LinkType def fromInt(l: Int): LinkType = - fromLong(l) + fromLong(l.toLong) def toInt(lt: LinkType): Int = lt match { case Null => 0 @@ -64,7 +64,7 @@ object LinkType { case other => Unknown(other) } - def toLong(lt: LinkType): Long = toInt(lt) + def toLong(lt: LinkType): Long = toInt(lt).toLong implicit def codec(implicit bo: ByteOrdering): Codec[LinkType] = guint32.xmap[LinkType](fromLong, toLong) diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/BodyBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/BodyBlock.scala index a6c321fc11..939df85dc8 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/BodyBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/BodyBlock.scala @@ -25,7 +25,7 @@ package pcapng import scodec.bits._ import scodec.Decoder -trait BodyBlock extends Block +trait BodyBlock object BodyBlock { @@ -36,6 +36,6 @@ object BodyBlock { NameResolutionBlock.codec, InterfaceStatisticsBlock.codec, ProcessInformationBlock.codec, - UnrecognizedBlock.codec, + UnrecognizedBlock.codec ) } diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/CaptureFile.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/CaptureFile.scala index c69a0703e2..eb4b806c53 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/CaptureFile.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/CaptureFile.scala @@ -40,7 +40,7 @@ object CaptureFile { ): Pipe[F, Byte, TimeStamped[A]] = { bytes => def go( idbs: Vector[InterfaceDescriptionBlock], - blocks: Stream[F, BodyBlock], + blocks: Stream[F, BodyBlock] ): Pull[F, TimeStamped[A], Unit] = blocks.pull.uncons1.flatMap { case Some((idb: InterfaceDescriptionBlock, tail)) => diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/EnhancedPacketBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/EnhancedPacketBlock.scala index d382cc44f7..8f93940654 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/EnhancedPacketBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/EnhancedPacketBlock.scala @@ -42,7 +42,7 @@ object EnhancedPacketBlock { // format: off def codec(implicit ord: ByteOrdering): Codec[EnhancedPacketBlock] = - "EPB" | Block.codecByLength(hexConstant, epbCodec).dropUnits.as[EnhancedPacketBlock] + "EPB" | BlockCodec.byBlockBytesCodec(hexConstant, epbCodec).dropUnits.as[EnhancedPacketBlock] private def epbCodec(implicit ord: ByteOrdering) = ("Interface ID" | guint32 ) :: @@ -51,16 +51,16 @@ object EnhancedPacketBlock { ("Captured Packet Length" | guint32 ).flatPrepend { packetLength => ("Original Packet Length" | guint32 ) :: ("Packet Data" | bytes(packetLength.toInt) ) :: - ("Packet padding" | ignore(padTo32Bits(packetLength.toInt) * 8) ) :: + ("Packet padding" | ignore(padTo32Bits(packetLength.toInt)) ) :: ("Options" | bytes )} // format: on private def hexConstant(implicit ord: ByteOrdering): ByteVector = orderDependent(hex"00000006", hex"06000000") - private def padTo32Bits(length: Int) = { + private def padTo32Bits(length: Int): Long = { val rem = length % 4 - if (rem == 0) 0 - else 4 - rem + val bytes = if (rem == 0) 0 else 4 - rem + bytes.toLong * 8 } } diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceDescriptionBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceDescriptionBlock.scala index 443b7d0c47..4ece0c2f8c 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceDescriptionBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceDescriptionBlock.scala @@ -45,7 +45,7 @@ object InterfaceDescriptionBlock { // format: off def codec(implicit ord: ByteOrdering): Codec[InterfaceDescriptionBlock] = - "IDB" | Block.codecByLength(hexConstant, idbCodec).dropUnits.as[InterfaceDescriptionBlock] + "IDB" | BlockCodec.byBlockBytesCodec(hexConstant, idbCodec).dropUnits.as[InterfaceDescriptionBlock] private def idbCodec(implicit ord: ByteOrdering) = ("LinkType" | guint16.xmap[LinkType](LinkType.fromInt, LinkType.toInt) ) :: diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceStatisticsBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceStatisticsBlock.scala index 6d1393cb60..602db53108 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceStatisticsBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/InterfaceStatisticsBlock.scala @@ -31,7 +31,7 @@ case class InterfaceStatisticsBlock(length: Length, bytes: ByteVector) extends B object InterfaceStatisticsBlock { def codec(implicit ord: ByteOrdering): Codec[InterfaceStatisticsBlock] = - "ISB" | Block.codecIgnored(hexConstant).as[InterfaceStatisticsBlock] + "ISB" | BlockCodec.ignored(hexConstant).as[InterfaceStatisticsBlock] private def hexConstant(implicit ord: ByteOrdering) = orderDependent(hex"00000005", hex"05000000") diff --git a/protocols/shared/src/test/scala/fs2/protocols/pcapng/DummyBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/Length.scala similarity index 63% rename from protocols/shared/src/test/scala/fs2/protocols/pcapng/DummyBlock.scala rename to protocols/shared/src/main/scala/fs2/protocols/pcapng/Length.scala index ea387642f1..513bd42471 100644 --- a/protocols/shared/src/test/scala/fs2/protocols/pcapng/DummyBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/Length.scala @@ -22,24 +22,8 @@ package fs2.protocols package pcapng -import scodec.Codec -import scodec.bits._ -import scodec.codecs._ +import scodec.bits.{ByteOrdering, ByteVector} -case class DummyBlock( - blockType: ByteVector, - totalLength: Length, - body: ByteVector -) extends BodyBlock - -object DummyBlock { - - // format: off - def codec(implicit ord: ByteOrdering): Codec[DummyBlock] = "Dummy" | { - ("Block Type" | bytes(4) ) :: - ("Block Total Length" | bytes(4).xmapc(Length)(_.bv) ).flatPrepend { length => - ("Block Body" | bytes(length.toLong.toInt - 12) ) :: - ("Block Total Length" | constant(length.bv) )} - }.dropUnits.as[DummyBlock] - // format: on +case class Length(bv: ByteVector) extends AnyVal { + def toLong(implicit ord: ByteOrdering): Long = bv.toLong(signed = false, ord) } diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/NameResolutionBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/NameResolutionBlock.scala index 42ccfd50e2..1429f29774 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/NameResolutionBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/NameResolutionBlock.scala @@ -31,7 +31,7 @@ case class NameResolutionBlock(length: Length, bytes: ByteVector) extends BodyBl object NameResolutionBlock { def codec(implicit ord: ByteOrdering): Codec[NameResolutionBlock] = - "NRB" | Block.codecIgnored(hexConstant).as[NameResolutionBlock] + "NRB" | BlockCodec.ignored(hexConstant).as[NameResolutionBlock] private def hexConstant(implicit ord: ByteOrdering) = orderDependent(hex"00000004", hex"04000000") diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/ProcessInformationBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/ProcessInformationBlock.scala index f479e37f03..2d009cfc8d 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/ProcessInformationBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/ProcessInformationBlock.scala @@ -31,7 +31,7 @@ case class ProcessInformationBlock(length: Length, bytes: ByteVector) extends Bo object ProcessInformationBlock { def codec(implicit ord: ByteOrdering): Codec[ProcessInformationBlock] = - "PIB" | Block.codecIgnored(hexConstant).as[ProcessInformationBlock] + "PIB" | BlockCodec.ignored(hexConstant).as[ProcessInformationBlock] private def hexConstant(implicit ord: ByteOrdering) = orderDependent(hex"80000001", hex"01000080") diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/SectionHeaderBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/SectionHeaderBlock.scala index 2580954632..61f25eb5a7 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/SectionHeaderBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/SectionHeaderBlock.scala @@ -33,7 +33,7 @@ case class SectionHeaderBlock( majorVersion: Int, minorVersion: Int, bytes: ByteVector -) extends Block +) object SectionHeaderBlock { @@ -41,8 +41,8 @@ object SectionHeaderBlock { // format: off val codec: Codec[SectionHeaderBlock] = - "SHB" | Block.codecByHex(hexConstant) { length => - ("Byte-Order Magic" | ByteOrderMagic ).flatPrepend { implicit ord => + "SHB" | BlockCodec.unknownByteOrder(hexConstant) { length => + ("Byte-Order Magic" | ByteOrderMagic ).flatPrepend { implicit byteOrder => ("Major Version" | guint16 ) :: ("Minor Version" | guint16 ) :: ("Block Bytes" | bytes(length.toLong.toInt - 20) ) diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/SimplePacketBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/SimplePacketBlock.scala index 191708b506..80e46c503d 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/SimplePacketBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/SimplePacketBlock.scala @@ -30,7 +30,7 @@ case class SimplePacketBlock(length: Length, bytes: ByteVector) extends BodyBloc object SimplePacketBlock { def codec(implicit ord: ByteOrdering): Codec[ProcessInformationBlock] = - "SPB" | Block.codecIgnored(hexConstant).as[ProcessInformationBlock] + "SPB" | BlockCodec.ignored(hexConstant).as[ProcessInformationBlock] private def hexConstant(implicit ord: ByteOrdering) = orderDependent(hex"00000003", hex"03000000") diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/UnrecognizedBlock.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/UnrecognizedBlock.scala index 561b302b2e..64ccebb0b9 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/UnrecognizedBlock.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/UnrecognizedBlock.scala @@ -1,13 +1,36 @@ -package fs2.protocols.pcapng +/* + * Copyright (c) 2013 Functional Streams for Scala + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package fs2.protocols +package pcapng import scodec.Codec import scodec.bits._ import scodec.codecs._ -case class UnrecognizedBlock(blockType: ByteVector, length: Length, bytes: ByteVector) extends BodyBlock +case class UnrecognizedBlock(blockType: ByteVector, length: Length, bytes: ByteVector) + extends BodyBlock object UnrecognizedBlock { def codec(implicit ord: ByteOrdering): Codec[UnrecognizedBlock] = - "UB" | Block.codecUnrecognized.as[UnrecognizedBlock] + "UB" | BlockCodec.unrecognizedBlockType.as[UnrecognizedBlock] } diff --git a/protocols/shared/src/main/scala/fs2/protocols/pcapng/package.scala b/protocols/shared/src/main/scala/fs2/protocols/pcapng/package.scala index cc3d97c0a3..f7b0e8ffe2 100644 --- a/protocols/shared/src/main/scala/fs2/protocols/pcapng/package.scala +++ b/protocols/shared/src/main/scala/fs2/protocols/pcapng/package.scala @@ -25,10 +25,6 @@ import scodec.bits.{ByteOrdering, ByteVector} package object pcapng { - case class Length(bv: ByteVector) extends AnyVal { - def toLong(implicit ord: ByteOrdering): Long = bv.toLong(signed = false, ord) - } - def orderDependent[T]( big: ByteVector, little: ByteVector diff --git a/protocols/shared/src/test/scala/fs2/protocols/PcapNgExample.scala b/protocols/shared/src/test/scala/fs2/protocols/PcapNgExample.scala index 1a2b442546..e11753205f 100644 --- a/protocols/shared/src/test/scala/fs2/protocols/PcapNgExample.scala +++ b/protocols/shared/src/test/scala/fs2/protocols/PcapNgExample.scala @@ -23,30 +23,19 @@ package fs2 package protocols import cats.effect.{IO, IOApp} -import cats.syntax.all._ +import cats.syntax.foldable._ +import cats.syntax.option._ import fs2.io.file.{Files, Path} import fs2.protocols.pcap.LinkType -import fs2.protocols.pcapng.{CaptureFile, DummyBlock} +import fs2.protocols.pcapng.CaptureFile object PcapNgExample extends IOApp.Simple { def run: IO[Unit] = - output.compile.toList.flatMap(x => IO.println(x.length)) // _.traverse_(IO.println) + output.compile.toList.flatMap(_.traverse_(IO.println)) private def byteStream: Stream[IO, Byte] = - Files[IO].readAll(Path("/Users/anikiforov/pcapng/many_interfaces.pcapng")) - - private def revealFailed = - byteStream - .through(CaptureFile.streamDecoder.toPipeByte) - .flatMap { - case dummy: DummyBlock => Stream.emit(dummy) - case _ => Stream.empty - } - .debug() - - private def decode = - byteStream.through(CaptureFile.streamDecoder.toPipeByte) + Files[IO].readAll(Path("/path/to/pcapng")) private def output = byteStream.through( diff --git a/protocols/shared/src/test/scala/fs2/protocols/pcapng/BlockTest.scala b/protocols/shared/src/test/scala/fs2/protocols/pcapng/BlockTest.scala index a8d09c6bee..461954fb6f 100644 --- a/protocols/shared/src/test/scala/fs2/protocols/pcapng/BlockTest.scala +++ b/protocols/shared/src/test/scala/fs2/protocols/pcapng/BlockTest.scala @@ -62,8 +62,8 @@ class BlockTest extends munit.FunSuite { assertEquals(actual, fullyDecoded(Enhanced4.expected)) } - test("real-data dummy") { - val actual = DummyBlock.codec(LittleEndian).decode(RD.bytes.bits) + test("real-data UnrecognizedBlock") { + val actual = UnrecognizedBlock.codec(LittleEndian).decode(RD.bytes.bits) assertEquals(actual, fullyDecoded(RD.expectedDummy)) } @@ -203,6 +203,6 @@ private object BlockTest { val bytes = header ++ length.bv ++ props ++ data ++ padding ++ opts ++ length.bv val expectedEPB = EnhancedPacketBlock(length, 0, 381443, 399317124, 66, 66, data, opts) - val expectedDummy = DummyBlock(header, length, props ++ data ++ padding ++ opts) + val expectedDummy = UnrecognizedBlock(header, length, props ++ data ++ padding ++ opts) } }