mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-06 05:30:21 +00:00
Create new packet codec QuantizedDoubleCodec
This commit is contained in:
parent
4a4f0b4466
commit
d2b6a8c451
3 changed files with 98 additions and 0 deletions
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2016 PSForever.net to present
|
||||
package net.psforever.newcodecs
|
||||
|
||||
import scodec.{ Attempt, Codec, DecodeResult, Err, SizeBound }
|
||||
import scodec.bits.{ BitVector, ByteOrdering }
|
||||
|
||||
final class QuantizedDoubleCodec(min: Double, max: Double, bits: Int) extends Codec[Double] {
|
||||
|
||||
require(bits > 0 && bits <= 32, "bits must be in range [1, 32]")
|
||||
|
||||
private val bitsL = bits.toLong
|
||||
|
||||
private def description = s"$bits-bit q_double [$min, $max]"
|
||||
|
||||
override def sizeBound = SizeBound.exact(bitsL)
|
||||
|
||||
def QuantizeDouble(value : Double) : Int = {
|
||||
val range : Double = max - min;
|
||||
|
||||
if (range == 0.0)
|
||||
return 0
|
||||
|
||||
val bit_max : Int = 1 << bits;
|
||||
val rounded_quantized : Int = math.floor((value - min) * bit_max.toDouble / range + 0.5).toInt
|
||||
|
||||
if (rounded_quantized < 0)
|
||||
return 0
|
||||
|
||||
if (rounded_quantized > bit_max - 1)
|
||||
return (bit_max - 1)
|
||||
|
||||
return rounded_quantized
|
||||
}
|
||||
|
||||
def UnquantizeDouble(value : Int) : Double = {
|
||||
return ((max - min) * value.toDouble / (1 << bitsL).toDouble + min)
|
||||
}
|
||||
|
||||
override def encode(value: Double) = {
|
||||
if (value == 0.0)
|
||||
Attempt.successful(BitVector.fromInt(0, bits))
|
||||
else
|
||||
Attempt.successful(BitVector.fromInt(QuantizeDouble(value), bits, ByteOrdering.LittleEndian))
|
||||
}
|
||||
|
||||
override def decode(buffer: BitVector) = {
|
||||
if (buffer.sizeGreaterThanOrEqual(bitsL))
|
||||
Attempt.successful(DecodeResult(UnquantizeDouble(buffer.take(bitsL).toInt(false, ByteOrdering.LittleEndian)), buffer.drop(bitsL)))
|
||||
else
|
||||
Attempt.failure(Err.insufficientBits(bitsL, buffer.size))
|
||||
}
|
||||
|
||||
override def toString = description
|
||||
}
|
||||
10
common/src/main/scala/net/psforever/newcodecs/package.scala
Normal file
10
common/src/main/scala/net/psforever/newcodecs/package.scala
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2016 PSForever.net to present
|
||||
package net.psforever.newcodecs
|
||||
|
||||
import scodec.Codec
|
||||
|
||||
package object newcodecs {
|
||||
|
||||
def q_double(min: Double, max: Double, bits: Int): Codec[Double] = new QuantizedDoubleCodec(min, max, bits)
|
||||
|
||||
}
|
||||
34
common/src/test/scala/CodecTest.scala
Normal file
34
common/src/test/scala/CodecTest.scala
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2016 PSForever.net to present
|
||||
import org.specs2.mutable._
|
||||
import net.psforever.newcodecs._
|
||||
import scodec.bits._
|
||||
|
||||
class CodecTest extends Specification {
|
||||
|
||||
"QuantizedDoubleCodec" should {
|
||||
val string_1 = hex"6E2D70"
|
||||
val string_2 = hex"000000"
|
||||
val string_3 = hex"B616"
|
||||
val string_4 = hex"857C"
|
||||
val string_5 = hex"5380"
|
||||
val string_6 = hex"FFFC"
|
||||
|
||||
"decode" in {
|
||||
newcodecs.q_double(0.0, 8192.0, 20).decode(string_1.bits).require.value mustEqual 3674.859375
|
||||
newcodecs.q_double(0.0, 8192.0, 20).decode(string_2.bits).require.value mustEqual 0.0
|
||||
newcodecs.q_double(0.0, 1024.0, 16).decode(string_3.bits).require.value mustEqual 90.84375
|
||||
newcodecs.q_double(-256.0, 256.0, 14).decode(string_4.bits).require.value mustEqual -3.84375
|
||||
newcodecs.q_double(-256.0, 256.0, 14).decode(string_5.bits).require.value mustEqual 2.59375
|
||||
newcodecs.q_double(-256.0, 256.0, 14).decode(string_6.bits).require.value mustEqual 255.96875
|
||||
}
|
||||
|
||||
"encode" in {
|
||||
newcodecs.q_double(0.0, 8192.0, 20).encode(3674.859375).require.bytes mustEqual string_1
|
||||
newcodecs.q_double(0.0, 8192.0, 20).encode(-1.23).require.bytes mustEqual string_2
|
||||
newcodecs.q_double(0.0, 1024.0, 16).encode(90.84375).require.bytes mustEqual string_3
|
||||
newcodecs.q_double(-256.0, 256.0, 14).encode(-3.84375).require.bytes mustEqual string_4
|
||||
newcodecs.q_double(-256.0, 256.0, 14).encode(2.59375).require.bytes mustEqual string_5
|
||||
newcodecs.q_double(-256.0, 256.0, 14).encode(257.0).require.bytes mustEqual string_6
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue