Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of using scodec to decode a document of fields
package foo
import scodec.bits._
import scodec._
import scodec.codecs._
case class Document(fields: Vector[(String, Field)])
sealed trait Field
case class IntField(value: Int) extends Field
case class StringField(value: String) extends Field
object Document {
val field: Codec[(String, Field)] = {
discriminated[(String, Field)].by(uint8).
subcaseO(1) { case (nme, fld: IntField) => Some(nme -> fld); case _ => None } (cstring ~ int32.as[IntField]).
subcaseO(2) { case (nme, fld: StringField) => Some(nme -> fld); case _ => None } (cstring ~ cstring.as[StringField])
}
def nullTerminated[A](c: Codec[A]): Codec[A] = new Codec[A] {
def sizeBound = c.sizeBound + SizeBound.exact(8)
def encode(a: A) = c.encode(a).map { _ ++ hex"00".bits }
def decode(b: BitVector) = {
if (b.takeRight(8) == hex"00".bits)
c.decode(b.dropRight(8))
else Attempt.failure(Err("Was not null terminated!"))
}
}
val codec: Codec[Document] = {
nullTerminated(variableSizeBytes(int32, vector(field), 4).as[Document])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment