Added DF02 format to TaggedEnvelopeFormat.

This commit is contained in:
Alexander Nozik 2019-11-01 19:47:03 +03:00
parent 257601d945
commit 6f341f705a

View File

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