From d969993997f914afd6b84dc431edac7d2e86d25a Mon Sep 17 00:00:00 2001 From: sergeych Date: Fri, 11 Jul 2025 06:09:09 +0300 Subject: [PATCH] ref #35 bitwise pack/unpack for integers --- .../kotlin/net/sergeych/lynon/BitInput.kt | 10 ++++++++++ .../kotlin/net/sergeych/lynon/BitOutput.kt | 2 +- lynglib/src/jvmTest/kotlin/LynonTests.kt | 19 ++++++++++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitInput.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitInput.kt index 16e5fc3..f2f2ada 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitInput.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitInput.kt @@ -47,6 +47,10 @@ abstract class BitInput { return getBitsOrNull(count) ?: throw IllegalStateException("Unexpected end of stream") } + fun getBit(): Int { + return getBitOrNull() ?: throw IllegalStateException("Unexpected end of stream") + } + fun unpackUnsigned(): ULong { val tetrades = getBits(4).toInt() var result = 0UL @@ -57,5 +61,11 @@ abstract class BitInput { } return result } + + fun unpackSigned(): Long { + val isNegative = getBit() + val value = unpackUnsigned().toLong() + return if( isNegative == 1) -value else value + } } diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitOutput.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitOutput.kt index 4b94520..abed9b7 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitOutput.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lynon/BitOutput.kt @@ -45,7 +45,7 @@ abstract class BitOutput { } @Suppress("unused") - fun putSigned(value: Long) { + fun packSigned(value: Long) { if( value < 0 ) { putBit(1) packUnsigned((-value).toULong()) diff --git a/lynglib/src/jvmTest/kotlin/LynonTests.kt b/lynglib/src/jvmTest/kotlin/LynonTests.kt index 685153d..f8be460 100644 --- a/lynglib/src/jvmTest/kotlin/LynonTests.kt +++ b/lynglib/src/jvmTest/kotlin/LynonTests.kt @@ -37,13 +37,26 @@ class LynonTests { } @Test - fun testPackInteger() { + fun testUnsignedPackInteger() { val bout = MemoryBitOutput() - bout.packUnsigned(147179UL) + bout.packUnsigned(1471792UL) bout.close() println(bout.toUByteArray().toDump()) val bin = MemoryBitInput(bout.toUByteArray()) - assertEquals(147179UL, bin.unpackUnsigned()) + assertEquals(1471792UL, bin.unpackUnsigned()) + } + + @Test + fun testSignedPackInteger() { + val bout = MemoryBitOutput() + bout.packSigned(-1471792L) + bout.packSigned(1471792L) +// bout.packSigned(147179L) + bout.close() + println(bout.toUByteArray().toDump()) + val bin = MemoryBitInput(bout.toUByteArray()) + assertEquals(-1471792L, bin.unpackSigned()) + assertEquals(1471792L, bin.unpackSigned()) } } \ No newline at end of file