Compare commits

..

No commits in common. "c754dc34717db30a2408c5d3f49a50d87899e144" and "7fca5db3909279a605bf8103978c5a93a5702714" have entirely different histories.

73 changed files with 786 additions and 998 deletions

4
.space.kts Normal file
View File

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

View File

@ -14,41 +14,15 @@
### 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
@ -58,7 +32,6 @@
- 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
@ -80,11 +53,9 @@
- 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
@ -93,12 +64,10 @@
## 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.
@ -106,11 +75,9 @@
## 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
@ -121,28 +88,24 @@
- **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
@ -152,22 +115,18 @@
- 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
@ -175,7 +134,6 @@
- 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
@ -192,7 +150,6 @@
## 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 ""
@ -202,16 +159,13 @@
- 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,29 +5,32 @@
### [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

View File

@ -1,4 +1,5 @@
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
@ -8,7 +9,7 @@ plugins {
allprojects { allprojects {
group = "space.kscience" group = "space.kscience"
version = "0.7.0" version = "0.6.2"
} }
subprojects { subprojects {
@ -30,7 +31,14 @@ ksciencePublish {
useApache2Licence() useApache2Licence()
useSPCTeam() useSPCTeam()
} }
repository("spc","https://maven.sciprog.center/kscience") github("dataforge-core", "SciProgCentre")
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,18 +6,27 @@ Context and provider definitions
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-context:0.7.0`. The Maven coordinates of this project are `space.kscience:dataforge-context:0.6.2-dev-2`.
**Gradle Kotlin DSL:** **Gradle Groovy:**
```kotlin ```groovy
repositories { repositories {
maven("https://repo.kotlin.link") maven { url '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.7.0") implementation 'space.kscience:dataforge-context:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-context:0.6.2-dev-2")
} }
``` ```

View File

@ -195,6 +195,7 @@ 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;
@ -210,6 +211,7 @@ 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
*/ */
@DfId(TARGET) @Type(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.DfId import space.kscience.dataforge.misc.Type
@DfId(PluginFactory.TYPE) @Type(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,8 +1,7 @@
package space.kscience.dataforge.properties package space.kscience.dataforge.properties
import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.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
@ -25,7 +24,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(this[name])) if (name.startsWith(this@MetaProperty.name)) callback(converter.nullableMetaToObject(get(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<*>.dfId: String public val KClass<*>.dfType: String
get() = findAnnotation<DfId>()?.id ?: simpleName ?: "" get() = findAnnotation<Type>()?.id ?: simpleName ?: ""
/** /**
* Provide an object with given name inferring target from its type using [DfId] annotation * Provide an object with given name inferring target from its type using [Type] 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.dfId val target = T::class.dfType
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.dfId val target = T::class.dfType
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.dfId, inherit) gather<T>(T::class.dfType, 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.dfId, items) provides(T::class.dfType, 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.dfId, *items) provides(T::class.dfType, *items)
} }

View File

@ -6,18 +6,27 @@
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-data:0.7.0`. The Maven coordinates of this project are `space.kscience:dataforge-data:0.6.2-dev-2`.
**Gradle Kotlin DSL:** **Gradle Groovy:**
```kotlin ```groovy
repositories { repositories {
maven("https://repo.kotlin.link") maven { url '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.7.0") implementation 'space.kscience:dataforge-data:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-data:0.6.2-dev-2")
} }
``` ```

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.DfId import space.kscience.dataforge.misc.Type
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
*/ */
@DfId(Data.TYPE) @Type(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,6 +6,7 @@ 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.DfId import space.kscience.dataforge.misc.Type
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
*/ */
@DfId(DataTree.TYPE) @Type(DataTree.TYPE)
public interface DataTree<out T : Any> : DataSet<T> { public interface DataTree<out T : Any> : DataSet<T> {
/** /**

View File

@ -6,18 +6,27 @@ IO module
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-io:0.7.0`. The Maven coordinates of this project are `space.kscience:dataforge-io:0.6.2-dev-2`.
**Gradle Kotlin DSL:** **Gradle Groovy:**
```kotlin ```groovy
repositories { repositories {
maven("https://repo.kotlin.link") maven { url '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.7.0") implementation 'space.kscience:dataforge-io:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-io:0.6.2-dev-2")
} }
``` ```

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,12 +15,11 @@ kscience {
cbor() cbor()
} }
dependencies { dependencies {
api(projects.dataforgeContext) api(project(":dataforge-context"))
api("org.jetbrains.kotlinx:kotlinx-io-core:$ioVersion") api("io.ktor:ktor-io:${KScienceVersions.ktorVersion}")
api("org.jetbrains.kotlinx:kotlinx-io-bytestring:$ioVersion")
} }
} }
readme{ readme {
maturity = space.kscience.gradle.Maturity.EXPERIMENTAL maturity = space.kscience.gradle.Maturity.PROTOTYPE
} }

View File

@ -6,18 +6,27 @@ YAML meta IO
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-io-yaml:0.7.0`. The Maven coordinates of this project are `space.kscience:dataforge-io-yaml:0.6.2-dev-2`.
**Gradle Kotlin DSL:** **Gradle Groovy:**
```kotlin ```groovy
repositories { repositories {
maven("https://repo.kotlin.link") maven { url '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.7.0") implementation 'space.kscience:dataforge-io-yaml:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-io-yaml:0.6.2-dev-2")
} }
``` ```

View File

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

View File

@ -1,13 +1,13 @@
package space.kscience.dataforge.io.yaml package space.kscience.dataforge.io.yaml
import kotlinx.io.Sink import io.ktor.utils.io.core.Input
import kotlinx.io.Source import io.ktor.utils.io.core.Output
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)?.let { Value.parse(it) } get() = yamlMap.getStringOrNull(null)?.parseValue()
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.parse(value.content)) is YamlLiteral -> map[token] = Meta(value.content.parseValue())
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
Value.parse((it as YamlLiteral).content) (it as YamlLiteral).content.parseValue()
} }
) )
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(Value.parse(content)) is YamlLiteral -> Meta(content.parseValue())
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(sink: Sink, meta: Meta, descriptor: MetaDescriptor?) { override fun writeMeta(output: Output, 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)
sink.writeString(string) output.writeUtf8String(string)
} }
override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta { override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta {
val yaml = Yaml.decodeYamlMapFromString(source.readString()) val yaml = Yaml.decodeYamlMapFromString(input.readUtf8String())
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(sink: Sink, meta: Meta, descriptor: MetaDescriptor?): Unit = override fun writeMeta(output: Output, meta: Meta, descriptor: MetaDescriptor?): Unit =
default.writeMeta(sink, meta, descriptor) default.writeMeta(output, meta, descriptor)
override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta = override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta =
default.readMeta(source, descriptor) default.readMeta(input, descriptor)
} }
} }

View File

@ -1,9 +1,6 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.Sink import io.ktor.utils.io.core.*
import kotlinx.io.Source
import kotlinx.io.buffered
import kotlinx.io.readByteArray
import kotlin.math.min import kotlin.math.min
/** /**
@ -20,13 +17,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: Source.() -> R): R public fun <R> read(offset: Int = 0, atMost: Int = size - offset, block: Input.() -> R): R
public suspend fun <R> readSuspend(offset: Int = 0, atMost: Int = size - offset, block: suspend Source.() -> R): R public suspend fun <R> readSuspend(offset: Int = 0, atMost: Int = size - offset, block: suspend Input.() -> 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, the resulting binary is of the same type as this one, but it is not guaranteed. * In general, 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
@ -41,27 +38,25 @@ 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: Source.() -> R): R { override fun <R> read(offset: Int, atMost: Int, block: Input.() -> 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 Source.() -> R): R { override suspend fun <R> readSuspend(offset: Int, atMost: Int, block: suspend Input.() -> 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 {
@ -82,26 +77,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 {
readByteArray() readBytes()
} }
} }
//TODO optimize for file-based Inputs //TODO optimize for file-based Inputs
public fun Source.readBinary(size: Int? = null): Binary { public fun Input.readBinary(size: Int? = null): Binary {
val array = if (size == null) readByteArray() else readByteArray(size) val array = if (size == null) readBytes() else readBytes(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 Sink.writeBinary(binary: Binary): Int { public fun Output.writeBinary(binary: Binary): Int {
return if (binary is ByteArrayBinary) { return if (binary is ByteArrayBinary) {
write(binary.array, binary.start, binary.start + binary.size) writeFully(binary.array, binary.start, binary.start + binary.size)
binary.size binary.size
} else { } else {
binary.read { binary.read {
transferTo(this@writeBinary).toInt() copyTo(this@writeBinary).toInt()
} }
} }
} }

View File

@ -1,6 +1,6 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.Sink import io.ktor.utils.io.core.Output
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: Sink.() -> Unit) { public inline fun data(block: Output.() -> 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 kotlinx.io.Source import io.ktor.utils.io.core.Input
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.DfId 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
@ -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: Source): Envelope = readFrom(input) public fun EnvelopeFormat.read(input: Input): Envelope = readObject(input)
@DfId(ENVELOPE_FORMAT_TYPE) @Type(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,8 +1,5 @@
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
@ -23,7 +20,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"
val DEFAULT_MULTIPART_DATA_SEPARATOR = "\r\n#~PART~#\r\n".toAsciiByteString() const val DEFAULT_MULTIPART_DATA_SEPARATOR = "\r\n#~PART~#\r\n"
const val MULTIPART_DATA_TYPE = "envelope.multipart" const val MULTIPART_DATA_TYPE = "envelope.multipart"
} }
@ -35,12 +32,12 @@ public typealias EnvelopeParts = List<EnvelopePart>
public fun EnvelopeBuilder.multipart( public fun EnvelopeBuilder.multipart(
parts: EnvelopeParts, parts: EnvelopeParts,
separator: ByteString = DEFAULT_MULTIPART_DATA_SEPARATOR, separator: String = DEFAULT_MULTIPART_DATA_SEPARATOR,
) { ) {
dataType = MULTIPART_DATA_TYPE dataType = MULTIPART_DATA_TYPE
var offsetCounter = 0 var offsetCounter = 0
val separatorSize = separator.size val separatorSize = separator.length
val partDescriptors = parts.map { (binary, description) -> val partDescriptors = parts.map { (binary, description) ->
offsetCounter += separatorSize offsetCounter += separatorSize
PartDescriptor { PartDescriptor {
@ -54,14 +51,14 @@ public fun EnvelopeBuilder.multipart(
meta { meta {
if (separator != DEFAULT_MULTIPART_DATA_SEPARATOR) { if (separator != DEFAULT_MULTIPART_DATA_SEPARATOR) {
SEPARATOR_KEY put separator.decodeToString() SEPARATOR_KEY put separator
} }
setIndexed(PARTS_KEY, partDescriptors.map { it.toMeta() }) setIndexed(PARTS_KEY, partDescriptors.map { it.toMeta() })
} }
data { data {
parts.forEach { parts.forEach {
write(separator) writeRawString(separator)
writeBinary(it.binary) writeBinary(it.binary)
} }
} }
@ -72,7 +69,7 @@ public fun EnvelopeBuilder.multipart(
*/ */
public fun EnvelopeBuilder.envelopes( public fun EnvelopeBuilder.envelopes(
envelopes: List<Envelope>, envelopes: List<Envelope>,
separator: ByteString = DEFAULT_MULTIPART_DATA_SEPARATOR, separator: String = 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,14 +1,12 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.Sink import io.ktor.utils.io.core.*
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
@ -23,9 +21,9 @@ public interface IOReader<out T> {
*/ */
public val type: KType public val type: KType
public fun readFrom(source: Source): T public fun readObject(input: Input): T
public fun readFrom(binary: Binary): T = binary.read { readFrom(this) } public fun readObject(binary: Binary): T = binary.read { readObject(this) }
public companion object { public companion object {
/** /**
@ -34,21 +32,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 readFrom(source: Source): Binary = source.readByteArray().asBinary() override fun readObject(input: Input): Binary = input.readBytes().asBinary()
override fun readFrom(binary: Binary): Binary = binary override fun readObject(binary: Binary): Binary = binary
} }
} }
} }
public inline fun <reified T> IOReader(crossinline read: Source.() -> T): IOReader<T> = object : IOReader<T> { public inline fun <reified T> IOReader(crossinline read: Input.() -> T): IOReader<T> = object : IOReader<T> {
override val type: KType = typeOf<T>() override val type: KType = typeOf<T>()
override fun readFrom(source: Source): T = source.read() override fun readObject(input: Input): T = input.read()
} }
public fun interface IOWriter<in T> { public fun interface IOWriter<in T> {
public fun writeTo(sink: Sink, obj: T) public fun writeObject(output: Output, obj: T)
} }
/** /**
@ -56,23 +54,24 @@ 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> Source.readWith(format: IOReader<T>): T = format.readFrom(this) public fun <T : Any> Input.readObject(format: IOReader<T>): T = format.readObject(this@readObject)
/** public fun <T : Any> IOFormat<T>.readObjectFrom(binary: Binary): T = binary.read {
* Read given binary as an object using given format readObject(this)
*/
public fun <T : Any> Binary.readWith(format: IOReader<T>): T = read {
readWith(format)
} }
/** /**
* Write an object to the [Sink] with given [format] * Read given binary as object using given format
*/ */
public fun <T : Any> Sink.writeWith(format: IOWriter<T>, obj: T): Unit = public fun <T : Any> Binary.readWith(format: IOReader<T>): T = read {
format.writeTo(this, obj) readObject(format)
}
public fun <T : Any> Output.writeObject(format: IOWriter<T>, obj: T): Unit =
format.writeObject(this@writeObject, obj)
@DfId(IO_FORMAT_TYPE) @Type(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
@ -86,33 +85,18 @@ public interface IOFormatFactory<T : Any> : Factory<IOFormat<T>>, Named {
} }
} }
public fun <T : Any> Binary(obj: T, format: IOWriter<T>): Binary = Binary { format.writeTo(this, obj) } public fun <T : Any> Binary(obj: T, format: IOWriter<T>): Binary = Binary { format.writeObject(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 = "float64".asName() override val name: Name = "double".asName()
override val type: KType get() = typeOf<Double>() override val type: KType get() = typeOf<Double>()
override fun writeTo(sink: Sink, obj: Double) { override fun writeObject(output: Output, obj: Double) {
sink.writeLong(obj.toBits()) output.writeDouble(obj)
} }
override fun readFrom(source: Source): Double = source.readDouble() override fun readObject(input: Input): Double = input.readDouble()
} }

View File

@ -1,10 +1,10 @@
@file:Suppress("UNUSED_PARAMETER")
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.Sink import io.ktor.utils.io.core.Input
import kotlinx.io.Source import io.ktor.utils.io.core.Output
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(sink: Sink, meta: Meta, descriptor: MetaDescriptor?) { override fun writeMeta(output: Output, meta: Meta, descriptor: MetaDescriptor?) {
val jsonElement = meta.toJson(descriptor) val jsonElement = meta.toJson(descriptor)
sink.writeString(json.encodeToString(JsonElement.serializer(), jsonElement)) output.writeUtf8String(json.encodeToString(JsonElement.serializer(), jsonElement))
} }
override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta { override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta {
val str = source.readString() val str = input.readUtf8String()//readByteArray().decodeToString()
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(sink: Sink, meta: Meta, descriptor: MetaDescriptor?): Unit = override fun writeMeta(output: Output, meta: Meta, descriptor: MetaDescriptor?): Unit =
default.run { writeMeta(sink, meta, descriptor) } default.run { writeMeta(output, meta, descriptor) }
override fun readMeta(source: Source, descriptor: MetaDescriptor?): Meta = override fun readMeta(input: Input, descriptor: MetaDescriptor?): Meta =
default.run { readMeta(source, descriptor) } default.run { readMeta(input, 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 kotlinx.io.Sink import io.ktor.utils.io.core.Input
import kotlinx.io.Source import io.ktor.utils.io.core.Output
import kotlinx.io.buffered import io.ktor.utils.io.core.use
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.DfId 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 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 writeTo(sink: Sink, obj: Meta) { override fun writeObject(output: Output, obj: Meta) {
writeMeta(sink, obj, null) writeMeta(output, obj, null)
} }
override fun readFrom(source: Source): Meta = readMeta(source) override fun readObject(input: Input): Meta = readMeta(input)
public fun writeMeta( public fun writeMeta(
sink: Sink, output: Output,
meta: Meta, meta: Meta,
descriptor: MetaDescriptor? = null, descriptor: MetaDescriptor? = null,
) )
public fun readMeta(source: Source, descriptor: MetaDescriptor? = null): Meta public fun readMeta(input: Input, descriptor: MetaDescriptor? = null): Meta
} }
@DfId(META_FORMAT_TYPE) @Type(META_FORMAT_TYPE)
public interface MetaFormatFactory : IOFormatFactory<Meta>, MetaFormat { public interface MetaFormatFactory : IOFormatFactory<Meta>, MetaFormat {
public val shortName: String public val shortName: String
@ -57,13 +57,15 @@ 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 {
writeTo(this@ByteArray, this@toString) writeObject(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 = readFrom(StringSource(str).buffered()) public fun MetaFormat.parse(str: String): Meta {
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,7 +1,6 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.* import io.ktor.utils.io.core.*
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
@ -19,7 +18,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)
@ -27,60 +26,59 @@ public class TaggedEnvelopeFormat(
private fun Tag.toBinary() = Binary { private fun Tag.toBinary() = Binary {
write(START_SEQUENCE) writeRawString(START_SEQUENCE)
writeString(version.name) writeRawString(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)
} }
} }
write(END_SEQUENCE) writeRawString(END_SEQUENCE)
} }
override fun writeTo( override fun writeObject(
sink: Sink, output: Output,
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)
sink.writeBinary(tag.toBinary()) output.writeBinary(tag.toBinary())
sink.writeBinary(metaBytes) output.writeBinary(metaBytes)
sink.writeString("\r\n") output.writeRawString("\r\n")
obj.data?.let { obj.data?.let {
sink.writeBinary(it) output.writeBinary(it)
} }
} }
/** /**
* Read an envelope from input into memory * Read an envelope from input into memory
* *
* @param source an input to read from * @param input 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 readFrom(source: Source): Envelope { override fun readObject(input: Input): Envelope {
val tag = source.readTag(this.version) val tag = input.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 = source.readBinary(tag.metaSize.toInt()) val metaBinary = input.readBinary(tag.metaSize.toInt())
val meta: Meta = metaFormat.readFrom(metaBinary) val meta: Meta = metaFormat.readObjectFrom(metaBinary)
val data = source.readBinary(tag.dataSize.toInt()) val data = input.readBinary(tag.dataSize.toInt())
return SimpleEnvelope(meta, data) return SimpleEnvelope(meta, data)
} }
override fun readFrom(binary: Binary): Envelope = binary.read { override fun readObject(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)
@ -88,7 +86,7 @@ public class TaggedEnvelopeFormat(
val metaBinary = readBinary(tag.metaSize.toInt()) val metaBinary = readBinary(tag.metaSize.toInt())
val meta: Meta = metaFormat.readFrom(metaBinary) val meta: Meta = metaFormat.readObjectFrom(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()))
@ -106,8 +104,8 @@ public class TaggedEnvelopeFormat(
} }
public companion object : EnvelopeFormatFactory { public companion object : EnvelopeFormatFactory {
private val START_SEQUENCE = "#~".toAsciiByteString() private const val START_SEQUENCE = "#~"
private val END_SEQUENCE = "~#\r\n".toAsciiByteString() private const val END_SEQUENCE = "~#\r\n"
override val name: Name = EnvelopeFormatFactory.ENVELOPE_FACTORY_NAME + "tagged" override val name: Name = EnvelopeFormatFactory.ENVELOPE_FACTORY_NAME + "tagged"
@ -123,48 +121,53 @@ public class TaggedEnvelopeFormat(
return TaggedEnvelopeFormat(io, version) return TaggedEnvelopeFormat(io, version)
} }
private fun Source.readTag(version: VERSION): Tag { private fun Input.readTag(version: VERSION): Tag {
val start = readByteString(2) val start = readRawString(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 = readByteString(4) val versionString = readRawString(4)
if (version.name.toAsciiByteString() != versionString) error("Wrong version of DataForge: expected $version but found $versionString") if (version.name != 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 = readByteString(4) val end = readRawString(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? = try { override fun peekFormat(io: IOPlugin, binary: Binary): EnvelopeFormat? {
binary.read { return try {
val header = readByteString(6) binary.read {
when (header.substring(2, 6).decodeToString()) { val header = readRawString(6)
VERSION.DF02.name -> TaggedEnvelopeFormat(io, VERSION.DF02) return@read when (header.substring(2..5)) {
VERSION.DF03.name -> TaggedEnvelopeFormat(io, VERSION.DF03) VERSION.DF02.name -> TaggedEnvelopeFormat(io, VERSION.DF02)
else -> null VERSION.DF03.name -> TaggedEnvelopeFormat(io, VERSION.DF03)
else -> null
}
} }
} catch (ex: Exception) {
null
} }
} catch (ex: Exception) {
null
} }
private val default by lazy { build(Global, Meta.EMPTY) } private val default by lazy { build(Global, Meta.EMPTY) }
override fun readFrom(binary: Binary): Envelope = override fun readObject(binary: Binary): Envelope =
default.run { readFrom(binary) } default.run { readObject(binary) }
override fun writeTo( override fun writeObject(
sink: Sink, output: Output,
obj: Envelope, obj: Envelope,
): Unit = default.run { ): Unit = default.run {
writeTo(sink, obj) writeObject(
output,
obj,
)
} }
override fun readFrom(source: Source): Envelope = default.readFrom(source) override fun readObject(input: Input): Envelope = default.readObject(input)
} }
} }

View File

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

View File

@ -1,41 +1,40 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.* import io.ktor.utils.io.bits.Memory
import kotlinx.io.bytestring.ByteString import io.ktor.utils.io.charsets.Charsets
import kotlinx.io.bytestring.decodeToString import io.ktor.utils.io.charsets.decodeExactBytes
import kotlinx.io.bytestring.encodeToByteString import io.ktor.utils.io.core.*
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) {
* Convert a string literal, containing only ASCII characters to a [ByteString]. writeFully(str.toByteArray(Charsets.ISO_8859_1))
* 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 inline fun Buffer(block: Sink.() -> Unit): Buffer = Buffer().apply(block) public fun Output.writeUtf8String(str: String) {
writeFully(str.encodeToByteArray())
}
//public fun Source.readSafeUtf8Line(): String = readUTF8Line() ?: error("Line not found") public fun Input.readRawString(size: Int): String {
return Charsets.ISO_8859_1.newDecoder().decodeExactBytes(this, size)
}
public inline fun ByteArray(block: Sink.() -> Unit): ByteArray = public fun Input.readUtf8String(): String = readBytes().decodeToString()
Buffer(block).readByteArray()
public inline fun Binary(block: Sink.() -> Unit): Binary = public fun Input.readSafeUtf8Line(): String = readUTF8Line() ?: error("Line not found")
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 accept binary, throw an error. * multiple formats accepts 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 ->
@ -57,7 +56,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)?.readFrom(binary) ?: if (readNonEnvelopes) { ): Envelope = formatPicker(binary)?.readObject(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")
@ -97,139 +96,74 @@ 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 [Source] into [output] until designated multibyte [separator] and optionally continues until * Read [Input] 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.
* *
* The Separator itself is not read into [Sink]. * Separator itself is not read into Output.
* *
* @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 Source.readWithSeparatorTo( public fun Input.readWithSeparatorTo(
output: Sink?, output: Output,
separator: ByteString, separator: ByteArray,
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 (!exhausted()) { while (buffer.canRead()) {
val byte = readByte() val byte = buffer.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 {
* Discard all bytes until [separator] is encountered. Separator is discarded sa well. return discardUntilDelimiter('\n'.code.toByte()).also {
* Return the total number of bytes read. discard(1)
*/ }.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 = readWithSeparatorTo(null, separator, atMost, errorOnEof) ): Int {
val dummy: Output = object : Output(ChunkBuffer.Pool) {
override fun closeDestination() {
// Do nothing
}
/** override fun flush(source: Memory, offset: Int, length: Int) {
* Discard all symbol until newline is discovered. Carriage return is not discarded. // Do nothing
*/ }
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 return readWithSeparatorTo(dummy, separator, atMost, errorOnEof)
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.write(byteArray, pointer, pointer + byteRead)
pointer += byteRead
return byteRead.toLong()
}
} }
/**
* 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,5 +1,6 @@
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,7 +1,6 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.readByteArray import io.ktor.utils.io.core.readBytes
import kotlinx.io.writeString
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -13,7 +12,7 @@ class EnvelopeFormatTest {
"d" put 22.2 "d" put 22.2
} }
data { data {
writeString("12345678") writeUtf8String("12345678")
} }
} }
@ -23,7 +22,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 {
readByteArray() readBytes()
} }
assertEquals("12345678", bytes?.decodeToString()) assertEquals("12345678", bytes?.decodeToString())
} }
@ -35,13 +34,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 {
readByteArray() readBytes()
} }
assertEquals("12345678", bytes?.decodeToString()) assertEquals("12345678", bytes?.decodeToString())
} }
@Test @Test
fun testManualDftl() { fun testManualDftl(){
val envelopeString = """ val envelopeString = """
#~DFTL #~DFTL
#~META #~META
@ -57,8 +56,8 @@ 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 {
readByteArray() readBytes()
} }
assertEquals("12345678", bytes?.decodeToString()) assertEquals("12345678", bytes?.decodeToString())
} }
} }

View File

@ -1,9 +1,8 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.buffered import io.ktor.utils.io.core.ByteReadPacket
import kotlinx.io.bytestring.encodeToByteString import io.ktor.utils.io.core.readBytes
import kotlinx.io.readByteArray import io.ktor.utils.io.core.readUTF8Line
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
@ -12,9 +11,9 @@ class IOTest {
@Test @Test
fun readBytes() { fun readBytes() {
val bytes = ByteArray(8) { it.toByte() } val bytes = ByteArray(8) { it.toByte() }
val input = ByteArraySource(bytes).buffered() val input = ByteReadPacket(bytes)
@Suppress("UNUSED_VARIABLE") val first = input.readByteArray(4) @Suppress("UNUSED_VARIABLE") val first = input.readBytes(4)
val second = input.readByteArray(4) val second = input.readBytes(4)
assertEquals(4.toByte(), second[0]) assertEquals(4.toByte(), second[0])
} }
@ -32,25 +31,25 @@ class IOTest {
binary.read { binary.read {
val array = ByteArray { val array = ByteArray {
val read = readWithSeparatorTo(this, "---".encodeToByteString()) + discardLine() val read = readWithSeparatorTo(this, "---".encodeToByteArray()) + discardLine()
assertEquals(12, read) assertEquals(12, read)
} }
assertEquals(""" assertEquals("""
aaa aaa
bbb bbb
""".trimIndent(),array.decodeToString().trim()) """.trimIndent(),array.decodeToString().trim())
assertEquals("ccc", readLine()?.trim()) assertEquals("ccc", readUTF8Line()?.trim())
} }
assertFails { assertFails {
binary.read { binary.read {
discardWithSeparator("---".encodeToByteString(), atMost = 3 ) discardWithSeparator("---".encodeToByteArray(), atMost = 3 )
} }
} }
assertFails { assertFails {
binary.read{ binary.read{
discardWithSeparator("-+-".encodeToByteString(), errorOnEof = true) discardWithSeparator("-+-".encodeToByteArray(), 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.writeTo(this@ByteArray, this@toByteArray) format.writeObject(this@ByteArray, this@toByteArray)
} }
fun MetaFormat.fromByteArray(packet: ByteArray): Meta { fun MetaFormat.fromByteArray(packet: ByteArray): Meta {
return packet.asBinary().read { readFrom(this) } return packet.asBinary().read { readObject(this) }
} }
class MetaFormatTest { class MetaFormatTest {

View File

@ -1,6 +1,5 @@
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
@ -19,9 +18,9 @@ class MultipartTest {
"value" put it "value" put it
} }
data { data {
writeString("Hello World $it") writeUtf8String("Hello World $it")
repeat(300) { repeat(300) {
writeString("$it ") writeRawString("$it ")
} }
} }
} }

View File

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

View File

@ -1,11 +1,8 @@
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
@ -26,18 +23,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: Source.() -> R): R = runBlocking { override fun <R> read(offset: Int, atMost: Int, block: Input.() -> R): R = runBlocking {
readSuspend(offset, atMost, block) readSuspend(offset, atMost, block)
} }
override suspend fun <R> readSuspend(offset: Int, atMost: Int, block: suspend Source.() -> R): R { override suspend fun <R> readSuspend(offset: Int, atMost: Int, block: suspend Input.() -> 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 ByteArraySource(array).buffered().use { it.block() } return ByteReadPacket(array).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)
@ -45,40 +42,40 @@ internal class PathBinary(
public fun Path.asBinary(): Binary = PathBinary(this) public fun Path.asBinary(): Binary = PathBinary(this)
public fun <R> Path.read(block: Source.() -> R): R = asBinary().read(block = block) public fun <R> Path.read(block: Input.() -> 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: Sink.() -> Unit): Unit { public fun Path.write(block: Output.() -> Unit): Unit {
val stream = Files.newOutputStream(this, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW) val stream = Files.newOutputStream(this, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)
stream.asSink().buffered().use(block) stream.asOutput().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: Sink.() -> Unit): Unit { public fun Path.append(block: Output.() -> 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.asSink().buffered().use(block) stream.asOutput().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: Sink.() -> Unit): Unit { public fun Path.rewrite(block: Output.() -> 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.asSink().buffered().use(block) stream.asOutput().use(block)
} }
@DFExperimental @DFExperimental
public fun EnvelopeFormat.readFile(path: Path): Envelope = readFrom(path.asBinary()) public fun EnvelopeFormat.readFile(path: Path): Envelope = readObject(path.asBinary())
/** /**
* Resolve IOFormat based on type * Resolve IOFormat based on type
@ -238,7 +235,7 @@ public fun IOPlugin.writeEnvelopeFile(
envelopeFormat: EnvelopeFormat = TaggedEnvelopeFormat, envelopeFormat: EnvelopeFormat = TaggedEnvelopeFormat,
) { ) {
path.rewrite { path.rewrite {
envelopeFormat.writeTo(this, envelope) envelopeFormat.writeObject(this, envelope)
} }
} }
@ -263,7 +260,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 = transferTo(this@write) val copied = copyTo(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,11 +1,9 @@
package space.kscience.dataforge.io package space.kscience.dataforge.io
import kotlinx.io.Source import io.ktor.utils.io.core.Input
import kotlinx.io.asSource import io.ktor.utils.io.streams.asInput
import kotlinx.io.buffered
public fun IOPlugin.resource(name: String): Binary? = context.javaClass.getResource(name)?.readBytes()?.asBinary()
public fun IOPlugin.resource(name: String): Binary? = { }.javaClass.getResource(name)?.readBytes()?.asBinary() public inline fun <R> IOPlugin.readResource(name: String, block: Input.() -> R): R =
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,6 +1,7 @@
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,5 +1,6 @@
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,5 +1,6 @@
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,18 +6,27 @@ Meta definition and basic operations on meta
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-meta:0.7.0`. The Maven coordinates of this project are `space.kscience:dataforge-meta:0.6.2-dev-2`.
**Gradle Kotlin DSL:** **Gradle Groovy:**
```kotlin ```groovy
repositories { repositories {
maven("https://repo.kotlin.link") maven { url '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.7.0") implementation 'space.kscience:dataforge-meta:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-meta:0.6.2-dev-2")
} }
``` ```

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/JsonElement; 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/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/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/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,26 +137,10 @@ 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 final class space/kscience/dataforge/meta/MetaBuilder : space/kscience/dataforge/meta/MutableMeta { public abstract interface annotation class space/kscience/dataforge/meta/MetaBuilder : java/lang/annotation/Annotation {
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 {
@ -220,7 +204,11 @@ 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;
@ -235,7 +223,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 get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta; public abstract fun getMeta (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;
} }
@ -253,10 +241,9 @@ 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
@ -282,10 +269,6 @@ 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;
@ -342,9 +325,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 ObservableMutableMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta; public static final fun MutableMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta;
public static final fun ObservableMutableMeta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ObservableMutableMeta; public static final fun MutableMeta (Lkotlin/jvm/functions/Function1;)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 synthetic fun MutableMeta$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
@ -360,6 +343,7 @@ 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
@ -371,8 +355,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 get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta; public abstract fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableMeta;
public abstract fun set (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V public abstract fun setMeta (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
} }
@ -386,7 +370,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 get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta; public abstract fun getMeta (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;
} }
@ -429,11 +413,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 get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta; 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/MutableMeta; 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/MutableTypedMeta; public synthetic fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/MutableTypedMeta;
public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/ObservableMutableMeta; public fun getMeta (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/ObservableMutableMeta;
public synthetic fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMeta; public synthetic fun getMeta (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;
} }
@ -445,12 +429,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 fun set (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V 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 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;
@ -479,12 +463,13 @@ 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 fun <init> (Lspace/kscience/dataforge/meta/Value;Ljava/util/Map;)V public synthetic fun <init> (ILspace/kscience/dataforge/meta/Value;Ljava/util/Map;Lkotlinx/serialization/internal/SerializationConstructorMarker;)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 {
@ -505,13 +490,9 @@ 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/Meta; public static final fun Meta (Lkotlin/jvm/functions/Function1;)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 (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;
} }
@ -560,9 +541,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;
} }
@ -580,8 +561,6 @@ 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 {
@ -656,11 +635,21 @@ 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;
} }
@ -672,30 +661,34 @@ 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 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 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 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 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/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/ValueRestriction; public final fun component4 ()Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;
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 ()Lspace/kscience/dataforge/meta/Meta; public final fun component8 ()Z
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 component9 ()Lspace/kscience/dataforge/meta/Meta;
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 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/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 getValueRestriction ()Lspace/kscience/dataforge/meta/descriptors/ValueRestriction; public final fun getReadOnly ()Z
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 {
@ -710,7 +703,6 @@ 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;
} }
@ -727,8 +719,9 @@ 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 getValueRestriction ()Lspace/kscience/dataforge/meta/descriptors/ValueRestriction; public final fun getReadOnly ()Z
public final fun getValueTypes ()Ljava/util/List; public final fun getType ()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;
@ -740,9 +733,10 @@ 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 setValueRestriction (Lspace/kscience/dataforge/meta/descriptors/ValueRestriction;)V public final fun setReadOnly (Z)V
public final fun setValueTypes (Ljava/util/List;)V public final fun setType (Ljava/util/List;)V
public final fun valueType (Lspace/kscience/dataforge/meta/ValueType;[Lspace/kscience/dataforge/meta/ValueType;)V public final fun setValueRequirement (Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;)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 {
@ -770,13 +764,12 @@ 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/ValueRestriction : java/lang/Enum { public final class space/kscience/dataforge/meta/descriptors/ValueRequirement : java/lang/Enum {
public static final field ABSENT Lspace/kscience/dataforge/meta/descriptors/ValueRestriction; public static final field ABSENT Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;
public static final field NONE Lspace/kscience/dataforge/meta/descriptors/ValueRestriction; public static final field NONE Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;
public static final field REQUIRED Lspace/kscience/dataforge/meta/descriptors/ValueRestriction; public static final field REQUIRED Lspace/kscience/dataforge/meta/descriptors/ValueRequirement;
public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)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/ValueRequirement;
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 {
@ -795,10 +788,7 @@ 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 fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; public abstract fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
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;
} }
@ -903,10 +893,6 @@ 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;
@ -920,6 +906,10 @@ 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;
@ -954,7 +944,6 @@ 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
Value.parse(content) content.parseValue()
} }
} }
} }

View File

@ -17,8 +17,8 @@ public class Laminate internal constructor(public val layers: List<Meta>) : Type
} }
} }
override fun get(name: Name): Laminate? { override fun getMeta(name: Name): Laminate? {
val childLayers = layers.mapNotNull { it.get(name) } val childLayers = layers.mapNotNull { it.getMeta(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.DfId import space.kscience.dataforge.misc.Type
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 operator fun get(name: Name): Meta? public fun getMeta(name: Name): Meta?
override fun getValue(name: Name): Value? = get(name)?.value override fun getValue(name: Name): Value? = getMeta(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.
*/ */
@DfId(Meta.TYPE) @Type(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 get(name: Name): Meta? { override fun getMeta(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,9 +50,7 @@ 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 {
@ -108,13 +106,21 @@ 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?.get(name) public operator fun Meta?.get(name: Name): Meta? = this?.getMeta(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.
@ -151,7 +157,7 @@ public interface TypedMeta<out M : TypedMeta<M>> : Meta {
override val items: Map<NameToken, M> override val items: Map<NameToken, M>
override fun get(name: Name): M? { override fun getMeta(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 {
@ -174,17 +180,28 @@ 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)
/** /**
* Retrieves a meta node with the given name from the nullable [TypedMeta] object. * Perform recursive item search using given [name]. Each [NameToken] is treated as a name in [TypedMeta.items] of a parent node.
* *
* @param name The name of the meta node to retrieve. * If [name] is empty return current [Meta]
* @return The meta node with the given name, or null if it doesn't exist.
*/ */
public operator fun <M : TypedMeta<M>> M?.get(name: Name): M? = this?.get(name) public tailrec operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(name: Name): M? = when {
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>> M?.get(key: String): M? = this?.get(key.parseAsName(true)) public operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(key: String): M? = this[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 ->
get(key ?: property.name.asName()) getMeta(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 ->
get(key ?: property.name.asName())?.let { converter.metaToObject(it) } getMeta(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 ->
get(key ?: property.name.asName())?.value getMeta(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(get(key ?: property.name.asName())?.value) reader(getMeta(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 MetaBuilderMarker public annotation class MetaBuilder
/** /**
* 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 get(name: Name): MutableMeta? override fun getMeta(name: Name): MutableMeta?
public operator fun set(name: Name, node: Meta?) public fun setMeta(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)
@MetaBuilderMarker @MetaBuilder
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 get(name: Name): MutableMeta? { override fun getMeta(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) {
set(this, meta) setMeta(this, meta)
} }
public infix fun Name.put(repr: MetaRepr) { public infix fun Name.put(repr: MetaRepr) {
set(this, repr.toMeta()) setMeta(this, repr.toMeta())
} }
public infix fun Name.put(builder: MutableMeta.() -> Unit) { public infix fun Name.put(mutableMeta: MutableMeta.() -> Unit) {
getOrCreate(this).apply(builder) setMeta(this, Meta(mutableMeta))
} }
public infix fun String.put(meta: Meta) { public infix fun String.put(meta: Meta) {
set(Name.parse(this), meta) setMeta(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) {
set(Name.parse(this), repr.toMeta()) setMeta(Name.parse(this), repr.toMeta())
} }
public infix fun String.putIndexed(iterable: Iterable<Meta>) { public infix fun String.putIndexed(iterable: Iterable<Meta>) {
@ -131,10 +131,15 @@ public interface MutableMeta : Meta, MutableMetaProvider {
} }
public infix fun String.put(builder: MutableMeta.() -> Unit) { public infix fun String.put(builder: MutableMeta.() -> Unit) {
getOrCreate(parseAsName()).apply(builder) setMeta(Name.parse(this), MutableMeta(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]
*/ */
@ -149,24 +154,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 get(name: Name): M? override fun getMeta(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) {
set(name, null) setMeta(name, null)
} }
public fun MutableMetaProvider.remove(key: String) { public fun MutableMetaProvider.remove(key: String) {
set(Name.parse(key), null) setMeta(Name.parse(key), null)
} }
// node setters // node setters
public operator fun MutableMetaProvider.set(Key: NameToken, value: Meta): Unit = set(Key.asName(), value) public operator fun MutableMetaProvider.set(Key: NameToken, value: Meta): Unit = setMeta(Key.asName(), value)
public operator fun MutableMetaProvider.set(key: String, value: Meta): Unit = set(Name.parse(key), value) public operator fun MutableMetaProvider.set(key: String, value: Meta): Unit = setMeta(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 =
@ -314,7 +319,7 @@ private class MutableMetaImpl(
) )
@ThreadSafe @ThreadSafe
override fun set(name: Name, node: Meta?) { override fun setMeta(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) {
@ -341,7 +346,7 @@ private class MutableMetaImpl(
newNode.adoptBy(this, token) newNode.adoptBy(this, token)
children[token] = newNode children[token] = newNode
} }
items[token]?.set(name.cutFirst(), node) items[token]?.setMeta(name.cutFirst(), node)
} }
} }
invalidate(name) invalidate(name)
@ -376,14 +381,16 @@ 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()
@JsName("newObservableMutableMeta") @Suppress("FunctionName")
public fun ObservableMutableMeta(): ObservableMutableMeta = MutableMetaImpl(null) @JsName("newMutableMeta")
public fun MutableMeta(): ObservableMutableMeta = MutableMetaImpl(null)
/** /**
* Build a [MutableMeta] using given transformation * Build a [MutableMeta] using given transformation
*/ */
public inline fun ObservableMutableMeta(builder: MutableMeta.() -> Unit = {}): ObservableMutableMeta = @Suppress("FunctionName")
ObservableMutableMeta().apply(builder) public inline fun MutableMeta(builder: MutableMeta.() -> Unit = {}): ObservableMutableMeta =
MutableMeta().apply(builder)
/** /**
@ -400,7 +407,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[rootName]?.items?.keys ?: emptyList() val defaultKeys: Collection<NameToken> = default.getMeta(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)
@ -408,12 +415,12 @@ private class MutableMetaWithDefault(
} }
override var value: Value? override var value: Value?
get() = source[rootName]?.value ?: default.get(rootName)?.value get() = source[rootName]?.value ?: default.getMeta(rootName)?.value
set(value) { set(value) {
source[rootName] = value source[rootName] = value
} }
override fun get(name: Name): MutableMeta = MutableMetaWithDefault(source, default, rootName + name) override fun getMeta(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 get(key ?: property.name.asName()) return getMeta(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()
set(name, value) setMeta(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 get(key ?: property.name.asName())?.let { converter.metaToObject(it) } return getMeta(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()
set(name, value?.let { converter.objectToMeta(it) }) setMeta(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? =
get(key ?: property.name.asName())?.value getMeta(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(get(key ?: property.name.asName())?.value) reader(getMeta(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 get(name: Name): ObservableMutableMeta? { override fun getMeta(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 get(name: Name): ObservableMutableMeta? = override fun getMeta(name: Name): ObservableMutableMeta? =
root.get(name)?.let { ObservableMetaWrapper(root, this.absoluteName + name, listeners) } root.getMeta(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,11 +49,9 @@ 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 set(name: Name, node: Meta?) { override fun setMeta(name: Name, node: Meta?) {
val oldMeta = get(name) val oldMeta = get(name)
//don't forget to remove listener root.setMeta(absoluteName + name, node)
oldMeta?.removeListener(this)
root.set(absoluteName + name, node)
if (oldMeta != node) { if (oldMeta != node) {
invalidate(name) invalidate(name)
} }
@ -69,7 +67,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 ->
set(name + changeName, this[changeName]) setMeta(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 get(name: Name): MutableMeta? = meta.get(name) override fun getMeta(name: Name): MutableMeta? = meta.getMeta(name)
override fun set(name: Name, node: Meta?) { override fun setMeta(name: Name, node: Meta?) {
if (validate(name, meta)) { if (validate(name, meta)) {
meta.set(name, node) meta.setMeta(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 set(name: Name, node: Meta?) { override fun setMeta(name: Name, node: Meta?) {
targetMeta.set(name, node) targetMeta.setMeta(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
set(name, node) setMeta(name, node)
node.onChange(this) { changeName -> node.onChange(this) { changeName ->
set(name + changeName, this[changeName]) setMeta(name + changeName, this[changeName])
} }
} }

View File

@ -1,17 +1,16 @@
package space.kscience.dataforge.meta package space.kscience.dataforge.meta
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import space.kscience.dataforge.names.* import space.kscience.dataforge.names.NameToken
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( public class SealedMeta internal constructor(
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)
@ -27,7 +26,7 @@ public class SealedMeta(
} }
/** /**
* 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,
@ -48,79 +47,7 @@ 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,7 +64,6 @@ 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()
@ -77,41 +76,6 @@ 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)
}
} }
} }
@ -176,7 +140,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) {
@ -264,5 +228,34 @@ 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
*/ */
@Deprecated("Use Value.parse(this) instead", ReplaceWith("Value.parse(this)")) public fun String.parseValue(): Value {
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 ValueRestriction { public enum class ValueRequirement {
/** /**
* No restrictions * No restrictions
*/ */
@ -26,25 +26,26 @@ public enum class ValueRestriction {
/** /**
* The descriptor for a meta * The descriptor for a meta
* @param description description text * @param info 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 valueRestriction The requirements for node content * @param valueRequirement 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 description: String? = null, public val info: 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 valueRestriction: ValueRestriction = ValueRestriction.NONE, public val valueRequirement: ValueRequirement = ValueRequirement.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,
) { ) {
/** /**
@ -62,12 +63,11 @@ 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() = valueRestriction == ValueRestriction.REQUIRED || children.values.any { required } public val MetaDescriptor.required: Boolean get() = valueRequirement == ValueRequirement.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) {
valueRestriction != ValueRestriction.REQUIRED valueRequirement != ValueRequirement.REQUIRED
} else { } else {
if (valueRestriction == ValueRestriction.ABSENT) false if (valueRequirement == ValueRequirement.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

@ -8,26 +8,20 @@ import space.kscience.dataforge.names.first
import space.kscience.dataforge.names.length import space.kscience.dataforge.names.length
import kotlin.collections.set import kotlin.collections.set
public class MetaDescriptorBuilder @PublishedApi internal constructor() { 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 valueRestriction: ValueRestriction = ValueRestriction.NONE public var valueRequirement: ValueRequirement = ValueRequirement.NONE
public var readOnly: Boolean = false
public var valueTypes: List<ValueType>? = null public var type: List<ValueType>? = null
public fun valueType(primaryType: ValueType, vararg otherTypes: ValueType) { public fun type(primaryType: ValueType, vararg otherTypes: ValueType) {
valueTypes = listOf(primaryType, *otherTypes) type = 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?) {
@ -48,7 +42,6 @@ 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)
} }
@ -58,17 +51,16 @@ 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 {
valueRestriction = ValueRestriction.ABSENT valueRequirement = ValueRequirement.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)
@ -87,13 +79,14 @@ public class MetaDescriptorBuilder @PublishedApi internal constructor() {
@PublishedApi @PublishedApi
internal fun build(): MetaDescriptor = MetaDescriptor( internal fun build(): MetaDescriptor = MetaDescriptor(
description = info, info = info,
children = children.mapValues { it.value.build() }, children = children.mapValues { it.value.build() },
multiple = multiple, multiple = multiple,
valueRestriction = valueRestriction, valueRequirement = valueRequirement,
valueTypes = valueTypes, valueTypes = type,
indexKey = indexKey, indexKey = indexKey,
defaultValue = default, defaultValue = default,
readOnly = readOnly,
attributes = attributes attributes = attributes
) )
} }
@ -111,9 +104,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) {
valueType(type, *additionalTypes) type(type, *additionalTypes)
block() block()
} }
@ -121,16 +114,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) {
valueRestriction = ValueRestriction.ABSENT valueRequirement = ValueRequirement.ABSENT
block() block()
} }
@ -149,7 +142,7 @@ public fun MetaDescriptorBuilder.node(
} }
public fun MetaDescriptorBuilder.required() { public fun MetaDescriptorBuilder.required() {
valueRestriction = ValueRestriction.REQUIRED valueRequirement = ValueRequirement.REQUIRED
} }
public inline fun <reified E : Enum<E>> MetaDescriptorBuilder.enum( public inline fun <reified E : Enum<E>> MetaDescriptorBuilder.enum(
@ -165,11 +158,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.description info = this@toBuilder.info
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
valueRestriction = this@toBuilder.valueRestriction valueRequirement = this@toBuilder.valueRequirement
valueTypes = this@toBuilder.valueTypes type = 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 { Value.parse(string) } private val parsedValue by lazy { string.parseValue() }
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,155 +1,79 @@
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 val type: KType = typeOf<Meta>() override fun metaToObject(meta: Meta): Meta = 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 val type: KType = typeOf<Value>() override fun metaToObject(meta: Meta): Value? = meta.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 val type: KType = typeOf<String>() override fun metaToObject(meta: Meta): String? = meta.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 val type: KType = typeOf<Boolean>() override fun metaToObject(meta: Meta): Boolean? = meta.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 val type: KType = typeOf<Number>() override fun metaToObject(meta: Meta): Number? = meta.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 val type: KType = typeOf<Double>() override fun metaToObject(meta: Meta): Double? = meta.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 val type: KType = typeOf<Float>() override fun metaToObject(meta: Meta): Float? = meta.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 val type: KType = typeOf<Int>() override fun metaToObject(meta: Meta): Int? = meta.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 val type: KType = typeOf<Long>() override fun metaToObject(meta: Meta): Long? = meta.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 metaToObjectOrNull(meta: Meta): E = meta.enum<E>() as? E ?: error("The Item is not a Enum") override fun metaToObject(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 val type: KType = typeOf<List<T>>() override fun metaToObject(meta: Meta): 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.set(name, item) if (selector(name)) target.setMeta(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 = ObservableMutableMeta{ public fun generate(source: ObservableMeta): ObservableMeta = MutableMeta().apply {
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 ->
set(name, Meta) setMeta(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 ->
set(to, operation(item)) setMeta(to, operation(item))
} }
) )
} }

View File

@ -2,7 +2,9 @@ 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 DfId(val id: String) public annotation class Type(val id: String)

View File

@ -134,11 +134,6 @@ 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

@ -0,0 +1,15 @@
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,18 +6,27 @@
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-scripting:0.7.0`. The Maven coordinates of this project are `space.kscience:dataforge-scripting:0.6.2-dev-2`.
**Gradle Kotlin DSL:** **Gradle Groovy:**
```kotlin ```groovy
repositories { repositories {
maven("https://repo.kotlin.link") maven { url '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.7.0") implementation 'space.kscience:dataforge-scripting:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-scripting:0.6.2-dev-2")
} }
``` ```

View File

@ -6,18 +6,27 @@
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-workspace:0.7.0`. The Maven coordinates of this project are `space.kscience:dataforge-workspace:0.6.2-dev-2`.
**Gradle Kotlin DSL:** **Gradle Groovy:**
```kotlin ```groovy
repositories { repositories {
maven("https://repo.kotlin.link") maven { url '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.7.0") implementation 'space.kscience:dataforge-workspace:0.6.2-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-workspace:0.6.2-dev-2")
} }
``` ```

View File

@ -10,18 +10,14 @@ 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)
}
} }
jvmTest{ dependencies(jvmTest){
dependencies { implementation(spclibs.logback.classic)
implementation(spclibs.logback.classic) implementation(projects.dataforgeIo.dataforgeIoYaml)
implementation(projects.dataforgeIo.dataforgeIoYaml)
}
} }
} }

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.DfId import space.kscience.dataforge.misc.Type
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.
*/ */
@DfId(TYPE) @Type(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.DfId import space.kscience.dataforge.misc.Type
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
*/ */
@DfId(Workspace.TYPE) @Type(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,12 +33,9 @@ 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()
val res = workspace.produce(plugin.name + taskReference.taskName, dependencyMeta) return workspace.produce(plugin.name + taskReference.taskName, dependencyMeta) as TaskResult<T>
//TODO add explicit check after https://youtrack.jetbrains.com/issue/KT-32956
@Suppress("UNCHECKED_CAST")
return res as TaskResult<T>
} }
/** /**
@ -48,7 +45,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 <reified T : Any, reified P : WorkspacePlugin> TaskResultBuilder<*>.from( public suspend inline fun <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>,
@ -56,10 +53,7 @@ public suspend inline fun <reified T : Any, reified P : WorkspacePlugin> TaskRes
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()
val res = workspace.produce(plugin.name + taskReference.taskName, dependencyMeta) return workspace.produce(plugin.name + taskReference.taskName, dependencyMeta) as TaskResult<T>
//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<*>
@ -85,7 +79,7 @@ public suspend inline fun <T : Any, reified R : Any> TaskResultBuilder<R>.pipeFr
) { ) {
from(selector, dependencyMeta).forEach { data -> from(selector, dependencyMeta).forEach { data ->
val meta = data.meta.toMutableMeta().apply { val meta = data.meta.toMutableMeta().apply {
taskMeta[taskName]?.let { taskName.put(it) } taskMeta[taskName]?.let { taskName.put(it) }
dataMetaTransform(data.name) dataMetaTransform(data.name)
} }

View File

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

View File

@ -1,10 +1,13 @@
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.* import space.kscience.dataforge.io.EnvelopeFormat
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
@ -25,15 +28,11 @@ 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 {
//TODO remove additional copy envelopeFormat.writeObject(this, envelope)
val bytes = ByteArray { flush()
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,18 +1,12 @@
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.Envelope import space.kscience.dataforge.io.*
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
@ -42,11 +36,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 writeTo(sink: Sink, obj: String) { override fun writeObject(output: Output, obj: String) {
sink.writeString(obj) output.writeUtf8String(obj)
} }
override fun readFrom(source: Source): String = source.readString() override fun readObject(input: Input): String = input.readUtf8String()
} }
@Test @Test
@ -65,9 +59,9 @@ class FileDataTest {
@Test @Test
@DFExperimental @DFExperimental
fun testZipWriteRead() = runTest { fun testZipWriteRead() = with(Global.io) {
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,5 +6,4 @@ 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.15.1-kotlin-1.9.21 toolsVersion=0.14.9-kotlin-1.8.20
#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.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -1,6 +1,7 @@
rootProject.name = "dataforge-core" rootProject.name = "dataforge-core"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
//enableFeaturePreview("VERSION_CATALOGS")
pluginManagement { pluginManagement {
@ -14,7 +15,6 @@ 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