@@ -38,25 +38,87 @@ class EfficientBinaryFormat(
38
38
return deserializer.deserialize(decoder)
39
39
}
40
40
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
+ }
53
104
54
105
@ExperimentalSerializationApi
55
106
override fun shouldEncodeElementDefault (descriptor : SerialDescriptor , index : Int ): Boolean = true
56
107
108
+ override fun beginStructure (descriptor : SerialDescriptor ): CompositeEncoder {
109
+ return Encoder (serializersModule, byteBuffer, descriptor.elementsCount)
110
+ }
111
+
57
112
override fun beginCollection (descriptor : SerialDescriptor , collectionSize : Int ): CompositeEncoder {
58
113
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
+ }
60
122
}
61
123
62
124
override fun encodeNull () = encodeBoolean(false )
0 commit comments