Merge pull request '0.7.0' (!79) from dev into master

Reviewed-on: #79
This commit is contained in:
Alexander Nozik 2023-11-26 10:08:10 +03:00
commit c754dc3471
73 changed files with 977 additions and 765 deletions

View File

@ -1,4 +0,0 @@
job("Build") {
gradlew("openjdk:11", "build")
}

View File

@ -14,15 +14,41 @@
### Security ### Security
## 0.7.0 - 2023-11-26
### Added
- Obligatory `type: KType` and `descriptor` property for `MetaConverters`
- Added separate `Meta`, `SealedMeta` and `ObservableMutableMeta` builders.
### Changed
- Meta converter `metaToObject` returns a non-nullable type. Additional method `metaToObjectOrNull` for nullable return.
- Kotlin 1.9.20.
- Migrated from ktor-io to kotlinx-io.
- `MutableMeta` builder now returns a simplified version of meta that does not hold listeners.
- More concise names for read/write methods in IO.
- Remove unnecessary confusion with `get`/`getMeta` by removing `getMeta` from the interface.
### Deprecated
- `String.parseValue` is replaced with `Value.parse`
### Fixed
- Memory leak in SealedMeta builder
## 0.6.2 - 2023-07-29 ## 0.6.2 - 2023-07-29
### Changed ### Changed
- Meta to Json serializer now serializes a single item with index as an array. It is important for plotly integration. - Meta to Json serializer now serializes a single item with index as an array. It is important for plotly integration.
- Meta to Json serializes Meta without children a value as literal or array instead of an object with `@value` field. - Meta to Json serializes Meta without children a value as literal or array instead of an object with `@value` field.
## 0.6.1 - 2023-03-31 ## 0.6.1 - 2023-03-31
### Added ### Added
- File cache for workspace - File cache for workspace
- Smart task metadata transformation for workspace - Smart task metadata transformation for workspace
- Add `readOnly` property to descriptors - Add `readOnly` property to descriptors
@ -32,6 +58,7 @@
- More fine-grained types in Action builders. - More fine-grained types in Action builders.
### Changed ### Changed
- `Name::replaceLast` API - `Name::replaceLast` API
- `PluginFactory` no longer requires plugin class - `PluginFactory` no longer requires plugin class
- Collection<Named> toMap -> associateByName - Collection<Named> toMap -> associateByName
@ -53,9 +80,11 @@
- Separate interfaces for `IOReader` and `IOWriter` - Separate interfaces for `IOReader` and `IOWriter`
### Deprecated ### Deprecated
- Context.fetch -> Context.request - Context.fetch -> Context.request
### Fixed ### Fixed
- `readDataDirectory` does not split names with dots - `readDataDirectory` does not split names with dots
- Front matter reader does not crash on non-UTF files - Front matter reader does not crash on non-UTF files
- Meta file name in readMeta from directory - Meta file name in readMeta from directory
@ -64,10 +93,12 @@
## 0.5.2 ## 0.5.2
### Added ### Added
- Yaml plugin - Yaml plugin
- Partial fix to #53 - Partial fix to #53
### Fixed ### Fixed
- MutableMetaImpl attachment and checks - MutableMetaImpl attachment and checks
- Listeners in observable meta are replaced by lists - Listeners in observable meta are replaced by lists
- JS number comparison bug. - JS number comparison bug.
@ -75,9 +106,11 @@
## 0.5.0 ## 0.5.0
### Added ### Added
- Experimental `listOfSpec` delegate. - Experimental `listOfSpec` delegate.
### Changed ### Changed
- **API breaking** Config is deprecated, use `ObservableMeta` instead. - **API breaking** Config is deprecated, use `ObservableMeta` instead.
- **API breaking** Descriptor no has a member property `defaultValue` instead of `defaultItem()` extension. It caches default value state on the first call. It is done because computing default on each call is too expensive. - **API breaking** Descriptor no has a member property `defaultValue` instead of `defaultItem()` extension. It caches default value state on the first call. It is done because computing default on each call is too expensive.
- Kotlin 1.5.10 - Kotlin 1.5.10
@ -88,24 +121,28 @@
- **API breaking** Configurable`config` changed to `meta` - **API breaking** Configurable`config` changed to `meta`
### Removed ### Removed
- `Config` - `Config`
- Public PluginManager mutability - Public PluginManager mutability
- Tables and tables-exposed moved to the separate project `tables.kt` - Tables and tables-exposed moved to the separate project `tables.kt`
- BinaryMetaFormat. Use CBOR encoding instead - BinaryMetaFormat. Use CBOR encoding instead
### Fixed ### Fixed
- Proper json array index treatment. - Proper json array index treatment.
- Proper json index for single-value array. - Proper json index for single-value array.
## 0.4.0 ## 0.4.0
### Added ### Added
- LogManager plugin - LogManager plugin
- dataforge-context API dependency on SLF4j - dataforge-context API dependency on SLF4j
- Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation. - Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation.
- Split `ItemDescriptor` into builder and read-only part - Split `ItemDescriptor` into builder and read-only part
### Changed ### Changed
- Kotlin-logging moved from common to JVM and JS. Replaced by console for native. - Kotlin-logging moved from common to JVM and JS. Replaced by console for native.
- Package changed to `space.kscience` - Package changed to `space.kscience`
- Scheme made observable - Scheme made observable
@ -115,18 +152,22 @@
- Refactor loggers - Refactor loggers
### Deprecated ### Deprecated
- Direct use of PluginManager - Direct use of PluginManager
### Removed ### Removed
- Common dependency on Kotlin-logging - Common dependency on Kotlin-logging
- Kotlinx-io fork dependency. Replaced by Ktor-io. - Kotlinx-io fork dependency. Replaced by Ktor-io.
### Fixed ### Fixed
- Scheme properties properly handle children property change. - Scheme properties properly handle children property change.
## 0.3.0 ## 0.3.0
### Added ### Added
- Yaml meta format based on yaml.kt - Yaml meta format based on yaml.kt
- `Path` builders - `Path` builders
- Special ValueType for lists - Special ValueType for lists
@ -134,6 +175,7 @@
- Multiplatform yaml meta - Multiplatform yaml meta
### Changed ### Changed
- `ListValue` and `DoubleArrayValue` implement `Iterable`. - `ListValue` and `DoubleArrayValue` implement `Iterable`.
- Changed the logic of `Value::isList` to check for type instead of size - Changed the logic of `Value::isList` to check for type instead of size
- `Meta{}` builder made inline - `Meta{}` builder made inline
@ -150,6 +192,7 @@
## 0.2.0 ## 0.2.0
### Changed ### Changed
- Context content resolution refactor - Context content resolution refactor
- Kotlin 1.4.10 (build tools 0.6.0) - Kotlin 1.4.10 (build tools 0.6.0)
- Empty query in Name is null instead of "" - Empty query in Name is null instead of ""
@ -159,13 +202,16 @@
- Configurable is no longer MutableItemProvider. All functionality moved to Scheme. - Configurable is no longer MutableItemProvider. All functionality moved to Scheme.
### Deprecated ### Deprecated
- Context activation API - Context activation API
- TextRenderer - TextRenderer
### Removed ### Removed
- Functional server prototype - Functional server prototype
- `dataforge-output` module - `dataforge-output` module
### Fixed ### Fixed
- Global context CoroutineScope resolution - Global context CoroutineScope resolution
- Library mode compliance - Library mode compliance

View File

@ -5,33 +5,30 @@
### [dataforge-context](dataforge-context) ### [dataforge-context](dataforge-context)
> > Context and provider definitions
> >
> **Maturity**: DEVELOPMENT > **Maturity**: DEVELOPMENT
### [dataforge-data](dataforge-data) ### [dataforge-data](dataforge-data)
> >
>
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
### [dataforge-io](dataforge-io) ### [dataforge-io](dataforge-io)
> IO module
> >
> > **Maturity**: EXPERIMENTAL
> **Maturity**: PROTOTYPE
### [dataforge-meta](dataforge-meta) ### [dataforge-meta](dataforge-meta)
> > Meta definition and basic operations on meta
> >
> **Maturity**: DEVELOPMENT > **Maturity**: DEVELOPMENT
### [dataforge-scripting](dataforge-scripting) ### [dataforge-scripting](dataforge-scripting)
> >
>
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
### [dataforge-workspace](dataforge-workspace) ### [dataforge-workspace](dataforge-workspace)
> >
>
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
### [dataforge-io/dataforge-io-yaml](dataforge-io/dataforge-io-yaml) ### [dataforge-io/dataforge-io-yaml](dataforge-io/dataforge-io-yaml)

View File

@ -1,5 +1,4 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import space.kscience.gradle.isInDevelopment
import space.kscience.gradle.useApache2Licence import space.kscience.gradle.useApache2Licence
import space.kscience.gradle.useSPCTeam import space.kscience.gradle.useSPCTeam
@ -9,7 +8,7 @@ plugins {
allprojects { allprojects {
group = "space.kscience" group = "space.kscience"
version = "0.6.2" version = "0.7.0"
} }
subprojects { subprojects {
@ -31,14 +30,7 @@ ksciencePublish {
useApache2Licence() useApache2Licence()
useSPCTeam() useSPCTeam()
} }
github("dataforge-core", "SciProgCentre") repository("spc","https://maven.sciprog.center/kscience")
space(
if (isInDevelopment) {
"https://maven.pkg.jetbrains.space/spc/p/sci/dev"
} else {
"https://maven.pkg.jetbrains.space/spc/p/sci/maven"
}
)
sonatype() sonatype()
} }

View File

@ -6,27 +6,18 @@ Context and provider definitions
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-context:0.6.2-dev-2`. The Maven coordinates of this project are `space.kscience:dataforge-context:0.7.0`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:dataforge-context:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("space.kscience:dataforge-context:0.6.2-dev-2") implementation("space.kscience:dataforge-context:0.7.0")
} }
``` ```

View File

@ -195,7 +195,6 @@ public final class space/kscience/dataforge/context/PluginManager : java/lang/It
public final class space/kscience/dataforge/context/PluginTag : space/kscience/dataforge/meta/MetaRepr { public final class space/kscience/dataforge/context/PluginTag : space/kscience/dataforge/meta/MetaRepr {
public static final field Companion Lspace/kscience/dataforge/context/PluginTag$Companion; public static final field Companion Lspace/kscience/dataforge/context/PluginTag$Companion;
public static final field DATAFORGE_GROUP Ljava/lang/String; public static final field DATAFORGE_GROUP Ljava/lang/String;
public synthetic fun <init> (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String; public final fun component1 ()Ljava/lang/String;
@ -211,7 +210,6 @@ public final class space/kscience/dataforge/context/PluginTag : space/kscience/d
public final fun matches (Lspace/kscience/dataforge/context/PluginTag;)Z public final fun matches (Lspace/kscience/dataforge/context/PluginTag;)Z
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun toString ()Ljava/lang/String; public fun toString ()Ljava/lang/String;
public static final synthetic fun write$Self (Lspace/kscience/dataforge/context/PluginTag;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
} }
public final class space/kscience/dataforge/context/PluginTag$$serializer : kotlinx/serialization/internal/GeneratedSerializer { public final class space/kscience/dataforge/context/PluginTag$$serializer : kotlinx/serialization/internal/GeneratedSerializer {

View File

@ -3,8 +3,8 @@ package space.kscience.dataforge.context
import space.kscience.dataforge.context.Plugin.Companion.TARGET import space.kscience.dataforge.context.Plugin.Companion.TARGET
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MetaRepr import space.kscience.dataforge.meta.MetaRepr
import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.misc.Named import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.misc.Type
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.parseAsName
import space.kscience.dataforge.provider.Provider import space.kscience.dataforge.provider.Provider
@ -18,7 +18,7 @@ import space.kscience.dataforge.provider.Provider
* *
* create - configure - attach - detach - destroy * create - configure - attach - detach - destroy
*/ */
@Type(TARGET) @DfId(TARGET)
public interface Plugin : Named, ContextAware, Provider, MetaRepr { public interface Plugin : Named, ContextAware, Provider, MetaRepr {
/** /**

View File

@ -1,9 +1,9 @@
package space.kscience.dataforge.context package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
@Type(PluginFactory.TYPE) @DfId(PluginFactory.TYPE)
public interface PluginFactory<T : Plugin> : Factory<T> { public interface PluginFactory<T : Plugin> : Factory<T> {
public val tag: PluginTag public val tag: PluginTag

View File

@ -1,7 +1,8 @@
package space.kscience.dataforge.properties package space.kscience.dataforge.properties
import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.ObservableMutableMeta
import space.kscience.dataforge.meta.transformations.MetaConverter import space.kscience.dataforge.meta.transformations.MetaConverter
import space.kscience.dataforge.meta.transformations.nullableMetaToObject import space.kscience.dataforge.meta.transformations.nullableMetaToObject
import space.kscience.dataforge.meta.transformations.nullableObjectToMeta import space.kscience.dataforge.meta.transformations.nullableObjectToMeta
@ -24,7 +25,7 @@ public class MetaProperty<T : Any>(
override fun onChange(owner: Any?, callback: (T?) -> Unit) { override fun onChange(owner: Any?, callback: (T?) -> Unit) {
meta.onChange(owner) { name -> meta.onChange(owner) { name ->
if (name.startsWith(this@MetaProperty.name)) callback(converter.nullableMetaToObject(get(name))) if (name.startsWith(this@MetaProperty.name)) callback(converter.nullableMetaToObject(this[name]))
} }
} }

View File

@ -4,29 +4,29 @@ import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginBuilder import space.kscience.dataforge.context.PluginBuilder
import space.kscience.dataforge.context.gather import space.kscience.dataforge.context.gather
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.misc.Named import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.misc.Type
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation import kotlin.reflect.full.findAnnotation
@DFExperimental @DFExperimental
public val KClass<*>.dfType: String public val KClass<*>.dfId: String
get() = findAnnotation<Type>()?.id ?: simpleName ?: "" get() = findAnnotation<DfId>()?.id ?: simpleName ?: ""
/** /**
* Provide an object with given name inferring target from its type using [Type] annotation * Provide an object with given name inferring target from its type using [DfId] annotation
*/ */
@DFExperimental @DFExperimental
public inline fun <reified T : Any> Provider.provideByType(name: String): T? { public inline fun <reified T : Any> Provider.provideByType(name: String): T? {
val target = T::class.dfType val target = T::class.dfId
return provide(target, name) return provide(target, name)
} }
@DFExperimental @DFExperimental
public inline fun <reified T : Any> Provider.top(): Map<Name, T> { public inline fun <reified T : Any> Provider.top(): Map<Name, T> {
val target = T::class.dfType val target = T::class.dfId
return top(target) return top(target)
} }
@ -35,15 +35,15 @@ public inline fun <reified T : Any> Provider.top(): Map<Name, T> {
*/ */
@DFExperimental @DFExperimental
public inline fun <reified T : Any> Context.gather(inherit: Boolean = true): Map<Name, T> = public inline fun <reified T : Any> Context.gather(inherit: Boolean = true): Map<Name, T> =
gather<T>(T::class.dfType, inherit) gather<T>(T::class.dfId, inherit)
@DFExperimental @DFExperimental
public inline fun <reified T : Any> PluginBuilder.provides(items: Map<Name, T>) { public inline fun <reified T : Any> PluginBuilder.provides(items: Map<Name, T>) {
provides(T::class.dfType, items) provides(T::class.dfId, items)
} }
@DFExperimental @DFExperimental
public inline fun <reified T : Any> PluginBuilder.provides(vararg items: Named) { public inline fun <reified T : Any> PluginBuilder.provides(vararg items: Named) {
provides(T::class.dfType, *items) provides(T::class.dfId, *items)
} }

View File

@ -6,27 +6,18 @@
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-data:0.6.2-dev-2`. The Maven coordinates of this project are `space.kscience:dataforge-data:0.7.0`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:dataforge-data:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("space.kscience:dataforge-data:0.6.2-dev-2") implementation("space.kscience:dataforge-data:0.7.0")
} }
``` ```

View File

