All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ch.softappeal.yass2.serialize.binary.BaseEncoders.kt Maven / Gradle / Ivy

There is a newer version: 5.0.0
Show newest version
package ch.softappeal.yass2.serialize.binary

import ch.softappeal.yass2.serialize.*
import kotlin.reflect.*

class BaseEncoder(
    type: KClass<*>,
    internal val write: (writer: Writer, value: T) -> Unit,
    internal val read: (reader: Reader) -> T
) : Encoder(type) {
    @Suppress("UNCHECKED_CAST")
    override fun write(writer: EncoderWriter, value: Any?) = write(writer.writer, value as T)

    override fun read(reader: EncoderReader) = read(reader.reader)
}

val BooleanEncoder = BaseEncoder(Boolean::class,
    { writer, value -> writer.writeByte(if (value) 1 else 0) },
    { reader -> reader.readByte().toInt() != 0 }
)

val ByteEncoder = BaseEncoder(Byte::class,
    { writer, value -> writer.writeVarInt(value.toInt().toZigZag()) },
    { reader -> reader.readVarInt().fromZigZag().toByte() }
)

val ShortEncoder = BaseEncoder(Short::class,
    { writer, value -> writer.writeVarInt(value.toInt().toZigZag()) },
    { reader -> reader.readVarInt().fromZigZag().toShort() }
)

val IntEncoder = BaseEncoder(Int::class,
    { writer, value -> writer.writeVarInt(value.toZigZag()) },
    { reader -> reader.readVarInt().fromZigZag() }
)

val LongEncoder = BaseEncoder(Long::class,
    { writer, value -> writer.writeVarLong(value.toZigZag()) },
    { reader -> reader.readVarLong().fromZigZag() }
)

// note: There is no CharEncoder because who the heck needs Char?

// note: There is no FloatEncoder because there is no Float in JavaScript.

val DoubleEncoder = BaseEncoder(Double::class,
    { writer, value -> writer.writeLong(value.toBits()) },
    { reader -> Double.fromBits(reader.readLong()) }
)

val ByteArrayEncoder = BaseEncoder(ByteArray::class,
    { writer, value ->
        writer.writeVarInt(value.size)
        writer.writeBytes(value)
    },
    { reader -> reader.readBytes(reader.readVarInt()) }
)

val StringEncoder = BaseEncoder(String::class,
    { writer, value ->
        writer.writeVarInt(value.utf8Length())
        writer.toUtf8(value)
    },
    { reader -> reader.fromUtf8(reader.readVarInt()) }
)

@PublishedApi
internal fun > enumEncoder(type: KClass, constants: Array) = BaseEncoder(type,
    { writer, value -> writer.writeVarInt(value.ordinal) },
    { reader -> constants[reader.readVarInt()] }
)

inline fun > enumEncoder() = enumEncoder(T::class, enumValues())




© 2015 - 2025 Weber Informatics LLC | Privacy Policy