refs #35 refac to get caching out of Obj; it is decoder/encoder matter now

This commit is contained in:
Sergey Chernov 2025-07-19 14:19:50 +03:00
parent 405ff2ec2b
commit 20181c63a1
4 changed files with 70 additions and 68 deletions

View File

@ -84,9 +84,9 @@ data class ObjString(val value: String) : Obj() {
override suspend fun lynonType(): LynonType = LynonType.String override suspend fun lynonType(): LynonType = LynonType.String
override suspend fun serialize(scope: Scope, encoder: LynonEncoder, lynonType: LynonType?) { override suspend fun serialize(scope: Scope, encoder: LynonEncoder, lynonType: LynonType?) {
if( lynonType == null ) // if( lynonType == null )
encoder.encodeCached(this) { encoder.encodeBinaryData(value.encodeToByteArray()) } // encoder.encodeCached(this) { encoder.encodeBinaryData(value.encodeToByteArray()) }
else // else
encoder.encodeBinaryData(value.encodeToByteArray()) encoder.encodeBinaryData(value.encodeToByteArray())
} }
@ -94,11 +94,12 @@ data class ObjString(val value: String) : Obj() {
companion object { companion object {
val type = object : ObjClass("String") { val type = object : ObjClass("String") {
override suspend fun deserialize(scope: Scope, decoder: LynonDecoder, lynonType: LynonType?): Obj = override suspend fun deserialize(scope: Scope, decoder: LynonDecoder, lynonType: LynonType?): Obj =
if( lynonType == null ) // if( lynonType == null )
decoder.decodeCached { // decoder.decodeCached {
ObjString(decoder.unpackBinaryData().decodeToString()) // ObjString(decoder.unpackBinaryData().decodeToString())
} // }
else ObjString(decoder.unpackBinaryData().decodeToString()) // else
ObjString(decoder.unpackBinaryData().decodeToString())
}.apply { }.apply {
addFn("toInt") { addFn("toInt") {
ObjInt(thisAs<ObjString>().value.toLong()) ObjInt(thisAs<ObjString>().value.toLong())

View File

@ -39,9 +39,8 @@ open class LynonDecoder(val bin: BitInput, val settings: LynonSettings = LynonSe
type.objClass.deserialize(scope, this, type) type.objClass.deserialize(scope, this, type)
} }
// todo: rewrite/remove? suspend fun decodeObject(scope: Scope, type: ObjClass): Obj {
suspend fun unpackObject(scope: Scope, type: ObjClass): Obj { return decodeCached { type.deserialize(scope, this, null) }
return type.deserialize(scope, this, null)
} }
fun unpackBinaryData(): ByteArray = bin.decompress() fun unpackBinaryData(): ByteArray = bin.decompress()

View File

@ -65,8 +65,10 @@ open class LynonEncoder(val bout: BitOutput, val settings: LynonSettings = Lynon
bout.putBits(type.ordinal.toULong(), 4) bout.putBits(type.ordinal.toULong(), 4)
} }
suspend fun encodeObj(scope: Scope, obj: Obj) { suspend fun encodeObject(scope: Scope, obj: Obj) {
encodeCached(obj) {
obj.serialize(scope, this, null) obj.serialize(scope, this, null)
}
} }
fun encodeBinaryData(data: ByteArray) { fun encodeBinaryData(data: ByteArray) {

View File

@ -150,28 +150,28 @@ class LynonTests {
val encoder = LynonEncoder(bout) val encoder = LynonEncoder(bout)
val s = "Hello, World!".toObj() val s = "Hello, World!".toObj()
val scope = Scope() val scope = Scope()
encoder.encodeObj(scope, s) // 1 encoder.encodeObject(scope, s) // 1
encoder.encodeObj(scope, s) encoder.encodeObject(scope, s)
encoder.encodeObj(scope, s) encoder.encodeObject(scope, s)
encoder.encodeObj(scope, s) encoder.encodeObject(scope, s)
encoder.encodeObj(scope, s) encoder.encodeObject(scope, s)
encoder.encodeObj(scope, s) encoder.encodeObject(scope, s)
encoder.encodeObj(scope, s) encoder.encodeObject(scope, s)
encoder.encodeObj(scope, s) // 8 encoder.encodeObject(scope, s) // 8
val decoder = LynonDecoder(MemoryBitInput(bout)) val decoder = LynonDecoder(MemoryBitInput(bout))
val s1 = decoder.unpackObject(scope, ObjString.type) // 1 val s1 = decoder.decodeObject(scope, ObjString.type) // 1
assertEquals(s, s1) assertEquals(s, s1)
assertNotSame(s, s1) assertNotSame(s, s1)
val s2 = decoder.unpackObject(scope, ObjString.type) val s2 = decoder.decodeObject(scope, ObjString.type)
assertEquals(s, s2) assertEquals(s, s2)
assertSame(s1, s2) assertSame(s1, s2)
assertSame(s1, decoder.unpackObject(scope, ObjString.type)) assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type)) assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type)) assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type)) assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type)) assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type)) // 8 assertSame(s1, decoder.decodeObject(scope, ObjString.type)) // 8
} }
@Test @Test
@ -182,12 +182,12 @@ class LynonTests {
val encoder = LynonPacker() val encoder = LynonPacker()
val scope = Scope() val scope = Scope()
for (s in source) { for (s in source) {
encoder.encodeObj(scope, s) encoder.encodeObject(scope, s)
} }
val decoder = LynonUnpacker(encoder) val decoder = LynonUnpacker(encoder)
val restored = mutableListOf<Obj>() val restored = mutableListOf<Obj>()
for (i in source.indices) { for (i in source.indices) {
restored.add(decoder.unpackObject(scope, ObjString.type)) restored.add(decoder.decodeObject(scope, ObjString.type))
} }
assertEquals(restored, source) assertEquals(restored, source)
} }
@ -196,58 +196,58 @@ class LynonTests {
fun testUnpackBoolean() = runTest { fun testUnpackBoolean() = runTest {
val scope = Scope() val scope = Scope()
val decoder = LynonUnpacker(LynonPacker().apply { val decoder = LynonUnpacker(LynonPacker().apply {
encodeObj(scope, ObjBool(true)) encodeObject(scope, ObjBool(true))
encodeObj(scope, ObjBool(false)) encodeObject(scope, ObjBool(false))
encodeObj(scope, ObjBool(true)) encodeObject(scope, ObjBool(true))
encodeObj(scope, ObjBool(true)) encodeObject(scope, ObjBool(true))
}) })
assertEquals(ObjTrue, decoder.unpackObject(scope, ObjBool.type)) assertEquals(ObjTrue, decoder.decodeObject(scope, ObjBool.type))
assertEquals(ObjFalse, decoder.unpackObject(scope, ObjBool.type)) assertEquals(ObjFalse, decoder.decodeObject(scope, ObjBool.type))
assertEquals(ObjTrue, decoder.unpackObject(scope, ObjBool.type)) assertEquals(ObjTrue, decoder.decodeObject(scope, ObjBool.type))
assertEquals(ObjTrue, decoder.unpackObject(scope, ObjBool.type)) assertEquals(ObjTrue, decoder.decodeObject(scope, ObjBool.type))
} }
@Test @Test
fun testUnpackReal() = runTest { fun testUnpackReal() = runTest {
val scope = Scope() val scope = Scope()
val decoder = LynonUnpacker(LynonPacker().apply { val decoder = LynonUnpacker(LynonPacker().apply {
encodeObj(scope, ObjReal(-Math.PI)) encodeObject(scope, ObjReal(-Math.PI))
encodeObj(scope, ObjReal(Math.PI)) encodeObject(scope, ObjReal(Math.PI))
encodeObj(scope, ObjReal(-Math.PI)) encodeObject(scope, ObjReal(-Math.PI))
encodeObj(scope, ObjReal(Math.PI)) encodeObject(scope, ObjReal(Math.PI))
encodeObj(scope, ObjReal(Double.NaN)) encodeObject(scope, ObjReal(Double.NaN))
encodeObj(scope, ObjReal(Double.NEGATIVE_INFINITY)) encodeObject(scope, ObjReal(Double.NEGATIVE_INFINITY))
encodeObj(scope, ObjReal(Double.POSITIVE_INFINITY)) encodeObject(scope, ObjReal(Double.POSITIVE_INFINITY))
encodeObj(scope, ObjReal(Double.MIN_VALUE)) encodeObject(scope, ObjReal(Double.MIN_VALUE))
encodeObj(scope, ObjReal(Double.MAX_VALUE)) encodeObject(scope, ObjReal(Double.MAX_VALUE))
}) })
assertEquals(ObjReal(-Math.PI), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(-Math.PI), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Math.PI), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(Math.PI), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(-Math.PI), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(-Math.PI), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Math.PI), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(Math.PI), decoder.decodeObject(scope, ObjReal.type))
assert((decoder.unpackObject(scope, ObjReal.type)).toDouble().isNaN()) assert((decoder.decodeObject(scope, ObjReal.type)).toDouble().isNaN())
assertEquals(ObjReal(Double.NEGATIVE_INFINITY), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(Double.NEGATIVE_INFINITY), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.POSITIVE_INFINITY), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(Double.POSITIVE_INFINITY), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.MIN_VALUE), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(Double.MIN_VALUE), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.MAX_VALUE), decoder.unpackObject(scope, ObjReal.type)) assertEquals(ObjReal(Double.MAX_VALUE), decoder.decodeObject(scope, ObjReal.type))
} }
@Test @Test
fun testUnpackInt() = runTest { fun testUnpackInt() = runTest {
val scope = Scope() val scope = Scope()
val decoder = LynonUnpacker(LynonPacker().apply { val decoder = LynonUnpacker(LynonPacker().apply {
encodeObj(scope, ObjInt(0)) encodeObject(scope, ObjInt(0))
encodeObj(scope, ObjInt(-1)) encodeObject(scope, ObjInt(-1))
encodeObj(scope, ObjInt(23)) encodeObject(scope, ObjInt(23))
encodeObj(scope, ObjInt(Long.MIN_VALUE)) encodeObject(scope, ObjInt(Long.MIN_VALUE))
encodeObj(scope, ObjInt(Long.MAX_VALUE)) encodeObject(scope, ObjInt(Long.MAX_VALUE))
encodeObj(scope, ObjInt(Long.MAX_VALUE)) encodeObject(scope, ObjInt(Long.MAX_VALUE))
}) })
assertEquals(ObjInt(0), decoder.unpackObject(scope, ObjInt.type)) assertEquals(ObjInt(0), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(-1), decoder.unpackObject(scope, ObjInt.type)) assertEquals(ObjInt(-1), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(23), decoder.unpackObject(scope, ObjInt.type)) assertEquals(ObjInt(23), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MIN_VALUE), decoder.unpackObject(scope, ObjInt.type)) assertEquals(ObjInt(Long.MIN_VALUE), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MAX_VALUE), decoder.unpackObject(scope, ObjInt.type)) assertEquals(ObjInt(Long.MAX_VALUE), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MAX_VALUE), decoder.unpackObject(scope, ObjInt.type)) assertEquals(ObjInt(Long.MAX_VALUE), decoder.decodeObject(scope, ObjInt.type))
} }
@Test @Test