Added peek format functionality to EnvelopeFormat
This commit is contained in:
parent
44a34eee40
commit
bf787fb5fc
@ -32,6 +32,12 @@ interface EnvelopeFormatFactory : IOFormatFactory<Envelope> {
|
||||
|
||||
override fun invoke(meta: Meta, context: Context): EnvelopeFormat
|
||||
|
||||
/**
|
||||
* Try to infer specific format from input and return null if the attempt is failed.
|
||||
* This method does **not** return Input into initial state.
|
||||
*/
|
||||
fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat?
|
||||
|
||||
companion object {
|
||||
const val ENVELOPE_FORMAT_TYPE = "io.format.envelope"
|
||||
}
|
||||
|
@ -10,20 +10,14 @@ import hep.dataforge.names.toName
|
||||
import kotlinx.io.core.*
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
class TaggedEnvelopeFormat(val io: IOPlugin, meta: Meta) : EnvelopeFormat {
|
||||
|
||||
private val metaFormat: MetaFormat
|
||||
|
||||
class TaggedEnvelopeFormat(
|
||||
val io: IOPlugin,
|
||||
private val metaFormatKey: Short
|
||||
) : EnvelopeFormat {
|
||||
|
||||
init {
|
||||
val metaName = meta["name"].string?.toName() ?: JsonMetaFormat.name
|
||||
val metaFormatFactory = io.metaFormatFactories.find { it.name == metaName }
|
||||
?: error("Meta format could not be resolved")
|
||||
private val metaFormat =
|
||||
io.metaFormat(metaFormatKey) ?: error("Meta format with key $metaFormatKey could not be resolved in $io")
|
||||
|
||||
metaFormat = metaFormatFactory(meta, io.context)
|
||||
metaFormatKey = metaFormatFactory.key
|
||||
}
|
||||
|
||||
private fun Tag.toBytes(): ByteReadPacket = buildPacket(24) {
|
||||
writeText(START_SEQUENCE)
|
||||
@ -34,19 +28,6 @@ class TaggedEnvelopeFormat(val io: IOPlugin, meta: Meta) : EnvelopeFormat {
|
||||
writeText(END_SEQUENCE)
|
||||
}
|
||||
|
||||
private fun Input.readTag(): Tag {
|
||||
val start = readTextExactBytes(2)
|
||||
if (start != START_SEQUENCE) error("The input is not an envelope")
|
||||
val version = readTextExactBytes(4)
|
||||
if (version != VERSION) error("Wrong version of DataForge: expected $VERSION but found $version")
|
||||
val metaFormatKey = readShort()
|
||||
val metaLength = readUInt()
|
||||
val dataLength = readULong()
|
||||
val end = readTextExactBytes(4)
|
||||
if (end != END_SEQUENCE) error("The input is not an envelope")
|
||||
return Tag(metaFormatKey, metaLength, dataLength)
|
||||
}
|
||||
|
||||
override fun Output.writeThis(obj: Envelope) {
|
||||
val metaBytes = metaFormat.writeBytes(obj.meta)
|
||||
val tag = Tag(metaFormatKey, metaBytes.size.toUInt(), obj.data?.size ?: 0.toULong())
|
||||
@ -101,8 +82,35 @@ class TaggedEnvelopeFormat(val io: IOPlugin, meta: Meta) : EnvelopeFormat {
|
||||
override val name: Name = super.name + VERSION
|
||||
|
||||
override fun invoke(meta: Meta, context: Context): EnvelopeFormat {
|
||||
val plugin = context.plugins.fetch(IOPlugin)
|
||||
return TaggedEnvelopeFormat(plugin, meta)
|
||||
val io = context.io
|
||||
|
||||
val metaFormatName = meta["name"].string?.toName() ?: JsonMetaFormat.name
|
||||
val metaFormatFactory = io.metaFormatFactories.find { it.name == metaFormatName }
|
||||
?: error("Meta format could not be resolved")
|
||||
|
||||
return TaggedEnvelopeFormat(io, metaFormatFactory.key)
|
||||
}
|
||||
|
||||
private fun Input.readTag(): Tag {
|
||||
val start = readTextExactBytes(2)
|
||||
if (start != START_SEQUENCE) error("The input is not an envelope")
|
||||
val version = readTextExactBytes(4)
|
||||
if (version != VERSION) error("Wrong version of DataForge: expected $VERSION but found $version")
|
||||
val metaFormatKey = readShort()
|
||||
val metaLength = readUInt()
|
||||
val dataLength = readULong()
|
||||
val end = readTextExactBytes(4)
|
||||
if (end != END_SEQUENCE) error("The input is not an envelope")
|
||||
return Tag(metaFormatKey, metaLength, dataLength)
|
||||
}
|
||||
|
||||
override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? {
|
||||
return try {
|
||||
val tag = input.readTag()
|
||||
TaggedEnvelopeFormat(io, tag.metaFormatKey)
|
||||
} catch (ex: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
val default = invoke()
|
||||
|
Loading…
Reference in New Issue
Block a user