@@ -38,25 +38,87 @@ class EfficientBinaryFormat(
3838 return deserializer.deserialize(decoder)
3939 }
4040
41- class Encoder (override val serializersModule : SerializersModule ): AbstractEncoder() {
42- val byteBuffer = ByteWritingBuffer ()
43- override fun encodeBoolean (value : Boolean ) = byteBuffer.writeByte(if (value) 1 else 0 )
44- override fun encodeByte (value : Byte ) = byteBuffer.writeByte(value)
45- override fun encodeShort (value : Short ) = byteBuffer.writeShort(value)
46- override fun encodeInt (value : Int ) = byteBuffer.writeInt(value)
47- override fun encodeLong (value : Long ) = byteBuffer.writeLong(value)
48- override fun encodeFloat (value : Float ) = byteBuffer.writeFloat(value)
49- override fun encodeDouble (value : Double ) = byteBuffer.writeDouble(value)
50- override fun encodeChar (value : Char ) = byteBuffer.writeChar(value)
51- override fun encodeString (value : String ) = byteBuffer.writeString(value)
52- override fun encodeEnum (enumDescriptor : SerialDescriptor , index : Int ) = byteBuffer.writeInt(index)
41+ class Encoder (
42+ override val serializersModule : SerializersModule ,
43+ internal val byteBuffer : ByteWritingBuffer = ByteWritingBuffer (),
44+ elementsCount : Int = -1
45+ ): AbstractEncoder() {
46+ var lastWrittenIndex = - 1
47+ var currentIndex = - 1
48+ val notInStruct = elementsCount < 0
49+
50+ val pending : Array < (() -> Unit )? > = when {
51+ elementsCount <= 0 -> emptyArray()
52+ else -> arrayOfNulls(elementsCount)
53+ }
54+
55+ override fun encodeBoolean (value : Boolean ) = writeOrSuspend { byteBuffer.writeByte(if (value) 1 else 0 ) }
56+ override fun encodeByte (value : Byte ) = writeOrSuspend { byteBuffer.writeByte(value) }
57+ override fun encodeShort (value : Short ) = writeOrSuspend { byteBuffer.writeShort(value) }
58+ override fun encodeInt (value : Int ) = writeOrSuspend { byteBuffer.writeInt(value) }
59+ override fun encodeLong (value : Long ) = writeOrSuspend { byteBuffer.writeLong(value) }
60+ override fun encodeFloat (value : Float ) = writeOrSuspend { byteBuffer.writeFloat(value) }
61+ override fun encodeDouble (value : Double ) = writeOrSuspend { byteBuffer.writeDouble(value) }
62+ override fun encodeChar (value : Char ) = writeOrSuspend { byteBuffer.writeChar(value) }
63+ override fun encodeString (value : String ) = writeOrSuspend { byteBuffer.writeString(value) }
64+ override fun encodeEnum (enumDescriptor : SerialDescriptor , index : Int ) = writeOrSuspend {
65+ byteBuffer.writeInt(index)
66+ }
67+
68+ @ExperimentalSerializationApi
69+ override fun <T : Any > encodeNullableSerializableValue (
70+ serializer : SerializationStrategy <T >,
71+ value : T ?
72+ ) {
73+ writeOrSuspend {
74+ super .encodeNullableSerializableValue(serializer, value)
75+ }
76+ }
77+
78+ override fun <T > encodeSerializableValue (serializer : SerializationStrategy <T >, value : T ) {
79+ writeOrSuspend {
80+ super .encodeSerializableValue(serializer, value)
81+ }
82+ }
83+
84+ @Suppress(" NOTHING_TO_INLINE" )
85+ private inline fun writeOrSuspend (noinline action : () -> Unit ) {
86+ val c = currentIndex
87+ currentIndex = - 1
88+ when {
89+ notInStruct || c< 0 -> action()
90+ lastWrittenIndex < - 1 -> pending[c] = action
91+ lastWrittenIndex + 1 == c -> {
92+ ++ lastWrittenIndex
93+ action()
94+ }
95+ c < pending.size -> pending[c] = action
96+ else -> error(" Unexpected index" )
97+ }
98+ }
99+
100+ override fun encodeElement (descriptor : SerialDescriptor , index : Int ): Boolean {
101+ currentIndex = index
102+ return true
103+ }
53104
54105 @ExperimentalSerializationApi
55106 override fun shouldEncodeElementDefault (descriptor : SerialDescriptor , index : Int ): Boolean = true
56107
108+ override fun beginStructure (descriptor : SerialDescriptor ): CompositeEncoder {
109+ return Encoder (serializersModule, byteBuffer, descriptor.elementsCount)
110+ }
111+
57112 override fun beginCollection (descriptor : SerialDescriptor , collectionSize : Int ): CompositeEncoder {
58113 encodeInt(collectionSize)
59- return this
114+ return Encoder (serializersModule, byteBuffer, - 1 )
115+ }
116+
117+ override fun endStructure (descriptor : SerialDescriptor ) {
118+ currentIndex = - 2 // mark negative to ensure writing
119+ for (i in 0 until pending.size) {
120+ pending[i]?.invoke()
121+ }
60122 }
61123
62124 override fun encodeNull () = encodeBoolean(false )
0 commit comments