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) {
|
||||
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) {
|
||||
|
@ -34,6 +34,14 @@ interface DataSource {
|
||||
|
||||
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 =
|
||||
|
@ -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:
|
||||
var count = descriptor.elementsCount
|
||||
for (a in descriptor.annotations) {
|
||||
if (a is ExtendableFormat)
|
||||
count = source.readNumber<UInt>().toInt()
|
||||
if (a is Extendable)
|
||||
count = source.readSmartUInt().toInt()
|
||||
else if (a is Framed) {
|
||||
val code = CRC.crc32(descriptor.serialName.encodeToByteArray())
|
||||
// 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(
|
||||
CRC.crc32(descriptor.serialName.encodeToByteArray())
|
||||
)
|
||||
} else if (a is ExtendableFormat) {
|
||||
sink.writeNumber(descriptor.elementsCount.toUInt())
|
||||
} else if (a is Extendable) {
|
||||
sink.writeSmartUInt(descriptor.elementsCount.toUInt())
|
||||
}
|
||||
}
|
||||
return BipackEncoder(sink)
|
||||
|
@ -15,7 +15,7 @@ import kotlinx.serialization.SerialInfo
|
||||
*/
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@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
|
||||
* 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.
|
||||
*
|
||||
* __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)
|
||||
|
||||
@Serializable
|
||||
@ExtendableFormat
|
||||
@Extendable
|
||||
data class Foobar1(val bar: Int, val foo: Int = 117)
|
||||
|
||||
@Serializable
|
||||
@ExtendableFormat
|
||||
@Extendable
|
||||
@SerialName("bipack.Foobar1")
|
||||
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
|
||||
@Framed
|
||||
@ExtendableFormat
|
||||
@Extendable
|
||||
data class FoobarF3(val bar: Int, val foo: Int, val other: Int = -1)
|
||||
|
||||
@Serializable
|
||||
@Framed
|
||||
@ExtendableFormat
|
||||
@Extendable
|
||||
@CrcProtected()
|
||||
data class FoobarFP1(val bar: Int, val foo: Int, val other: Int = -1)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user