Generalization of cstring combinator
Created
February 29, 2016 23:55
-
-
Save searler/3892e21d413c0867b543 to your computer and use it in GitHub Desktop.
Bracket scodec with start and end markers
This file contains 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
def bracketed[T](start:BitVector, end:BitVector, extract: Codec[T]): Codec[T] = filtered(extract, new Codec[BitVector] { | |
override def sizeBound: SizeBound = SizeBound.unknown | |
override def encode(bits: BitVector): Attempt[BitVector] = Attempt.successful(start ++ bits ++ end) | |
override def decode(bits: BitVector): Attempt[DecodeResult[BitVector]] = { | |
bits.bytes.indexOfSlice(start.bytes) match { | |
case -1 => Attempt.failure(Err("Does not contain start.")) | |
case si => bits.bytes.indexOfSlice(end.bytes) match { | |
case -1 => Attempt.failure(Err("Does not contain end.")) | |
case ei => Attempt.successful(DecodeResult(bits.slice((si + start.size) * 8L, ei * 8L), bits.drop((ei + end.size) * 8L))) | |
} | |
} | |
} | |
}).withToString("bracketed") |
This file contains 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
import org.scalatest._ | |
import scodec.bits.BitVector | |
import scodec.DecodeResult | |
import scodec.Attempt.Successful | |
import scodec.Decoder | |
import scodec.codecs._ | |
import Codecs._ | |
class CodecTest extends FlatSpec with Matchers { | |
val string: Decoder[String] = bracketed(BitVector(2),BitVector(3, 0),ascii) | |
"simple string" should "extract" in { | |
val bv = BitVector("\u0002xxx\u0003\u0000".getBytes) | |
string.decode(bv) match { | |
case Successful(DecodeResult(value, remainder)) => | |
value should be("xxx") | |
remainder should be(BitVector.empty) | |
case _@ x => fail(x.toString) | |
} | |
} | |
"prefixed string" should "extract" in { | |
val bv = BitVector("aaa\u0002xxx\u0003\u0000".getBytes) | |
string.decode(bv) match { | |
case Successful(DecodeResult(value, remainder)) => | |
value should be("xxx") | |
remainder should be(BitVector.empty) | |
case _@ x => fail(x.toString) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment