Implements Envelope parts
An envelope consisting of other envelopes
This commit is contained in:
parent
f63a2b6e93
commit
5265c0e5ab
@ -1,11 +1,11 @@
|
|||||||
package hep.dataforge.io
|
package hep.dataforge.io
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.Laminate
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.get
|
||||||
|
import hep.dataforge.meta.string
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import kotlinx.io.core.Output
|
|
||||||
import kotlinx.io.core.buildPacket
|
|
||||||
import kotlinx.io.core.readBytes
|
|
||||||
|
|
||||||
interface Envelope {
|
interface Envelope {
|
||||||
val meta: Meta
|
val meta: Meta
|
||||||
@ -83,32 +83,3 @@ fun Envelope.withMetaLayers(vararg layers: Meta): Envelope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EnvelopeBuilder {
|
|
||||||
private val metaBuilder = MetaBuilder()
|
|
||||||
var data: Binary? = null
|
|
||||||
|
|
||||||
fun meta(block: MetaBuilder.() -> Unit) {
|
|
||||||
metaBuilder.apply(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun meta(meta: Meta) {
|
|
||||||
metaBuilder.update(meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
var type by metaBuilder.string(key = Envelope.ENVELOPE_TYPE_KEY)
|
|
||||||
var dataType by metaBuilder.string(key = Envelope.ENVELOPE_DATA_TYPE_KEY)
|
|
||||||
var dataID by metaBuilder.string(key = Envelope.ENVELOPE_DATA_ID_KEY)
|
|
||||||
var description by metaBuilder.string(key = Envelope.ENVELOPE_DESCRIPTION_KEY)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a binary and transform it into byte-array based buffer
|
|
||||||
*/
|
|
||||||
fun data(block: Output.() -> Unit) {
|
|
||||||
val bytes = buildPacket {
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
data = ArrayBinary(bytes.readBytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun build() = SimpleEnvelope(metaBuilder.seal(), data)
|
|
||||||
}
|
|
@ -0,0 +1,36 @@
|
|||||||
|
package hep.dataforge.io
|
||||||
|
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import kotlinx.io.core.Output
|
||||||
|
import kotlinx.io.core.buildPacket
|
||||||
|
import kotlinx.io.core.readBytes
|
||||||
|
|
||||||
|
class EnvelopeBuilder {
|
||||||
|
private val metaBuilder = MetaBuilder()
|
||||||
|
var data: Binary? = null
|
||||||
|
|
||||||
|
fun meta(block: MetaBuilder.() -> Unit) {
|
||||||
|
metaBuilder.apply(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun meta(meta: Meta) {
|
||||||
|
metaBuilder.update(meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
var type by metaBuilder.string(key = Envelope.ENVELOPE_TYPE_KEY)
|
||||||
|
var dataType by metaBuilder.string(key = Envelope.ENVELOPE_DATA_TYPE_KEY)
|
||||||
|
var dataID by metaBuilder.string(key = Envelope.ENVELOPE_DATA_ID_KEY)
|
||||||
|
var description by metaBuilder.string(key = Envelope.ENVELOPE_DESCRIPTION_KEY)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a binary and transform it into byte-array based buffer
|
||||||
|
*/
|
||||||
|
fun data(block: Output.() -> Unit) {
|
||||||
|
val bytes = buildPacket {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
data = ArrayBinary(bytes.readBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun build() = SimpleEnvelope(metaBuilder.seal(), data)
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package hep.dataforge.io
|
||||||
|
|
||||||
|
import hep.dataforge.context.Global
|
||||||
|
import hep.dataforge.io.EnvelopeParts.FORMAT_META_KEY
|
||||||
|
import hep.dataforge.io.EnvelopeParts.FORMAT_NAME_KEY
|
||||||
|
import hep.dataforge.io.EnvelopeParts.PARTS_DATA_TYPE
|
||||||
|
import hep.dataforge.io.EnvelopeParts.SIZE_KEY
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.names.plus
|
||||||
|
import hep.dataforge.names.toName
|
||||||
|
|
||||||
|
object EnvelopeParts {
|
||||||
|
val SIZE_KEY = Envelope.ENVELOPE_NODE_KEY + "parts" + "size"
|
||||||
|
val FORMAT_NAME_KEY = Envelope.ENVELOPE_NODE_KEY + "parts" + "format"
|
||||||
|
val FORMAT_META_KEY = Envelope.ENVELOPE_NODE_KEY + "parts" + "meta"
|
||||||
|
|
||||||
|
const val PARTS_DATA_TYPE = "envelope.parts"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EnvelopeBuilder.parts(formatFactory: EnvelopeFormatFactory, envelopes: Collection<Envelope>) {
|
||||||
|
dataType = PARTS_DATA_TYPE
|
||||||
|
meta {
|
||||||
|
SIZE_KEY put envelopes.size
|
||||||
|
FORMAT_NAME_KEY put formatFactory.name.toString()
|
||||||
|
}
|
||||||
|
val format = formatFactory()
|
||||||
|
data {
|
||||||
|
format.run {
|
||||||
|
envelopes.forEach {
|
||||||
|
writeObject(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EnvelopeBuilder.parts(formatFactory: EnvelopeFormatFactory, builder: suspend SequenceScope<Envelope>.() -> Unit) =
|
||||||
|
parts(formatFactory, sequence(builder).toList())
|
||||||
|
|
||||||
|
fun Envelope.parts(io: IOPlugin = Global.plugins.fetch(IOPlugin)): Sequence<Envelope> {
|
||||||
|
return when (dataType) {
|
||||||
|
PARTS_DATA_TYPE -> {
|
||||||
|
val size = meta[SIZE_KEY].int ?: error("Unsized parts not supported yet")
|
||||||
|
val formatName = meta[FORMAT_NAME_KEY].string?.toName()
|
||||||
|
?: error("Inferring parts format is not supported at the moment")
|
||||||
|
val formatMeta = meta[FORMAT_META_KEY].node ?: EmptyMeta
|
||||||
|
val format = io.envelopeFormat(formatName, formatMeta)
|
||||||
|
?: error("Format $formatName is not resolved by $io")
|
||||||
|
return format.run {
|
||||||
|
data?.read {
|
||||||
|
sequence {
|
||||||
|
repeat(size) {
|
||||||
|
yield(readObject())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: emptySequence()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> emptySequence()
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,9 @@ class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
context.content<EnvelopeFormatFactory>(ENVELOPE_FORMAT_TYPE).values
|
context.content<EnvelopeFormatFactory>(ENVELOPE_FORMAT_TYPE).values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun envelopeFormat(name: Name, meta: Meta = EmptyMeta) =
|
||||||
|
envelopeFormatFactories.find { it.name == name }?.invoke(meta, context)
|
||||||
|
|
||||||
override fun provideTop(target: String): Map<Name, Any> {
|
override fun provideTop(target: String): Map<Name, Any> {
|
||||||
return when (target) {
|
return when (target) {
|
||||||
META_FORMAT_TYPE -> defaultMetaFormats.toMap()
|
META_FORMAT_TYPE -> defaultMetaFormats.toMap()
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package hep.dataforge.io
|
||||||
|
|
||||||
|
import hep.dataforge.meta.get
|
||||||
|
import hep.dataforge.meta.int
|
||||||
|
import kotlinx.io.core.writeText
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class EnvelopePartsTest {
|
||||||
|
val envelopes = (0..5).map {
|
||||||
|
Envelope {
|
||||||
|
meta {
|
||||||
|
"value" put it
|
||||||
|
}
|
||||||
|
data {
|
||||||
|
writeText("Hello World $it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val partsEnvelope = Envelope {
|
||||||
|
parts(TaggedEnvelopeFormat, envelopes)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testParts() {
|
||||||
|
val bytes = TaggedEnvelopeFormat.default.writeBytes(partsEnvelope)
|
||||||
|
val reconstructed = TaggedEnvelopeFormat.default.readBytes(bytes)
|
||||||
|
val parts = reconstructed.parts().toList()
|
||||||
|
assertEquals(2, parts[2].meta["value"].int)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user