xref: /aosp_15_r20/external/kotlinx.serialization/guide/example/example-formats-15.kt (revision 57b5a4a64c534cf7f27ac9427ceab07f3d8ed3d8)
1*57b5a4a6SAndroid Build Coastguard Worker // This file was automatically generated from formats.md by Knit tool. Do not edit.
2*57b5a4a6SAndroid Build Coastguard Worker package example.exampleFormats15
3*57b5a4a6SAndroid Build Coastguard Worker 
4*57b5a4a6SAndroid Build Coastguard Worker import kotlinx.serialization.*
5*57b5a4a6SAndroid Build Coastguard Worker import kotlinx.serialization.Serializable
6*57b5a4a6SAndroid Build Coastguard Worker import kotlinx.serialization.descriptors.*
7*57b5a4a6SAndroid Build Coastguard Worker import kotlinx.serialization.encoding.*
8*57b5a4a6SAndroid Build Coastguard Worker import kotlinx.serialization.modules.*
9*57b5a4a6SAndroid Build Coastguard Worker import java.io.*
10*57b5a4a6SAndroid Build Coastguard Worker 
11*57b5a4a6SAndroid Build Coastguard Worker class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() {
12*57b5a4a6SAndroid Build Coastguard Worker     override val serializersModule: SerializersModule = EmptySerializersModule()
encodeBooleannull13*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0)
14*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeByte(value: Byte) = output.writeByte(value.toInt())
15*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeShort(value: Short) = output.writeShort(value.toInt())
16*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeInt(value: Int) = output.writeInt(value)
17*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeLong(value: Long) = output.writeLong(value)
18*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeFloat(value: Float) = output.writeFloat(value)
19*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeDouble(value: Double) = output.writeDouble(value)
20*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeChar(value: Char) = output.writeChar(value.code)
21*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeString(value: String) = output.writeUTF(value)
22*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output.writeInt(index)
23*57b5a4a6SAndroid Build Coastguard Worker 
24*57b5a4a6SAndroid Build Coastguard Worker     override fun beginCollection(descriptor: SerialDescriptor, collectionSize: Int): CompositeEncoder {
25*57b5a4a6SAndroid Build Coastguard Worker         encodeInt(collectionSize)
26*57b5a4a6SAndroid Build Coastguard Worker         return this
27*57b5a4a6SAndroid Build Coastguard Worker     }
28*57b5a4a6SAndroid Build Coastguard Worker 
encodeNullnull29*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeNull() = encodeBoolean(false)
30*57b5a4a6SAndroid Build Coastguard Worker     override fun encodeNotNullMark() = encodeBoolean(true)
31*57b5a4a6SAndroid Build Coastguard Worker }
32*57b5a4a6SAndroid Build Coastguard Worker 
33*57b5a4a6SAndroid Build Coastguard Worker fun <T> encodeTo(output: DataOutput, serializer: SerializationStrategy<T>, value: T) {
34*57b5a4a6SAndroid Build Coastguard Worker     val encoder = DataOutputEncoder(output)
35*57b5a4a6SAndroid Build Coastguard Worker     encoder.encodeSerializableValue(serializer, value)
36*57b5a4a6SAndroid Build Coastguard Worker }
37*57b5a4a6SAndroid Build Coastguard Worker 
encodeTonull38*57b5a4a6SAndroid Build Coastguard Worker inline fun <reified T> encodeTo(output: DataOutput, value: T) = encodeTo(output, serializer(), value)
39*57b5a4a6SAndroid Build Coastguard Worker 
40*57b5a4a6SAndroid Build Coastguard Worker class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : AbstractDecoder() {
41*57b5a4a6SAndroid Build Coastguard Worker     private var elementIndex = 0
42*57b5a4a6SAndroid Build Coastguard Worker     override val serializersModule: SerializersModule = EmptySerializersModule()
43*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeBoolean(): Boolean = input.readByte().toInt() != 0
44*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeByte(): Byte = input.readByte()
45*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeShort(): Short = input.readShort()
46*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeInt(): Int = input.readInt()
47*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeLong(): Long = input.readLong()
48*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeFloat(): Float = input.readFloat()
49*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeDouble(): Double = input.readDouble()
50*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeChar(): Char = input.readChar()
51*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeString(): String = input.readUTF()
52*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readInt()
53*57b5a4a6SAndroid Build Coastguard Worker 
54*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
55*57b5a4a6SAndroid Build Coastguard Worker         if (elementIndex == elementsCount) return CompositeDecoder.DECODE_DONE
56*57b5a4a6SAndroid Build Coastguard Worker         return elementIndex++
57*57b5a4a6SAndroid Build Coastguard Worker     }
58*57b5a4a6SAndroid Build Coastguard Worker 
59*57b5a4a6SAndroid Build Coastguard Worker     override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder =
60*57b5a4a6SAndroid Build Coastguard Worker         DataInputDecoder(input, descriptor.elementsCount)
61*57b5a4a6SAndroid Build Coastguard Worker 
62*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeSequentially(): Boolean = true
63*57b5a4a6SAndroid Build Coastguard Worker 
64*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeCollectionSize(descriptor: SerialDescriptor): Int =
65*57b5a4a6SAndroid Build Coastguard Worker         decodeInt().also { elementsCount = it }
66*57b5a4a6SAndroid Build Coastguard Worker 
67*57b5a4a6SAndroid Build Coastguard Worker     override fun decodeNotNullMark(): Boolean = decodeBoolean()
68*57b5a4a6SAndroid Build Coastguard Worker }
69*57b5a4a6SAndroid Build Coastguard Worker 
decodeFromnull70*57b5a4a6SAndroid Build Coastguard Worker fun <T> decodeFrom(input: DataInput, deserializer: DeserializationStrategy<T>): T {
71*57b5a4a6SAndroid Build Coastguard Worker     val decoder = DataInputDecoder(input)
72*57b5a4a6SAndroid Build Coastguard Worker     return decoder.decodeSerializableValue(deserializer)
73*57b5a4a6SAndroid Build Coastguard Worker }
74*57b5a4a6SAndroid Build Coastguard Worker 
decodeFromnull75*57b5a4a6SAndroid Build Coastguard Worker inline fun <reified T> decodeFrom(input: DataInput): T = decodeFrom(input, serializer())
76*57b5a4a6SAndroid Build Coastguard Worker 
77*57b5a4a6SAndroid Build Coastguard Worker fun ByteArray.toAsciiHexString() = joinToString("") {
78*57b5a4a6SAndroid Build Coastguard Worker     if (it in 32..127) it.toInt().toChar().toString() else
79*57b5a4a6SAndroid Build Coastguard Worker         "{${it.toUByte().toString(16).padStart(2, '0').uppercase()}}"
80*57b5a4a6SAndroid Build Coastguard Worker }
81*57b5a4a6SAndroid Build Coastguard Worker 
82*57b5a4a6SAndroid Build Coastguard Worker @Serializable
83*57b5a4a6SAndroid Build Coastguard Worker data class Project(val name: String, val language: String)
84*57b5a4a6SAndroid Build Coastguard Worker 
mainnull85*57b5a4a6SAndroid Build Coastguard Worker fun main() {
86*57b5a4a6SAndroid Build Coastguard Worker     val data = Project("kotlinx.serialization", "Kotlin")
87*57b5a4a6SAndroid Build Coastguard Worker     val output = ByteArrayOutputStream()
88*57b5a4a6SAndroid Build Coastguard Worker     encodeTo(DataOutputStream(output), data)
89*57b5a4a6SAndroid Build Coastguard Worker     val bytes = output.toByteArray()
90*57b5a4a6SAndroid Build Coastguard Worker     println(bytes.toAsciiHexString())
91*57b5a4a6SAndroid Build Coastguard Worker     val input = ByteArrayInputStream(bytes)
92*57b5a4a6SAndroid Build Coastguard Worker     val obj = decodeFrom<Project>(DataInputStream(input))
93*57b5a4a6SAndroid Build Coastguard Worker     println(obj)
94*57b5a4a6SAndroid Build Coastguard Worker }
95