com.lightningkite.lightningserver.serialization.JavaData.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of server-core Show documentation
Show all versions of server-core Show documentation
A set of tools to fill in/replace what Ktor is lacking in.
The newest version!
package com.lightningkite.lightningserver.serialization
import com.lightningkite.lightningserver.logger
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.AbstractDecoder
import kotlinx.serialization.encoding.AbstractEncoder
import kotlinx.serialization.encoding.CompositeDecoder
import kotlinx.serialization.encoding.CompositeEncoder
import kotlinx.serialization.modules.SerializersModule
import java.io.*
class JavaData(override val serializersModule: SerializersModule) : BinaryFormat {
override fun decodeFromByteArray(deserializer: DeserializationStrategy, bytes: ByteArray): T {
logger.debug("Decoding $deserializer from ${bytes.contentToString()}")
return DataInputDecoder(DataInputStream(ByteArrayInputStream(bytes))).decodeSerializableValue(deserializer)
}
override fun encodeToByteArray(serializer: SerializationStrategy, value: T): ByteArray {
val out = ByteArrayOutputStream()
DataOutputEncoder(DataOutputStream(out)).encodeSerializableValue(serializer, value)
return out.toByteArray()
}
private inner class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() {
override val serializersModule: SerializersModule get() = [email protected]
override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0)
override fun encodeByte(value: Byte) = output.writeByte(value.toInt())
override fun encodeShort(value: Short) = output.writeShort(value.toInt())
override fun encodeInt(value: Int) = output.writeInt(value)
override fun encodeLong(value: Long) = output.writeLong(value)
override fun encodeFloat(value: Float) = output.writeFloat(value)
override fun encodeDouble(value: Double) = output.writeDouble(value)
override fun encodeChar(value: Char) = output.writeChar(value.code)
override fun encodeString(value: String) {
output.writeShort(value.length)
output.write(value.toByteArray(Charsets.UTF_8))
}
override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output.writeInt(index)
override fun beginCollection(descriptor: SerialDescriptor, collectionSize: Int): CompositeEncoder {
encodeInt(collectionSize)
return this
}
override fun encodeNull() = encodeBoolean(false)
override fun encodeNotNullMark() = encodeBoolean(true)
}
private inner class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : AbstractDecoder() {
private var elementIndex = 0
override val serializersModule: SerializersModule get() = [email protected]
override fun decodeBoolean(): Boolean = input.readByte().toInt() != 0
override fun decodeByte(): Byte = input.readByte()
override fun decodeShort(): Short = input.readShort()
override fun decodeInt(): Int = input.readInt()
override fun decodeLong(): Long = input.readLong()
override fun decodeFloat(): Float = input.readFloat()
override fun decodeDouble(): Double = input.readDouble()
override fun decodeChar(): Char = input.readChar()
override fun decodeString(): String {
val size = input.readUnsignedShort()
val bytes = ByteArray(size)
for (i in 0 until size)
bytes[i] = input.readByte()
return bytes.toString(Charsets.UTF_8)
}
override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readInt()
override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
if (elementIndex == elementsCount) return CompositeDecoder.DECODE_DONE
return elementIndex++
}
override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder =
DataInputDecoder(input, descriptor.elementsCount)
override fun decodeSequentially(): Boolean = true
override fun decodeCollectionSize(descriptor: SerialDescriptor): Int =
decodeInt().also { elementsCount = it }
override fun decodeNotNullMark(): Boolean = decodeBoolean()
}
}