0.0.7: oendOfData support, correct decoding with default values past it

This commit is contained in:
Sergey Chernov 2023-12-24 00:39:38 +03:00
parent 06f8bc7ef2
commit 47b450c597
5 changed files with 34 additions and 5 deletions

View File

@ -8,7 +8,7 @@ plugins {
val serialization_version = "1.3.4" val serialization_version = "1.3.4"
group = "net.sergeych" group = "net.sergeych"
version = "0.0.6" version = "0.0.7"
repositories { repositories {
mavenCentral() mavenCentral()

View File

@ -16,6 +16,12 @@ interface DataSource {
fun readByte(): Byte fun readByte(): Byte
/**
* true if there is no more data available and next read operation will surely
* throw EndOfData. Can return null if it is impossible to determine (for some
* async sources)
*/
fun isEnd(): Boolean? = null
fun readUByte() = readByte().toUByte() fun readUByte() = readByte().toUByte()
@ -50,6 +56,9 @@ fun ByteArray.toDataSource(): DataSource =
var position = 0 var position = 0
private set private set
@Suppress("RedundantNullableReturnType")
override fun isEnd(): Boolean? = position == size
override fun readByte(): Byte = override fun readByte(): Byte =
if (position < size) this@toDataSource[position++] if (position < size) this@toDataSource[position++]
else throw DataSource.EndOfData() else throw DataSource.EndOfData()
@ -65,6 +74,9 @@ fun UByteArray.toDataSource(): DataSource =
var position = 0 var position = 0
private set private set
@Suppress("RedundantNullableReturnType")
override fun isEnd(): Boolean? = position == size
override fun readByte(): Byte = override fun readByte(): Byte =
if (position < size) this@toDataSource[position++].toByte() if (position < size) this@toDataSource[position++].toByte()
else throw DataSource.EndOfData() else throw DataSource.EndOfData()

View File

@ -57,7 +57,8 @@ class BipackDecoder(
override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readNumber<UInt>().toInt() override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readNumber<UInt>().toInt()
override fun decodeElementIndex(descriptor: SerialDescriptor): Int { override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
if (elementIndex >= elementsCount) return CompositeDecoder.DECODE_DONE if (elementIndex >= elementsCount || input.isEnd() == true )
return CompositeDecoder.DECODE_DONE
nextIsUnsigned = false nextIsUnsigned = false
for (a in descriptor.getElementAnnotations(elementIndex)) { for (a in descriptor.getElementAnnotations(elementIndex)) {
when (a) { when (a) {

View File

@ -4,9 +4,16 @@ import kotlinx.serialization.SerialInfo
/** /**
* If this annotation is presented in some @Serializable class definition, its instances * If this annotation is presented in some @Serializable class definition, its instances
* will be serialized with leading number of fields. This allows to extend class later * will be serialized with the leading number of fields. This allows extending class later
* providing new parameters __to the end of the class__ and _with default values__. * providing new parameters __to the end of the class__ and _with default values__.
* *
* __IMPORTANT NOTE__. Since version 0.0.7 it's been also possible to use default values
* for non-serialized fields after the end-of-data. If the source reports it correctly, e.g.
* [net.sergeych.bintools.DataSource.isEnd] returns true, the unset fields are initialized
* with default value. This approach ___is not working when the loading instance is not the last
* in the deciding array!___, still it is useful to decode isolated objects. We recommend to
* use [Extendable] where needed and possible.
*
* Whe deserializing such instances from previous version binaries, the new parameters * Whe deserializing such instances from previous version binaries, the new parameters
* will get default values. * will get default values.
* *

View File

@ -393,7 +393,16 @@ class BipackEncoderTest {
assertEquals(xv, yv) assertEquals(xv, yv)
println(xv) println(xv)
println(yv) println(yv)
}
@Test
fun testStrangeUnpack() {
@Serializable
data class SFoo(val code: Int,val s1: String?=null,val s2: String?=null)
val z = BipackEncoder.encode(117)
println(z.toDump())
val sf = BipackDecoder.decode<SFoo>(z)
println(sf)
}
} }
}