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
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)
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,8 +123,12 @@ 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
}