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

commonMain.space.kscience.dataforge.io.IOFormat.kt Maven / Gradle / Ivy

package space.kscience.dataforge.io

import kotlinx.io.Sink
import kotlinx.io.Source
import kotlinx.io.readByteArray
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Factory
import space.kscience.dataforge.io.IOFormatFactory.Companion.IO_FORMAT_TYPE
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import kotlin.reflect.KType
import kotlin.reflect.typeOf

/**
 * Reader of a custom object from input
 */
public interface IOReader {
    /**
     * The type of object being read
     */
    public val type: KType

    public fun readFrom(source: Source): T

    public fun readFrom(binary: Binary): T = binary.read { readFrom(this) }

    public companion object {
        /**
         * no-op reader for binaries.
         */
        public val binary: IOReader = object : IOReader {
            override val type: KType = typeOf()

            override fun readFrom(source: Source): Binary = source.readByteArray().asBinary()

            override fun readFrom(binary: Binary): Binary = binary
        }
    }
}

public inline fun  IOReader(crossinline read: Source.() -> T): IOReader = object : IOReader {
    override val type: KType = typeOf()

    override fun readFrom(source: Source): T = source.read()
}

public fun interface IOWriter {
    public fun writeTo(sink: Sink, obj: T)
}

/**
 * And interface for reading and writing objects into with IO streams
 */
public interface IOFormat : IOReader, IOWriter

public fun  Source.readWith(format: IOReader): T = format.readFrom(this)

/**
 * Read given binary as an object using given format
 */
public fun  Binary.readWith(format: IOReader): T = read {
    readWith(format)
}

/**
 * Write an object to the [Sink] with given [format]
 */
public fun  Sink.writeWith(format: IOWriter, obj: T): Unit =
    format.writeTo(this, obj)


@DfId(IO_FORMAT_TYPE)
public interface IOFormatFactory : Factory>, Named {
    /**
     * Explicit type for dynamic type checks
     */
    public val type: KType

    public companion object {
        public const val IO_FORMAT_TYPE: String = "io.format"
        public val NAME_KEY: Name = "name".asName()
        public val META_KEY: Name = "meta".asName()
    }
}

public fun  Binary(obj: T, format: IOWriter): Binary = Binary { format.writeTo(this, obj) }

public object FloatIOFormat : IOFormat, IOFormatFactory {
    override fun build(context: Context, meta: Meta): IOFormat = this

    override val name: Name = "float32".asName()

    override val type: KType get() = typeOf()

    override fun writeTo(sink: Sink, obj: Float) {
        sink.writeFloat(obj)
    }

    override fun readFrom(source: Source): Float = source.readFloat()
}


public object DoubleIOFormat : IOFormat, IOFormatFactory {
    override fun build(context: Context, meta: Meta): IOFormat = this

    override val name: Name = "float64".asName()

    override val type: KType get() = typeOf()

    override fun writeTo(sink: Sink, obj: Double) {
        sink.writeLong(obj.toBits())
    }

    override fun readFrom(source: Source): Double = source.readDouble()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy