diff --git a/src/commonMain/kotlin/net.sergeych.bintools/DataSource.kt b/src/commonMain/kotlin/net.sergeych.bintools/DataSource.kt index fd8fde4..cb02731 100644 --- a/src/commonMain/kotlin/net.sergeych.bintools/DataSource.kt +++ b/src/commonMain/kotlin/net.sergeych.bintools/DataSource.kt @@ -13,7 +13,7 @@ interface DataSource { /** * Exception that implementations must throw on end of data */ - class EndOfData: Exception("no more data available") + class EndOfData : Exception("no more data available") fun readByte(): Byte @@ -32,6 +32,7 @@ interface DataSource { fun readI64(): Long = bytesToLong(readBytes(8)) fun readDouble() = Double.fromBits(readI64()) + fun readFloat() = Float.fromBits(readI32()) } @@ -42,11 +43,11 @@ fun ByteArray.toDataSource(): DataSource = private set override fun readByte(): Byte = - if( position < size ) this@toDataSource[position++] - else throw DataSource.EndOfData() + if (position < size) this@toDataSource[position++] + else throw DataSource.EndOfData() } -inline fun DataSource.readNumber(): T = when(typeOf()) { +inline fun DataSource.readNumber(): T = when (typeOf()) { typeOf() -> readDouble() as T typeOf() -> readFloat() as T else -> Smartint.decode(this) diff --git a/src/commonMain/kotlin/net.sergeych.bintools/simple_codecs.kt b/src/commonMain/kotlin/net.sergeych.bintools/simple_codecs.kt index 656d481..ae0c76e 100644 --- a/src/commonMain/kotlin/net.sergeych.bintools/simple_codecs.kt +++ b/src/commonMain/kotlin/net.sergeych.bintools/simple_codecs.kt @@ -13,7 +13,7 @@ fun longToBytes(value: Long): ByteArray { fun intToBytes(value: Int): ByteArray { var l = value - val result = ByteArray(8) + val result = ByteArray(4) for (i in 3 downTo 0) { result[i] = (l and 0xFF).toByte() l = l shr 8 diff --git a/src/commonMain/kotlin/net.sergeych.bipack/BipackDecoder.kt b/src/commonMain/kotlin/net.sergeych.bipack/BipackDecoder.kt index 6bf28b0..8d52e9a 100644 --- a/src/commonMain/kotlin/net.sergeych.bipack/BipackDecoder.kt +++ b/src/commonMain/kotlin/net.sergeych.bipack/BipackDecoder.kt @@ -77,6 +77,7 @@ class BipackDecoder(val input: DataSource, var elementsCount: Int = 0) : Abstrac super.endStructure(descriptor) } + override fun decodeSequentially(): Boolean = true override fun decodeCollectionSize(descriptor: SerialDescriptor): Int = input.readNumber().toInt().also { elementsCount = it @@ -96,3 +97,5 @@ class BipackDecoder(val input: DataSource, var elementsCount: Int = 0) : Abstrac decode(source.toDataSource(), serializer()) } } + +inline fun ByteArray.decodeFromBipack() = BipackDecoder.decode(this) diff --git a/src/commonMain/kotlin/net.sergeych.bipack/BipackEncoder.kt b/src/commonMain/kotlin/net.sergeych.bipack/BipackEncoder.kt index e61db38..ed4576a 100644 --- a/src/commonMain/kotlin/net.sergeych.bipack/BipackEncoder.kt +++ b/src/commonMain/kotlin/net.sergeych.bipack/BipackEncoder.kt @@ -18,9 +18,7 @@ class BipackEncoder(var output: DataSink) : AbstractEncoder() { override fun encodeElement(descriptor: SerialDescriptor, index: Int): Boolean { return super.encodeElement(descriptor, index).also { - println(">> $index: ${descriptor.getElementAnnotations(index)}") nextIsUnsigned = descriptor.getElementAnnotations(index).any { it is Unsigned } - println("${descriptor.getElementDescriptor(index)} -> $nextIsUnsigned") } } // fun isUnsigned(): Boolean { @@ -37,7 +35,6 @@ class BipackEncoder(var output: DataSink) : AbstractEncoder() { else output.writeNumber(value.toInt()) override fun encodeInt(value: Int) { - println("EncodeInt: $value / $nextIsUnsigned") if (nextIsUnsigned) output.writeNumber(value.toUInt()) else diff --git a/src/commonTest/kotlin/bipack/BipackEncoderTest.kt b/src/commonTest/kotlin/bipack/BipackEncoderTest.kt index 091d107..43bb310 100644 --- a/src/commonTest/kotlin/bipack/BipackEncoderTest.kt +++ b/src/commonTest/kotlin/bipack/BipackEncoderTest.kt @@ -16,7 +16,8 @@ data class Foobar1(val bar: Int, val foo: Int = 117) @Serializable @ExtendableFormat -data class Foobar2(val bar: Int, val foo: Int,val other: Int = -1) +data class Foobar2(val bar: Int, val foo: Int, val other: Int = -1) + @Serializable @Framed @ExtendableFormat @@ -26,17 +27,18 @@ data class FoobarF1(val bar: Int, val foo: Int = 117) @Framed @ExtendableFormat @SerialName("bipack.FoobarF1") -data class FoobarF2(val bar: Int, val foo: Int,val other: Int = -1) +data class FoobarF2(val bar: Int, val foo: Int, val other: Int = -1) + @Serializable @Framed @ExtendableFormat -data class FoobarF3(val bar: Int, val foo: Int,val other: Int = -1) +data class FoobarF3(val bar: Int, val foo: Int, val other: Int = -1) @Serializable @Framed @ExtendableFormat @CrcProtected() -data class FoobarFP1(val bar: Int, val foo: Int,val other: Int = -1) +data class FoobarFP1(val bar: Int, val foo: Int, val other: Int = -1) class BipackEncoderTest { @@ -61,6 +63,7 @@ class BipackEncoderTest { assertEquals(-1, c.other) assertEquals(a.bar, c.bar) } + @Test fun encodeFramed() { val a = FoobarF1(42)//, "bum") @@ -103,13 +106,15 @@ class BipackEncoderTest { val u: UInt, @Unsigned val i: Int, - val k: UInt = 3u) + val k: UInt = 3u, + ) + @Test fun testByteArray() { // val z = Foobar1(42)//, "bum") // println(BipackEncoder.encode(z).toDump()) - val x = byteArrayOf(1,2,3) + val x = byteArrayOf(1, 2, 3) var d = BipackEncoder.encode(x) println(d.toDump()) assertEquals(0x0c, d[0]) @@ -128,4 +133,54 @@ class BipackEncoderTest { assertEquals(f, BipackDecoder.decode(d)) } + + @Serializable + data class Types1( + val i: Int = 7, + val f: Float = 1f/3f, + val d: Double = 1.0/3.0, + val b: Boolean = true, + val s: String = "жёпа", + val ba: ByteArray = byteArrayOf(1,2,3), + val ch: Char = 'Ы', + ) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as Types1 + + if (i != other.i) return false + if (f != other.f) return false + if (d != other.d) return false + if (b != other.b) return false + if (s != other.s) return false + if (!ba.contentEquals(other.ba)) return false + if (ch != other.ch) return false + + return true + } + + override fun hashCode(): Int { + var result = i + result = 31 * result + f.hashCode() + result = 31 * result + d.hashCode() + result = 31 * result + b.hashCode() + result = 31 * result + s.hashCode() + result = 31 * result + ba.contentHashCode() + result = 31 * result + ch.hashCode() + return result + } + } + + @Test + fun testTypes() { +// val t1 = Types1(10, 1.0f / 10.0f, 1.0 / 10.0, true, "жесть", byteArrayOf(1, 2, 3), 'Ы') + val t1 = Types1(f=17f/7f) + val d = BipackEncoder.encode(t1) +// println(d.toDump()) +// println(t1) +// println(d.decodeFromBipack()) + assertEquals(t1, d.decodeFromBipack()) + } } \ No newline at end of file