diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt index c51cb36d..97a23fb9 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt @@ -13,7 +13,8 @@ import kotlinx.io.core.* @ExperimentalUnsignedTypes class TaggedEnvelopeFormat( val io: IOPlugin, - private val metaFormatKey: Short + private val metaFormatKey: Short, + val version: VERSION = TaggedEnvelopeFormat.VERSION.DF02 ) : EnvelopeFormat { private val metaFormat = io.metaFormat(metaFormatKey) @@ -22,10 +23,17 @@ class TaggedEnvelopeFormat( private fun Tag.toBytes(): ByteReadPacket = buildPacket(24) { writeText(START_SEQUENCE) - writeText(VERSION) + writeText(version.name) writeShort(metaFormatKey) writeUInt(metaSize) - writeULong(dataSize) + when (version) { + TaggedEnvelopeFormat.VERSION.DF02 -> { + writeUInt(dataSize.toUInt()) + } + TaggedEnvelopeFormat.VERSION.DF03 -> { + writeULong(dataSize) + } + } writeText(END_SEQUENCE) } @@ -46,7 +54,7 @@ class TaggedEnvelopeFormat( * @param formats a collection of meta formats to resolve */ override fun Input.readObject(): Envelope { - val tag = readTag() + val tag = readTag(version) val metaFormat = io.metaFormat(tag.metaFormatKey) ?: error("Meta format with key ${tag.metaFormatKey} not found") @@ -59,7 +67,7 @@ class TaggedEnvelopeFormat( } override fun Input.readPartial(): PartialEnvelope { - val tag = readTag() + val tag = readTag(version) val metaFormat = io.metaFormat(tag.metaFormatKey) ?: error("Meta format with key ${tag.metaFormatKey} not found") @@ -67,7 +75,7 @@ class TaggedEnvelopeFormat( val metaPacket = ByteReadPacket(readBytes(tag.metaSize.toInt())) val meta = metaFormat.run { metaPacket.readObject() } - return PartialEnvelope(meta, TAG_SIZE + tag.metaSize, tag.dataSize) + return PartialEnvelope(meta, version.tagSize + tag.metaSize, tag.dataSize) } private data class Tag( @@ -76,13 +84,16 @@ class TaggedEnvelopeFormat( val dataSize: ULong ) + enum class VERSION(val tagSize: UInt) { + DF02(20u), + DF03(24u) + } + companion object : EnvelopeFormatFactory { - const val VERSION = "DF03" private const val START_SEQUENCE = "#~" private const val END_SEQUENCE = "~#\r\n" - private const val TAG_SIZE = 24u - override val name: Name = super.name + VERSION + override val name: Name = super.name + "tagged" override fun invoke(meta: Meta, context: Context): EnvelopeFormat { val io = context.io @@ -94,14 +105,17 @@ class TaggedEnvelopeFormat( return TaggedEnvelopeFormat(io, metaFormatFactory.key) } - private fun Input.readTag(): Tag { + private fun Input.readTag(version: VERSION): Tag { val start = readTextExactBytes(2, charset = Charsets.ISO_8859_1) if (start != START_SEQUENCE) error("The input is not an envelope") - val version = readTextExactBytes(4, charset = Charsets.ISO_8859_1) - if (version != VERSION) error("Wrong version of DataForge: expected $VERSION but found $version") + val versionString = readTextExactBytes(4, charset = Charsets.ISO_8859_1) + if (version.name != versionString) error("Wrong version of DataForge: expected $version but found $versionString") val metaFormatKey = readShort() val metaLength = readUInt() - val dataLength = readULong() + val dataLength: ULong = when (version) { + VERSION.DF02 -> readUInt().toULong() + VERSION.DF03 -> readULong() + } val end = readTextExactBytes(4, charset = Charsets.ISO_8859_1) if (end != END_SEQUENCE) error("The input is not an envelope") return Tag(metaFormatKey, metaLength, dataLength) @@ -109,14 +123,18 @@ class TaggedEnvelopeFormat( override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? { return try { - val tag = input.readTag() - TaggedEnvelopeFormat(io, tag.metaFormatKey) + 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) + else -> null + } } catch (ex: Exception) { null } } - val default by lazy { invoke()} + val default by lazy { invoke() } } } \ No newline at end of file