Last active
December 23, 2016 01:41
-
-
Save ajaychandran/92b5eeade99d0855b066 to your computer and use it in GitHub Desktop.
Revisions
-
ajaychandran revised this gist
Jun 4, 2015 . 1 changed file with 9 additions and 3 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -19,7 +19,14 @@ object DelimitedCodec { case Attempt.Failure(err) => return Attempt.failure(err.pushContext(buf.size.toString)) } } def merge(offset: Int, size: Int): BitVector = size match { case 0 => BitVector.empty case 1 => buf(offset) case n => val half = size / 2 merge(offset, half) ++ delimiter ++ merge(offset + half, half + (if (size % 2 == 0) 0 else 1)) } Attempt.successful(merge(0, buf.size)) } /** @@ -42,11 +49,10 @@ object DelimitedCodec { next = remaining.take(i) remaining = remaining.drop(i + delimiter.size) } dec.decode(next) match { case Attempt.Successful(DecodeResult(value, rest)) => bldr += value count += 1 case Attempt.Failure(err) => error = Some(err.pushContext(count.toString)) remaining = BitVector.empty -
ajaychandran created this gist
Jun 4, 2015 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,73 @@ package scodec.codecs import scala.language.higherKinds import scodec._ import scodec.bits.BitVector object DelimitedCodec { /** * Encodes all elements of the specified sequence and concatenates the results separated by `delimiter`, * or returns the first encountered error. */ final def encode[A](enc: Encoder[A], delimiter: BitVector)(seq: collection.immutable.Seq[A]): Attempt[BitVector] = { val buf = new collection.mutable.ArrayBuffer[BitVector](seq.size) seq foreach { a => enc.encode(a) match { case Attempt.Successful(aa) => buf += aa case Attempt.Failure(err) => return Attempt.failure(err.pushContext(buf.size.toString)) } } Attempt.successful(buf.reduce(_ ++ delimiter ++ _)) } /** * Repeatedly decodes values of type `A`, separated by `delimiter`, from the specified vector and * returns a collection of the specified type. * Terminates when no more bits are available in the vector. Exits upon first decoding error. */ final def decode[F[_], A](dec: Decoder[A], delimiter: BitVector)(buffer: BitVector)(implicit cbf: collection.generic.CanBuildFrom[F[A], A, F[A]]): Attempt[DecodeResult[F[A]]] = { val bldr = cbf() var remaining = buffer var next = BitVector.empty var count = 0 var error: Option[Err] = None while (remaining.nonEmpty) { buffer.indexOfSlice(delimiter) match { case -1 => next = remaining remaining = BitVector.empty case i => next = remaining.take(i) remaining = remaining.drop(i + delimiter.size) } dec.decode(remaining) match { case Attempt.Successful(DecodeResult(value, rest)) => bldr += value count += 1 remaining = rest case Attempt.Failure(err) => error = Some(err.pushContext(count.toString)) remaining = BitVector.empty } } Attempt.fromErrOption(error, DecodeResult(bldr.result, remaining)) } } private[codecs] class VectorDelimitedCodec[A](delimiter: BitVector, codec: Codec[A]) extends Codec[Vector[A]] { def encode(value: Vector[A]): Attempt[BitVector] = DelimitedCodec.encode(codec, delimiter)(value) def sizeBound: SizeBound = SizeBound.unknown def decode(bits: BitVector): Attempt[DecodeResult[Vector[A]]] = DelimitedCodec.decode[Vector, A](codec, delimiter)(bits) } private[codecs] class ListDelimitedCodec[A](delimiter: BitVector, codec: Codec[A]) extends Codec[List[A]] { def encode(value: List[A]): Attempt[BitVector] = DelimitedCodec.encode(codec, delimiter)(value) def sizeBound: SizeBound = SizeBound.unknown def decode(bits: BitVector): Attempt[DecodeResult[List[A]]] = DelimitedCodec.decode[List, A](codec, delimiter)(bits) }