Created
March 3, 2016 18:48
-
-
Save mpilquist/84470c6de1b82ed4472b to your computer and use it in GitHub Desktop.
Example of using scodec to decode a document of fields
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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