MetaFormat service loader
This commit is contained in:
parent
3d65a1b409
commit
013a1a935c
@ -1,7 +1,7 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.0'
|
||||
ext.serialization_version = '0.9.0'
|
||||
ext.kotlinx_io_version = '0.1.0-beta-1'
|
||||
ext.kotlin_version = '1.3.10'
|
||||
ext.serialization_version = '0.9.1'
|
||||
ext.kotlinx_io_version = '0.1.1'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'kotlin-multiplatform'
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'kotlin-multiplatform'
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'kotlin-multiplatform'
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -1,8 +1,10 @@
|
||||
plugins {
|
||||
id 'kotlin-multiplatform'
|
||||
id 'kotlinx-serialization'
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
description = "IO for meta"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
@ -0,0 +1,132 @@
|
||||
package hep.dataforge.meta.io
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.values.*
|
||||
import kotlinx.io.core.Input
|
||||
import kotlinx.io.core.Output
|
||||
import kotlinx.io.core.readText
|
||||
import kotlinx.io.core.writeText
|
||||
|
||||
object BinaryMetaFormat : MetaFormat {
|
||||
override fun write(meta: Meta, out: Output) {
|
||||
out.writeMeta(meta)
|
||||
}
|
||||
|
||||
override fun read(input: Input): Meta {
|
||||
return (input.readMetaItem() as MetaItem.NodeItem).node
|
||||
}
|
||||
|
||||
private fun Output.writeChar(char: Char) = writeByte(char.toByte())
|
||||
|
||||
private fun Output.writeString(str: String) {
|
||||
writeInt(str.length)
|
||||
writeText(str)
|
||||
}
|
||||
|
||||
private fun Output.writeValue(value: Value) {
|
||||
if (value.isList()) {
|
||||
writeChar('L')
|
||||
writeInt(value.list.size)
|
||||
value.list.forEach {
|
||||
writeValue(it)
|
||||
}
|
||||
} else when (value.type) {
|
||||
ValueType.NUMBER -> when (value.value) {
|
||||
is Short -> {
|
||||
writeChar('s')
|
||||
writeShort(value.number.toShort())
|
||||
}
|
||||
is Int -> {
|
||||
writeChar('i')
|
||||
writeInt(value.number.toInt())
|
||||
}
|
||||
is Long -> {
|
||||
writeChar('l')
|
||||
writeLong(value.number.toLong())
|
||||
}
|
||||
is Float -> {
|
||||
writeChar('f')
|
||||
writeFloat(value.number.toFloat())
|
||||
}
|
||||
else -> {
|
||||
writeChar('d')
|
||||
writeDouble(value.number.toDouble())
|
||||
}
|
||||
}
|
||||
ValueType.STRING -> {
|
||||
writeChar('S')
|
||||
writeString(value.string)
|
||||
}
|
||||
ValueType.BOOLEAN -> {
|
||||
if (value.boolean) {
|
||||
writeChar('+')
|
||||
} else {
|
||||
writeChar('-')
|
||||
}
|
||||
}
|
||||
ValueType.NULL -> {
|
||||
writeChar('N')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Output.writeMeta(meta: Meta) {
|
||||
writeChar('M')
|
||||
writeInt(meta.items.size)
|
||||
meta.items.forEach { (key, item) ->
|
||||
writeString(key.toString())
|
||||
when (item) {
|
||||
is MetaItem.ValueItem -> {
|
||||
writeValue(item.value)
|
||||
}
|
||||
is MetaItem.NodeItem -> {
|
||||
writeMeta(item.node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Input.readString(): String {
|
||||
val length = readInt()
|
||||
return readText(max = length)
|
||||
}
|
||||
|
||||
private fun Input.readMetaItem(): MetaItem<MetaBuilder> {
|
||||
val keyChar = readByte().toChar()
|
||||
return when (keyChar) {
|
||||
'S' -> MetaItem.ValueItem(StringValue(readString()))
|
||||
'N' -> MetaItem.ValueItem(Null)
|
||||
'+' -> MetaItem.ValueItem(True)
|
||||
'-' -> MetaItem.ValueItem(True)
|
||||
's' -> MetaItem.ValueItem(NumberValue(readShort()))
|
||||
'i' -> MetaItem.ValueItem(NumberValue(readInt()))
|
||||
'l' -> MetaItem.ValueItem(NumberValue(readInt()))
|
||||
'f' -> MetaItem.ValueItem(NumberValue(readFloat()))
|
||||
'd' -> MetaItem.ValueItem(NumberValue(readDouble()))
|
||||
'L' -> {
|
||||
val length = readInt()
|
||||
val list = (1..length).map { (readMetaItem() as MetaItem.ValueItem).value }
|
||||
MetaItem.ValueItem(Value.of(list))
|
||||
}
|
||||
'M' -> {
|
||||
val length = readInt()
|
||||
val meta = buildMeta {
|
||||
(1..length).forEach { _ ->
|
||||
val name = readString()
|
||||
val item = readMetaItem()
|
||||
setItem(name, item)
|
||||
}
|
||||
}
|
||||
MetaItem.NodeItem(meta)
|
||||
}
|
||||
else -> error("Unknown serialization key character: $keyChar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryMetaFormatFactory: MetaFormatFactory{
|
||||
override val name: String = "bin"
|
||||
override val key: Short = 0x4249//BI
|
||||
|
||||
override fun build(): MetaFormat = BinaryMetaFormat
|
||||
}
|
@ -11,9 +11,7 @@ import kotlinx.io.core.writeText
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
|
||||
object JSONMetaFormat : MetaFormat {
|
||||
override val name: String = "json"
|
||||
override val key: Short = 0x4a53//"JS"
|
||||
object JsonMetaFormat : MetaFormat {
|
||||
|
||||
override fun write(meta: Meta, out: Output) {
|
||||
val str = meta.toJson().toString()
|
||||
@ -74,4 +72,11 @@ class JsonMeta(val json: JsonObject) : Meta {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JsonMetaFormatFactory: MetaFormatFactory{
|
||||
override val name: String = "json"
|
||||
override val key: Short = 0x4a53//"JS"
|
||||
|
||||
override fun build() = JsonMetaFormat
|
||||
}
|
@ -1,21 +1,27 @@
|
||||
package hep.dataforge.meta.io
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.values.*
|
||||
import hep.dataforge.meta.Meta
|
||||
import kotlinx.io.core.*
|
||||
|
||||
/**
|
||||
* A format for meta serialization
|
||||
*/
|
||||
interface MetaFormat {
|
||||
val name: String
|
||||
val key: Short
|
||||
|
||||
fun write(meta: Meta, out: Output)
|
||||
fun read(input: Input): Meta
|
||||
}
|
||||
|
||||
fun Meta.asString(format: MetaFormat = JSONMetaFormat): String{
|
||||
/**
|
||||
* ServiceLoader compatible factory
|
||||
*/
|
||||
interface MetaFormatFactory {
|
||||
val name: String
|
||||
val key: Short
|
||||
|
||||
fun build(): MetaFormat
|
||||
}
|
||||
|
||||
fun Meta.asString(format: MetaFormat = JsonMetaFormat): String{
|
||||
val builder = BytePacketBuilder()
|
||||
format.write(this,builder)
|
||||
return builder.build().readText()
|
||||
@ -26,123 +32,3 @@ fun MetaFormat.parse(str: String): Meta{
|
||||
}
|
||||
|
||||
|
||||
object BinaryMetaFormat : MetaFormat {
|
||||
override val name: String = "bin"
|
||||
override val key: Short = 0x4249//BI
|
||||
|
||||
override fun write(meta: Meta, out: Output) {
|
||||
out.writeMeta(meta)
|
||||
}
|
||||
|
||||
override fun read(input: Input): Meta {
|
||||
return (input.readMetaItem() as MetaItem.NodeItem).node
|
||||
}
|
||||
|
||||
private fun Output.writeChar(char: Char) = writeByte(char.toByte())
|
||||
|
||||
private fun Output.writeString(str: String) {
|
||||
writeInt(str.length)
|
||||
writeText(str)
|
||||
}
|
||||
|
||||
private fun Output.writeValue(value: Value) {
|
||||
if (value.isList()) {
|
||||
writeChar('L')
|
||||
writeInt(value.list.size)
|
||||
value.list.forEach {
|
||||
writeValue(it)
|
||||
}
|
||||
} else when (value.type) {
|
||||
ValueType.NUMBER -> when (value.value) {
|
||||
is Short -> {
|
||||
writeChar('s')
|
||||
writeShort(value.number.toShort())
|
||||
}
|
||||
is Int -> {
|
||||
writeChar('i')
|
||||
writeInt(value.number.toInt())
|
||||
}
|
||||
is Long -> {
|
||||
writeChar('l')
|
||||
writeLong(value.number.toLong())
|
||||
}
|
||||
is Float -> {
|
||||
writeChar('f')
|
||||
writeFloat(value.number.toFloat())
|
||||
}
|
||||
else -> {
|
||||
writeChar('d')
|
||||
writeDouble(value.number.toDouble())
|
||||
}
|
||||
}
|
||||
ValueType.STRING -> {
|
||||
writeChar('S')
|
||||
writeString(value.string)
|
||||
}
|
||||
ValueType.BOOLEAN -> {
|
||||
if (value.boolean) {
|
||||
writeChar('+')
|
||||
} else {
|
||||
writeChar('-')
|
||||
}
|
||||
}
|
||||
ValueType.NULL -> {
|
||||
writeChar('N')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Output.writeMeta(meta: Meta) {
|
||||
writeChar('M')
|
||||
writeInt(meta.items.size)
|
||||
meta.items.forEach { (key, item) ->
|
||||
writeString(key.toString())
|
||||
when (item) {
|
||||
is MetaItem.ValueItem -> {
|
||||
writeValue(item.value)
|
||||
}
|
||||
is MetaItem.NodeItem -> {
|
||||
writeMeta(item.node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Input.readString(): String {
|
||||
val length = readInt()
|
||||
return readText(max = length)
|
||||
}
|
||||
|
||||
private fun Input.readMetaItem(): MetaItem<MetaBuilder> {
|
||||
val keyChar = readByte().toChar()
|
||||
return when (keyChar) {
|
||||
'S' -> MetaItem.ValueItem(StringValue(readString()))
|
||||
'N' -> MetaItem.ValueItem(Null)
|
||||
'+' -> MetaItem.ValueItem(True)
|
||||
'-' -> MetaItem.ValueItem(True)
|
||||
's' -> MetaItem.ValueItem(NumberValue(readShort()))
|
||||
'i' -> MetaItem.ValueItem(NumberValue(readInt()))
|
||||
'l' -> MetaItem.ValueItem(NumberValue(readInt()))
|
||||
'f' -> MetaItem.ValueItem(NumberValue(readFloat()))
|
||||
'd' -> MetaItem.ValueItem(NumberValue(readDouble()))
|
||||
'L' -> {
|
||||
val length = readInt()
|
||||
val list = (1..length).map { (readMetaItem() as MetaItem.ValueItem).value }
|
||||
MetaItem.ValueItem(Value.of(list))
|
||||
}
|
||||
'M' -> {
|
||||
val length = readInt()
|
||||
val meta = buildMeta {
|
||||
(1..length).forEach { _ ->
|
||||
val name = readString()
|
||||
val item = readMetaItem()
|
||||
setItem(name, item)
|
||||
}
|
||||
}
|
||||
MetaItem.NodeItem(meta)
|
||||
}
|
||||
else -> error("Unknown serialization key character: $keyChar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,8 @@ class MetaFormatTest{
|
||||
"c" to 11.1
|
||||
}
|
||||
}
|
||||
val string = meta.asString(JSONMetaFormat)
|
||||
val result = JSONMetaFormat.parse(string)
|
||||
val string = meta.asString(JsonMetaFormat)
|
||||
val result = JsonMetaFormat.parse(string)
|
||||
assertEquals(meta,result)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,2 @@
|
||||
hep.dataforge.meta.io.BinaryMetaFormatFactory
|
||||
hep.dataforge.meta.io.JsonMetaFormatFactory
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'kotlin-multiplatform'
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'kotlin-multiplatform'
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'kotlin-multiplatform'
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -10,7 +10,7 @@ pluginManagement {
|
||||
if (requested.id.id == "kotlin-platform-js") {
|
||||
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||
}
|
||||
if (requested.id.id == "kotlin-multiplatform") {
|
||||
if (requested.id.id == "org.jetbrains.kotlin.multiplatform") {
|
||||
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,7 @@ pluginManagement {
|
||||
}
|
||||
}
|
||||
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
|
||||
rootProject.name = 'dataforge-core'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user