@ -5,7 +5,7 @@ import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MetaRepr import space.kscience.dataforge.meta.MetaRepr
import space.kscience.dataforge.meta.isEmpty import space.kscience.dataforge.meta.isEmpty
import space.kscience.dataforge.misc.DFInternal import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KType import kotlin.reflect.KType
@ -14,7 +14,7 @@ import kotlin.reflect.typeOf
/** /**
* A data element characterized by its meta * A data element characterized by its meta
*/ */
@Type(Data.TYPE) @DfId(Data.TYPE)
public interface Data<out T> : Goal<T>, MetaRepr { public interface Data<out T> : Goal<T>, MetaRepr {
/** /**
* Type marker for the data. The type is known before the calculation takes place so it could be checked. * Type marker for the data. The type is known before the calculation takes place so it could be checked.

View File

@ -6,7 +6,6 @@ import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
import space.kscience.dataforge.data.Data.Companion.TYPE_OF_NOTHING import space.kscience.dataforge.data.Data.Companion.TYPE_OF_NOTHING
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.set
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.endsWith import space.kscience.dataforge.names.endsWith

View File

@ -2,7 +2,7 @@ package space.kscience.dataforge.data
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFInternal import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.names.* import space.kscience.dataforge.names.*
import kotlin.collections.component1 import kotlin.collections.component1
import kotlin.collections.component2 import kotlin.collections.component2
@ -31,7 +31,7 @@ public val <T : Any> DataTreeItem<T>.type: KType
/** /**
* A tree-like [DataSet] grouped into the node. All data inside the node must inherit its type * A tree-like [DataSet] grouped into the node. All data inside the node must inherit its type
*/ */
@Type(DataTree.TYPE) @DfId(DataTree.TYPE)
public interface DataTree<out T : Any> : DataSet<T> { public interface DataTree<out T : Any> : DataSet<T> {
/** /**

View File

@ -6,27 +6,18 @@ IO module
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-io:0.6.2-dev-2`. The Maven coordinates of this project are `space.kscience:dataforge-io:0.7.0`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:dataforge-io:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("space.kscience:dataforge-io:0.6.2-dev-2") implementation("space.kscience:dataforge-io:0.7.0")
} }
``` ```

View File

@ -1,11 +1,11 @@
import space.kscience.gradle.KScienceVersions
plugins { plugins {
id("space.kscience.gradle.mpp") id("space.kscience.gradle.mpp")
} }
description = "IO module" description = "IO module"
val ioVersion = "0.2.1"
kscience { kscience {
jvm() jvm()
js() js()
@ -15,11 +15,12 @@ kscience {
cbor() cbor()
} }
dependencies { dependencies {
api(project(":dataforge-context")) api(projects.dataforgeContext)
api("io.ktor:ktor-io:${KScienceVersions.ktorVersion}") api("org.jetbrains.kotlinx:kotlinx-io-core:$ioVersion")
api("org.jetbrains.kotlinx:kotlinx-io-bytestring:$ioVersion")
} }
} }
readme { readme{
maturity = space.kscience.gradle.Maturity.PROTOTYPE maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
} }

View File

@ -6,27 +6,18 @@ YAML meta IO
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-io-yaml:0.6.2-dev-2`. The Maven coordinates of this project are `space.kscience:dataforge-io-yaml:0.7.0`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:dataforge-io-yaml:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("space.kscience:dataforge-io-yaml:0.6.2-dev-2") implementation("space.kscience:dataforge-io-yaml:0.7.0")
} }
``` ```

View File

@ -1,7 +1,11 @@
package space.kscience.dataforge.io.yaml package space.kscience.dataforge.io.yaml
import io.ktor.utils.io.core.Input import kotlinx.io.Sink
import io.ktor.utils.io.core.Output import kotlinx.io.Source
import kotlinx.io.bytestring.ByteString
import kotlinx.io.bytestring.encodeToByteString
import kotlinx.io.readByteString
import kotlinx.io.writeString
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.io.* import space.kscience.dataforge.io.*
@ -15,49 +19,49 @@ public class FrontMatterEnvelopeFormat(
private val metaFormatFactory: MetaFormatFactory = YamlMetaFormat, private val metaFormatFactory: MetaFormatFactory = YamlMetaFormat,
) : EnvelopeFormat { ) : EnvelopeFormat {
override fun readObject(binary: Binary): Envelope = binary.read { override fun readFrom(binary: Binary): Envelope = binary.read {
var offset = 0 var offset = 0
offset += discardWithSeparator( offset += discardWithSeparator(
SEPARATOR.encodeToByteArray(), SEPARATOR,
atMost = 1024, atMost = 1024,
) )
val line = ByteArray { val line = ByteArray {
offset += readWithSeparatorTo(this, "\n".encodeToByteArray()) offset += readWithSeparatorTo(this, "\n".encodeToByteString())
}.decodeToString() }.decodeToString()
val readMetaFormat = line.trim().takeIf { it.isNotBlank() }?.let { io.resolveMetaFormat(it) } ?: YamlMetaFormat val readMetaFormat = line.trim().takeIf { it.isNotBlank() }?.let { io.resolveMetaFormat(it) } ?: YamlMetaFormat
val packet = ByteArray { val packet = ByteArray {
offset += readWithSeparatorTo(this, SEPARATOR.encodeToByteArray()) offset += readWithSeparatorTo(this, SEPARATOR)
} }
offset += discardLine() offset += discardLine()
val meta = readMetaFormat.readObject(packet.asBinary()) val meta = readMetaFormat.readFrom(packet.asBinary())
Envelope(meta, binary.view(offset)) Envelope(meta, binary.view(offset))
} }
override fun readObject(input: Input): Envelope = readObject(input.readBinary()) override fun readFrom(source: Source): Envelope = readFrom(source.readBinary())
override fun writeObject( override fun writeTo(
output: Output, sink: Sink,
obj: Envelope, obj: Envelope,
) { ) {
val metaFormat = metaFormatFactory.build(io.context, meta) val metaFormat = metaFormatFactory.build(io.context, meta)
val formatSuffix = if (metaFormat is YamlMetaFormat) "" else metaFormatFactory.shortName val formatSuffix = if (metaFormat is YamlMetaFormat) "" else metaFormatFactory.shortName
output.writeRawString("$SEPARATOR${formatSuffix}\r\n") sink.writeString("$SEPARATOR${formatSuffix}\r\n")
metaFormat.run { metaFormat.writeObject(output, obj.meta) } metaFormat.run { metaFormat.writeTo(sink, obj.meta) }
output.writeRawString("$SEPARATOR\r\n") sink.writeString("$SEPARATOR\r\n")
//Printing data //Printing data
obj.data?.let { data -> obj.data?.let { data ->
output.writeBinary(data) sink.writeBinary(data)
} }
} }
public companion object : EnvelopeFormatFactory { public companion object : EnvelopeFormatFactory {
public const val SEPARATOR: String = "---" public val SEPARATOR: ByteString = "---".encodeToByteString()
private val metaTypeRegex = "---(\\w*)\\s*".toRegex() private val metaTypeRegex = "---(\\w*)\\s*".toRegex()
@ -69,8 +73,8 @@ public class FrontMatterEnvelopeFormat(
override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? = binary.read { override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? = binary.read {
//read raw string to avoid UTF issues //read raw string to avoid UTF issues
val line = readRawString(3) val line = readByteString(3)
return@read if (line == "---") { return@read if (line == "---".encodeToByteString()) {
default default
} else { } else {
null null
@ -79,15 +83,15 @@ public class FrontMatterEnvelopeFormat(
private val default by lazy { build(Global, Meta.EMPTY) } private val default by lazy { build(Global, Meta.EMPTY) }
override fun readObject(binary: Binary): Envelope = default.readObject(binary) override fun readFrom(binary: Binary): Envelope = default.readFrom(binary)
override fun writeObject( override fun writeTo(
output: Output, sink: Sink,
obj: Envelope, obj: Envelope,
): Unit = default.writeObject(output, obj) ): Unit = default.writeTo(sink, obj)
override fun readObject(input: Input): Envelope = default.readObject(input) override fun readFrom(source: Source): Envelope = default.readFrom(source)
} }
} }

View File

@ -1,13 +1,13 @@
package space.kscience.dataforge.io.yaml package space.kscience.dataforge.io.yaml
import io.ktor.utils.io.core.Input import kotlinx.io.Sink
import io.ktor.utils.io.core.Output import kotlinx.io.Source
import kotlinx.io.readString
import kotlinx.io.writeString
import net.mamoe.yamlkt.* import net.mamoe.yamlkt.*
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.io.MetaFormat import space.kscience.dataforge.io.MetaFormat
import space.kscience.dataforge.io.MetaFormatFactory import space.kscience.dataforge.io.MetaFormatFactory
import space.kscience.dataforge.io.readUtf8String
import space.kscience.dataforge.io.writeUtf8String
import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.*
import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.meta.descriptors.get
@ -32,7 +32,7 @@ public fun Meta.toYaml(): YamlMap {
private class YamlMeta(private val yamlMap: YamlMap, private val descriptor: MetaDescriptor? = null) : Meta { private class YamlMeta(private val yamlMap: YamlMap, private val descriptor: MetaDescriptor? = null) : Meta {
override val value: Value? override val value: Value?
get() = yamlMap.getStringOrNull(null)?.parseValue() get() = yamlMap.getStringOrNull(null)?.let { Value.parse(it) }
private fun buildItems(): Map<NameToken, Meta> { private fun buildItems(): Map<NameToken, Meta> {
val map = LinkedHashMap<NameToken, Meta>() val map = LinkedHashMap<NameToken, Meta>()
@ -43,13 +43,13 @@ private class YamlMeta(private val yamlMap: YamlMap, private val descriptor: Met
val token = NameToken(stringKey) val token = NameToken(stringKey)
when (value) { when (value) {
YamlNull -> Meta(Null) YamlNull -> Meta(Null)
is YamlLiteral -> map[token] = Meta(value.content.parseValue()) is YamlLiteral -> map[token] = Meta(Value.parse(value.content))
is YamlMap -> map[token] = value.toMeta() is YamlMap -> map[token] = value.toMeta()
is YamlList -> if (value.all { it is YamlLiteral }) { is YamlList -> if (value.all { it is YamlLiteral }) {
val listValue = ListValue( val listValue = ListValue(
value.map { value.map {
//We already checked that all values are primitives //We already checked that all values are primitives
(it as YamlLiteral).content.parseValue() Value.parse((it as YamlLiteral).content)
} }
) )
map[token] = Meta(listValue) map[token] = Meta(listValue)
@ -75,7 +75,7 @@ private class YamlMeta(private val yamlMap: YamlMap, private val descriptor: Met
public fun YamlElement.toMeta(descriptor: MetaDescriptor? = null): Meta = when (this) { public fun YamlElement.toMeta(descriptor: MetaDescriptor? = null): Meta = when (this) {
YamlNull -> Meta(Null) YamlNull -> Meta(Null)
is YamlLiteral -> Meta(content.parseValue()) is YamlLiteral -> Meta(Value.parse(content))
is YamlMap -> toMeta() is YamlMap -> toMeta()
//We can't return multiple items therefore we create top level node //We can't return multiple items therefore we create top level node
is YamlList -> YamlMap(mapOf("@yamlArray" to this)).toMeta(descriptor) is YamlList -> YamlMap(mapOf("@yamlArray" to this)).toMeta(descriptor)
@ -89,14 +89,14 @@ public fun YamlMap.toMeta(): Meta = YamlMeta(this)
*/ */
public class YamlMetaFormat(private val meta: Meta) : MetaFormat { public class YamlMetaFormat(private val meta: Meta) : MetaFormat {
override fun writeMeta(output: Output, meta: Meta, descriptor: MetaDescriptor?) { override fun writeMeta(sink: Sink, meta: Meta, descriptor: MetaDescriptor?) {
val yaml: YamlMap = meta.toYaml() val yaml: YamlMap = meta.toYaml()
val string = Yaml.encodeToString(YamlMap.serializer(), yaml) val string = Yaml.encodeToString(YamlMap.serializer(), yaml)
output.writeUtf8String(string) sink.writeString(string)
} }
override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta { override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta {
val yaml = Yaml.decodeYamlMapFromString(input.readUtf8String()) val yaml = Yaml.decodeYamlMapFromString(source.readString())
return yaml.toMeta() return yaml.toMeta()
} }
@ -109,10 +109,10 @@ public class YamlMetaFormat(private val meta: Meta) : MetaFormat {
private val default = YamlMetaFormat(Meta.EMPTY) private val default = YamlMetaFormat(Meta.EMPTY)
override fun writeMeta(output: Output, meta: Meta, descriptor: MetaDescriptor?): Unit = override fun writeMeta(sink: Sink, meta: Meta, descriptor: MetaDescriptor?): Unit =
default.writeMeta(output, meta, descriptor) default.writeMeta(sink, meta, descriptor)
override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta = override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta =
default.readMeta(input, descriptor) default.readMeta(source, descriptor)
} }
} }

View File

@ -1,6 +1,9 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.* import kotlinx.io.Sink
import kotlinx.io.Source
import kotlinx.io.buffered
import kotlinx.io.readByteArray
import kotlin.math.min import kotlin.math.min
/** /**
@ -17,13 +20,13 @@ public interface Binary {
* Read maximum of [atMost] bytes as input from the binary, starting at [offset]. The generated input is always closed * Read maximum of [atMost] bytes as input from the binary, starting at [offset]. The generated input is always closed
* when leaving scope, so it could not be leaked outside of scope of [block]. * when leaving scope, so it could not be leaked outside of scope of [block].
*/ */
public fun <R> read(offset: Int = 0, atMost: Int = size - offset, block: Input.() -> R): R public fun <R> read(offset: Int = 0, atMost: Int = size - offset, block: Source.() -> R): R
public suspend fun <R> readSuspend(offset: Int = 0, atMost: Int = size - offset, block: suspend Input.() -> R): R public suspend fun <R> readSuspend(offset: Int = 0, atMost: Int = size - offset, block: suspend Source.() -> R): R
/** /**
* Read a binary with given [offset] relative to this binary and given [binarySize]. * Read a binary with given [offset] relative to this binary and given [binarySize].
* In general, resulting binary is of the same type as this one, but it is not guaranteed. * In general, the resulting binary is of the same type as this one, but it is not guaranteed.
*/ */
public fun view(offset: Int, binarySize: Int = size - offset): Binary public fun view(offset: Int, binarySize: Int = size - offset): Binary
@ -38,25 +41,27 @@ internal class ByteArrayBinary(
override val size: Int = array.size - start, override val size: Int = array.size - start,
) : Binary { ) : Binary {
override fun <R> read(offset: Int, atMost: Int, block: Input.() -> R): R { override fun <R> read(offset: Int, atMost: Int, block: Source.() -> R): R {
require(offset >= 0) { "Offset must be positive" } require(offset >= 0) { "Offset must be positive" }
require(offset < array.size) { "Offset $offset is larger than array size" } require(offset < array.size) { "Offset $offset is larger than array size" }
val input = ByteReadPacket(
return ByteArraySource(
array, array,
offset + start, offset + start,
min(atMost, size - offset) min(atMost, size - offset)
) ).buffered().use(block)
return input.use(block)
} }
override suspend fun <R> readSuspend(offset: Int, atMost: Int, block: suspend Input.() -> R): R { override suspend fun <R> readSuspend(offset: Int, atMost: Int, block: suspend Source.() -> R): R {
require(offset >= 0) { "Offset must be positive" } require(offset >= 0) { "Offset must be positive" }
require(offset < array.size) { "Offset $offset is larger than array size" } require(offset < array.size) { "Offset $offset is larger than array size" }
val input = ByteReadPacket(
val input = ByteArraySource(
array, array,
offset + start, offset + start,
min(atMost, size - offset) min(atMost, size - offset)
) ).buffered()
return try { return try {
block(input) block(input)
} finally { } finally {
@ -77,26 +82,26 @@ public fun Binary.toByteArray(): ByteArray = if (this is ByteArrayBinary) {
array.copyOfRange(start, start + size) // TODO do we need to ensure data safety here? array.copyOfRange(start, start + size) // TODO do we need to ensure data safety here?
} else { } else {
read { read {
readBytes() readByteArray()
} }
} }
//TODO optimize for file-based Inputs //TODO optimize for file-based Inputs
public fun Input.readBinary(size: Int? = null): Binary { public fun Source.readBinary(size: Int? = null): Binary {
val array = if (size == null) readBytes() else readBytes(size) val array = if (size == null) readByteArray() else readByteArray(size)
return ByteArrayBinary(array) return ByteArrayBinary(array)
} }
/** /**
* Direct write of binary to the output. Returns the number of bytes written * Direct write of binary to the output. Returns the number of bytes written
*/ */
public fun Output.writeBinary(binary: Binary): Int { public fun Sink.writeBinary(binary: Binary): Int {
return if (binary is ByteArrayBinary) { return if (binary is ByteArrayBinary) {
writeFully(binary.array, binary.start, binary.start + binary.size) write(binary.array, binary.start, binary.start + binary.size)
binary.size binary.size
} else { } else {
binary.read { binary.read {
copyTo(this@writeBinary).toInt() transferTo(this@writeBinary).toInt()
} }
} }
} }

View File

@ -1,6 +1,6 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.Output import kotlinx.io.Sink
import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.*
public class EnvelopeBuilder : Envelope { public class EnvelopeBuilder : Envelope {
@ -33,7 +33,7 @@ public class EnvelopeBuilder : Envelope {
/** /**
* Construct a data binary from given builder * Construct a data binary from given builder
*/ */
public inline fun data(block: Output.() -> Unit) { public inline fun data(block: Sink.() -> Unit) {
data = ByteArray { block() }.asBinary() data = ByteArray { block() }.asBinary()
} }

View File

@ -1,10 +1,10 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.Input import kotlinx.io.Source
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.io.EnvelopeFormatFactory.Companion.ENVELOPE_FORMAT_TYPE import space.kscience.dataforge.io.EnvelopeFormatFactory.Companion.ENVELOPE_FORMAT_TYPE
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import kotlin.reflect.KType import kotlin.reflect.KType
@ -15,9 +15,9 @@ public interface EnvelopeFormat : IOFormat<Envelope> {
override val type: KType get() = typeOf<Envelope>() override val type: KType get() = typeOf<Envelope>()
} }
public fun EnvelopeFormat.read(input: Input): Envelope = readObject(input) public fun EnvelopeFormat.read(input: Source): Envelope = readFrom(input)
@Type(ENVELOPE_FORMAT_TYPE) @DfId(ENVELOPE_FORMAT_TYPE)
public interface EnvelopeFormatFactory : IOFormatFactory<Envelope>, EnvelopeFormat { public interface EnvelopeFormatFactory : IOFormatFactory<Envelope>, EnvelopeFormat {
override val type: KType get() = typeOf<Envelope>() override val type: KType get() = typeOf<Envelope>()

View File

@ -1,5 +1,8 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.bytestring.ByteString
import kotlinx.io.bytestring.decodeToString
import kotlinx.io.write
import space.kscience.dataforge.io.Envelope.Companion.ENVELOPE_NODE_KEY import space.kscience.dataforge.io.Envelope.Companion.ENVELOPE_NODE_KEY
import space.kscience.dataforge.io.PartDescriptor.Companion.DEFAULT_MULTIPART_DATA_SEPARATOR import space.kscience.dataforge.io.PartDescriptor.Companion.DEFAULT_MULTIPART_DATA_SEPARATOR
import space.kscience.dataforge.io.PartDescriptor.Companion.MULTIPART_DATA_TYPE import space.kscience.dataforge.io.PartDescriptor.Companion.MULTIPART_DATA_TYPE
@ -20,7 +23,7 @@ private class PartDescriptor : Scheme() {
val PARTS_KEY = MULTIPART_KEY + "parts" val PARTS_KEY = MULTIPART_KEY + "parts"
val SEPARATOR_KEY = MULTIPART_KEY + "separator" val SEPARATOR_KEY = MULTIPART_KEY + "separator"
const val DEFAULT_MULTIPART_DATA_SEPARATOR = "\r\n#~PART~#\r\n" val DEFAULT_MULTIPART_DATA_SEPARATOR = "\r\n#~PART~#\r\n".toAsciiByteString()
const val MULTIPART_DATA_TYPE = "envelope.multipart" const val MULTIPART_DATA_TYPE = "envelope.multipart"
} }
@ -32,12 +35,12 @@ public typealias EnvelopeParts = List<EnvelopePart>
public fun EnvelopeBuilder.multipart( public fun EnvelopeBuilder.multipart(
parts: EnvelopeParts, parts: EnvelopeParts,
separator: String = DEFAULT_MULTIPART_DATA_SEPARATOR, separator: ByteString = DEFAULT_MULTIPART_DATA_SEPARATOR,
) { ) {
dataType = MULTIPART_DATA_TYPE dataType = MULTIPART_DATA_TYPE
var offsetCounter = 0 var offsetCounter = 0
val separatorSize = separator.length val separatorSize = separator.size
val partDescriptors = parts.map { (binary, description) -> val partDescriptors = parts.map { (binary, description) ->
offsetCounter += separatorSize offsetCounter += separatorSize
PartDescriptor { PartDescriptor {
@ -51,14 +54,14 @@ public fun EnvelopeBuilder.multipart(
meta { meta {
if (separator != DEFAULT_MULTIPART_DATA_SEPARATOR) { if (separator != DEFAULT_MULTIPART_DATA_SEPARATOR) {
SEPARATOR_KEY put separator SEPARATOR_KEY put separator.decodeToString()
} }
setIndexed(PARTS_KEY, partDescriptors.map { it.toMeta() }) setIndexed(PARTS_KEY, partDescriptors.map { it.toMeta() })
} }
data { data {
parts.forEach { parts.forEach {
writeRawString(separator) write(separator)
writeBinary(it.binary) writeBinary(it.binary)
} }
} }
@ -69,7 +72,7 @@ public fun EnvelopeBuilder.multipart(
*/ */
public fun EnvelopeBuilder.envelopes( public fun EnvelopeBuilder.envelopes(
envelopes: List<Envelope>, envelopes: List<Envelope>,
separator: String = DEFAULT_MULTIPART_DATA_SEPARATOR, separator: ByteString = DEFAULT_MULTIPART_DATA_SEPARATOR,
) { ) {
val parts = envelopes.map { val parts = envelopes.map {
val binary = Binary(it, TaggedEnvelopeFormat) val binary = Binary(it, TaggedEnvelopeFormat)

View File

@ -1,12 +1,14 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.* import kotlinx.io.Sink
import kotlinx.io.Source
import kotlinx.io.readByteArray
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Factory import space.kscience.dataforge.context.Factory
import space.kscience.dataforge.io.IOFormatFactory.Companion.IO_FORMAT_TYPE import space.kscience.dataforge.io.IOFormatFactory.Companion.IO_FORMAT_TYPE
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.misc.Named import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.misc.Type
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import kotlin.reflect.KType import kotlin.reflect.KType
@ -21,9 +23,9 @@ public interface IOReader<out T> {
*/ */
public val type: KType public val type: KType
public fun readObject(input: Input): T public fun readFrom(source: Source): T
public fun readObject(binary: Binary): T = binary.read { readObject(this) } public fun readFrom(binary: Binary): T = binary.read { readFrom(this) }
public companion object { public companion object {
/** /**
@ -32,21 +34,21 @@ public interface IOReader<out T> {
public val binary: IOReader<Binary> = object : IOReader<Binary> { public val binary: IOReader<Binary> = object : IOReader<Binary> {
override val type: KType = typeOf<Binary>() override val type: KType = typeOf<Binary>()
override fun readObject(input: Input): Binary = input.readBytes().asBinary() override fun readFrom(source: Source): Binary = source.readByteArray().asBinary()
override fun readObject(binary: Binary): Binary = binary override fun readFrom(binary: Binary): Binary = binary
} }
} }
} }
public inline fun <reified T> IOReader(crossinline read: Input.() -> T): IOReader<T> = object : IOReader<T> { public inline fun <reified T> IOReader(crossinline read: Source.() -> T): IOReader<T> = object : IOReader<T> {
override val type: KType = typeOf<T>() override val type: KType = typeOf<T>()
override fun readObject(input: Input): T = input.read() override fun readFrom(source: Source): T = source.read()
} }
public fun interface IOWriter<in T> { public fun interface IOWriter<in T> {
public fun writeObject(output: Output, obj: T) public fun writeTo(sink: Sink, obj: T)
} }
/** /**
@ -54,24 +56,23 @@ public fun interface IOWriter<in T> {
*/ */
public interface IOFormat<T> : IOReader<T>, IOWriter<T> public interface IOFormat<T> : IOReader<T>, IOWriter<T>
public fun <T : Any> Input.readObject(format: IOReader<T>): T = format.readObject(this@readObject) public fun <T : Any> Source.readWith(format: IOReader<T>): T = format.readFrom(this)
public fun <T : Any> IOFormat<T>.readObjectFrom(binary: Binary): T = binary.read { /**
readObject(this) * Read given binary as an object using given format
*/
public fun <T : Any> Binary.readWith(format: IOReader<T>): T = read {
readWith(format)
} }
/** /**
* Read given binary as object using given format * Write an object to the [Sink] with given [format]
*/ */
public fun <T : Any> Binary.readWith(format: IOReader<T>): T = read { public fun <T : Any> Sink.writeWith(format: IOWriter<T>, obj: T): Unit =
readObject(format) format.writeTo(this, obj)
}
public fun <T : Any> Output.writeObject(format: IOWriter<T>, obj: T): Unit =
format.writeObject(this@writeObject, obj)
@Type(IO_FORMAT_TYPE) @DfId(IO_FORMAT_TYPE)
public interface IOFormatFactory<T : Any> : Factory<IOFormat<T>>, Named { public interface IOFormatFactory<T : Any> : Factory<IOFormat<T>>, Named {
/** /**
* Explicit type for dynamic type checks * Explicit type for dynamic type checks
@ -85,18 +86,33 @@ public interface IOFormatFactory<T : Any> : Factory<IOFormat<T>>, Named {
} }
} }
public fun <T : Any> Binary(obj: T, format: IOWriter<T>): Binary = Binary { format.writeObject(this, obj) } public fun <T : Any> Binary(obj: T, format: IOWriter<T>): Binary = Binary { format.writeTo(this, obj) }
public object FloatIOFormat : IOFormat<Float>, IOFormatFactory<Float> {
override fun build(context: Context, meta: Meta): IOFormat<Float> = this
override val name: Name = "float32".asName()
override val type: KType get() = typeOf<Float>()
override fun writeTo(sink: Sink, obj: Float) {
sink.writeFloat(obj)
}
override fun readFrom(source: Source): Float = source.readFloat()
}
public object DoubleIOFormat : IOFormat<Double>, IOFormatFactory<Double> { public object DoubleIOFormat : IOFormat<Double>, IOFormatFactory<Double> {
override fun build(context: Context, meta: Meta): IOFormat<Double> = this override fun build(context: Context, meta: Meta): IOFormat<Double> = this
override val name: Name = "double".asName() override val name: Name = "float64".asName()
override val type: KType get() = typeOf<Double>() override val type: KType get() = typeOf<Double>()
override fun writeObject(output: Output, obj: Double) { override fun writeTo(sink: Sink, obj: Double) {
output.writeDouble(obj) sink.writeLong(obj.toBits())
} }
override fun readObject(input: Input): Double = input.readDouble() override fun readFrom(source: Source): Double = source.readDouble()
} }

View File

@ -1,10 +1,10 @@
@file:Suppress("UNUSED_PARAMETER")
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.Input import kotlinx.io.Sink
import io.ktor.utils.io.core.Output import kotlinx.io.Source
import kotlinx.io.readString
import kotlinx.io.writeString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
@ -18,13 +18,13 @@ import space.kscience.dataforge.meta.toMeta
*/ */
public class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat { public class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat {
override fun writeMeta(output: Output, meta: Meta, descriptor: MetaDescriptor?) { override fun writeMeta(sink: Sink, meta: Meta, descriptor: MetaDescriptor?) {
val jsonElement = meta.toJson(descriptor) val jsonElement = meta.toJson(descriptor)
output.writeUtf8String(json.encodeToString(JsonElement.serializer(), jsonElement)) sink.writeString(json.encodeToString(JsonElement.serializer(), jsonElement))
} }
override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta { override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta {
val str = input.readUtf8String()//readByteArray().decodeToString() val str = source.readString()
val jsonElement = json.parseToJsonElement(str) val jsonElement = json.parseToJsonElement(str)
return jsonElement.toMeta(descriptor) return jsonElement.toMeta(descriptor)
} }
@ -39,10 +39,10 @@ public class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat
private val default = JsonMetaFormat() private val default = JsonMetaFormat()
override fun writeMeta(output: Output, meta: Meta, descriptor: MetaDescriptor?): Unit = override fun writeMeta(sink: Sink, meta: Meta, descriptor: MetaDescriptor?): Unit =
default.run { writeMeta(output, meta, descriptor) } default.run { writeMeta(sink, meta, descriptor) }
override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta = override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta =
default.run { readMeta(input, descriptor) } default.run { readMeta(source, descriptor) }
} }
} }

View File

@ -1,15 +1,15 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.ByteReadPacket
import io.ktor.utils.io.core.Input import kotlinx.io.Sink
import io.ktor.utils.io.core.Output import kotlinx.io.Source
import io.ktor.utils.io.core.use import kotlinx.io.buffered
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.io.MetaFormatFactory.Companion.META_FORMAT_TYPE import space.kscience.dataforge.io.MetaFormatFactory.Companion.META_FORMAT_TYPE
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.plus
@ -23,22 +23,22 @@ public interface MetaFormat : IOFormat<Meta> {
override val type: KType get() = typeOf<Meta>() override val type: KType get() = typeOf<Meta>()
override fun writeObject(output: Output, obj: Meta) { override fun writeTo(sink: Sink, obj: Meta) {
writeMeta(output, obj, null) writeMeta(sink, obj, null)
} }
override fun readObject(input: Input): Meta = readMeta(input) override fun readFrom(source: Source): Meta = readMeta(source)
public fun writeMeta( public fun writeMeta(
output: Output, sink: Sink,
meta: Meta, meta: Meta,
descriptor: MetaDescriptor? = null, descriptor: MetaDescriptor? = null,
) )
public fun readMeta(input: Input, descriptor: MetaDescriptor? = null): Meta public fun readMeta(source: Source, descriptor: MetaDescriptor? = null): Meta
} }
@Type(META_FORMAT_TYPE) @DfId(META_FORMAT_TYPE)
public interface MetaFormatFactory : IOFormatFactory<Meta>, MetaFormat { public interface MetaFormatFactory : IOFormatFactory<Meta>, MetaFormat {
public val shortName: String public val shortName: String
@ -57,15 +57,13 @@ public interface MetaFormatFactory : IOFormatFactory<Meta>, MetaFormat {
public fun Meta.toString(format: MetaFormat): String = ByteArray { public fun Meta.toString(format: MetaFormat): String = ByteArray {
format.run { format.run {
writeObject(this@ByteArray, this@toString) writeTo(this@ByteArray, this@toString)
} }
}.decodeToString() }.decodeToString()
public fun Meta.toString(formatFactory: MetaFormatFactory): String = toString(formatFactory.build(Global, Meta.EMPTY)) public fun Meta.toString(formatFactory: MetaFormatFactory): String = toString(formatFactory.build(Global, Meta.EMPTY))
public fun MetaFormat.parse(str: String): Meta { public fun MetaFormat.parse(str: String): Meta = readFrom(StringSource(str).buffered())
return ByteReadPacket(str.encodeToByteArray()).use { readObject(it) }
}
public fun MetaFormatFactory.parse(str: String, formatMeta: Meta): Meta = build(Global, formatMeta).parse(str) public fun MetaFormatFactory.parse(str: String, formatMeta: Meta): Meta = build(Global, formatMeta).parse(str)

View File

@ -1,6 +1,7 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.* import kotlinx.io.*
import kotlinx.io.bytestring.decodeToString
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
@ -18,7 +19,7 @@ import space.kscience.dataforge.names.plus
public class TaggedEnvelopeFormat( public class TaggedEnvelopeFormat(
public val io: IOPlugin, public val io: IOPlugin,
public val version: VERSION = VERSION.DF02, public val version: VERSION = VERSION.DF02,
public val metaFormatFactory: MetaFormatFactory = JsonMetaFormat public val metaFormatFactory: MetaFormatFactory = JsonMetaFormat,
) : EnvelopeFormat { ) : EnvelopeFormat {
// private val metaFormat = io.metaFormat(metaFormatKey) // private val metaFormat = io.metaFormat(metaFormatKey)
@ -26,59 +27,60 @@ public class TaggedEnvelopeFormat(
private fun Tag.toBinary() = Binary { private fun Tag.toBinary() = Binary {
writeRawString(START_SEQUENCE) write(START_SEQUENCE)
writeRawString(version.name) writeString(version.name)
writeShort(metaFormatKey) writeShort(metaFormatKey)
writeUInt(metaSize) writeUInt(metaSize)
when (version) { when (version) {
VERSION.DF02 -> { VERSION.DF02 -> {
writeUInt(dataSize.toUInt()) writeUInt(dataSize.toUInt())
} }
VERSION.DF03 -> { VERSION.DF03 -> {
writeULong(dataSize) writeULong(dataSize)
} }
} }
writeRawString(END_SEQUENCE) write(END_SEQUENCE)
} }
override fun writeObject( override fun writeTo(
output: Output, sink: Sink,
obj: Envelope, obj: Envelope,
) { ) {
val metaFormat = metaFormatFactory.build(io.context, Meta.EMPTY) val metaFormat = metaFormatFactory.build(io.context, Meta.EMPTY)
val metaBytes = Binary(obj.meta,metaFormat) val metaBytes = Binary(obj.meta, metaFormat)
val actualSize: ULong = (obj.data?.size ?: 0).toULong() val actualSize: ULong = (obj.data?.size ?: 0).toULong()
val tag = Tag(metaFormatFactory.key, metaBytes.size.toUInt() + 2u, actualSize) val tag = Tag(metaFormatFactory.key, metaBytes.size.toUInt() + 2u, actualSize)
output.writeBinary(tag.toBinary()) sink.writeBinary(tag.toBinary())
output.writeBinary(metaBytes) sink.writeBinary(metaBytes)
output.writeRawString("\r\n") sink.writeString("\r\n")
obj.data?.let { obj.data?.let {
output.writeBinary(it) sink.writeBinary(it)
} }
} }
/** /**
* Read an envelope from input into memory * Read an envelope from input into memory
* *
* @param input an input to read from * @param source an input to read from
* @param formats a collection of meta formats to resolve * @param formats a collection of meta formats to resolve
*/ */
override fun readObject(input: Input): Envelope { override fun readFrom(source: Source): Envelope {
val tag = input.readTag(this.version) val tag = source.readTag(this.version)
val metaFormat = io.resolveMetaFormat(tag.metaFormatKey) val metaFormat = io.resolveMetaFormat(tag.metaFormatKey)
?: error("Meta format with key ${tag.metaFormatKey} not found") ?: error("Meta format with key ${tag.metaFormatKey} not found")
val metaBinary = input.readBinary(tag.metaSize.toInt()) val metaBinary = source.readBinary(tag.metaSize.toInt())
val meta: Meta = metaFormat.readObjectFrom(metaBinary) val meta: Meta = metaFormat.readFrom(metaBinary)
val data = input.readBinary(tag.dataSize.toInt()) val data = source.readBinary(tag.dataSize.toInt())
return SimpleEnvelope(meta, data) return SimpleEnvelope(meta, data)
} }
override fun readObject(binary: Binary): Envelope = binary.read{ override fun readFrom(binary: Binary): Envelope = binary.read {
val tag = readTag(version) val tag = readTag(version)
val metaFormat = io.resolveMetaFormat(tag.metaFormatKey) val metaFormat = io.resolveMetaFormat(tag.metaFormatKey)
@ -86,7 +88,7 @@ public class TaggedEnvelopeFormat(
val metaBinary = readBinary(tag.metaSize.toInt()) val metaBinary = readBinary(tag.metaSize.toInt())
val meta: Meta = metaFormat.readObjectFrom(metaBinary) val meta: Meta = metaFormat.readFrom(metaBinary)
SimpleEnvelope(meta, binary.view((version.tagSize + tag.metaSize).toInt(), tag.dataSize.toInt())) SimpleEnvelope(meta, binary.view((version.tagSize + tag.metaSize).toInt(), tag.dataSize.toInt()))
@ -104,8 +106,8 @@ public class TaggedEnvelopeFormat(
} }
public companion object : EnvelopeFormatFactory { public companion object : EnvelopeFormatFactory {
private const val START_SEQUENCE = "#~" private val START_SEQUENCE = "#~".toAsciiByteString()
private const val END_SEQUENCE = "~#\r\n" private val END_SEQUENCE = "~#\r\n".toAsciiByteString()
override val name: Name = EnvelopeFormatFactory.ENVELOPE_FACTORY_NAME + "tagged" override val name: Name = EnvelopeFormatFactory.ENVELOPE_FACTORY_NAME + "tagged"
@ -121,27 +123,26 @@ public class TaggedEnvelopeFormat(
return TaggedEnvelopeFormat(io, version) return TaggedEnvelopeFormat(io, version)
} }
private fun Input.readTag(version: VERSION): Tag { private fun Source.readTag(version: VERSION): Tag {
val start = readRawString(2) val start = readByteString(2)
if (start != START_SEQUENCE) error("The input is not an envelope") if (start != START_SEQUENCE) error("The input is not an envelope")
val versionString = readRawString(4) val versionString = readByteString(4)
if (version.name != versionString) error("Wrong version of DataForge: expected $version but found $versionString") if (version.name.toAsciiByteString() != 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: ULong = when (version) { val dataLength: ULong = when (version) {
VERSION.DF02 -> readUInt().toULong() VERSION.DF02 -> readUInt().toULong()
VERSION.DF03 -> readULong() VERSION.DF03 -> readULong()
} }
val end = readRawString(4) val end = readByteString(4)
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)
} }
override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? { override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? = try {
return try {
binary.read { binary.read {
val header = readRawString(6) val header = readByteString(6)
return@read when (header.substring(2..5)) { when (header.substring(2, 6).decodeToString()) {
VERSION.DF02.name -> TaggedEnvelopeFormat(io, VERSION.DF02) VERSION.DF02.name -> TaggedEnvelopeFormat(io, VERSION.DF02)
VERSION.DF03.name -> TaggedEnvelopeFormat(io, VERSION.DF03) VERSION.DF03.name -> TaggedEnvelopeFormat(io, VERSION.DF03)
else -> null else -> null
@ -150,24 +151,20 @@ public class TaggedEnvelopeFormat(
} catch (ex: Exception) { } catch (ex: Exception) {
null null
} }
}
private val default by lazy { build(Global, Meta.EMPTY) } private val default by lazy { build(Global, Meta.EMPTY) }
override fun readObject(binary: Binary): Envelope = override fun readFrom(binary: Binary): Envelope =
default.run { readObject(binary) } default.run { readFrom(binary) }
override fun writeObject( override fun writeTo(
output: Output, sink: Sink,
obj: Envelope, obj: Envelope,
): Unit = default.run { ): Unit = default.run {
writeObject( writeTo(sink, obj)
output,
obj,
)
} }
override fun readObject(input: Input): Envelope = default.readObject(input) override fun readFrom(source: Source): Envelope = default.readFrom(source)
} }
} }

View File

@ -1,9 +1,9 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.ByteReadPacket
import io.ktor.utils.io.core.Input import kotlinx.io.*
import io.ktor.utils.io.core.Output import kotlinx.io.bytestring.ByteString
import io.ktor.utils.io.core.readUTF8UntilDelimiterTo import kotlinx.io.bytestring.encodeToByteString
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
@ -28,35 +28,36 @@ public class TaglessEnvelopeFormat(
// writeFully("#? $key: $value;\r\n".encodeToByteArray()) // writeFully("#? $key: $value;\r\n".encodeToByteArray())
// } // }
override fun writeObject( override fun writeTo(
output: Output, sink: Sink,
obj: Envelope, obj: Envelope,
) { ) {
val metaFormat = metaFormatFactory.build(this.io.context, meta) val metaFormat = metaFormatFactory.build(this.io.context, meta)
//printing header //printing header
output.writeRawString(TAGLESS_ENVELOPE_HEADER + "\r\n") sink.write(TAGLESS_ENVELOPE_HEADER)
sink.writeString("\r\n")
//Printing meta //Printing meta
if (!obj.meta.isEmpty()) { if (!obj.meta.isEmpty()) {
val metaBinary = Binary(obj.meta, metaFormat) val metaBinary = Binary(obj.meta, metaFormat)
output.writeUtf8String(META_START + "-${metaFormatFactory.shortName}\r\n") sink.writeString(META_START + "-${metaFormatFactory.shortName}\r\n")
output.writeBinary(metaBinary) sink.writeBinary(metaBinary)
output.writeRawString("\r\n") sink.writeString("\r\n")
} }
//Printing data //Printing data
obj.data?.let { data -> obj.data?.let { data ->
//val actualSize: Int = envelope.data?.size ?: 0 //val actualSize: Int = envelope.data?.size ?: 0
output.writeUtf8String(DATA_START + "\r\n") sink.writeString(DATA_START + "\r\n")
output.writeBinary(data) sink.writeBinary(data)
} }
} }
override fun readObject(input: Input): Envelope { override fun readFrom(source: Source): Envelope {
//read preamble //read preamble
input.discardWithSeparator( source.discardWithSeparator(
TAGLESS_ENVELOPE_HEADER.encodeToByteArray(), TAGLESS_ENVELOPE_HEADER,
atMost = 1024, atMost = 1024,
) )
@ -64,22 +65,22 @@ public class TaglessEnvelopeFormat(
var data: Binary? = null var data: Binary? = null
input.discardWithSeparator( source.discardWithSeparator(
SEPARATOR_PREFIX, SEPARATOR_PREFIX,
atMost = 1024, atMost = 1024,
) )
var header: String = ByteArray { var header: String = ByteArray {
input.readUTF8UntilDelimiterTo(this, "\n") source.readWithSeparatorTo(this, "\n".encodeToByteString())
}.decodeToString() }.decodeToString()
while (!input.endOfInput) { while (!source.exhausted()) {
val block = ByteArray { val block = ByteArray {
input.readWithSeparatorTo(this, SEPARATOR_PREFIX) source.readWithSeparatorTo(this, SEPARATOR_PREFIX)
} }
val nextHeader = ByteArray { val nextHeader = ByteArray {
input.readWithSeparatorTo(this, "\n".encodeToByteArray()) source.readWithSeparatorTo(this, "\n".encodeToByteString())
}.decodeToString() }.decodeToString()
//terminate on end //terminate on end
@ -89,7 +90,7 @@ public class TaglessEnvelopeFormat(
if (header.startsWith("META")) { if (header.startsWith("META")) {
//TODO check format //TODO check format
val metaFormat: MetaFormatFactory = JsonMetaFormat val metaFormat: MetaFormatFactory = JsonMetaFormat
meta = metaFormat.readMeta(ByteReadPacket(block)) meta = metaFormat.readMeta(ByteArraySource(block).buffered())
} }
if (header.startsWith("DATA")) { if (header.startsWith("DATA")) {
@ -111,9 +112,9 @@ public class TaglessEnvelopeFormat(
public const val TAGLESS_ENVELOPE_TYPE: String = "tagless" public const val TAGLESS_ENVELOPE_TYPE: String = "tagless"
public val SEPARATOR_PREFIX: ByteArray = "\n#~".encodeToByteArray() public val SEPARATOR_PREFIX: ByteString = "\n#~".encodeToByteString()
public const val TAGLESS_ENVELOPE_HEADER: String = "#~DFTL" public val TAGLESS_ENVELOPE_HEADER: ByteString = "#~DFTL".encodeToByteString()
// public const val META_START_PROPERTY: String = "metaSeparator" // public const val META_START_PROPERTY: String = "metaSeparator"
public const val META_START: String = "#~META" public const val META_START: String = "#~META"
@ -131,24 +132,21 @@ public class TaglessEnvelopeFormat(
private val default by lazy { build(Global, Meta.EMPTY) } private val default by lazy { build(Global, Meta.EMPTY) }
override fun readObject(binary: Binary): Envelope = default.run { readObject(binary) } override fun readFrom(binary: Binary): Envelope = default.run { readFrom(binary) }
override fun writeObject( override fun writeTo(
output: Output, sink: Sink,
obj: Envelope, obj: Envelope,
): Unit = default.run { ): Unit = default.run {
writeObject( writeTo(sink, obj)
output,
obj,
)
} }
override fun readObject(input: Input): Envelope = default.readObject(input) override fun readFrom(source: Source): Envelope = default.readFrom(source)
override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? { override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? {
return try { return try {
binary.read { binary.read {
val string = readRawString(TAGLESS_ENVELOPE_HEADER.length) val string = readByteString(TAGLESS_ENVELOPE_HEADER.size)
return@read if (string == TAGLESS_ENVELOPE_HEADER) { return@read if (string == TAGLESS_ENVELOPE_HEADER) {
TaglessEnvelopeFormat(io) TaglessEnvelopeFormat(io)
} else { } else {

View File

@ -1,40 +1,41 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.bits.Memory import kotlinx.io.*
import io.ktor.utils.io.charsets.Charsets import kotlinx.io.bytestring.ByteString
import io.ktor.utils.io.charsets.decodeExactBytes import kotlinx.io.bytestring.decodeToString
import io.ktor.utils.io.core.* import kotlinx.io.bytestring.encodeToByteString
import io.ktor.utils.io.core.internal.ChunkBuffer
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import kotlin.math.min
public fun Output.writeRawString(str: String) { /**
writeFully(str.toByteArray(Charsets.ISO_8859_1)) * Convert a string literal, containing only ASCII characters to a [ByteString].
* Throws an error if there are non-ASCII characters.
*/
public fun String.toAsciiByteString(): ByteString {
val bytes = ByteArray(length) {
val char = get(it)
val code = char.code
if (code > Byte.MAX_VALUE) error("Symbol $char is not ASCII symbol") else code.toByte()
}
return ByteString(bytes)
} }
public fun Output.writeUtf8String(str: String) { public inline fun Buffer(block: Sink.() -> Unit): Buffer = Buffer().apply(block)
writeFully(str.encodeToByteArray())
}
public fun Input.readRawString(size: Int): String { //public fun Source.readSafeUtf8Line(): String = readUTF8Line() ?: error("Line not found")
return Charsets.ISO_8859_1.newDecoder().decodeExactBytes(this, size)
}
public fun Input.readUtf8String(): String = readBytes().decodeToString() public inline fun ByteArray(block: Sink.() -> Unit): ByteArray =
Buffer(block).readByteArray()
public fun Input.readSafeUtf8Line(): String = readUTF8Line() ?: error("Line not found") public inline fun Binary(block: Sink.() -> Unit): Binary =
public inline fun ByteArray(block: Output.() -> Unit): ByteArray =
buildPacket(block).readBytes()
public inline fun Binary(block: Output.() -> Unit): Binary =
ByteArray(block).asBinary() ByteArray(block).asBinary()
public operator fun Binary.get(range: IntRange): Binary = view(range.first, range.last - range.first) public operator fun Binary.get(range: IntRange): Binary = view(range.first, range.last - range.first)
/** /**
* Return inferred [EnvelopeFormat] if only one format could read given file. If no format accepts the binary, return null. If * Return inferred [EnvelopeFormat] if only one format could read given file. If no format accepts the binary, return null. If
* multiple formats accepts binary, throw an error. * multiple formats accept binary, throw an error.
*/ */
public fun IOPlugin.peekBinaryEnvelopeFormat(binary: Binary): EnvelopeFormat? { public fun IOPlugin.peekBinaryEnvelopeFormat(binary: Binary): EnvelopeFormat? {
val formats = envelopeFormatFactories.mapNotNull { factory -> val formats = envelopeFormatFactories.mapNotNull { factory ->
@ -56,7 +57,7 @@ public fun IOPlugin.readEnvelope(
binary: Binary, binary: Binary,
readNonEnvelopes: Boolean = false, readNonEnvelopes: Boolean = false,
formatPicker: IOPlugin.(Binary) -> EnvelopeFormat? = IOPlugin::peekBinaryEnvelopeFormat, formatPicker: IOPlugin.(Binary) -> EnvelopeFormat? = IOPlugin::peekBinaryEnvelopeFormat,
): Envelope = formatPicker(binary)?.readObject(binary) ?: if (readNonEnvelopes) { ): Envelope = formatPicker(binary)?.readFrom(binary) ?: if (readNonEnvelopes) {
// if no format accepts file, read it as binary // if no format accepts file, read it as binary
Envelope(Meta.EMPTY, binary) Envelope(Meta.EMPTY, binary)
} else error("Can't infer format for $binary") } else error("Can't infer format for $binary")
@ -96,74 +97,139 @@ private class RingByteArray(
else -> inputArray.indices.all { inputArray[it] == get(it) } else -> inputArray.indices.all { inputArray[it] == get(it) }
} }
fun contentEquals(byteString: ByteString): Boolean = when {
byteString.size != buffer.size -> false
size < buffer.size -> false
else -> (0 until byteString.size).all { byteString[it] == get(it) }
}
} }
private fun RingByteArray.toArray(): ByteArray = ByteArray(size) { get(it) } private fun RingByteArray.toArray(): ByteArray = ByteArray(size) { get(it) }
/** /**
* Read [Input] into [output] until designated multibyte [separator] and optionally continues until * Read [Source] into [output] until designated multibyte [separator] and optionally continues until
* the end of the line after it. Throw error if [separator] not found and [atMost] bytes are read. * the end of the line after it. Throw error if [separator] not found and [atMost] bytes are read.
* Also fails if [separator] not found until the end of input. * Also fails if [separator] not found until the end of input.
* *
* Separator itself is not read into Output. * The Separator itself is not read into [Sink].
* *
* @param errorOnEof if true error is thrown if separator is never encountered * @param errorOnEof if true error is thrown if separator is never encountered
* *
* @return bytes actually being read, including separator * @return bytes actually being read, including separator
*/ */
public fun Input.readWithSeparatorTo( public fun Source.readWithSeparatorTo(
output: Output, output: Sink?,
separator: ByteArray, separator: ByteString,
atMost: Int = Int.MAX_VALUE, atMost: Int = Int.MAX_VALUE,
errorOnEof: Boolean = false, errorOnEof: Boolean = false,
): Int { ): Int {
var counter = 0 var counter = 0
val rb = RingByteArray(ByteArray(separator.size)) val rb = RingByteArray(ByteArray(separator.size))
takeWhile { buffer ->
while (buffer.canRead()) { while (!exhausted()) {
val byte = buffer.readByte() val byte = readByte()
counter++ counter++
if (counter >= atMost) error("Maximum number of bytes to be read $atMost reached.") if (counter >= atMost) error("Maximum number of bytes to be read $atMost reached.")
rb.push(byte) rb.push(byte)
if (rb.contentEquals(separator)) { if (rb.contentEquals(separator)) {
return counter return counter
} else if (rb.isFull()) { } else if (rb.isFull()) {
output.writeByte(rb[0]) output?.writeByte(rb[0])
} }
} }
!endOfInput
}
if (errorOnEof) { if (errorOnEof) {
error("Read to the end of input without encountering ${separator.decodeToString()}") error("Read to the end of input without encountering ${separator.decodeToString()}")
} else { } else {
for(i in 1 until rb.size){ for (i in 1 until rb.size) {
output.writeByte(rb[i]) output?.writeByte(rb[i])
} }
counter += (rb.size - 1) counter += (rb.size - 1)
return counter return counter
} }
} }
public fun Input.discardLine(): Int { /**
return discardUntilDelimiter('\n'.code.toByte()).also { * Discard all bytes until [separator] is encountered. Separator is discarded sa well.
discard(1) * Return the total number of bytes read.
}.toInt() + 1 */
} public fun Source.discardWithSeparator(
separator: ByteString,
public fun Input.discardWithSeparator(
separator: ByteArray,
atMost: Int = Int.MAX_VALUE, atMost: Int = Int.MAX_VALUE,
errorOnEof: Boolean = false, errorOnEof: Boolean = false,
): Int { ): Int = readWithSeparatorTo(null, separator, atMost, errorOnEof)
val dummy: Output = object : Output(ChunkBuffer.Pool) {
override fun closeDestination() { /**
* Discard all symbol until newline is discovered. Carriage return is not discarded.
*/
public fun Source.discardLine(
atMost: Int = Int.MAX_VALUE,
errorOnEof: Boolean = false,
): Int = discardWithSeparator("\n".encodeToByteString(), atMost, errorOnEof)
/**
* A [Source] based on [ByteArray]
*/
internal class ByteArraySource(
private val byteArray: ByteArray,
private val offset: Int = 0,
private val size: Int = byteArray.size - offset,
) : RawSource {
init {
require(offset >= 0) { "Offset must be positive" }
require(offset + size <= byteArray.size) { "End index is ${offset + size}, but the array size is ${byteArray.size}" }
}
private var pointer = offset
override fun close() {
// Do nothing // Do nothing
} }
override fun flush(source: Memory, offset: Int, length: Int) { override fun readAtMostTo(sink: Buffer, byteCount: Long): Long {
// Do nothing if (pointer == offset + size) return -1
val byteRead = min(byteCount.toInt(), (size + offset - pointer))
sink.write(byteArray, pointer, pointer + byteRead)
pointer += byteRead
return byteRead.toLong()
} }
}
return readWithSeparatorTo(dummy, separator, atMost, errorOnEof)
} }
/**
* A [Source] based on [String]
*/
public class StringSource(
public val string: String,
public val offset: Int = 0,
public val size: Int = string.length - offset,
) : RawSource {
private var pointer = offset
override fun close() {
// Do nothing
}
override fun readAtMostTo(sink: Buffer, byteCount: Long): Long {
if (pointer == offset + size) return -1
val byteRead = min(byteCount.toInt(), (size + offset - pointer))
sink.writeString(string, pointer, pointer + byteRead)
pointer += byteRead
return byteRead.toLong()
}
}
public fun Sink.writeDouble(value: Double) {
writeLong(value.toBits())
}
public fun Source.readDouble(): Double = Double.fromBits(readLong())
public fun Sink.writeFloat(value: Float) {
writeInt(value.toBits())
}
public fun Source.readFloat(): Float = Float.fromBits(readInt())

View File

@ -1,6 +1,5 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.readInt
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@ -1,6 +1,7 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.readBytes import kotlinx.io.readByteArray
import kotlinx.io.writeString
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -12,7 +13,7 @@ class EnvelopeFormatTest {
"d" put 22.2 "d" put 22.2
} }
data { data {
writeUtf8String("12345678") writeString("12345678")
} }
} }
@ -22,7 +23,7 @@ class EnvelopeFormatTest {
val res = readFromByteArray(byteArray) val res = readFromByteArray(byteArray)
assertEquals(envelope.meta, res.meta) assertEquals(envelope.meta, res.meta)
val bytes = res.data?.read { val bytes = res.data?.read {
readBytes() readByteArray()
} }
assertEquals("12345678", bytes?.decodeToString()) assertEquals("12345678", bytes?.decodeToString())
} }
@ -34,13 +35,13 @@ class EnvelopeFormatTest {
val res = readFromByteArray(byteArray) val res = readFromByteArray(byteArray)
assertEquals(envelope.meta, res.meta) assertEquals(envelope.meta, res.meta)
val bytes = res.data?.read { val bytes = res.data?.read {
readBytes() readByteArray()
} }
assertEquals("12345678", bytes?.decodeToString()) assertEquals("12345678", bytes?.decodeToString())
} }
@Test @Test
fun testManualDftl(){ fun testManualDftl() {
val envelopeString = """ val envelopeString = """
#~DFTL #~DFTL
#~META #~META
@ -56,7 +57,7 @@ class EnvelopeFormatTest {
val res = TaglessEnvelopeFormat.readFromByteArray(envelopeString.encodeToByteArray()) val res = TaglessEnvelopeFormat.readFromByteArray(envelopeString.encodeToByteArray())
assertEquals(envelope.meta, res.meta) assertEquals(envelope.meta, res.meta)
val bytes = res.data?.read { val bytes = res.data?.read {
readBytes() readByteArray()
} }
assertEquals("12345678", bytes?.decodeToString()) assertEquals("12345678", bytes?.decodeToString())
} }

View File

@ -1,8 +1,9 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.ByteReadPacket import kotlinx.io.buffered
import io.ktor.utils.io.core.readBytes import kotlinx.io.bytestring.encodeToByteString
import io.ktor.utils.io.core.readUTF8Line import kotlinx.io.readByteArray
import kotlinx.io.readLine
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFails import kotlin.test.assertFails
@ -11,9 +12,9 @@ class IOTest {
@Test @Test
fun readBytes() { fun readBytes() {
val bytes = ByteArray(8) { it.toByte() } val bytes = ByteArray(8) { it.toByte() }
val input = ByteReadPacket(bytes) val input = ByteArraySource(bytes).buffered()
@Suppress("UNUSED_VARIABLE") val first = input.readBytes(4) @Suppress("UNUSED_VARIABLE") val first = input.readByteArray(4)
val second = input.readBytes(4) val second = input.readByteArray(4)
assertEquals(4.toByte(), second[0]) assertEquals(4.toByte(), second[0])
} }
@ -31,25 +32,25 @@ class IOTest {
binary.read { binary.read {
val array = ByteArray { val array = ByteArray {
val read = readWithSeparatorTo(this, "---".encodeToByteArray()) + discardLine() val read = readWithSeparatorTo(this, "---".encodeToByteString()) + discardLine()
assertEquals(12, read) assertEquals(12, read)
} }
assertEquals(""" assertEquals("""
aaa aaa
bbb bbb
""".trimIndent(),array.decodeToString().trim()) """.trimIndent(),array.decodeToString().trim())
assertEquals("ccc", readUTF8Line()?.trim()) assertEquals("ccc", readLine()?.trim())
} }
assertFails { assertFails {
binary.read { binary.read {
discardWithSeparator("---".encodeToByteArray(), atMost = 3 ) discardWithSeparator("---".encodeToByteString(), atMost = 3 )
} }
} }
assertFails { assertFails {
binary.read{ binary.read{
discardWithSeparator("-+-".encodeToByteArray(), errorOnEof = true) discardWithSeparator("-+-".encodeToByteString(), errorOnEof = true)
} }
} }

View File

@ -7,11 +7,11 @@ import kotlin.test.assertEquals
fun Meta.toByteArray(format: MetaFormat = JsonMetaFormat) = ByteArray { fun Meta.toByteArray(format: MetaFormat = JsonMetaFormat) = ByteArray {
format.writeObject(this@ByteArray, this@toByteArray) format.writeTo(this@ByteArray, this@toByteArray)
} }
fun MetaFormat.fromByteArray(packet: ByteArray): Meta { fun MetaFormat.fromByteArray(packet: ByteArray): Meta {
return packet.asBinary().read { readObject(this) } return packet.asBinary().read { readFrom(this) }
} }
class MetaFormatTest { class MetaFormatTest {

View File

@ -1,5 +1,6 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.writeString
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.int
@ -18,9 +19,9 @@ class MultipartTest {
"value" put it "value" put it
} }
data { data {
writeUtf8String("Hello World $it") writeString("Hello World $it")
repeat(300) { repeat(300) {
writeRawString("$it ") writeString("$it ")
} }
} }
} }

View File

@ -1,12 +1,11 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.ByteReadPacket import kotlinx.io.buffered
import io.ktor.utils.io.core.use
fun <T : Any> IOFormat<T>.writeToByteArray(obj: T): ByteArray = ByteArray { fun <T : Any> IOFormat<T>.writeToByteArray(obj: T): ByteArray = ByteArray {
writeObject(this, obj) writeTo(this, obj)
} }
fun <T : Any> IOFormat<T>.readFromByteArray(array: ByteArray): T = ByteReadPacket(array).use { fun <T : Any> IOFormat<T>.readFromByteArray(array: ByteArray): T = ByteArraySource(array).buffered().use {
readObject(it) readFrom(it)
} }

View File

@ -1,8 +1,11 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.*
import io.ktor.utils.io.streams.asOutput
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.io.Sink
import kotlinx.io.Source
import kotlinx.io.asSink
import kotlinx.io.buffered
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.meta.isEmpty import space.kscience.dataforge.meta.isEmpty
@ -23,18 +26,18 @@ internal class PathBinary(
override val size: Int = Files.size(path).toInt() - fileOffset, override val size: Int = Files.size(path).toInt() - fileOffset,
) : Binary { ) : Binary {
override fun <R> read(offset: Int, atMost: Int, block: Input.() -> R): R = runBlocking { override fun <R> read(offset: Int, atMost: Int, block: Source.() -> R): R = runBlocking {
readSuspend(offset, atMost, block) readSuspend(offset, atMost, block)
} }
override suspend fun <R> readSuspend(offset: Int, atMost: Int, block: suspend Input.() -> R): R { override suspend fun <R> readSuspend(offset: Int, atMost: Int, block: suspend Source.() -> R): R {
val actualOffset = offset + fileOffset val actualOffset = offset + fileOffset
val actualSize = min(atMost, size - offset) val actualSize = min(atMost, size - offset)
val array = path.inputStream().use { val array = path.inputStream().use {
it.skip(actualOffset.toLong()) it.skip(actualOffset.toLong())
it.readNBytes(actualSize) it.readNBytes(actualSize)
} }
return ByteReadPacket(array).block() return ByteArraySource(array).buffered().use { it.block() }
} }
override fun view(offset: Int, binarySize: Int) = PathBinary(path, fileOffset + offset, binarySize) override fun view(offset: Int, binarySize: Int) = PathBinary(path, fileOffset + offset, binarySize)
@ -42,40 +45,40 @@ internal class PathBinary(
public fun Path.asBinary(): Binary = PathBinary(this) public fun Path.asBinary(): Binary = PathBinary(this)
public fun <R> Path.read(block: Input.() -> R): R = asBinary().read(block = block) public fun <R> Path.read(block: Source.() -> R): R = asBinary().read(block = block)
/** /**
* Write a live output to a newly created file. If file does not exist, throws error * Write a live output to a newly created file. If file does not exist, throws error
*/ */
public fun Path.write(block: Output.() -> Unit): Unit { public fun Path.write(block: Sink.() -> Unit): Unit {
val stream = Files.newOutputStream(this, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW) val stream = Files.newOutputStream(this, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)
stream.asOutput().use(block) stream.asSink().buffered().use(block)
} }
/** /**
* Create a new file or append to exiting one with given output [block] * Create a new file or append to exiting one with given output [block]
*/ */
public fun Path.append(block: Output.() -> Unit): Unit { public fun Path.append(block: Sink.() -> Unit): Unit {
val stream = Files.newOutputStream( val stream = Files.newOutputStream(
this, this,
StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE
) )
stream.asOutput().use(block) stream.asSink().buffered().use(block)
} }
/** /**
* Create a new file or replace existing one using given output [block] * Create a new file or replace existing one using given output [block]
*/ */
public fun Path.rewrite(block: Output.() -> Unit): Unit { public fun Path.rewrite(block: Sink.() -> Unit): Unit {
val stream = Files.newOutputStream( val stream = Files.newOutputStream(
this, this,
StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE
) )
stream.asOutput().use(block) stream.asSink().buffered().use(block)
} }
@DFExperimental @DFExperimental
public fun EnvelopeFormat.readFile(path: Path): Envelope = readObject(path.asBinary()) public fun EnvelopeFormat.readFile(path: Path): Envelope = readFrom(path.asBinary())
/** /**
* Resolve IOFormat based on type * Resolve IOFormat based on type
@ -235,7 +238,7 @@ public fun IOPlugin.writeEnvelopeFile(
envelopeFormat: EnvelopeFormat = TaggedEnvelopeFormat, envelopeFormat: EnvelopeFormat = TaggedEnvelopeFormat,
) { ) {
path.rewrite { path.rewrite {
envelopeFormat.writeObject(this, envelope) envelopeFormat.writeTo(this, envelope)
} }
} }
@ -260,7 +263,7 @@ public fun IOPlugin.writeEnvelopeDirectory(
val dataFile = path.resolve(IOPlugin.DATA_FILE_NAME) val dataFile = path.resolve(IOPlugin.DATA_FILE_NAME)
dataFile.write { dataFile.write {
envelope.data?.read { envelope.data?.read {
val copied = copyTo(this@write) val copied = transferTo(this@write)
if (copied != envelope.data?.size?.toLong()) { if (copied != envelope.data?.size?.toLong()) {
error("The number of copied bytes does not equal data size") error("The number of copied bytes does not equal data size")
} }

View File

@ -1,9 +1,11 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.Input import kotlinx.io.Source
import io.ktor.utils.io.streams.asInput import kotlinx.io.asSource
import kotlinx.io.buffered
public fun IOPlugin.resource(name: String): Binary? = context.javaClass.getResource(name)?.readBytes()?.asBinary()
public inline fun <R> IOPlugin.readResource(name: String, block: Input.() -> R): R = public fun IOPlugin.resource(name: String): Binary? = { }.javaClass.getResource(name)?.readBytes()?.asBinary()
context.javaClass.getResource(name)?.openStream()?.asInput()?.block() ?: error("Can't read resource $name")
public inline fun <R> IOPlugin.readResource(name: String, block: Source.() -> R): R =
{ }.javaClass.getResource(name)?.openStream()?.asSource()?.buffered()?.block() ?: error("Can't read resource $name")

View File

@ -1,7 +1,6 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import space.kscience.dataforge.context.ContextBuilder import space.kscience.dataforge.context.ContextBuilder
import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.set import space.kscience.dataforge.meta.set
import space.kscience.dataforge.meta.string import space.kscience.dataforge.meta.string
import java.nio.file.Path import java.nio.file.Path

View File

@ -1,6 +1,5 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.writeDouble
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import java.nio.file.Files import java.nio.file.Files

View File

@ -1,6 +1,5 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import io.ktor.utils.io.core.writeDouble
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import java.nio.file.Files import java.nio.file.Files

View File

@ -6,27 +6,18 @@ Meta definition and basic operations on meta
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-meta:0.6.2-dev-2`. The Maven coordinates of this project are `space.kscience:dataforge-meta:0.7.0`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:dataforge-meta:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("space.kscience:dataforge-meta:0.6.2-dev-2") implementation("space.kscience:dataforge-meta:0.7.0")
} }
``` ```

View File

@ -45,9 +45,9 @@ public final class space/kscience/dataforge/meta/False : space/kscience/dataforg
public final class space/kscience/dataforge/meta/JsonMetaKt { public final class space/kscience/dataforge/meta/JsonMetaKt {
public static final fun getJSON_ARRAY_KEY (Lspace/kscience/dataforge/meta/Meta$Companion;)Ljava/lang/String; public static final fun getJSON_ARRAY_KEY (Lspace/kscience/dataforge/meta/Meta$Companion;)Ljava/lang/String;
public static final fun toJson (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lkotlinx/serialization/json/JsonObject; public static final fun toJson (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lkotlinx/serialization/json/JsonElement;
public static final fun toJson (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lkotlinx/serialization/json/JsonElement; public static final fun toJson (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lkotlinx/serialization/json/JsonElement;
public static synthetic fun toJson$default (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;ILjava/lang/Object;)Lkotlinx/serialization/json/JsonObject; public static synthetic fun toJson$default (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;ILjava/lang/Object;)Lkotlinx/serialization/json/JsonElement;
public static synthetic fun toJson$default (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;ILjava/lang/Object;)Lkotlinx/serialization/json/JsonElement; public static synthetic fun toJson$default (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;ILjava/lang/Object;)Lkotlinx/serialization/json/JsonElement;
public static final fun toMeta (Lkotlinx/serialization/json/JsonElement;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun toMeta (Lkotlinx/serialization/json/JsonElement;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lspace/kscience/dataforge/meta/SealedMeta;
public static final fun toMeta (Lkotlinx/serialization/json/JsonObject;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun toMeta (Lkotlinx/serialization/json/JsonObject;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)Lspace/kscience/dataforge/meta/SealedMeta;
@ -59,11 +59,11 @@ public final class space/kscience/dataforge/meta/JsonMetaKt {
public final class space/kscience/dataforge/meta/Laminate : space/kscience/dataforge/meta/TypedMeta { public final class space/kscience/dataforge/meta/Laminate : space/kscience/dataforge/meta/TypedMeta {
public static final field Companion Lspace/kscience/dataforge/meta/Laminate$Companion; public static final field Companion Lspace/kscience/dataforge/meta/Laminate$Companion;
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z
public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Laminate;
public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta;
public fun getItems ()Ljava/util/Map; public fun getItems ()Ljava/util/Map;
public final fun getLayers ()Ljava/util/List; public final fun getLayers ()Ljava/util/List;
public fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Laminate;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta;
public fun getValue ()Lspace/kscience/dataforge/meta/Value; public fun getValue ()Lspace/kscience/dataforge/meta/Value;
public fun hashCode ()I public fun hashCode ()I
public final fun merge ()Lspace/kscience/dataforge/meta/SealedMeta; public final fun merge ()Lspace/kscience/dataforge/meta/SealedMeta;
@ -122,8 +122,8 @@ public abstract interface class space/kscience/dataforge/meta/Meta : space/kscie
public static final field TYPE Ljava/lang/String; public static final field TYPE Ljava/lang/String;
public static final field VALUE_KEY Ljava/lang/String; public static final field VALUE_KEY Ljava/lang/String;
public abstract fun equals (Ljava/lang/Object;)Z public abstract fun equals (Ljava/lang/Object;)Z
public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public abstract fun getItems ()Ljava/util/Map; public abstract fun getItems ()Ljava/util/Map;
public fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public abstract fun getValue ()Lspace/kscience/dataforge/meta/Value; public abstract fun getValue ()Lspace/kscience/dataforge/meta/Value;
public abstract fun hashCode ()I public abstract fun hashCode ()I
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
@ -137,10 +137,26 @@ public final class space/kscience/dataforge/meta/Meta$Companion {
public final fun equals (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;)Z public final fun equals (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;)Z
public final fun getEMPTY ()Lspace/kscience/dataforge/meta/Meta; public final fun getEMPTY ()Lspace/kscience/dataforge/meta/Meta;
public final fun hashCode (Lspace/kscience/dataforge/meta/Meta;)I public final fun hashCode (Lspace/kscience/dataforge/meta/Meta;)I
public final fun serializer ()Lkotlinx/serialization/KSerializer;
public final fun toString (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/String; public final fun toString (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/String;
} }
public abstract interface annotation class space/kscience/dataforge/meta/MetaBuilder : java/lang/annotation/Annotation { public final class space/kscience/dataforge/meta/MetaBuilder : space/kscience/dataforge/meta/MutableMeta {
public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/Value;Ljava/util/Map;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Value;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun equals (Ljava/lang/Object;)Z
public fun getItems ()Ljava/util/Map;
public fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MetaBuilder;
public synthetic fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public fun getValue ()Lspace/kscience/dataforge/meta/Value;
public fun hashCode ()I
public fun set (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V
public fun setValue (Lspace/kscience/dataforge/meta/Value;)V
public fun toString ()Ljava/lang/String;
}
public abstract interface annotation class space/kscience/dataforge/meta/MetaBuilderMarker : java/lang/annotation/Annotation {
} }
public final class space/kscience/dataforge/meta/MetaDelegateKt { public final class space/kscience/dataforge/meta/MetaDelegateKt {
@ -204,11 +220,7 @@ public final class space/kscience/dataforge/meta/MetaKt {
public static final fun getIndexed (Lspace/kscience/dataforge/meta/TypedMeta;Lspace/kscience/dataforge/names/Name;)Ljava/util/Map; public static final fun getIndexed (Lspace/kscience/dataforge/meta/TypedMeta;Lspace/kscience/dataforge/names/Name;)Ljava/util/Map;
public static final fun getInt (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Integer; public static final fun getInt (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Integer;
public static final fun getLong (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Long; public static final fun getLong (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Long;
public static final synthetic fun getNonNullable (Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;)Lspace/kscience/dataforge/meta/Meta;
public static final synthetic fun getNonNullable (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public static final synthetic fun getNonNullable (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/NameToken;)Lspace/kscience/dataforge/meta/Meta; public static final synthetic fun getNonNullable (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/NameToken;)Lspace/kscience/dataforge/meta/Meta;
public static final synthetic fun getNonNullable (Lspace/kscience/dataforge/meta/TypedMeta;Ljava/lang/String;)Lspace/kscience/dataforge/meta/TypedMeta;
public static final synthetic fun getNonNullable (Lspace/kscience/dataforge/meta/TypedMeta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta;
public static final fun getNumber (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Number; public static final fun getNumber (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Number;
public static final fun getSelf (Lspace/kscience/dataforge/meta/TypedMeta;)Lspace/kscience/dataforge/meta/TypedMeta; public static final fun getSelf (Lspace/kscience/dataforge/meta/TypedMeta;)Lspace/kscience/dataforge/meta/TypedMeta;
public static final fun getShort (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Short; public static final fun getShort (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Short;
@ -223,7 +235,7 @@ public final class space/kscience/dataforge/meta/MetaKt {
} }
public abstract interface class space/kscience/dataforge/meta/MetaProvider : space/kscience/dataforge/meta/ValueProvider { public abstract interface class space/kscience/dataforge/meta/MetaProvider : space/kscience/dataforge/meta/ValueProvider {
public abstract fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta; public abstract fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public fun getValue (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Value; public fun getValue (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Value;
} }
@ -241,9 +253,10 @@ public final class space/kscience/dataforge/meta/MetaSerializer : kotlinx/serial
} }
public abstract interface class space/kscience/dataforge/meta/MutableMeta : space/kscience/dataforge/meta/Meta, space/kscience/dataforge/meta/MutableMetaProvider { public abstract interface class space/kscience/dataforge/meta/MutableMeta : space/kscience/dataforge/meta/Meta, space/kscience/dataforge/meta/MutableMetaProvider {
public static final field Companion Lspace/kscience/dataforge/meta/MutableMeta$Companion;
public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public abstract fun getItems ()Ljava/util/Map; public abstract fun getItems ()Ljava/util/Map;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public abstract fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta; public abstract fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public abstract fun getValue ()Lspace/kscience/dataforge/meta/Value; public abstract fun getValue ()Lspace/kscience/dataforge/meta/Value;
public fun put (Ljava/lang/String;Ljava/lang/Enum;)V public fun put (Ljava/lang/String;Ljava/lang/Enum;)V
@ -269,6 +282,10 @@ public abstract interface class space/kscience/dataforge/meta/MutableMeta : spac
public fun setValue (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V public fun setValue (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V
} }
public final class space/kscience/dataforge/meta/MutableMeta$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class space/kscience/dataforge/meta/MutableMetaDelegateKt { public final class space/kscience/dataforge/meta/MutableMetaDelegateKt {
public static final fun boolean (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; public static final fun boolean (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty;
public static final fun boolean (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty; public static final fun boolean (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty;
@ -325,9 +342,9 @@ public final class space/kscience/dataforge/meta/MutableMetaDelegateKt {
} }
public final class space/kscience/dataforge/meta/MutableMetaKt { public final class space/kscience/dataforge/meta/MutableMetaKt {
public static final fun MutableMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta; public static final fun ObservableMutableMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta;
public static final fun MutableMeta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ObservableMutableMeta; public static final fun ObservableMutableMeta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ObservableMutableMeta;
public static synthetic fun MutableMeta$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/ObservableMutableMeta; public static synthetic fun ObservableMutableMeta$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/ObservableMutableMeta;
public static final fun append (Lspace/kscience/dataforge/meta/MutableMeta;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;)V public static final fun append (Lspace/kscience/dataforge/meta/MutableMeta;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;)V
public static final fun append (Lspace/kscience/dataforge/meta/MutableMeta;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;)V public static final fun append (Lspace/kscience/dataforge/meta/MutableMeta;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;)V
public static final fun append (Lspace/kscience/dataforge/meta/MutableMeta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V public static final fun append (Lspace/kscience/dataforge/meta/MutableMeta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V
@ -343,7 +360,6 @@ public final class space/kscience/dataforge/meta/MutableMetaKt {
public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Ljava/lang/String;Ljava/lang/Iterable;)V public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Ljava/lang/String;Ljava/lang/Iterable;)V
public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;)V public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;)V
public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/Name;Ljava/lang/Iterable;)V public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/Name;Ljava/lang/Iterable;)V
public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V
public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/NameToken;Lspace/kscience/dataforge/meta/Meta;)V public static final fun set (Lspace/kscience/dataforge/meta/MutableMetaProvider;Lspace/kscience/dataforge/names/NameToken;Lspace/kscience/dataforge/meta/Meta;)V
public static final fun set (Lspace/kscience/dataforge/meta/MutableTypedMeta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V public static final fun set (Lspace/kscience/dataforge/meta/MutableTypedMeta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V
public static final fun set (Lspace/kscience/dataforge/meta/MutableValueProvider;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V public static final fun set (Lspace/kscience/dataforge/meta/MutableValueProvider;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V
@ -355,8 +371,8 @@ public final class space/kscience/dataforge/meta/MutableMetaKt {
} }
public abstract interface class space/kscience/dataforge/meta/MutableMetaProvider : space/kscience/dataforge/meta/MetaProvider, space/kscience/dataforge/meta/MutableValueProvider { public abstract interface class space/kscience/dataforge/meta/MutableMetaProvider : space/kscience/dataforge/meta/MetaProvider, space/kscience/dataforge/meta/MutableValueProvider {
public abstract fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta; public abstract fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public abstract fun setMeta (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V public abstract fun set (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V
public abstract fun setValue (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V public abstract fun setValue (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V
} }
@ -370,7 +386,7 @@ public final class space/kscience/dataforge/meta/MutableMetaSerializer : kotlinx
} }
public abstract interface class space/kscience/dataforge/meta/MutableTypedMeta : space/kscience/dataforge/meta/MutableMeta, space/kscience/dataforge/meta/TypedMeta { public abstract interface class space/kscience/dataforge/meta/MutableTypedMeta : space/kscience/dataforge/meta/MutableMeta, space/kscience/dataforge/meta/TypedMeta {
public abstract fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta; public abstract fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta;
public abstract fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta; public abstract fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta;
} }
@ -413,11 +429,11 @@ public final class space/kscience/dataforge/meta/ObservableMetaWrapperKt {
} }
public abstract interface class space/kscience/dataforge/meta/ObservableMutableMeta : space/kscience/dataforge/meta/MutableMeta, space/kscience/dataforge/meta/MutableTypedMeta, space/kscience/dataforge/meta/ObservableMeta { public abstract interface class space/kscience/dataforge/meta/ObservableMutableMeta : space/kscience/dataforge/meta/MutableMeta, space/kscience/dataforge/meta/MutableTypedMeta, space/kscience/dataforge/meta/ObservableMeta {
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta; public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta; public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta; public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta;
public fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/ObservableMutableMeta; public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/ObservableMutableMeta;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta; public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta;
public abstract fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/ObservableMutableMeta; public abstract fun getOrCreate (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/ObservableMutableMeta;
} }
@ -429,12 +445,12 @@ public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecificat
public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/Configurable, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/MutableMetaProvider, space/kscience/dataforge/meta/descriptors/Described { public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/Configurable, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/MutableMetaProvider, space/kscience/dataforge/meta/descriptors/Described {
public fun <init> ()V public fun <init> ()V
public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public final fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; public final fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
public synthetic fun getMeta ()Lspace/kscience/dataforge/meta/MutableMeta; public synthetic fun getMeta ()Lspace/kscience/dataforge/meta/MutableMeta;
public final fun getMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta; public final fun getMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta; public fun set (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V
public fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public fun setMeta (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V
public fun setValue (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V public fun setValue (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;)V
public fun toMeta ()Lspace/kscience/dataforge/meta/Laminate; public fun toMeta ()Lspace/kscience/dataforge/meta/Laminate;
public synthetic fun toMeta ()Lspace/kscience/dataforge/meta/Meta; public synthetic fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
@ -463,13 +479,12 @@ public class space/kscience/dataforge/meta/SchemeSpec : space/kscience/dataforge
public final class space/kscience/dataforge/meta/SealedMeta : space/kscience/dataforge/meta/TypedMeta { public final class space/kscience/dataforge/meta/SealedMeta : space/kscience/dataforge/meta/TypedMeta {
public static final field Companion Lspace/kscience/dataforge/meta/SealedMeta$Companion; public static final field Companion Lspace/kscience/dataforge/meta/SealedMeta$Companion;
public synthetic fun <init> (ILspace/kscience/dataforge/meta/Value;Ljava/util/Map;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V public fun <init> (Lspace/kscience/dataforge/meta/Value;Ljava/util/Map;)V
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z
public fun getItems ()Ljava/util/Map; public fun getItems ()Ljava/util/Map;
public fun getValue ()Lspace/kscience/dataforge/meta/Value; public fun getValue ()Lspace/kscience/dataforge/meta/Value;
public fun hashCode ()I public fun hashCode ()I
public fun toString ()Ljava/lang/String; public fun toString ()Ljava/lang/String;
public static final synthetic fun write$Self (Lspace/kscience/dataforge/meta/SealedMeta;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
} }
public final class space/kscience/dataforge/meta/SealedMeta$$serializer : kotlinx/serialization/internal/GeneratedSerializer { public final class space/kscience/dataforge/meta/SealedMeta$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
@ -490,9 +505,13 @@ public final class space/kscience/dataforge/meta/SealedMeta$Companion {
public final class space/kscience/dataforge/meta/SealedMetaKt { public final class space/kscience/dataforge/meta/SealedMetaKt {
public static final fun Meta (Ljava/lang/Number;)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun Meta (Ljava/lang/Number;)Lspace/kscience/dataforge/meta/SealedMeta;
public static final fun Meta (Ljava/lang/String;)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun Meta (Ljava/lang/String;)Lspace/kscience/dataforge/meta/SealedMeta;
public static final fun Meta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun Meta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/Meta;
public static final fun Meta (Lspace/kscience/dataforge/meta/Value;)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun Meta (Lspace/kscience/dataforge/meta/Value;)Lspace/kscience/dataforge/meta/SealedMeta;
public static final fun Meta (Z)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun Meta (Z)Lspace/kscience/dataforge/meta/SealedMeta;
public static final fun MutableMeta ()Lspace/kscience/dataforge/meta/MutableMeta;
public static final fun MutableMeta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/MutableMeta;
public static synthetic fun MutableMeta$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/MutableMeta;
public static final fun SealedMeta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/SealedMeta;
public static final fun seal (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/SealedMeta; public static final fun seal (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/SealedMeta;
} }
@ -541,9 +560,9 @@ public final class space/kscience/dataforge/meta/True : space/kscience/dataforge
} }
public abstract interface class space/kscience/dataforge/meta/TypedMeta : space/kscience/dataforge/meta/Meta { public abstract interface class space/kscience/dataforge/meta/TypedMeta : space/kscience/dataforge/meta/Meta {
public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta;
public abstract fun getItems ()Ljava/util/Map; public abstract fun getItems ()Ljava/util/Map;
public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta;
public fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta;
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
} }
@ -561,6 +580,8 @@ public abstract interface class space/kscience/dataforge/meta/Value {
public final class space/kscience/dataforge/meta/Value$Companion { public final class space/kscience/dataforge/meta/Value$Companion {
public static final field TYPE Ljava/lang/String; public static final field TYPE Ljava/lang/String;
public final fun of (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Value; public final fun of (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Value;
public final fun parse (Ljava/lang/String;)Lspace/kscience/dataforge/meta/Value;
public final fun serializer ()Lkotlinx/serialization/KSerializer;
} }
public final class space/kscience/dataforge/meta/ValueExtensionsKt { public final class space/kscience/dataforge/meta/ValueExtensionsKt {
@ -635,21 +656,11 @@ public final class space/kscience/dataforge/meta/ValueType : java/lang/Enum {
public static final field NULL Lspace/kscience/dataforge/meta/ValueType; public static final field NULL Lspace/kscience/dataforge/meta/ValueType;
public static final field NUMBER Lspace/kscience/dataforge/meta/ValueType; public static final field NUMBER Lspace/kscience/dataforge/meta/ValueType;
public static final field STRING Lspace/kscience/dataforge/meta/ValueType; public static final field STRING Lspace/kscience/dataforge/meta/ValueType;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lspace/kscience/dataforge/meta/ValueType; public static fun valueOf (Ljava/lang/String;)Lspace/kscience/dataforge/meta/ValueType;
public static fun values ()[Lspace/kscience/dataforge/meta/ValueType; public static fun values ()[Lspace/kscience/dataforge/meta/ValueType;
} }
public final class space/kscience/dataforge/meta/ValueType$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lspace/kscience/dataforge/meta/ValueType$$serializer;
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/dataforge/meta/ValueType;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/dataforge/meta/ValueType;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class space/kscience/dataforge/meta/ValueType$Companion { public final class space/kscience/dataforge/meta/ValueType$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer; public final fun serializer ()Lkotlinx/serialization/KSerializer;
} }
@ -661,34 +672,30 @@ public abstract interface class space/kscience/dataforge/meta/descriptors/Descri
public final class space/kscience/dataforge/meta/descriptors/MetaDescriptor { public final class space/kscience/dataforge/meta/descriptors/MetaDescriptor {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor$Companion; public static final field Companion Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor$Companion;
public fun <init> ()V public fun <init> ()V
public synthetic fun <init> (ILjava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRequirement;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;ZLspace/kscience/dataforge/meta/Meta;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V public fun <init> (Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRestriction;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/Meta;)V
public fun <init> (Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRequirement;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;ZLspace/kscience/dataforge/meta/Meta;)V public synthetic fun <init> (Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRestriction;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRequirement;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;ZLspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String; public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/util/Map; public final fun component2 ()Ljava/util/Map;
public final fun component3 ()Z public final fun component3 ()Z
public final fun component4 ()Lspace/kscience/dataforge/meta/descriptors/ValueRequirement; public final fun component4 ()Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
public final fun component5 ()Ljava/util/List; public final fun component5 ()Ljava/util/List;
public final fun component6 ()Ljava/lang/String; public final fun component6 ()Ljava/lang/String;
public final fun component7 ()Lspace/kscience/dataforge/meta/Value; public final fun component7 ()Lspace/kscience/dataforge/meta/Value;
public final fun component8 ()Z public final fun component8 ()Lspace/kscience/dataforge/meta/Meta;
public final fun component9 ()Lspace/kscience/dataforge/meta/Meta; public final fun copy (Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRestriction;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
public final fun copy (Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRequirement;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;ZLspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRestriction;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;Ljava/lang/String;Ljava/util/Map;ZLspace/kscience/dataforge/meta/descriptors/ValueRequirement;Ljava/util/List;Ljava/lang/String;Lspace/kscience/dataforge/meta/Value;ZLspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z
public final fun getAttributes ()Lspace/kscience/dataforge/meta/Meta; public final fun getAttributes ()Lspace/kscience/dataforge/meta/Meta;
public final fun getChildren ()Ljava/util/Map; public final fun getChildren ()Ljava/util/Map;
public final fun getDefaultNode ()Lspace/kscience/dataforge/meta/Meta; public final fun getDefaultNode ()Lspace/kscience/dataforge/meta/Meta;
public final fun getDefaultValue ()Lspace/kscience/dataforge/meta/Value; public final fun getDefaultValue ()Lspace/kscience/dataforge/meta/Value;
public final fun getDescription ()Ljava/lang/String;
public final fun getIndexKey ()Ljava/lang/String; public final fun getIndexKey ()Ljava/lang/String;
public final fun getInfo ()Ljava/lang/String;
public final fun getMultiple ()Z public final fun getMultiple ()Z
public final fun getReadOnly ()Z public final fun getValueRestriction ()Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
public final fun getValueRequirement ()Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;
public final fun getValueTypes ()Ljava/util/List; public final fun getValueTypes ()Ljava/util/List;
public fun hashCode ()I public fun hashCode ()I
public fun toString ()Ljava/lang/String; public fun toString ()Ljava/lang/String;
public static final synthetic fun write$Self (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
} }
public final class space/kscience/dataforge/meta/descriptors/MetaDescriptor$$serializer : kotlinx/serialization/internal/GeneratedSerializer { public final class space/kscience/dataforge/meta/descriptors/MetaDescriptor$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
@ -703,6 +710,7 @@ public final class space/kscience/dataforge/meta/descriptors/MetaDescriptor$$ser
} }
public final class space/kscience/dataforge/meta/descriptors/MetaDescriptor$Companion { public final class space/kscience/dataforge/meta/descriptors/MetaDescriptor$Companion {
public final fun getEMPTY ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
public final fun serializer ()Lkotlinx/serialization/KSerializer; public final fun serializer ()Lkotlinx/serialization/KSerializer;
} }
@ -719,9 +727,8 @@ public final class space/kscience/dataforge/meta/descriptors/MetaDescriptorBuild
public final fun getIndexKey ()Ljava/lang/String; public final fun getIndexKey ()Ljava/lang/String;
public final fun getInfo ()Ljava/lang/String; public final fun getInfo ()Ljava/lang/String;
public final fun getMultiple ()Z public final fun getMultiple ()Z
public final fun getReadOnly ()Z public final fun getValueRestriction ()Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
public final fun getType ()Ljava/util/List; public final fun getValueTypes ()Ljava/util/List;
public final fun getValueRequirement ()Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;
public final fun item (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder; public final fun item (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder;
public static synthetic fun item$default (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder; public static synthetic fun item$default (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder;
public final fun node (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder; public final fun node (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder;
@ -733,10 +740,9 @@ public final class space/kscience/dataforge/meta/descriptors/MetaDescriptorBuild
public final fun setIndexKey (Ljava/lang/String;)V public final fun setIndexKey (Ljava/lang/String;)V
public final fun setInfo (Ljava/lang/String;)V public final fun setInfo (Ljava/lang/String;)V
public final fun setMultiple (Z)V public final fun setMultiple (Z)V
public final fun setReadOnly (Z)V public final fun setValueRestriction (Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;)V
public final fun setType (Ljava/util/List;)V public final fun setValueTypes (Ljava/util/List;)V
public final fun setValueRequirement (Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;)V public final fun valueType (Lspace/kscience/dataforge/meta/ValueType;[Lspace/kscience/dataforge/meta/ValueType;)V
public final fun type (Lspace/kscience/dataforge/meta/ValueType;[Lspace/kscience/dataforge/meta/ValueType;)V
} }
public final class space/kscience/dataforge/meta/descriptors/MetaDescriptorBuilderKt { public final class space/kscience/dataforge/meta/descriptors/MetaDescriptorBuilderKt {
@ -764,12 +770,13 @@ public final class space/kscience/dataforge/meta/descriptors/MetaDescriptorKt {
public static final fun validate (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;Lspace/kscience/dataforge/meta/Value;)Z public static final fun validate (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;Lspace/kscience/dataforge/meta/Value;)Z
} }
public final class space/kscience/dataforge/meta/descriptors/ValueRequirement : java/lang/Enum { public final class space/kscience/dataforge/meta/descriptors/ValueRestriction : java/lang/Enum {
public static final field ABSENT Lspace/kscience/dataforge/meta/descriptors/ValueRequirement; public static final field ABSENT Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
public static final field NONE Lspace/kscience/dataforge/meta/descriptors/ValueRequirement; public static final field NONE Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
public static final field REQUIRED Lspace/kscience/dataforge/meta/descriptors/ValueRequirement; public static final field REQUIRED Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
public static fun valueOf (Ljava/lang/String;)Lspace/kscience/dataforge/meta/descriptors/ValueRequirement; public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun values ()[Lspace/kscience/dataforge/meta/descriptors/ValueRequirement; public static fun valueOf (Ljava/lang/String;)Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
public static fun values ()[Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;
} }
public final class space/kscience/dataforge/meta/transformations/KeepTransformationRule : space/kscience/dataforge/meta/transformations/TransformationRule { public final class space/kscience/dataforge/meta/transformations/KeepTransformationRule : space/kscience/dataforge/meta/transformations/TransformationRule {
@ -788,7 +795,10 @@ public final class space/kscience/dataforge/meta/transformations/KeepTransformat
public abstract interface class space/kscience/dataforge/meta/transformations/MetaConverter { public abstract interface class space/kscience/dataforge/meta/transformations/MetaConverter {
public static final field Companion Lspace/kscience/dataforge/meta/transformations/MetaConverter$Companion; public static final field Companion Lspace/kscience/dataforge/meta/transformations/MetaConverter$Companion;
public abstract fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object; public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
public abstract fun getType ()Lkotlin/reflect/KType;
public fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
public abstract fun metaToObjectOrNull (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
public abstract fun objectToMeta (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Meta; public abstract fun objectToMeta (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Meta;
} }
@ -893,6 +903,10 @@ public abstract interface annotation class space/kscience/dataforge/misc/DFExper
public abstract interface annotation class space/kscience/dataforge/misc/DFInternal : java/lang/annotation/Annotation { public abstract interface annotation class space/kscience/dataforge/misc/DFInternal : java/lang/annotation/Annotation {
} }
public abstract interface annotation class space/kscience/dataforge/misc/DfId : java/lang/annotation/Annotation {
public abstract fun id ()Ljava/lang/String;
}
public abstract interface class space/kscience/dataforge/misc/Named { public abstract interface class space/kscience/dataforge/misc/Named {
public static final field Companion Lspace/kscience/dataforge/misc/Named$Companion; public static final field Companion Lspace/kscience/dataforge/misc/Named$Companion;
public abstract fun getName ()Lspace/kscience/dataforge/names/Name; public abstract fun getName ()Lspace/kscience/dataforge/names/Name;
@ -906,10 +920,6 @@ public final class space/kscience/dataforge/misc/NamedKt {
public static final fun isAnonymous (Lspace/kscience/dataforge/misc/Named;)Z public static final fun isAnonymous (Lspace/kscience/dataforge/misc/Named;)Z
} }
public abstract interface annotation class space/kscience/dataforge/misc/Type : java/lang/annotation/Annotation {
public abstract fun id ()Ljava/lang/String;
}
public final class space/kscience/dataforge/names/Name { public final class space/kscience/dataforge/names/Name {
public static final field Companion Lspace/kscience/dataforge/names/Name$Companion; public static final field Companion Lspace/kscience/dataforge/names/Name$Companion;
public static final field NAME_SEPARATOR Ljava/lang/String; public static final field NAME_SEPARATOR Ljava/lang/String;
@ -944,6 +954,7 @@ public final class space/kscience/dataforge/names/NameKt {
public static synthetic fun get$default (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun get$default (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun getLength (Lspace/kscience/dataforge/names/Name;)I public static final fun getLength (Lspace/kscience/dataforge/names/Name;)I
public static final fun isEmpty (Lspace/kscience/dataforge/names/Name;)Z public static final fun isEmpty (Lspace/kscience/dataforge/names/Name;)Z
public static final fun last (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/names/NameToken;
public static final fun lastOrNull (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/names/NameToken; public static final fun lastOrNull (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/names/NameToken;
public static final fun parseAsName (Ljava/lang/String;Z)Lspace/kscience/dataforge/names/Name; public static final fun parseAsName (Ljava/lang/String;Z)Lspace/kscience/dataforge/names/Name;
public static synthetic fun parseAsName$default (Ljava/lang/String;ZILjava/lang/Object;)Lspace/kscience/dataforge/names/Name; public static synthetic fun parseAsName$default (Ljava/lang/String;ZILjava/lang/Object;)Lspace/kscience/dataforge/names/Name;

View File

@ -81,7 +81,7 @@ public fun JsonPrimitive.toValue(descriptor: MetaDescriptor?): Value = when (thi
content.asValue() content.asValue()
} else { } else {
//consider using LazyParse //consider using LazyParse
content.parseValue() Value.parse(content)
} }
} }
} }

View File

@ -17,8 +17,8 @@ public class Laminate internal constructor(public val layers: List<Meta>) : Type
} }
} }
override fun getMeta(name: Name): Laminate? { override fun get(name: Name): Laminate? {
val childLayers = layers.mapNotNull { it.getMeta(name) } val childLayers = layers.mapNotNull { it.get(name) }
return if (childLayers.isEmpty()) null else Laminate(childLayers) return if (childLayers.isEmpty()) null else Laminate(childLayers)
} }

View File

@ -2,7 +2,7 @@ package space.kscience.dataforge.meta
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.misc.unsafeCast import space.kscience.dataforge.misc.unsafeCast
import space.kscience.dataforge.names.* import space.kscience.dataforge.names.*
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
@ -21,9 +21,9 @@ public interface MetaRepr {
* A container for meta nodes * A container for meta nodes
*/ */
public fun interface MetaProvider : ValueProvider { public fun interface MetaProvider : ValueProvider {
public fun getMeta(name: Name): Meta? public operator fun get(name: Name): Meta?
override fun getValue(name: Name): Value? = getMeta(name)?.value override fun getValue(name: Name): Value? = get(name)?.value
} }
/** /**
@ -31,13 +31,13 @@ public fun interface MetaProvider : ValueProvider {
* TODO add documentation * TODO add documentation
* Same name siblings are supported via elements with the same [Name] but different indices. * Same name siblings are supported via elements with the same [Name] but different indices.
*/ */
@Type(Meta.TYPE) @DfId(Meta.TYPE)
@Serializable(MetaSerializer::class) @Serializable(MetaSerializer::class)
public interface Meta : MetaRepr, MetaProvider { public interface Meta : MetaRepr, MetaProvider {
public val value: Value? public val value: Value?
public val items: Map<NameToken, Meta> public val items: Map<NameToken, Meta>
override fun getMeta(name: Name): Meta? { override fun get(name: Name): Meta? {
tailrec fun Meta.find(name: Name): Meta? = if (name.isEmpty()) { tailrec fun Meta.find(name: Name): Meta? = if (name.isEmpty()) {
this this
} else { } else {
@ -50,7 +50,9 @@ public interface Meta : MetaRepr, MetaProvider {
override fun toMeta(): Meta = this override fun toMeta(): Meta = this
override fun toString(): String override fun toString(): String
override fun equals(other: Any?): Boolean override fun equals(other: Any?): Boolean
override fun hashCode(): Int override fun hashCode(): Int
public companion object { public companion object {
@ -106,21 +108,13 @@ public operator fun Meta.get(token: NameToken): Meta? = items[token]
* *
* If [name] is empty return current [Meta] * If [name] is empty return current [Meta]
*/ */
public operator fun Meta?.get(name: Name): Meta? = this?.getMeta(name) public operator fun Meta?.get(name: Name): Meta? = this?.get(name)
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
@JvmName("getNonNullable")
public operator fun Meta.get(name: Name): Meta? = getMeta(name)
/** /**
* Parse [Name] from [key] using full name notation and pass it to [Meta.get] * Parse [Name] from [key] using full name notation and pass it to [Meta.get]
*/ */
public operator fun Meta?.get(key: String): Meta? = this?.get(key.parseAsName(true)) public operator fun Meta?.get(key: String): Meta? = this?.get(key.parseAsName(true))
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
@JvmName("getNonNullable")
public operator fun Meta.get(key: String): Meta? = get(key.parseAsName(true))
/** /**
* Get all items matching given name. The index of the last element, if present is used as a [Regex], * Get all items matching given name. The index of the last element, if present is used as a [Regex],
* against which indexes of elements are matched. * against which indexes of elements are matched.
@ -157,7 +151,7 @@ public interface TypedMeta<out M : TypedMeta<M>> : Meta {
override val items: Map<NameToken, M> override val items: Map<NameToken, M>
override fun getMeta(name: Name): M? { override fun get(name: Name): M? {
tailrec fun M.find(name: Name): M? = if (name.isEmpty()) { tailrec fun M.find(name: Name): M? = if (name.isEmpty()) {
this this
} else { } else {
@ -180,28 +174,17 @@ public inline val <M : TypedMeta<M>> TypedMeta<M>.self: M get() = unsafeCast()
public operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(token: NameToken): M? = this?.items?.get(token) public operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(token: NameToken): M? = this?.items?.get(token)
/** /**
* Perform recursive item search using given [name]. Each [NameToken] is treated as a name in [TypedMeta.items] of a parent node. * Retrieves a meta node with the given name from the nullable [TypedMeta] object.
* *
* If [name] is empty return current [Meta] * @param name The name of the meta node to retrieve.
* @return The meta node with the given name, or null if it doesn't exist.
*/ */
public tailrec operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(name: Name): M? = when { public operator fun <M : TypedMeta<M>> M?.get(name: Name): M? = this?.get(name)
this == null -> null
name.isEmpty() -> self
else -> get(name.firstOrNull()!!)?.get(name.cutFirst())
}
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
@JvmName("getNonNullable")
public operator fun <M : TypedMeta<M>> TypedMeta<M>.get(name: Name): M? = get(name)
/** /**
* Parse [Name] from [key] using full name notation and pass it to [TypedMeta.get] * Parse [Name] from [key] using full name notation and pass it to [TypedMeta.get]
*/ */
public operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(key: String): M? = this[key.parseAsName(true)] public operator fun <M : TypedMeta<M>> M?.get(key: String): M? = this?.get(key.parseAsName(true))
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
@JvmName("getNonNullable")
public operator fun <M : TypedMeta<M>> TypedMeta<M>.get(key: String): M? = get(key)
/** /**

View File

@ -8,28 +8,28 @@ import kotlin.properties.ReadOnlyProperty
/* Meta delegates */ /* Meta delegates */
public fun MetaProvider.node(key: Name? = null): ReadOnlyProperty<Any?, Meta?> = ReadOnlyProperty { _, property -> public fun MetaProvider.node(key: Name? = null): ReadOnlyProperty<Any?, Meta?> = ReadOnlyProperty { _, property ->
getMeta(key ?: property.name.asName()) get(key ?: property.name.asName())
} }
public fun <T> MetaProvider.node( public fun <T> MetaProvider.node(
key: Name? = null, key: Name? = null,
converter: MetaConverter<T> converter: MetaConverter<T>
): ReadOnlyProperty<Any?, T?> = ReadOnlyProperty { _, property -> ): ReadOnlyProperty<Any?, T?> = ReadOnlyProperty { _, property ->
getMeta(key ?: property.name.asName())?.let { converter.metaToObject(it) } get(key ?: property.name.asName())?.let { converter.metaToObject(it) }
} }
/** /**
* A property delegate that uses custom key * A property delegate that uses custom key
*/ */
public fun MetaProvider.value(key: Name? = null): ReadOnlyProperty<Any?, Value?> = ReadOnlyProperty { _, property -> public fun MetaProvider.value(key: Name? = null): ReadOnlyProperty<Any?, Value?> = ReadOnlyProperty { _, property ->
getMeta(key ?: property.name.asName())?.value get(key ?: property.name.asName())?.value
} }
public fun <R> MetaProvider.value( public fun <R> MetaProvider.value(
key: Name? = null, key: Name? = null,
reader: (Value?) -> R reader: (Value?) -> R
): ReadOnlyProperty<Any?, R> = ReadOnlyProperty { _, property -> ): ReadOnlyProperty<Any?, R> = ReadOnlyProperty { _, property ->
reader(getMeta(key ?: property.name.asName())?.value) reader(get(key ?: property.name.asName())?.value)
} }
//TODO add caching for sealed nodes //TODO add caching for sealed nodes

View File

@ -11,14 +11,14 @@ import kotlin.js.JsName
* Mark a meta builder * Mark a meta builder
*/ */
@DslMarker @DslMarker
public annotation class MetaBuilder public annotation class MetaBuilderMarker
/** /**
* A generic interface that gives access to getting and setting meta notes and values * A generic interface that gives access to getting and setting meta notes and values
*/ */
public interface MutableMetaProvider : MetaProvider, MutableValueProvider { public interface MutableMetaProvider : MetaProvider, MutableValueProvider {
override fun getMeta(name: Name): MutableMeta? override fun get(name: Name): MutableMeta?
public fun setMeta(name: Name, node: Meta?) public operator fun set(name: Name, node: Meta?)
override fun setValue(name: Name, value: Value?) override fun setValue(name: Name, value: Value?)
} }
@ -27,7 +27,7 @@ public interface MutableMetaProvider : MetaProvider, MutableValueProvider {
* TODO documentation * TODO documentation
*/ */
@Serializable(MutableMetaSerializer::class) @Serializable(MutableMetaSerializer::class)
@MetaBuilder @MetaBuilderMarker
public interface MutableMeta : Meta, MutableMetaProvider { public interface MutableMeta : Meta, MutableMetaProvider {
override val items: Map<NameToken, MutableMeta> override val items: Map<NameToken, MutableMeta>
@ -37,7 +37,7 @@ public interface MutableMeta : Meta, MutableMetaProvider {
*/ */
override var value: Value? override var value: Value?
override fun getMeta(name: Name): MutableMeta? { override fun get(name: Name): MutableMeta? {
tailrec fun MutableMeta.find(name: Name): MutableMeta? = if (name.isEmpty()) { tailrec fun MutableMeta.find(name: Name): MutableMeta? = if (name.isEmpty()) {
this this
} else { } else {
@ -83,19 +83,19 @@ public interface MutableMeta : Meta, MutableMetaProvider {
} }
public infix fun Name.put(meta: Meta) { public infix fun Name.put(meta: Meta) {
setMeta(this, meta) set(this, meta)
} }
public infix fun Name.put(repr: MetaRepr) { public infix fun Name.put(repr: MetaRepr) {
setMeta(this, repr.toMeta()) set(this, repr.toMeta())
} }
public infix fun Name.put(mutableMeta: MutableMeta.() -> Unit) { public infix fun Name.put(builder: MutableMeta.() -> Unit) {
setMeta(this, Meta(mutableMeta)) getOrCreate(this).apply(builder)
} }
public infix fun String.put(meta: Meta) { public infix fun String.put(meta: Meta) {
setMeta(Name.parse(this), meta) set(Name.parse(this), meta)
} }
public infix fun String.put(value: Value?) { public infix fun String.put(value: Value?) {
@ -123,7 +123,7 @@ public interface MutableMeta : Meta, MutableMetaProvider {
} }
public infix fun String.put(repr: MetaRepr) { public infix fun String.put(repr: MetaRepr) {
setMeta(Name.parse(this), repr.toMeta()) set(Name.parse(this), repr.toMeta())
} }
public infix fun String.putIndexed(iterable: Iterable<Meta>) { public infix fun String.putIndexed(iterable: Iterable<Meta>) {
@ -131,15 +131,10 @@ public interface MutableMeta : Meta, MutableMetaProvider {
} }
public infix fun String.put(builder: MutableMeta.() -> Unit) { public infix fun String.put(builder: MutableMeta.() -> Unit) {
setMeta(Name.parse(this), MutableMeta(builder)) getOrCreate(parseAsName()).apply(builder)
} }
} }
/**
* Set or replace node at given [name]
*/
public operator fun MutableMetaProvider.set(name: Name, meta: Meta): Unit = setMeta(name, meta)
/** /**
* Set or replace value at given [name] * Set or replace value at given [name]
*/ */
@ -154,24 +149,24 @@ public interface MutableTypedMeta<M : MutableTypedMeta<M>> : TypedMeta<M>, Mutab
*/ */
@DFExperimental @DFExperimental
public fun attach(name: Name, node: M) public fun attach(name: Name, node: M)
override fun getMeta(name: Name): M? override fun get(name: Name): M?
override fun getOrCreate(name: Name): M override fun getOrCreate(name: Name): M
} }
public fun <M : MutableTypedMeta<M>> M.getOrCreate(key: String): M = getOrCreate(Name.parse(key)) public fun <M : MutableTypedMeta<M>> M.getOrCreate(key: String): M = getOrCreate(Name.parse(key))
public fun MutableMetaProvider.remove(name: Name) { public fun MutableMetaProvider.remove(name: Name) {
setMeta(name, null) set(name, null)
} }
public fun MutableMetaProvider.remove(key: String) { public fun MutableMetaProvider.remove(key: String) {
setMeta(Name.parse(key), null) set(Name.parse(key), null)
} }
// node setters // node setters
public operator fun MutableMetaProvider.set(Key: NameToken, value: Meta): Unit = setMeta(Key.asName(), value) public operator fun MutableMetaProvider.set(Key: NameToken, value: Meta): Unit = set(Key.asName(), value)
public operator fun MutableMetaProvider.set(key: String, value: Meta): Unit = setMeta(Name.parse(key), value) public operator fun MutableMetaProvider.set(key: String, value: Meta): Unit = set(Name.parse(key), value)
//public fun MutableMeta.set(key: String, index: String, value: Value?): Unit = //public fun MutableMeta.set(key: String, index: String, value: Value?): Unit =
@ -319,7 +314,7 @@ private class MutableMetaImpl(
) )
@ThreadSafe @ThreadSafe
override fun setMeta(name: Name, node: Meta?) { override fun set(name: Name, node: Meta?) {
val oldItem: ObservableMutableMeta? = get(name) val oldItem: ObservableMutableMeta? = get(name)
if (oldItem != node) { if (oldItem != node) {
when (name.length) { when (name.length) {
@ -346,7 +341,7 @@ private class MutableMetaImpl(
newNode.adoptBy(this, token) newNode.adoptBy(this, token)
children[token] = newNode children[token] = newNode
} }
items[token]?.setMeta(name.cutFirst(), node) items[token]?.set(name.cutFirst(), node)
} }
} }
invalidate(name) invalidate(name)
@ -381,16 +376,14 @@ public fun Meta.toMutableMeta(): ObservableMutableMeta = MutableMetaImpl(value,
public fun Meta.asMutableMeta(): MutableMeta = (this as? MutableMeta) ?: toMutableMeta() public fun Meta.asMutableMeta(): MutableMeta = (this as? MutableMeta) ?: toMutableMeta()
@Suppress("FunctionName") @JsName("newObservableMutableMeta")
@JsName("newMutableMeta") public fun ObservableMutableMeta(): ObservableMutableMeta = MutableMetaImpl(null)
public fun MutableMeta(): ObservableMutableMeta = MutableMetaImpl(null)
/** /**
* Build a [MutableMeta] using given transformation * Build a [MutableMeta] using given transformation
*/ */
@Suppress("FunctionName") public inline fun ObservableMutableMeta(builder: MutableMeta.() -> Unit = {}): ObservableMutableMeta =
public inline fun MutableMeta(builder: MutableMeta.() -> Unit = {}): ObservableMutableMeta = ObservableMutableMeta().apply(builder)
MutableMeta().apply(builder)
/** /**
@ -407,7 +400,7 @@ private class MutableMetaWithDefault(
override val items: Map<NameToken, MutableMeta> override val items: Map<NameToken, MutableMeta>
get() { get() {
val sourceKeys: Collection<NameToken> = source[rootName]?.items?.keys ?: emptyList() val sourceKeys: Collection<NameToken> = source[rootName]?.items?.keys ?: emptyList()
val defaultKeys: Collection<NameToken> = default.getMeta(rootName)?.items?.keys ?: emptyList() val defaultKeys: Collection<NameToken> = default[rootName]?.items?.keys ?: emptyList()
//merging keys for primary and default node //merging keys for primary and default node
return (sourceKeys + defaultKeys).associateWith { return (sourceKeys + defaultKeys).associateWith {
MutableMetaWithDefault(source, default, rootName + it) MutableMetaWithDefault(source, default, rootName + it)
@ -415,12 +408,12 @@ private class MutableMetaWithDefault(
} }
override var value: Value? override var value: Value?
get() = source[rootName]?.value ?: default.getMeta(rootName)?.value get() = source[rootName]?.value ?: default.get(rootName)?.value
set(value) { set(value) {
source[rootName] = value source[rootName] = value
} }
override fun getMeta(name: Name): MutableMeta = MutableMetaWithDefault(source, default, rootName + name) override fun get(name: Name): MutableMeta = MutableMetaWithDefault(source, default, rootName + name)
override fun toString(): String = Meta.toString(this) override fun toString(): String = Meta.toString(this)
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)

View File

@ -11,31 +11,31 @@ import kotlin.reflect.KProperty
public fun MutableMetaProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = public fun MutableMetaProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> =
object : ReadWriteProperty<Any?, Meta?> { object : ReadWriteProperty<Any?, Meta?> {
override fun getValue(thisRef: Any?, property: KProperty<*>): Meta? { override fun getValue(thisRef: Any?, property: KProperty<*>): Meta? {
return getMeta(key ?: property.name.asName()) return get(key ?: property.name.asName())
} }
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta?) { override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta?) {
val name = key ?: property.name.asName() val name = key ?: property.name.asName()
setMeta(name, value) set(name, value)
} }
} }
public fun <T> MutableMetaProvider.node(key: Name? = null, converter: MetaConverter<T>): ReadWriteProperty<Any?, T?> = public fun <T> MutableMetaProvider.node(key: Name? = null, converter: MetaConverter<T>): ReadWriteProperty<Any?, T?> =
object : ReadWriteProperty<Any?, T?> { object : ReadWriteProperty<Any?, T?> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T? { override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
return getMeta(key ?: property.name.asName())?.let { converter.metaToObject(it) } return get(key ?: property.name.asName())?.let { converter.metaToObject(it) }
} }
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
val name = key ?: property.name.asName() val name = key ?: property.name.asName()
setMeta(name, value?.let { converter.objectToMeta(it) }) set(name, value?.let { converter.objectToMeta(it) })
} }
} }
public fun MutableMetaProvider.value(key: Name? = null): ReadWriteProperty<Any?, Value?> = public fun MutableMetaProvider.value(key: Name? = null): ReadWriteProperty<Any?, Value?> =
object : ReadWriteProperty<Any?, Value?> { object : ReadWriteProperty<Any?, Value?> {
override fun getValue(thisRef: Any?, property: KProperty<*>): Value? = override fun getValue(thisRef: Any?, property: KProperty<*>): Value? =
getMeta(key ?: property.name.asName())?.value get(key ?: property.name.asName())?.value
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) { override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) {
setValue(key ?: property.name.asName(), value) setValue(key ?: property.name.asName(), value)
@ -48,7 +48,7 @@ public fun <T> MutableMetaProvider.value(
reader: (Value?) -> T reader: (Value?) -> T
): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> { ): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T = override fun getValue(thisRef: Any?, property: KProperty<*>): T =
reader(getMeta(key ?: property.name.asName())?.value) reader(get(key ?: property.name.asName())?.value)
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
setValue(key ?: property.name.asName(), writer(value)) setValue(key ?: property.name.asName(), writer(value))

View File

@ -36,7 +36,7 @@ public interface ObservableMeta : Meta {
public interface ObservableMutableMeta : ObservableMeta, MutableMeta, MutableTypedMeta<ObservableMutableMeta> { public interface ObservableMutableMeta : ObservableMeta, MutableMeta, MutableTypedMeta<ObservableMutableMeta> {
override fun getOrCreate(name: Name): ObservableMutableMeta override fun getOrCreate(name: Name): ObservableMutableMeta
override fun getMeta(name: Name): ObservableMutableMeta? { override fun get(name: Name): ObservableMutableMeta? {
tailrec fun ObservableMutableMeta.find(name: Name): ObservableMutableMeta? = if (name.isEmpty()) { tailrec fun ObservableMutableMeta.find(name: Name): ObservableMutableMeta? = if (name.isEmpty()) {
this this
} else { } else {

View File

@ -17,8 +17,8 @@ private class ObservableMetaWrapper(
ObservableMetaWrapper(root, absoluteName + it, listeners) ObservableMetaWrapper(root, absoluteName + it, listeners)
} }
override fun getMeta(name: Name): ObservableMutableMeta? = override fun get(name: Name): ObservableMutableMeta? =
root.getMeta(name)?.let { ObservableMetaWrapper(root, this.absoluteName + name, listeners) } root.get(name)?.let { ObservableMetaWrapper(root, this.absoluteName + name, listeners) }
@ThreadSafe @ThreadSafe
override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) { override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) {
@ -49,9 +49,11 @@ private class ObservableMetaWrapper(
override fun getOrCreate(name: Name): ObservableMutableMeta = override fun getOrCreate(name: Name): ObservableMutableMeta =
ObservableMetaWrapper(root, this.absoluteName + name, listeners) ObservableMetaWrapper(root, this.absoluteName + name, listeners)
override fun setMeta(name: Name, node: Meta?) { override fun set(name: Name, node: Meta?) {
val oldMeta = get(name) val oldMeta = get(name)
root.setMeta(absoluteName + name, node) //don't forget to remove listener
oldMeta?.removeListener(this)
root.set(absoluteName + name, node)
if (oldMeta != node) { if (oldMeta != node) {
invalidate(name) invalidate(name)
} }
@ -67,7 +69,7 @@ private class ObservableMetaWrapper(
override fun attach(name: Name, node: ObservableMutableMeta) { override fun attach(name: Name, node: ObservableMutableMeta) {
set(name, node) set(name, node)
node.onChange(this) { changeName -> node.onChange(this) { changeName ->
setMeta(name + changeName, this[changeName]) set(name + changeName, this[changeName])
} }
} }
} }

View File

@ -47,11 +47,11 @@ public open class Scheme : Described, MetaRepr, MutableMetaProvider, Configurabl
return descriptor?.validate(meta) ?: true return descriptor?.validate(meta) ?: true
} }
override fun getMeta(name: Name): MutableMeta? = meta.getMeta(name) override fun get(name: Name): MutableMeta? = meta.get(name)
override fun setMeta(name: Name, node: Meta?) { override fun set(name: Name, node: Meta?) {
if (validate(name, meta)) { if (validate(name, meta)) {
meta.setMeta(name, node) meta.set(name, node)
} else { } else {
error("Validation failed for node $node at $name") error("Validation failed for node $node at $name")
} }
@ -110,8 +110,8 @@ public open class Scheme : Described, MetaRepr, MutableMetaProvider, Configurabl
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)
override fun hashCode(): Int = Meta.hashCode(this) override fun hashCode(): Int = Meta.hashCode(this)
override fun setMeta(name: Name, node: Meta?) { override fun set(name: Name, node: Meta?) {
targetMeta.setMeta(name, node) targetMeta.set(name, node)
invalidate(name) invalidate(name)
} }
@ -120,9 +120,9 @@ public open class Scheme : Described, MetaRepr, MutableMetaProvider, Configurabl
@DFExperimental @DFExperimental
override fun attach(name: Name, node: ObservableMutableMeta) { override fun attach(name: Name, node: ObservableMutableMeta) {
//TODO implement zero-copy attachment //TODO implement zero-copy attachment
setMeta(name, node) set(name, node)
node.onChange(this) { changeName -> node.onChange(this) { changeName ->
setMeta(name + changeName, this[changeName]) set(name + changeName, this[changeName])
} }
} }

View File

@ -1,16 +1,17 @@
package space.kscience.dataforge.meta package space.kscience.dataforge.meta
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.*
import kotlin.js.JsName
/** /**
* The meta implementation which is guaranteed to be immutable. * The meta implementation which is guaranteed to be immutable.
* *
*/ */
@Serializable @Serializable
public class SealedMeta internal constructor( public class SealedMeta(
override val value: Value?, override val value: Value?,
override val items: Map<NameToken, SealedMeta> override val items: Map<NameToken, SealedMeta>,
) : TypedMeta<SealedMeta> { ) : TypedMeta<SealedMeta> {
override fun toString(): String = Meta.toString(this) override fun toString(): String = Meta.toString(this)
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)
@ -26,7 +27,7 @@ public class SealedMeta internal constructor(
} }
/** /**
* Generate sealed node from [this]. If it is already sealed return it as is. * Generate sealed node from [this]. If it is already sealed, return it as is.
*/ */
public fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta( public fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta(
value, value,
@ -47,7 +48,79 @@ public fun Meta(value: String): SealedMeta = Meta(value.asValue())
@Suppress("FunctionName") @Suppress("FunctionName")
public fun Meta(value: Boolean): SealedMeta = Meta(value.asValue()) public fun Meta(value: Boolean): SealedMeta = Meta(value.asValue())
@Suppress("FunctionName")
public inline fun Meta(builder: MutableMeta.() -> Unit): SealedMeta =
MutableMeta(builder).seal()
/**
* A lightweight mutable meta without an observability
*/
@PublishedApi
internal class MetaBuilder(
override var value: Value? = null,
override val items: MutableMap<NameToken, MetaBuilder> = hashMapOf(),
) : MutableMeta {
override fun getOrCreate(name: Name): MetaBuilder {
val existing = get(name) as? MetaBuilder
return if (existing == null) {
val newItem = MetaBuilder()
set(name, newItem)
newItem
} else {
existing
}
}
private fun wrap(meta: Meta): MetaBuilder = meta as? MetaBuilder ?: MetaBuilder(
meta.value,
meta.items.mapValuesTo(hashMapOf()) { wrap(it.value) }
)
override fun set(name: Name, node: Meta?) {
when (name.length) {
0 -> error("Can't set a meta with empty name")
1 -> {
val token = name.first()
//remove child and invalidate if argument is null
if (node == null) {
items.remove(token)
} else {
items[token] = wrap(node)
}
}
else -> {
getOrCreate(name.first().asName()).set(name.cutFirst(), node)
}
}
}
override fun toString(): String = Meta.toString(this)
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)
override fun hashCode(): Int = Meta.hashCode(this)
}
/**
* Create a read-only meta.
*/
public inline fun Meta(builder: MutableMeta.() -> Unit): Meta =
MetaBuilder().apply(builder).seal()
/**
* Create an immutable meta.
*/
public inline fun SealedMeta(builder: MutableMeta.() -> Unit): SealedMeta =
MetaBuilder().apply(builder).seal()
/**
* Create an empty meta mutable meta.
*/
@JsName("newMutableMeta")
public fun MutableMeta(): MutableMeta = MetaBuilder()
/**
* Create a mutable meta with given builder.
*/
public inline fun MutableMeta(builder: MutableMeta.() -> Unit = {}): MutableMeta =
MutableMeta().apply(builder)

View File

@ -64,6 +64,7 @@ public interface Value {
ListValue(list) ListValue(list)
} }
} }
is DoubleArray -> value.asValue() is DoubleArray -> value.asValue()
is IntArray -> value.asValue() is IntArray -> value.asValue()
is FloatArray -> value.asValue() is FloatArray -> value.asValue()
@ -76,6 +77,41 @@ public interface Value {
else -> throw IllegalArgumentException("Unrecognized type of the object (${value::class}) converted to Value") else -> throw IllegalArgumentException("Unrecognized type of the object (${value::class}) converted to Value")
} }
} }
/**
* Parse value from string. Double-quoted strings are parsed literally. true/false are parsed as booleans
*/
public fun parse(string: String): Value {
//Trying to get integer
if (string.isEmpty() || string == Null.string) {
return Null
}
//string constants
if (string.startsWith("\"") && string.endsWith("\"")) {
return StringValue(string.substring(1, string.length - 2))
}
string.toIntOrNull()?.let {
return NumberValue(it)
}
string.toDoubleOrNull()?.let {
return NumberValue(it)
}
if ("true" == string) {
return True
}
if ("false" == string) {
return False
}
//Give up and return a StringValue
return StringValue(string)
}
} }
} }
@ -140,7 +176,7 @@ public class NumberValue(public val number: Number) : Value {
val otherNumber = other.numberOrNull ?: return false val otherNumber = other.numberOrNull ?: return false
if(number == otherNumber) return true if (number == otherNumber) return true
//Do not change the order of comparison. On JS number is the instance of all types //Do not change the order of comparison. On JS number is the instance of all types
return when (numberOrNull) { return when (numberOrNull) {
@ -228,34 +264,5 @@ public fun <E : Enum<E>> E.asValue(): Value = EnumValue(this)
/** /**
* Create Value from String using the closest match conversion * Create Value from String using the closest match conversion
*/ */
public fun String.parseValue(): Value { @Deprecated("Use Value.parse(this) instead", ReplaceWith("Value.parse(this)"))
public fun String.parseValue(): Value = Value.parse(this)
//Trying to get integer
if (isEmpty() || this == Null.string) {
return Null
}
//string constants
if (startsWith("\"") && endsWith("\"")) {
return StringValue(substring(1, length - 2))
}
toIntOrNull()?.let {
return NumberValue(it)
}
toDoubleOrNull()?.let {
return NumberValue(it)
}
if ("true" == this) {
return True
}
if ("false" == this) {
return False
}
//Give up and return a StringValue
return StringValue(this)
}

View File

@ -7,7 +7,7 @@ import space.kscience.dataforge.names.*
/** /**
* Restrictions on value in the node * Restrictions on value in the node
*/ */
public enum class ValueRequirement { public enum class ValueRestriction {
/** /**
* No restrictions * No restrictions
*/ */
@ -26,26 +26,25 @@ public enum class ValueRequirement {
/** /**
* The descriptor for a meta * The descriptor for a meta
* @param info description text * @param description description text
* @param children child descriptors for this node * @param children child descriptors for this node
* @param multiple True if same name siblings with this name are allowed * @param multiple True if same name siblings with this name are allowed
* @param valueRequirement The requirements for node content * @param valueRestriction The requirements for node content
* @param valueTypes list of allowed types for [Meta.value], null if all values are allowed. * @param valueTypes list of allowed types for [Meta.value], null if all values are allowed.
* Empty list means that no value should be present in this node. * Empty list means that no value should be present in this node.
* @param indexKey An index field by which this node is identified in case of same name siblings construct * @param indexKey An index field by which this node is identified in case of same name siblings construct
* @param defaultValue the default [Meta.value] for the node * @param defaultValue the default [Meta.value] for the node
* @param attributes additional attributes of this descriptor. For example validation and widget parameters * @param attributes additional attributes of this descriptor. For example, validation and widget parameters
*/ */
@Serializable @Serializable
public data class MetaDescriptor( public data class MetaDescriptor(
public val info: String? = null, public val description: String? = null,
public val children: Map<String, MetaDescriptor> = emptyMap(), public val children: Map<String, MetaDescriptor> = emptyMap(),
public val multiple: Boolean = false, public val multiple: Boolean = false,
public val valueRequirement: ValueRequirement = ValueRequirement.NONE, public val valueRestriction: ValueRestriction = ValueRestriction.NONE,
public val valueTypes: List<ValueType>? = null, public val valueTypes: List<ValueType>? = null,
public val indexKey: String = Meta.INDEX_KEY, public val indexKey: String = Meta.INDEX_KEY,
public val defaultValue: Value? = null, public val defaultValue: Value? = null,
public val readOnly: Boolean = false,
public val attributes: Meta = Meta.EMPTY, public val attributes: Meta = Meta.EMPTY,
) { ) {
/** /**
@ -63,11 +62,12 @@ public data class MetaDescriptor(
} }
public companion object { public companion object {
public val EMPTY: MetaDescriptor = MetaDescriptor("Generic meta tree")
internal const val ALLOWED_VALUES_KEY = "allowedValues" internal const val ALLOWED_VALUES_KEY = "allowedValues"
} }
} }
public val MetaDescriptor.required: Boolean get() = valueRequirement == ValueRequirement.REQUIRED || children.values.any { required } public val MetaDescriptor.required: Boolean get() = valueRestriction == ValueRestriction.REQUIRED || children.values.any { required }
public val MetaDescriptor.allowedValues: List<Value>? get() = attributes[MetaDescriptor.ALLOWED_VALUES_KEY]?.value?.list public val MetaDescriptor.allowedValues: List<Value>? get() = attributes[MetaDescriptor.ALLOWED_VALUES_KEY]?.value?.list
@ -80,9 +80,9 @@ public operator fun MetaDescriptor.get(name: Name): MetaDescriptor? = when (name
public operator fun MetaDescriptor.get(name: String): MetaDescriptor? = get(name.parseAsName(true)) public operator fun MetaDescriptor.get(name: String): MetaDescriptor? = get(name.parseAsName(true))
public fun MetaDescriptor.validate(value: Value?): Boolean = if (value == null) { public fun MetaDescriptor.validate(value: Value?): Boolean = if (value == null) {
valueRequirement != ValueRequirement.REQUIRED valueRestriction != ValueRestriction.REQUIRED
} else { } else {
if (valueRequirement == ValueRequirement.ABSENT) false if (valueRestriction == ValueRestriction.ABSENT) false
else { else {
(valueTypes == null || value.type in valueTypes) && (allowedValues?.let { value in it } ?: true) (valueTypes == null || value.type in valueTypes) && (allowedValues?.let { value in it } ?: true)
} }

View File

@ -12,16 +12,22 @@ public class MetaDescriptorBuilder @PublishedApi internal constructor() {
public var info: String? = null public var info: String? = null
public var children: MutableMap<String, MetaDescriptorBuilder> = linkedMapOf() public var children: MutableMap<String, MetaDescriptorBuilder> = linkedMapOf()
public var multiple: Boolean = false public var multiple: Boolean = false
public var valueRequirement: ValueRequirement = ValueRequirement.NONE public var valueRestriction: ValueRestriction = ValueRestriction.NONE
public var readOnly: Boolean = false
public var type: List<ValueType>? = null public var valueTypes: List<ValueType>? = null
public fun type(primaryType: ValueType, vararg otherTypes: ValueType) { public fun valueType(primaryType: ValueType, vararg otherTypes: ValueType) {
type = listOf(primaryType, *otherTypes) valueTypes = listOf(primaryType, *otherTypes)
} }
/**
* A key for indexing values. Should be changed in case of the name clash.
*/
public var indexKey: String = Meta.INDEX_KEY public var indexKey: String = Meta.INDEX_KEY
/**
* The default value
*/
public var default: Value? = null public var default: Value? = null
public fun default(value: Any?) { public fun default(value: Any?) {
@ -42,6 +48,7 @@ public class MetaDescriptorBuilder @PublishedApi internal constructor() {
children[name.first().body] = target children[name.first().body] = target
target target
} }
else -> { else -> {
children.getOrPut(name.first().body) { MetaDescriptorBuilder() }.item(name.cutFirst(), block) children.getOrPut(name.first().body) { MetaDescriptorBuilder() }.item(name.cutFirst(), block)
} }
@ -51,16 +58,17 @@ public class MetaDescriptorBuilder @PublishedApi internal constructor() {
public fun node( public fun node(
name: Name, name: Name,
descriptor: MetaDescriptor, descriptor: MetaDescriptor,
block: MetaDescriptorBuilder.() -> Unit = {} block: MetaDescriptorBuilder.() -> Unit = {},
): MetaDescriptorBuilder = when (name.length) { ): MetaDescriptorBuilder = when (name.length) {
0 -> error("Can't set descriptor to root") 0 -> error("Can't set descriptor to root")
1 -> { 1 -> {
val item = descriptor.toBuilder().apply { val item = descriptor.toBuilder().apply {
valueRequirement = ValueRequirement.ABSENT valueRestriction = ValueRestriction.ABSENT
}.apply(block) }.apply(block)
children[name.first().body] = item children[name.first().body] = item
item item
} }
else -> children.getOrPut(name.first().body) { else -> children.getOrPut(name.first().body) {
MetaDescriptorBuilder() MetaDescriptorBuilder()
}.node(name.cutFirst(), descriptor, block) }.node(name.cutFirst(), descriptor, block)
@ -79,14 +87,13 @@ public class MetaDescriptorBuilder @PublishedApi internal constructor() {
@PublishedApi @PublishedApi
internal fun build(): MetaDescriptor = MetaDescriptor( internal fun build(): MetaDescriptor = MetaDescriptor(
info = info, description = info,
children = children.mapValues { it.value.build() }, children = children.mapValues { it.value.build() },
multiple = multiple, multiple = multiple,
valueRequirement = valueRequirement, valueRestriction = valueRestriction,
valueTypes = type, valueTypes = valueTypes,
indexKey = indexKey, indexKey = indexKey,
defaultValue = default, defaultValue = default,
readOnly = readOnly,
attributes = attributes attributes = attributes
) )
} }
@ -104,9 +111,9 @@ public fun MetaDescriptorBuilder.value(
name: Name, name: Name,
type: ValueType, type: ValueType,
vararg additionalTypes: ValueType, vararg additionalTypes: ValueType,
block: MetaDescriptorBuilder.() -> Unit = {} block: MetaDescriptorBuilder.() -> Unit = {},
): MetaDescriptorBuilder = item(name) { ): MetaDescriptorBuilder = item(name) {
type(type, *additionalTypes) valueType(type, *additionalTypes)
block() block()
} }
@ -114,16 +121,16 @@ public fun MetaDescriptorBuilder.value(
name: String, name: String,
type: ValueType, type: ValueType,
vararg additionalTypes: ValueType, vararg additionalTypes: ValueType,
block: MetaDescriptorBuilder.() -> Unit = {} block: MetaDescriptorBuilder.() -> Unit = {},
): MetaDescriptorBuilder = value(Name.parse(name), type, additionalTypes = additionalTypes, block) ): MetaDescriptorBuilder = value(Name.parse(name), type, additionalTypes = additionalTypes, block)
/** /**
* Create and configure child value descriptor * Create and configure child value descriptor
*/ */
public fun MetaDescriptorBuilder.node( public fun MetaDescriptorBuilder.node(
name: Name, block: MetaDescriptorBuilder.() -> Unit name: Name, block: MetaDescriptorBuilder.() -> Unit,
): MetaDescriptorBuilder = item(name) { ): MetaDescriptorBuilder = item(name) {
valueRequirement = ValueRequirement.ABSENT valueRestriction = ValueRestriction.ABSENT
block() block()
} }
@ -142,7 +149,7 @@ public fun MetaDescriptorBuilder.node(
} }
public fun MetaDescriptorBuilder.required() { public fun MetaDescriptorBuilder.required() {
valueRequirement = ValueRequirement.REQUIRED valueRestriction = ValueRestriction.REQUIRED
} }
public inline fun <reified E : Enum<E>> MetaDescriptorBuilder.enum( public inline fun <reified E : Enum<E>> MetaDescriptorBuilder.enum(
@ -158,11 +165,11 @@ public inline fun <reified E : Enum<E>> MetaDescriptorBuilder.enum(
} }
private fun MetaDescriptor.toBuilder(): MetaDescriptorBuilder = MetaDescriptorBuilder().apply { private fun MetaDescriptor.toBuilder(): MetaDescriptorBuilder = MetaDescriptorBuilder().apply {
info = this@toBuilder.info info = this@toBuilder.description
children = this@toBuilder.children.mapValuesTo(LinkedHashMap()) { it.value.toBuilder() } children = this@toBuilder.children.mapValuesTo(LinkedHashMap()) { it.value.toBuilder() }
multiple = this@toBuilder.multiple multiple = this@toBuilder.multiple
valueRequirement = this@toBuilder.valueRequirement valueRestriction = this@toBuilder.valueRestriction
type = this@toBuilder.valueTypes valueTypes = this@toBuilder.valueTypes
indexKey = this@toBuilder.indexKey indexKey = this@toBuilder.indexKey
default = defaultValue default = defaultValue
attributes = this@toBuilder.attributes.toMutableMeta() attributes = this@toBuilder.attributes.toMutableMeta()

View File

@ -5,7 +5,7 @@ package space.kscience.dataforge.meta
* A value built from string which content and type are parsed on-demand * A value built from string which content and type are parsed on-demand
*/ */
public class LazyParsedValue(public val string: String) : Value { public class LazyParsedValue(public val string: String) : Value {
private val parsedValue by lazy { string.parseValue() } private val parsedValue by lazy { Value.parse(string) }
override val value: Any? get() = parsedValue.value override val value: Any? get() = parsedValue.value
override val type: ValueType get() = parsedValue.type override val type: ValueType get() = parsedValue.type

View File

@ -1,79 +1,155 @@
package space.kscience.dataforge.meta.transformations package space.kscience.dataforge.meta.transformations
import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.*
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import kotlin.reflect.KType
import kotlin.reflect.typeOf
/** /**
* A converter of generic object to and from [Meta] * A converter of generic object to and from [Meta]
*/ */
public interface MetaConverter<T> { public interface MetaConverter<T> {
public fun metaToObject(meta: Meta): T?
/**
* Runtime type of [T]
*/
public val type: KType
/**
* A descriptor for resulting meta
*/
public val descriptor: MetaDescriptor get() = MetaDescriptor.EMPTY
/**
* Attempt conversion of [meta] to an object or return null if conversion failed
*/
public fun metaToObjectOrNull(meta: Meta): T?
public fun metaToObject(meta: Meta): T =
metaToObjectOrNull(meta) ?: error("Meta $meta could not be interpreted by $this")
public fun objectToMeta(obj: T): Meta public fun objectToMeta(obj: T): Meta
public companion object { public companion object {
public val meta: MetaConverter<Meta> = object : MetaConverter<Meta> { public val meta: MetaConverter<Meta> = object : MetaConverter<Meta> {
override fun metaToObject(meta: Meta): Meta = meta override val type: KType = typeOf<Meta>()
override fun metaToObjectOrNull(meta: Meta): Meta = meta
override fun objectToMeta(obj: Meta): Meta = obj override fun objectToMeta(obj: Meta): Meta = obj
} }
public val value: MetaConverter<Value> = object : MetaConverter<Value> { public val value: MetaConverter<Value> = object : MetaConverter<Value> {
override fun metaToObject(meta: Meta): Value? = meta.value override val type: KType = typeOf<Value>()
override fun metaToObjectOrNull(meta: Meta): Value? = meta.value
override fun objectToMeta(obj: Value): Meta = Meta(obj) override fun objectToMeta(obj: Value): Meta = Meta(obj)
} }
public val string: MetaConverter<String> = object : MetaConverter<String> { public val string: MetaConverter<String> = object : MetaConverter<String> {
override fun metaToObject(meta: Meta): String? = meta.string override val type: KType = typeOf<String>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.STRING)
}
override fun metaToObjectOrNull(meta: Meta): String? = meta.string
override fun objectToMeta(obj: String): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: String): Meta = Meta(obj.asValue())
} }
public val boolean: MetaConverter<Boolean> = object : MetaConverter<Boolean> { public val boolean: MetaConverter<Boolean> = object : MetaConverter<Boolean> {
override fun metaToObject(meta: Meta): Boolean? = meta.boolean override val type: KType = typeOf<Boolean>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.BOOLEAN)
}
override fun metaToObjectOrNull(meta: Meta): Boolean? = meta.boolean
override fun objectToMeta(obj: Boolean): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: Boolean): Meta = Meta(obj.asValue())
} }
public val number: MetaConverter<Number> = object : MetaConverter<Number> { public val number: MetaConverter<Number> = object : MetaConverter<Number> {
override fun metaToObject(meta: Meta): Number? = meta.number override val type: KType = typeOf<Number>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.NUMBER)
}
override fun metaToObjectOrNull(meta: Meta): Number? = meta.number
override fun objectToMeta(obj: Number): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: Number): Meta = Meta(obj.asValue())
} }
public val double: MetaConverter<Double> = object : MetaConverter<Double> { public val double: MetaConverter<Double> = object : MetaConverter<Double> {
override fun metaToObject(meta: Meta): Double? = meta.double override val type: KType = typeOf<Double>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.NUMBER)
}
override fun metaToObjectOrNull(meta: Meta): Double? = meta.double
override fun objectToMeta(obj: Double): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: Double): Meta = Meta(obj.asValue())
} }
public val float: MetaConverter<Float> = object : MetaConverter<Float> { public val float: MetaConverter<Float> = object : MetaConverter<Float> {
override fun metaToObject(meta: Meta): Float? = meta.float override val type: KType = typeOf<Float>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.NUMBER)
}
override fun metaToObjectOrNull(meta: Meta): Float? = meta.float
override fun objectToMeta(obj: Float): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: Float): Meta = Meta(obj.asValue())
} }
public val int: MetaConverter<Int> = object : MetaConverter<Int> { public val int: MetaConverter<Int> = object : MetaConverter<Int> {
override fun metaToObject(meta: Meta): Int? = meta.int override val type: KType = typeOf<Int>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.NUMBER)
}
override fun metaToObjectOrNull(meta: Meta): Int? = meta.int
override fun objectToMeta(obj: Int): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: Int): Meta = Meta(obj.asValue())
} }
public val long: MetaConverter<Long> = object : MetaConverter<Long> { public val long: MetaConverter<Long> = object : MetaConverter<Long> {
override fun metaToObject(meta: Meta): Long? = meta.long override val type: KType = typeOf<Long>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.NUMBER)
}
override fun metaToObjectOrNull(meta: Meta): Long? = meta.long
override fun objectToMeta(obj: Long): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: Long): Meta = Meta(obj.asValue())
} }
public inline fun <reified E : Enum<E>> enum(): MetaConverter<E> = object : MetaConverter<E> { public inline fun <reified E : Enum<E>> enum(): MetaConverter<E> = object : MetaConverter<E> {
override val type: KType = typeOf<E>()
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.STRING)
allowedValues(enumValues<E>())
}
@Suppress("USELESS_CAST") @Suppress("USELESS_CAST")
override fun metaToObject(meta: Meta): E = meta.enum<E>() as? E ?: error("The Item is not a Enum") override fun metaToObjectOrNull(meta: Meta): E = meta.enum<E>() as? E ?: error("The Item is not a Enum")
override fun objectToMeta(obj: E): Meta = Meta(obj.asValue()) override fun objectToMeta(obj: E): Meta = Meta(obj.asValue())
} }
public fun <T> valueList( public fun <T> valueList(
writer: (T) -> Value = { Value.of(it) }, writer: (T) -> Value = { Value.of(it) },
reader: (Value) -> T reader: (Value) -> T,
): MetaConverter<List<T>> = ): MetaConverter<List<T>> =
object : MetaConverter<List<T>> { object : MetaConverter<List<T>> {
override fun metaToObject(meta: Meta): List<T> = override val type: KType = typeOf<List<T>>()
meta.value?.list?.map(reader) ?: error("The item is not a value list")
override val descriptor: MetaDescriptor = MetaDescriptor {
valueType(ValueType.LIST)
}
override fun metaToObjectOrNull(meta: Meta): List<T>? = meta.value?.list?.map(reader)
override fun objectToMeta(obj: List<T>): Meta = Meta(obj.map(writer).asValue()) override fun objectToMeta(obj: List<T>): Meta = Meta(obj.map(writer).asValue())
} }

View File

@ -42,7 +42,7 @@ public data class KeepTransformationRule(val selector: (Name) -> Boolean) :
meta.nodeSequence().map { it.first }.filter(selector) meta.nodeSequence().map { it.first }.filter(selector)
override fun transformItem(name: Name, item: Meta?, target: MutableMeta) { override fun transformItem(name: Name, item: Meta?, target: MutableMeta) {
if (selector(name)) target.setMeta(name, item) if (selector(name)) target.set(name, item)
} }
} }
@ -105,7 +105,7 @@ public value class MetaTransformation(private val transformations: Collection<Tr
* Generate an observable configuration that contains only elements defined by transformation rules and changes with the source * Generate an observable configuration that contains only elements defined by transformation rules and changes with the source
*/ */
@DFExperimental @DFExperimental
public fun generate(source: ObservableMeta): ObservableMeta = MutableMeta().apply { public fun generate(source: ObservableMeta): ObservableMeta = ObservableMutableMeta{
transformations.forEach { rule -> transformations.forEach { rule ->
rule.selectItems(source).forEach { name -> rule.selectItems(source).forEach { name ->
rule.transformItem(name, source[name], this) rule.transformItem(name, source[name], this)
@ -174,7 +174,7 @@ public class MetaTransformationBuilder {
public fun keep(regex: String) { public fun keep(regex: String) {
transformations.add( transformations.add(
RegexItemTransformationRule(regex.toRegex()) { name, _, Meta -> RegexItemTransformationRule(regex.toRegex()) { name, _, Meta ->
setMeta(name, Meta) set(name, Meta)
}) })
} }
@ -184,7 +184,7 @@ public class MetaTransformationBuilder {
public fun move(from: Name, to: Name, operation: (Meta?) -> Meta? = { it }) { public fun move(from: Name, to: Name, operation: (Meta?) -> Meta? = { it }) {
transformations.add( transformations.add(
SingleItemTransformationRule(from) { _, item -> SingleItemTransformationRule(from) { _, item ->
setMeta(to, operation(item)) set(to, operation(item))
} }
) )
} }

View File

@ -2,9 +2,7 @@ package space.kscience.dataforge.misc
/** /**
* A text label for internal DataForge type classification. Alternative for mime container type. * A text label for internal DataForge type classification. Alternative for mime container type.
*
* The DataForge type notation presumes that type `A.B.C` is the subtype of `A.B`
*/ */
@MustBeDocumented @MustBeDocumented
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
public annotation class Type(val id: String) public annotation class DfId(val id: String)

View File

@ -134,6 +134,11 @@ public val Name.length: Int get() = tokens.size
*/ */
public fun Name.lastOrNull(): NameToken? = tokens.lastOrNull() public fun Name.lastOrNull(): NameToken? = tokens.lastOrNull()
/**
* Last token or throw exception
*/
public fun Name.last(): NameToken = tokens.last()
/** /**
* First token of the name or null if it is empty * First token of the name or null if it is empty
*/ */

View File

@ -1,15 +0,0 @@
package space.kscience.dataforge.meta
import org.junit.jupiter.api.Test
import kotlin.test.assertFails
class JvmMutableMetaTest {
@Test
fun recursiveMeta(){
val meta = MutableMeta {
"a" put 2
}
assertFails { meta["child.a"] = meta }
}
}

View File

@ -6,27 +6,18 @@
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-scripting:0.6.2-dev-2`. The Maven coordinates of this project are `space.kscience:dataforge-scripting:0.7.0`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:dataforge-scripting:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("space.kscience:dataforge-scripting:0.6.2-dev-2") implementation("space.kscience:dataforge-scripting:0.7.0")
} }
``` ```

View File

@ -6,27 +6,18 @@
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-workspace:0.6.2-dev-2`. The Maven coordinates of this project are `space.kscience:dataforge-workspace:0.7.0`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:dataforge-workspace:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("space.kscience:dataforge-workspace:0.6.2-dev-2") implementation("space.kscience:dataforge-workspace:0.7.0")
} }
``` ```

View File

@ -10,15 +10,19 @@ kscience{
useSerialization{ useSerialization{
protobuf() protobuf()
} }
commonMain{
dependencies { dependencies {
api(projects.dataforgeContext) api(projects.dataforgeContext)
api(projects.dataforgeData) api(projects.dataforgeData)
api(projects.dataforgeIo) api(projects.dataforgeIo)
} }
dependencies(jvmTest){ }
jvmTest{
dependencies {
implementation(spclibs.logback.classic) implementation(spclibs.logback.classic)
implementation(projects.dataforgeIo.dataforgeIoYaml) implementation(projects.dataforgeIo.dataforgeIoYaml)
} }
}
} }
readme{ readme{

View File

@ -9,7 +9,7 @@ import space.kscience.dataforge.meta.MetaRepr
import space.kscience.dataforge.meta.Specification import space.kscience.dataforge.meta.Specification
import space.kscience.dataforge.meta.descriptors.Described import space.kscience.dataforge.meta.descriptors.Described
import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.workspace.Task.Companion.TYPE import space.kscience.dataforge.workspace.Task.Companion.TYPE
import kotlin.reflect.KType import kotlin.reflect.KType
@ -19,7 +19,7 @@ import kotlin.reflect.typeOf
* A configurable task that could be executed on a workspace. The [TaskResult] represents a lazy result of the task. * A configurable task that could be executed on a workspace. The [TaskResult] represents a lazy result of the task.
* In general no computations should be made until the result is called. * In general no computations should be made until the result is called.
*/ */
@Type(TYPE) @DfId(TYPE)
public interface Task<out T : Any> : Described { public interface Task<out T : Any> : Described {
/** /**

View File

@ -6,7 +6,7 @@ import space.kscience.dataforge.data.DataSet
import space.kscience.dataforge.data.asSequence import space.kscience.dataforge.data.asSequence
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.provider.Provider import space.kscience.dataforge.provider.Provider
@ -18,7 +18,7 @@ public interface DataSelector<T: Any>{
/** /**
* An environment for pull-mode computation * An environment for pull-mode computation
*/ */
@Type(Workspace.TYPE) @DfId(Workspace.TYPE)
public interface Workspace : ContextAware, Provider { public interface Workspace : ContextAware, Provider {
/** /**
* The whole data node for current workspace * The whole data node for current workspace

View File

@ -33,9 +33,12 @@ public suspend inline fun <T : Any, reified P : WorkspacePlugin> TaskResultBuild
dependencyMeta: Meta = defaultDependencyMeta, dependencyMeta: Meta = defaultDependencyMeta,
selectorBuilder: P.() -> TaskReference<T>, selectorBuilder: P.() -> TaskReference<T>,
): DataSet<T> { ): DataSet<T> {
require(workspace.context.plugins.contains(plugin)){"Plugin $plugin is not loaded into $workspace"} require(workspace.context.plugins.contains(plugin)) { "Plugin $plugin is not loaded into $workspace" }
val taskReference: TaskReference<T> = plugin.selectorBuilder() val taskReference: TaskReference<T> = plugin.selectorBuilder()
return workspace.produce(plugin.name + taskReference.taskName, dependencyMeta) as TaskResult<T> val res = workspace.produce(plugin.name + taskReference.taskName, dependencyMeta)
//TODO add explicit check after https://youtrack.jetbrains.com/issue/KT-32956
@Suppress("UNCHECKED_CAST")
return res as TaskResult<T>
} }
/** /**
@ -45,7 +48,7 @@ public suspend inline fun <T : Any, reified P : WorkspacePlugin> TaskResultBuild
* @param dependencyMeta meta used for selector. The same meta is used for caching. By default, uses [defaultDependencyMeta]. * @param dependencyMeta meta used for selector. The same meta is used for caching. By default, uses [defaultDependencyMeta].
* @param selectorBuilder a builder of task from the plugin. * @param selectorBuilder a builder of task from the plugin.
*/ */
public suspend inline fun <T : Any, reified P : WorkspacePlugin> TaskResultBuilder<*>.from( public suspend inline fun <reified T : Any, reified P : WorkspacePlugin> TaskResultBuilder<*>.from(
pluginFactory: PluginFactory<P>, pluginFactory: PluginFactory<P>,
dependencyMeta: Meta = defaultDependencyMeta, dependencyMeta: Meta = defaultDependencyMeta,
selectorBuilder: P.() -> TaskReference<T>, selectorBuilder: P.() -> TaskReference<T>,
@ -53,7 +56,10 @@ public suspend inline fun <T : Any, reified P : WorkspacePlugin> TaskResultBuild
val plugin = workspace.context.plugins[pluginFactory] val plugin = workspace.context.plugins[pluginFactory]
?: error("Plugin ${pluginFactory.tag} not loaded into workspace context") ?: error("Plugin ${pluginFactory.tag} not loaded into workspace context")
val taskReference: TaskReference<T> = plugin.selectorBuilder() val taskReference: TaskReference<T> = plugin.selectorBuilder()
return workspace.produce(plugin.name + taskReference.taskName, dependencyMeta) as TaskResult<T> val res = workspace.produce(plugin.name + taskReference.taskName, dependencyMeta)
//TODO explicit check after https://youtrack.jetbrains.com/issue/KT-32956
@Suppress("UNCHECKED_CAST")
return res as TaskResult<T>
} }
public val TaskResultBuilder<*>.allData: DataSelector<*> public val TaskResultBuilder<*>.allData: DataSelector<*>

View File

@ -1,9 +1,6 @@
package space.kscience.dataforge.workspace package space.kscience.dataforge.workspace
import io.ktor.utils.io.core.Input import kotlinx.io.*
import io.ktor.utils.io.core.Output
import io.ktor.utils.io.core.readBytes
import io.ktor.utils.io.core.writeFully
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@ -30,10 +27,10 @@ public class JsonIOFormat<T : Any>(override val type: KType) : IOFormat<T> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private val serializer: KSerializer<T> = serializer(type) as KSerializer<T> private val serializer: KSerializer<T> = serializer(type) as KSerializer<T>
override fun readObject(input: Input): T = Json.decodeFromString(serializer, input.readUtf8String()) override fun readFrom(source: Source): T = Json.decodeFromString(serializer, source.readString())
override fun writeObject(output: Output, obj: T) { override fun writeTo(sink: Sink, obj: T) {
output.writeUtf8String(Json.encodeToString(serializer, obj)) sink.writeString(Json.encodeToString(serializer, obj))
} }
} }
@ -43,10 +40,10 @@ public class ProtobufIOFormat<T : Any>(override val type: KType) : IOFormat<T> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private val serializer: KSerializer<T> = serializer(type) as KSerializer<T> private val serializer: KSerializer<T> = serializer(type) as KSerializer<T>
override fun readObject(input: Input): T = ProtoBuf.decodeFromByteArray(serializer, input.readBytes()) override fun readFrom(source: Source): T = ProtoBuf.decodeFromByteArray(serializer, source.readByteArray())
override fun writeObject(output: Output, obj: T) { override fun writeTo(sink: Sink, obj: T) {
output.writeFully(ProtoBuf.encodeToByteArray(serializer, obj)) sink.write(ProtoBuf.encodeToByteArray(serializer, obj))
} }
} }
@ -88,7 +85,7 @@ public class FileWorkspaceCache(public val cacheDirectory: Path) : WorkspaceCach
val envelope = Envelope { val envelope = Envelope {
meta = data.meta meta = data.meta
data { data {
writeObject(format, result) writeWith(format, result)
} }
} }
io.writeEnvelopeFile(path, envelope) io.writeEnvelopeFile(path, envelope)

View File

@ -1,13 +1,10 @@
package space.kscience.dataforge.workspace package space.kscience.dataforge.workspace
import io.ktor.utils.io.streams.asOutput
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import space.kscience.dataforge.data.DataTree import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.data.DataTreeItem import space.kscience.dataforge.data.DataTreeItem
import space.kscience.dataforge.io.EnvelopeFormat import space.kscience.dataforge.io.*
import space.kscience.dataforge.io.IOFormat
import space.kscience.dataforge.io.TaggedEnvelopeFormat
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
@ -28,11 +25,15 @@ private suspend fun <T : Any> ZipOutputStream.writeNode(
val envelope = treeItem.data.toEnvelope(dataFormat) val envelope = treeItem.data.toEnvelope(dataFormat)
val entry = ZipEntry(name) val entry = ZipEntry(name)
putNextEntry(entry) putNextEntry(entry)
asOutput().run {
envelopeFormat.writeObject(this, envelope) //TODO remove additional copy
flush() val bytes = ByteArray {
writeWith(envelopeFormat, envelope)
} }
write(bytes)
} }
is DataTreeItem.Node -> { is DataTreeItem.Node -> {
val entry = ZipEntry("$name/") val entry = ZipEntry("$name/")
putNextEntry(entry) putNextEntry(entry)

View File

@ -1,12 +1,18 @@
package space.kscience.dataforge.workspace package space.kscience.dataforge.workspace
import io.ktor.utils.io.core.Input
import io.ktor.utils.io.core.Output
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlinx.io.Sink
import kotlinx.io.Source
import kotlinx.io.readString
import kotlinx.io.writeString
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.Global
import space.kscience.dataforge.data.* import space.kscience.dataforge.data.*
import space.kscience.dataforge.io.* import space.kscience.dataforge.io.Envelope
import space.kscience.dataforge.io.IOFormat
import space.kscience.dataforge.io.io
import space.kscience.dataforge.io.readEnvelopeFile
import space.kscience.dataforge.io.yaml.YamlPlugin import space.kscience.dataforge.io.yaml.YamlPlugin
import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.get
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
@ -36,11 +42,11 @@ class FileDataTest {
object StringIOFormat : IOFormat<String> { object StringIOFormat : IOFormat<String> {
override val type: KType get() = typeOf<String>() override val type: KType get() = typeOf<String>()
override fun writeObject(output: Output, obj: String) { override fun writeTo(sink: Sink, obj: String) {
output.writeUtf8String(obj) sink.writeString(obj)
} }
override fun readObject(input: Input): String = input.readUtf8String() override fun readFrom(source: Source): String = source.readString()
} }
@Test @Test
@ -59,9 +65,9 @@ class FileDataTest {
@Test @Test
@DFExperimental @DFExperimental
fun testZipWriteRead() = with(Global.io) { fun testZipWriteRead() = runTest {
with(Global.io) {
val zip = Files.createTempFile("df_data_node", ".zip") val zip = Files.createTempFile("df_data_node", ".zip")
runBlocking {
dataNode.writeZip(zip, StringIOFormat) dataNode.writeZip(zip, StringIOFormat)
println(zip.toUri().toString()) println(zip.toUri().toString())
val reconstructed = readDataDirectory(zip) { _, _ -> StringIOFormat } val reconstructed = readDataDirectory(zip) { _, _ -> StringIOFormat }

View File

@ -6,4 +6,5 @@ kotlin.mpp.stability.nowarn=true
kotlin.incremental.js.ir=true kotlin.incremental.js.ir=true
kotlin.native.ignoreDisabledTargets=true kotlin.native.ignoreDisabledTargets=true
toolsVersion=0.14.9-kotlin-1.8.20 toolsVersion=0.15.1-kotlin-1.9.21
#kotlin.experimental.tryK2=true

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -1,7 +1,6 @@
rootProject.name = "dataforge-core" rootProject.name = "dataforge-core"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
//enableFeaturePreview("VERSION_CATALOGS")
pluginManagement { pluginManagement {
@ -15,6 +14,7 @@ pluginManagement {
} }
plugins { plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
id("space.kscience.gradle.project") version toolsVersion id("space.kscience.gradle.project") version toolsVersion
id("space.kscience.gradle.mpp") version toolsVersion id("space.kscience.gradle.mpp") version toolsVersion
id("space.kscience.gradle.jvm") version toolsVersion id("space.kscience.gradle.jvm") version toolsVersion