optimization: ise varint on field counter for extendable format (it's rare for a struct to have so many fields so smartint will be better).
This commit is contained in:
parent
e556d4bc3d
commit
149a0e1850
@ -22,6 +22,11 @@ interface DataSink {
|
|||||||
fun writeBytes(data: ByteArray) {
|
fun writeBytes(data: ByteArray) {
|
||||||
for(d in data) writeByte(d)
|
for(d in data) writeByte(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun writeVarUInt(value: UInt) { Varint.encodeUnsigned(value.toULong())}
|
||||||
|
fun writeVarInt(value: UInt) { Varint.encodeSigned(value.toLong())}
|
||||||
|
fun writeSmartUInt(value: UInt) { Smartint.encodeUnsigned(value.toULong())}
|
||||||
|
fun writeSmartInt(value: UInt) { Smartint.encodeSigned(value.toLong())}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T:Any>DataSink.writeNumber(value: T) {
|
inline fun <reified T:Any>DataSink.writeNumber(value: T) {
|
||||||
|
@ -34,6 +34,14 @@ interface DataSource {
|
|||||||
|
|
||||||
fun readFloat() = Float.fromBits(readI32()).toFloat()
|
fun readFloat() = Float.fromBits(readI32()).toFloat()
|
||||||
|
|
||||||
|
fun readSmartUInt(): UInt = Smartint.decodeUnsigned(this).toUInt()
|
||||||
|
fun readSmartInt(): Int = Smartint.decodeSigned(this).toInt()
|
||||||
|
|
||||||
|
fun readVarUInt(): UInt = Varint.decodeUnsigned(this).toUInt()
|
||||||
|
fun readVarInt(): Int = Varint.decodeSigned(this).toInt()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ByteArray.toDataSource(): DataSource =
|
fun ByteArray.toDataSource(): DataSource =
|
||||||
|
@ -59,8 +59,8 @@ class BipackDecoder(val input: DataSource, var elementsCount: Int = 0,val isColl
|
|||||||
// CRC-calculating one, and the fields below are CRC protected too:
|
// CRC-calculating one, and the fields below are CRC protected too:
|
||||||
var count = descriptor.elementsCount
|
var count = descriptor.elementsCount
|
||||||
for (a in descriptor.annotations) {
|
for (a in descriptor.annotations) {
|
||||||
if (a is ExtendableFormat)
|
if (a is Extendable)
|
||||||
count = source.readNumber<UInt>().toInt()
|
count = source.readSmartUInt().toInt()
|
||||||
else if (a is Framed) {
|
else if (a is Framed) {
|
||||||
val code = CRC.crc32(descriptor.serialName.encodeToByteArray())
|
val code = CRC.crc32(descriptor.serialName.encodeToByteArray())
|
||||||
// if we fail to read CRC, it is IO error, so DataSource.EndOfData will be
|
// if we fail to read CRC, it is IO error, so DataSource.EndOfData will be
|
||||||
|
@ -72,8 +72,8 @@ class BipackEncoder(val output: DataSink) : AbstractEncoder() {
|
|||||||
sink.writeU32(
|
sink.writeU32(
|
||||||
CRC.crc32(descriptor.serialName.encodeToByteArray())
|
CRC.crc32(descriptor.serialName.encodeToByteArray())
|
||||||
)
|
)
|
||||||
} else if (a is ExtendableFormat) {
|
} else if (a is Extendable) {
|
||||||
sink.writeNumber(descriptor.elementsCount.toUInt())
|
sink.writeSmartUInt(descriptor.elementsCount.toUInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BipackEncoder(sink)
|
return BipackEncoder(sink)
|
||||||
|
@ -15,7 +15,7 @@ import kotlinx.serialization.SerialInfo
|
|||||||
*/
|
*/
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
@SerialInfo
|
@SerialInfo
|
||||||
annotation class ExtendableFormat
|
annotation class Extendable
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,7 +29,7 @@ annotation class Framed
|
|||||||
/**
|
/**
|
||||||
* Allow to CRC-protect structures (we suppose to use it with classes only). After the
|
* Allow to CRC-protect structures (we suppose to use it with classes only). After the
|
||||||
* data block its CRC32 will be written and checked. It is memory-wise: it calculates CRC
|
* data block its CRC32 will be written and checked. It is memory-wise: it calculates CRC
|
||||||
* on the fly without buffering the data. If used with [Framed] and [ExtendableFormat] the extra
|
* on the fly without buffering the data. If used with [Framed] and [Extendable] the extra
|
||||||
* data is protected too.
|
* data is protected too.
|
||||||
*
|
*
|
||||||
* __Common pitfalls__. When unpacking corrupted data protected this way, the not only [InvalidFrameCRCException]
|
* __Common pitfalls__. When unpacking corrupted data protected this way, the not only [InvalidFrameCRCException]
|
||||||
|
@ -11,11 +11,11 @@ import kotlin.test.*
|
|||||||
data class Foobar1N(val bar: Int, val foo: Int = 117)
|
data class Foobar1N(val bar: Int, val foo: Int = 117)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ExtendableFormat
|
@Extendable
|
||||||
data class Foobar1(val bar: Int, val foo: Int = 117)
|
data class Foobar1(val bar: Int, val foo: Int = 117)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ExtendableFormat
|
@Extendable
|
||||||
@SerialName("bipack.Foobar1")
|
@SerialName("bipack.Foobar1")
|
||||||
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)
|
||||||
|
|
||||||
@ -30,12 +30,12 @@ data class FoobarF2(val bar: Int, val foo: Int, val other: Int = -1)
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Framed
|
@Framed
|
||||||
@ExtendableFormat
|
@Extendable
|
||||||
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
|
@Serializable
|
||||||
@Framed
|
@Framed
|
||||||
@ExtendableFormat
|
@Extendable
|
||||||
@CrcProtected()
|
@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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user