All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scodec.codecs.VarPackedDecimalCodec.scala Maven / Gradle / Ivy

There is a newer version: 1.11.3
Show newest version
package scodec
package codecs

import scodec.bits.BitVector

import scala.annotation.tailrec


private [codecs] object VarPackedDecimalCodec extends Codec[Long] {
  override def sizeBound = SizeBound.bounded(1L, 9L)

  def encode (i: Long): Attempt[BitVector] = {
    if (i < 0) Attempt.failure(Err("VarPackedDecimal cannot encode negative longs"))
    else runEncoding(i, Attempt.successful(BitVector.empty))
  }

  def decode (buffer: BitVector): Attempt[DecodeResult[Long]] = runDecoding(buffer, 0L)

  @tailrec
  private def runDecoding (buffer: BitVector, value: Long): Attempt[DecodeResult[Long]] = {
    if (buffer.isEmpty) Attempt.successful(DecodeResult(value, buffer))
    else if (buffer.sizeLessThan(4)) Attempt.failure(Err.InsufficientBits(4L, buffer.size, Nil))
    else runDecoding(buffer.drop(4), value * 10 + buffer.take(4).toInt(false))
  }

  @tailrec
  private def runEncoding (value: Long, acc: Attempt[BitVector]): Attempt[BitVector] = {
    if (value < 10L) uint(4).encode(value.toInt).flatMap(x => acc.map(x ++ _))
    else runEncoding(value / 10, uint(4).encode((value % 10).toInt).flatMap(x => acc.map(x ++ _)))
  }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy