• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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