1 // This file was automatically generated from formats.md by Knit tool. Do not edit.
2 package example.exampleFormats17
3
4 import kotlinx.serialization.*
5 import kotlinx.serialization.Serializable
6 import kotlinx.serialization.descriptors.*
7 import kotlinx.serialization.modules.*
8 import kotlinx.serialization.encoding.*
9 import java.io.*
10
11 private val byteArraySerializer = serializer<ByteArray>()
12 @ExperimentalSerializationApi
13 class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() {
14 override val serializersModule: SerializersModule = EmptySerializersModule()
encodeBooleannull15 override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0)
16 override fun encodeByte(value: Byte) = output.writeByte(value.toInt())
17 override fun encodeShort(value: Short) = output.writeShort(value.toInt())
18 override fun encodeInt(value: Int) = output.writeInt(value)
19 override fun encodeLong(value: Long) = output.writeLong(value)
20 override fun encodeFloat(value: Float) = output.writeFloat(value)
21 override fun encodeDouble(value: Double) = output.writeDouble(value)
22 override fun encodeChar(value: Char) = output.writeChar(value.code)
23 override fun encodeString(value: String) = output.writeUTF(value)
24 override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output.writeInt(index)
25
26 override fun beginCollection(descriptor: SerialDescriptor, collectionSize: Int): CompositeEncoder {
27 encodeInt(collectionSize)
28 return this
29 }
30
encodeNullnull31 override fun encodeNull() = encodeBoolean(false)
32 override fun encodeNotNullMark() = encodeBoolean(true)
33
34 override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) {
35 if (serializer.descriptor == byteArraySerializer.descriptor)
36 encodeByteArray(value as ByteArray)
37 else
38 super.encodeSerializableValue(serializer, value)
39 }
40
encodeByteArraynull41 private fun encodeByteArray(bytes: ByteArray) {
42 encodeCompactSize(bytes.size)
43 output.write(bytes)
44 }
45
encodeCompactSizenull46 private fun encodeCompactSize(value: Int) {
47 if (value < 0xff) {
48 output.writeByte(value)
49 } else {
50 output.writeByte(0xff)
51 output.writeInt(value)
52 }
53 }
54 }
55
56 @ExperimentalSerializationApi
encodeTonull57 fun <T> encodeTo(output: DataOutput, serializer: SerializationStrategy<T>, value: T) {
58 val encoder = DataOutputEncoder(output)
59 encoder.encodeSerializableValue(serializer, value)
60 }
61
62 @ExperimentalSerializationApi
encodeTonull63 inline fun <reified T> encodeTo(output: DataOutput, value: T) = encodeTo(output, serializer(), value)
64
65 @ExperimentalSerializationApi
66 class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : AbstractDecoder() {
67 private var elementIndex = 0
68 override val serializersModule: SerializersModule = EmptySerializersModule()
69 override fun decodeBoolean(): Boolean = input.readByte().toInt() != 0
70 override fun decodeByte(): Byte = input.readByte()
71 override fun decodeShort(): Short = input.readShort()
72 override fun decodeInt(): Int = input.readInt()
73 override fun decodeLong(): Long = input.readLong()
74 override fun decodeFloat(): Float = input.readFloat()
75 override fun decodeDouble(): Double = input.readDouble()
76 override fun decodeChar(): Char = input.readChar()
77 override fun decodeString(): String = input.readUTF()
78 override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readInt()
79
80 override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
81 if (elementIndex == elementsCount) return CompositeDecoder.DECODE_DONE
82 return elementIndex++
83 }
84
85 override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder =
86 DataInputDecoder(input, descriptor.elementsCount)
87
88 override fun decodeSequentially(): Boolean = true
89
90 override fun decodeCollectionSize(descriptor: SerialDescriptor): Int =
91 decodeInt().also { elementsCount = it }
92
93 override fun decodeNotNullMark(): Boolean = decodeBoolean()
94
95 @Suppress("UNCHECKED_CAST")
96 override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>, previousValue: T?): T =
97 if (deserializer.descriptor == byteArraySerializer.descriptor)
98 decodeByteArray() as T
99 else
100 super.decodeSerializableValue(deserializer, previousValue)
101
102 private fun decodeByteArray(): ByteArray {
103 val bytes = ByteArray(decodeCompactSize())
104 input.readFully(bytes)
105 return bytes
106 }
107
108 private fun decodeCompactSize(): Int {
109 val byte = input.readByte().toInt() and 0xff
110 if (byte < 0xff) return byte
111 return input.readInt()
112 }
113 }
114
115 @ExperimentalSerializationApi
decodeFromnull116 fun <T> decodeFrom(input: DataInput, deserializer: DeserializationStrategy<T>): T {
117 val decoder = DataInputDecoder(input)
118 return decoder.decodeSerializableValue(deserializer)
119 }
120
121 @ExperimentalSerializationApi
decodeFromnull122 inline fun <reified T> decodeFrom(input: DataInput): T = decodeFrom(input, serializer())
123
124 fun ByteArray.toAsciiHexString() = joinToString("") {
125 if (it in 32..127) it.toInt().toChar().toString() else
126 "{${it.toUByte().toString(16).padStart(2, '0').uppercase()}}"
127 }
128
129 @Serializable
130 data class Project(val name: String, val attachment: ByteArray)
131
132 @OptIn(ExperimentalSerializationApi::class)
mainnull133 fun main() {
134 val data = Project("kotlinx.serialization", byteArrayOf(0x0A, 0x0B, 0x0C, 0x0D))
135 val output = ByteArrayOutputStream()
136 encodeTo(DataOutputStream(output), data)
137 val bytes = output.toByteArray()
138 println(bytes.toAsciiHexString())
139 val input = ByteArrayInputStream(bytes)
140 val obj = decodeFrom<Project>(DataInputStream(input))
141 println(obj)
142 }
143