Skip to content
This repository has been archived by the owner on Oct 24, 2021. It is now read-only.

Combination of stream decoders doesn't emit all expected items #169

Closed
mpod opened this issue Sep 6, 2021 · 4 comments
Closed

Combination of stream decoders doesn't emit all expected items #169

mpod opened this issue Sep 6, 2021 · 4 comments

Comments

@mpod
Copy link

mpod commented Sep 6, 2021

Output of the following program is abcd, while according to my understanding it should be abcdababc. Am I missing something?

import cats.effect.{ExitCode, IO, IOApp}
import fs2.Stream
import scodec.Err
import scodec.bits.{BitVector, HexStringSyntax}
import scodec.codecs.bits
import scodec.stream.StreamDecoder

object Test extends IOApp {
  val input = hex"1a bc d7 ab 7a bc"

  val decoder = StreamDecoder.many(bits(4)).flatMap { a =>
    //println(s"a: ${a.toHex}")
    StreamDecoder.tryMany(
      bits(4).flatMap { b =>
        //println(s"b: ${b.toHex}")
        if (b.toHex == "7") scodec.codecs.fail[BitVector](Err("AAA"))
        else scodec.codecs.provide(b)
      }
    )
  }

  override def run(args: List[String]): IO[ExitCode] =
    Stream
      .emits(input.toArray.map(BitVector.apply(_)))
      .covary[IO]
      .through(decoder.toPipe)
      .evalTap(a => IO(println(s"Decoded: ${a.toHex}")))
      .compile
      .drain >> IO(ExitCode.Success)
}
@mpilquist
Copy link
Contributor

What version of scodec-stream are you using? Using 2.x or 3.x gives the expected behavior:

scala> decoder.decode[Fallible](Stream(hex"1a bc d7 ab 7a bc".bits)).compile.fold(BitVector.empty)(_ ++ _)                                                                                   
val res7: Either[Throwable, scodec.bits.BitVector] = Right(BitVector(36 bits, 0xabcdababc))

@mpod
Copy link
Author

mpod commented Sep 6, 2021

I don't see how your example is equivalent to mine.

Here is my build.sbt:

scalaVersion := "2.13.6"

libraryDependencies ++= Seq(
  "org.scodec"                 %% "scodec-stream"   % "3.0.1",
)

$ sbt run returns:

... 
Decoded: a
Decoded: b
Decoded: c
Decoded: d

@mpilquist
Copy link
Contributor

Okay yeah, I can reproduce your results if I chunk up the input in to an individual BitVector for each byte of input:

scala> decoder.decode[Fallible](Stream.emits(hex"1a bc d7 ab 7a bc".toArray.map(BitVector.apply(_)))).compile.fold(BitVector.empty)(_ ++ _)                                                                                          
val res9: Either[Throwable, scodec.bits.BitVector] = Right(BitVector(16 bits, 0xabcd))

mpilquist added a commit that referenced this issue Sep 7, 2021
@mpilquist
Copy link
Contributor

Fixed in 3.0.2 and 2.0.3, which are releasing now and should be available for download within the hour.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants