Optimized EnvelopeFormat generation API

This commit is contained in:
Alexander Nozik 2019-11-01 20:04:11 +03:00
parent 6f341f705a
commit 33b1de2865
4 changed files with 33 additions and 34 deletions

View File

@ -2,20 +2,18 @@ package hep.dataforge.io.yaml
import hep.dataforge.context.Context
import hep.dataforge.io.*
import hep.dataforge.meta.*
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta
import kotlinx.io.core.*
import kotlinx.serialization.toUtf8Bytes
@DFExperimental
class FrontMatterEnvelopeFormat(
val io: IOPlugin,
val metaType: String = YamlMetaFormat.name.toString(),
meta: Meta = EmptyMeta
) : EnvelopeFormat {
val metaFormat = io.metaFormat(metaType, meta)
?: error("Meta format with type $metaType could not be resolved in $io")
override fun Input.readPartial(): PartialEnvelope {
var line: String = ""
var offset = 0u
@ -60,11 +58,12 @@ class FrontMatterEnvelopeFormat(
return SimpleEnvelope(meta, data)
}
override fun Output.writeObject(obj: Envelope) {
override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) {
val metaFormat = metaFormatFactory(formatMeta, io.context)
writeText("$SEPARATOR\r\n")
metaFormat.run { writeObject(obj.meta) }
metaFormat.run { writeObject(envelope.meta) }
writeText("$SEPARATOR\r\n")
obj.data?.read { copyTo(this@writeObject) }
envelope.data?.read { copyTo(this@writeEnvelope) }
}
companion object : EnvelopeFormatFactory {
@ -73,8 +72,7 @@ class FrontMatterEnvelopeFormat(
private val metaTypeRegex = "---(\\w*)\\s*".toRegex()
override fun invoke(meta: Meta, context: Context): EnvelopeFormat {
val metaFormatName: String = meta["name"].string ?: YamlMetaFormat.name.toString()
return FrontMatterEnvelopeFormat(context.io, metaFormatName, meta)
return FrontMatterEnvelopeFormat(context.io, meta)
}
override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? {

View File

@ -2,6 +2,7 @@ package hep.dataforge.io
import hep.dataforge.context.Context
import hep.dataforge.io.EnvelopeFormatFactory.Companion.ENVELOPE_FORMAT_TYPE
import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta
import hep.dataforge.names.Name
import hep.dataforge.names.asName
@ -18,11 +19,15 @@ data class PartialEnvelope(val meta: Meta, val dataOffset: UInt, val dataSize: U
interface EnvelopeFormat : IOFormat<Envelope> {
val defaultMetaFormat: MetaFormatFactory get() = JsonMetaFormat
fun Input.readPartial(): PartialEnvelope
fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta = EmptyMeta)
override fun Input.readObject(): Envelope
override fun Output.writeObject(obj: Envelope)
override fun Output.writeObject(obj: Envelope): Unit = writeEnvelope(obj, defaultMetaFormat)
}
@Type(ENVELOPE_FORMAT_TYPE)

View File

@ -13,12 +13,11 @@ import kotlinx.io.core.*
@ExperimentalUnsignedTypes
class TaggedEnvelopeFormat(
val io: IOPlugin,
private val metaFormatKey: Short,
val version: VERSION = TaggedEnvelopeFormat.VERSION.DF02
) : EnvelopeFormat {
private val metaFormat = io.metaFormat(metaFormatKey)
?: error("Meta format with key $metaFormatKey could not be resolved in $io")
// private val metaFormat = io.metaFormat(metaFormatKey)
// ?: error("Meta format with key $metaFormatKey could not be resolved in $io")
private fun Tag.toBytes(): ByteReadPacket = buildPacket(24) {
@ -37,13 +36,14 @@ class TaggedEnvelopeFormat(
writeText(END_SEQUENCE)
}
override fun Output.writeObject(obj: Envelope) {
val metaBytes = metaFormat.writeBytes(obj.meta)
val tag = Tag(metaFormatKey, metaBytes.size.toUInt() + 2u, obj.data?.size ?: 0.toULong())
override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) {
val metaFormat = metaFormatFactory.invoke(formatMeta, io.context)
val metaBytes = metaFormat.writeBytes(envelope.meta)
val tag = Tag(metaFormatFactory.key, metaBytes.size.toUInt() + 2u, envelope.data?.size ?: 0.toULong())
writePacket(tag.toBytes())
writeFully(metaBytes)
writeText("\r\n")
obj.data?.read { copyTo(this@writeObject) }
envelope.data?.read { copyTo(this@writeEnvelope) }
flush()
}
@ -102,7 +102,7 @@ class TaggedEnvelopeFormat(
val metaFormatFactory = io.metaFormatFactories.find { it.name == metaFormatName }
?: error("Meta format could not be resolved")
return TaggedEnvelopeFormat(io, metaFormatFactory.key)
return TaggedEnvelopeFormat(io)
}
private fun Input.readTag(version: VERSION): Tag {
@ -124,9 +124,9 @@ class TaggedEnvelopeFormat(
override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? {
return try {
val header = input.readTextExactBytes(6)
when(header.substring(2..5)){
VERSION.DF02.name-> TaggedEnvelopeFormat(io, JsonMetaFormat.key,VERSION.DF02)
VERSION.DF03.name-> TaggedEnvelopeFormat(io, JsonMetaFormat.key,VERSION.DF03)
when (header.substring(2..5)) {
VERSION.DF02.name -> TaggedEnvelopeFormat(io, VERSION.DF02)
VERSION.DF03.name -> TaggedEnvelopeFormat(io, VERSION.DF03)
else -> null
}
} catch (ex: Exception) {

View File

@ -8,33 +8,30 @@ import kotlinx.serialization.toUtf8Bytes
class TaglessEnvelopeFormat(
val io: IOPlugin,
val metaType: String = JsonMetaFormat.name.toString(),
meta: Meta = EmptyMeta
) : EnvelopeFormat {
private val metaStart = meta[META_START_PROPERTY].string ?: DEFAULT_META_START
private val dataStart = meta[DATA_START_PROPERTY].string ?: DEFAULT_DATA_START
val metaFormat = io.metaFormat(metaType, meta)
?: error("Meta format with type $metaType could not be resolved in $io")
private fun Output.writeProperty(key: String, value: Any) {
writeText("#? $key: $value;\r\n")
}
override fun Output.writeObject(obj: Envelope) {
override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) {
val metaFormat = metaFormatFactory(formatMeta, io.context)
//printing header
writeText(TAGLESS_ENVELOPE_HEADER + "\r\n")
//printing all properties
writeProperty(META_TYPE_PROPERTY, metaType)
writeProperty(META_TYPE_PROPERTY, metaFormatFactory.type)
//TODO add optional metaFormat properties
writeProperty(DATA_LENGTH_PROPERTY, obj.data?.size ?: 0)
writeProperty(DATA_LENGTH_PROPERTY, envelope.data?.size ?: 0)
//Printing meta
if (!obj.meta.isEmpty()) {
val metaBytes = metaFormat.writeBytes(obj.meta)
if (!envelope.meta.isEmpty()) {
val metaBytes = metaFormat.writeBytes(envelope.meta)
writeProperty(META_LENGTH_PROPERTY, metaBytes.size)
writeText(metaStart + "\r\n")
writeFully(metaBytes)
@ -42,7 +39,7 @@ class TaglessEnvelopeFormat(
}
//Printing data
obj.data?.let { data ->
envelope.data?.let { data ->
writeText(dataStart + "\r\n")
writeFully(data.toBytes())
}
@ -170,8 +167,7 @@ class TaglessEnvelopeFormat(
override val name = TAGLESS_ENVELOPE_TYPE.asName()
override fun invoke(meta: Meta, context: Context): EnvelopeFormat {
val metaFormatName: String = meta["name"].string ?: JsonMetaFormat.name.toString()
return TaglessEnvelopeFormat(context.io, metaFormatName, meta)
return TaglessEnvelopeFormat(context.io, meta)
}
val default by lazy { invoke() }