├── .github ├── FUNDING.yml ├── dependabot.yml ├── release.yml └── workflows │ ├── CI.yml │ ├── dependencies.yml │ ├── codeql.yml │ ├── Docs.yml │ └── CD.yml ├── .gitignore ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── build-logic │ ├── settings.gradle.kts │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ ├── MyRepos.settings.gradle.kts │ │ └── mpp.gradle.kts ├── libs.versions.toml └── gradle-daemon-jvm.properties ├── .devcontainer └── devcontainer.json ├── kotlinx-serialization-csv ├── src │ ├── jvm9Main │ │ └── java │ │ │ └── module-info.java │ ├── commonMain │ │ └── kotlin │ │ │ └── app │ │ │ └── softwork │ │ │ └── serialization │ │ │ └── csv │ │ │ ├── StatefulIterator.kt │ │ │ ├── DescriptorChecks.kt │ │ │ ├── CSVEncoder.kt │ │ │ ├── CSVFormat.kt │ │ │ ├── CSVParser.kt │ │ │ └── CSVDecoder.kt │ └── commonTest │ │ └── kotlin │ │ └── app │ │ └── softwork │ │ └── serialization │ │ └── csv │ │ ├── TestClasses.kt │ │ ├── StatefulIteratorTest.kt │ │ └── CsvEncoderTest.kt ├── build.gradle.kts ├── README.md └── api │ ├── kotlinx-serialization-csv.api │ └── kotlinx-serialization-csv.klib.api ├── kotlinx-serialization-flf ├── src │ ├── jvm9Main │ │ └── java │ │ │ └── module-info.java │ ├── commonMain │ │ └── kotlin │ │ │ └── app │ │ │ └── softwork │ │ │ └── serialization │ │ │ └── flf │ │ │ ├── SealedClassClassDiscriminator.kt │ │ │ ├── FixedLength.kt │ │ │ ├── FixedLengthList.kt │ │ │ ├── FixedLengthSealedClassDiscriminator.kt │ │ │ ├── FixedLengthSealedClassDiscriminatorLength.kt │ │ │ ├── FixedLengthSealedEncoder.kt │ │ │ ├── FailingPrimitiveDecoder.kt │ │ │ ├── FixedLengthSealedDecoder.kt │ │ │ ├── FailingPrimitiveEncoder.kt │ │ │ ├── FixedLengthPrimitiveDecoder.kt │ │ │ ├── FixedLengthPrimitiveEncoder.kt │ │ │ ├── Ebcdic.kt │ │ │ ├── FixedLengthEncoder.kt │ │ │ ├── FixedLengthFormat.kt │ │ │ └── FixedLengthDecoder.kt │ ├── jvmTest │ │ └── kotlin │ │ │ └── app │ │ │ └── softwork │ │ │ └── serialization │ │ │ └── flf │ │ │ └── JvmExtensionsTest.kt │ ├── commonTest │ │ └── kotlin │ │ │ └── app │ │ │ └── softwork │ │ │ └── serialization │ │ │ └── flf │ │ │ ├── JsonTest.kt │ │ │ ├── Sample.kt │ │ │ ├── EbcdicTest.kt │ │ │ ├── FlfEncoderTest.kt │ │ │ └── FlfDecoderTest.kt │ └── jvmMain │ │ └── kotlin │ │ └── app │ │ └── softwork │ │ └── serialization │ │ └── flf │ │ └── SequenceWriteLines.kt ├── build.gradle.kts ├── README.md └── api │ ├── kotlinx-serialization-flf.api │ └── kotlinx-serialization-flf.klib.api ├── settings.gradle.kts ├── README.md ├── gradle.properties ├── kotlin-js-store └── wasm │ └── package-lock.json ├── detekt-baseline.xml ├── gradlew.bat ├── gradlew └── LICENSE /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: hfhbd 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | .kotlin 4 | build 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfhbd/kotlinx-serialization-csv/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/java:21", 3 | "features": { 4 | "ghcr.io/devcontainers/features/sshd:1": {} 5 | }, 6 | "onCreateCommand": "./gradlew build" 7 | } 8 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/jvm9Main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module app.softwork.serialization.csv { 2 | exports app.softwork.serialization.csv; 3 | 4 | requires kotlin.stdlib; 5 | 6 | requires transitive kotlinx.serialization.core; 7 | } 8 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/jvm9Main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module app.softwork.serialization.flf { 2 | exports app.softwork.serialization.flf; 3 | 4 | requires kotlin.stdlib; 5 | 6 | requires transitive kotlinx.serialization.core; 7 | } 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-rc-1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | assignees: 8 | - "hfhbd" 9 | - package-ecosystem: "gradle" 10 | directory: "/" 11 | schedule: 12 | interval: "daily" 13 | assignees: 14 | - "hfhbd" 15 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | categories: 3 | - title: Features 4 | labels: 5 | - '*' 6 | exclude: 7 | labels: 8 | - dependencies 9 | - build 10 | - title: Updated Dependencies 11 | labels: 12 | - dependencies 13 | exclude: 14 | labels: 15 | - build 16 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/SealedClassClassDiscriminator.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | internal sealed interface SealedClassClassDiscriminator { 4 | data class Property(val classDiscriminator: String) : SealedClassClassDiscriminator 5 | data class Length(val length: Int) : SealedClassClassDiscriminator 6 | } 7 | -------------------------------------------------------------------------------- /gradle/build-logic/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 3 | repositories { 4 | mavenCentral() 5 | gradlePluginPortal() 6 | } 7 | versionCatalogs.register("libs") { 8 | from(files("../libs.versions.toml")) 9 | } 10 | } 11 | 12 | rootProject.name = "build-logic" 13 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLength.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerialInfo 5 | 6 | @ExperimentalSerializationApi 7 | @Target(AnnotationTarget.PROPERTY) 8 | @SerialInfo 9 | public annotation class FixedLength(val length: Int) 10 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthList.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerialInfo 5 | 6 | @ExperimentalSerializationApi 7 | @Target(AnnotationTarget.PROPERTY) 8 | @SerialInfo 9 | public annotation class FixedLengthList(val serialName: String) 10 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthSealedClassDiscriminator.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerialInfo 5 | 6 | @ExperimentalSerializationApi 7 | @Target(AnnotationTarget.PROPERTY) 8 | @SerialInfo 9 | public annotation class FixedLengthSealedClassDiscriminator(val serialName: String) 10 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthSealedClassDiscriminatorLength.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerialInfo 5 | 6 | @ExperimentalSerializationApi 7 | @Target(AnnotationTarget.CLASS) 8 | @SerialInfo 9 | public annotation class FixedLengthSealedClassDiscriminatorLength(val length: Int) 10 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | includeBuild("gradle/build-logic") 3 | repositories { 4 | mavenCentral() 5 | gradlePluginPortal() 6 | } 7 | } 8 | 9 | plugins { 10 | id("MyRepos") 11 | } 12 | 13 | enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 14 | enableFeaturePreview("STABLE_CONFIGURATION_CACHE") 15 | 16 | rootProject.name = "kotlinx-serialization-csv-flf" 17 | 18 | include("kotlinx-serialization-csv") 19 | include("kotlinx-serialization-flf") 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kotlinx-serialization-csv-flf 2 | 3 | Serialize and deserialize ordered CSV and Fixed Length Format Files with kotlinx-serialization. 4 | 5 | - [Source code](https://github.com/hfhbd/kotlinx-serialization-csv) 6 | - [Docs](https://csv.softwork.app) 7 | 8 | ## Install 9 | 10 | This package is uploaded to MavenCentral and supports JVM, JS(IR) and all native targets as well. 11 | 12 | ````kotlin 13 | repositories { 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | implementation("app.softwork:kotlinx-serialization-csv:LATEST") 19 | implementation("app.softwork:kotlinx-serialization-flf:LATEST") 20 | } 21 | ```` 22 | 23 | ## License 24 | 25 | Apache 2 26 | -------------------------------------------------------------------------------- /gradle/build-logic/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `kotlin-dsl` 3 | } 4 | 5 | dependencies { 6 | implementation(libs.plugins.kotlin.multiplatform.toDep()) 7 | implementation(libs.plugins.kotlin.serialization.toDep()) 8 | implementation(libs.plugins.licensee.toDep()) 9 | implementation(libs.plugins.mavencentral.toDep()) 10 | implementation(libs.plugins.dokka.toDep()) 11 | implementation(libs.plugins.detekt.toDep()) 12 | implementation(libs.plugins.foojay.toDep()) 13 | implementation(libs.plugins.develocity.toDep()) 14 | } 15 | 16 | fun Provider.toDep() = map { 17 | "${it.pluginId}:${it.pluginId}.gradle.plugin:${it.version}" 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: macos-latest 12 | permissions: 13 | contents: read 14 | security-events: write 15 | 16 | steps: 17 | - uses: actions/checkout@v6 18 | - uses: gradle/actions/setup-gradle@v5 19 | 20 | - name: Build with Gradle 21 | run: ./gradlew build 22 | - name: Upload SARIF to Github using the upload-sarif action 23 | uses: github/codeql-action/upload-sarif@v3 24 | if: success() || failure() 25 | with: 26 | sarif_file: build/reports/detekt/detekt.sarif 27 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | kotlin.jvm.addClassesVariant=true 3 | kotlin.js.yarn=false 4 | kotlin.native.ignoreDisabledTargets=true 5 | kotlin.native.enableKlibsCrossCompilation=true 6 | org.gradle.parallel=true 7 | org.gradle.jvmargs=-Xmx2048m 8 | org.gradle.caching=true 9 | org.gradle.configuration-cache=true 10 | org.gradle.configuration-cache.parallel=true 11 | org.gradle.configuration-cache.entries-per-key=100 12 | org.gradle.unsafe.isolated-projects=false 13 | kotlin.kmp.isolated-projects.support=enable 14 | org.gradle.kotlin.dsl.skipMetadataVersionCheck=false 15 | org.gradle.kotlin.dsl.dcl=true 16 | group=app.softwork 17 | kotlin.build.archivesTaskOutputAsFriendModule=false 18 | -------------------------------------------------------------------------------- /.github/workflows/dependencies.yml: -------------------------------------------------------------------------------- 1 | name: Dependency review for pull requests 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | dependency-submission: 11 | runs-on: ubuntu-latest 12 | 13 | permissions: 14 | contents: write 15 | 16 | steps: 17 | - uses: actions/checkout@v6 18 | - name: Generate and submit dependency graph 19 | uses: gradle/actions/dependency-submission@v5 20 | 21 | dependency-review: 22 | runs-on: ubuntu-latest 23 | needs: dependency-submission 24 | if: github.event_name == 'pull_request' 25 | steps: 26 | - name: Perform dependency review 27 | uses: actions/dependency-review-action@v4 28 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | analyze: 11 | name: Analyze 12 | runs-on: ubuntu-latest 13 | permissions: 14 | security-events: write 15 | 16 | steps: 17 | - uses: actions/checkout@v6 18 | - uses: gradle/actions/setup-gradle@v5 19 | 20 | - name: Initialize CodeQL 21 | uses: github/codeql-action/init@v3 22 | with: 23 | languages: kotlin 24 | build-mode: manual 25 | 26 | - name: Build with Gradle 27 | run: ./gradlew --no-build-cache jvmMainClasses 28 | 29 | - name: Perform CodeQL Analysis 30 | uses: github/codeql-action/analyze@v3 31 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("mpp") 3 | } 4 | 5 | kotlin { 6 | sourceSets { 7 | commonMain { 8 | dependencies { 9 | api(libs.serialization.core) 10 | } 11 | } 12 | } 13 | } 14 | 15 | tasks.compileJvm9MainJava { 16 | options.compilerArgumentProviders += object : CommandLineArgumentProvider { 17 | 18 | @InputFiles 19 | @PathSensitive(PathSensitivity.RELATIVE) 20 | val kotlinClasses = tasks.compileKotlinJvm.flatMap { it.destinationDirectory } 21 | 22 | override fun asArguments(): List = listOf( 23 | "--patch-module", 24 | "app.softwork.serialization.csv=${kotlinClasses.get().asFile.absolutePath}" 25 | ) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.github/workflows/Docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | release: 5 | types: [ created ] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: read 13 | pages: write 14 | id-token: write 15 | 16 | environment: 17 | name: github-pages 18 | url: ${{ steps.deployment.outputs.page_url }} 19 | 20 | steps: 21 | - uses: actions/checkout@v6 22 | - uses: actions/configure-pages@v5 23 | - uses: gradle/actions/setup-gradle@v5 24 | 25 | - name: Generate Docs 26 | run: ./gradlew :dokkaGenerate 27 | - name: Upload Docs 28 | uses: actions/upload-pages-artifact@v4 29 | with: 30 | path: build/dokka/html 31 | - name: Deploy to GitHub Pages 32 | id: deployment 33 | uses: actions/deploy-pages@v4 34 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("mpp") 3 | } 4 | 5 | kotlin { 6 | sourceSets { 7 | commonMain { 8 | dependencies { 9 | api(libs.serialization.core) 10 | } 11 | } 12 | commonTest { 13 | dependencies { 14 | implementation(libs.serialization.json) 15 | } 16 | } 17 | } 18 | } 19 | 20 | tasks.compileJvm9MainJava { 21 | options.compilerArgumentProviders += object : CommandLineArgumentProvider { 22 | 23 | @InputFiles 24 | @PathSensitive(PathSensitivity.RELATIVE) 25 | val kotlinClasses = tasks.compileKotlinJvm.flatMap { it.destinationDirectory } 26 | 27 | override fun asArguments(): List = listOf( 28 | "--patch-module", 29 | "app.softwork.serialization.flf=${kotlinClasses.get().asFile.absolutePath}" 30 | ) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | kotlin = "2.2.10" 3 | serialization = "1.9.0" 4 | 5 | [libraries] 6 | serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" } 7 | serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } 8 | 9 | [plugins] 10 | kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } 11 | kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } 12 | mavencentral = { id = "io.github.hfhbd.mavencentral", version = "0.0.23" } 13 | dokka = { id = "org.jetbrains.dokka", version = "2.1.0" } 14 | licensee = { id = "app.cash.licensee", version = "1.14.1" } 15 | detekt = { id = "io.gitlab.arturbosch.detekt", version = "1.23.8" } 16 | foojay = { id = "org.gradle.toolchains.foojay-resolver-convention", version = "1.0.0" } 17 | develocity = { id = "com.gradle.develocity", version = "4.2" } 18 | -------------------------------------------------------------------------------- /.github/workflows/CD.yml: -------------------------------------------------------------------------------- 1 | name: CD 2 | 3 | on: 4 | release: 5 | types: [ created ] 6 | 7 | concurrency: 8 | group: "cd" 9 | cancel-in-progress: false 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | environment: 16 | name: CD 17 | 18 | steps: 19 | - name: Set environment for version 20 | run: long="${{ github.ref }}"; version=${long#"refs/tags/v"}; echo "version=${version}" >> $GITHUB_OUTPUT 21 | id: version 22 | - uses: actions/checkout@v6 23 | - uses: gradle/actions/setup-gradle@v5 24 | 25 | - name: Publish 26 | run: ./gradlew -Pversion=${{ steps.version.outputs.version }} publish 27 | env: 28 | ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_PRIVATE_KEY }} 29 | ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }} 30 | ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.CENTRAL_USERNAME }} 31 | ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.CENTRAL_PASSWORD }} 32 | -------------------------------------------------------------------------------- /gradle/gradle-daemon-jvm.properties: -------------------------------------------------------------------------------- 1 | #This file is generated by updateDaemonJvm 2 | toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e2d97f28068cf05b0467aa8e97b19f69/redirect 3 | toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/a41f952f4496c2309be30fd168c6c117/redirect 4 | toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e2d97f28068cf05b0467aa8e97b19f69/redirect 5 | toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/a41f952f4496c2309be30fd168c6c117/redirect 6 | toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e7806cd9471741d622398825f14d2da6/redirect 7 | toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/0402cc5012ae8124ea0ad01bd29342ef/redirect 8 | toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e2d97f28068cf05b0467aa8e97b19f69/redirect 9 | toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/a41f952f4496c2309be30fd168c6c117/redirect 10 | toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/86ea5d26c5757681ffe78d87258b45ec/redirect 11 | toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/ea8232621e1368089cec8b12816df5e3/redirect 12 | toolchainVersion=21 13 | -------------------------------------------------------------------------------- /gradle/build-logic/src/main/kotlin/MyRepos.settings.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" 3 | id("com.gradle.develocity") version "4.1" 4 | } 5 | 6 | develocity { 7 | buildScan { 8 | termsOfUseUrl.set("https://gradle.com/terms-of-service") 9 | termsOfUseAgree.set("yes") 10 | publishing { 11 | val isCI = providers.environmentVariable("CI").isPresent 12 | onlyIf { 13 | isCI 14 | } 15 | } 16 | } 17 | } 18 | 19 | dependencyResolutionManagement { 20 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 21 | 22 | repositories { 23 | mavenCentral() 24 | google() 25 | 26 | exclusiveContent { 27 | forRepository { 28 | ivy(url = "https://nodejs.org/dist/") { 29 | name = "Node Distributions at $url" 30 | patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } 31 | metadataSources { artifact() } 32 | content { includeModule("org.nodejs", "node") } 33 | } 34 | } 35 | filter { includeGroup("org.nodejs") } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/README.md: -------------------------------------------------------------------------------- 1 | # Module kotlinx-serialization-flf 2 | 3 | This module contains the [Fixed LengthFile Format](https://www.ibm.com/docs/en/psfa/7.2.1?topic=format-fixed-length-files). 4 | 5 | ## Usage 6 | 7 | ``` 8 | John Doe 9 | ``` 10 | 11 | To decode from the given Fixed-Length string you need to apply `@FixedLength(length = n)`: 12 | 13 | ```kotlin 14 | @Serializable 15 | data class Names( 16 | @FixedLength(5) val firstName: String, 17 | @FixedLength(5) val lastName: String 18 | ) 19 | 20 | FixedLengthFormat.decodeFromString(Names.serializer(), flf) 21 | ``` 22 | 23 | And to encode: 24 | 25 | ```kotlin 26 | FixedLengthFormat.encodeToString(Names.serializer(), Names("John", "Doe")) 27 | ``` 28 | 29 | ``` 30 | John Doe 31 | ``` 32 | 33 | ## Limitations 34 | 35 | - The order of the properties of the class must match the order of the fields! 36 | - All whitespaces are trimmed. 37 | - Because this format does not have any delimiters, there is no check, if a given length is too long and consumes the 38 | next value. 39 | - Because this format does not have any delimiters, it is not possible to decode/encode primitives. You must use a class 40 | with `@FixedLength` annotated properties. 41 | - Inner lists are not supported, eg. `data class NotSupported(val innerList: List)` 42 | - Maps are not supported. 43 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthSealedEncoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.descriptors.SerialDescriptor 5 | import kotlinx.serialization.encoding.CompositeEncoder 6 | import kotlinx.serialization.encoding.Encoder 7 | import kotlinx.serialization.modules.SerializersModule 8 | 9 | @ExperimentalSerializationApi 10 | internal class FixedLengthSealedEncoder( 11 | private val typeLength: Int?, 12 | private val originalEncoder: FixedLengthEncoder 13 | ) : Encoder by originalEncoder, CompositeEncoder by originalEncoder { 14 | override val serializersModule: SerializersModule = originalEncoder.serializersModule 15 | 16 | override fun beginStructure(descriptor: SerialDescriptor): FixedLengthSealedEncoder { 17 | originalEncoder.beginStructure(descriptor) 18 | return this 19 | } 20 | 21 | override fun encodeStringElement(descriptor: SerialDescriptor, index: Int, value: String) { 22 | if (index == 0) { 23 | if (typeLength != null) { 24 | originalEncoder.encode(value, typeLength) 25 | } 26 | } else { 27 | originalEncoder.encodeStringElement(descriptor, index, value) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/README.md: -------------------------------------------------------------------------------- 1 | # Module kotlinx-serialization-csv 2 | 3 | This module contains the [CSV-Format](https://datatracker.ietf.org/doc/html/rfc4180). 4 | 5 | ## Usage 6 | 7 | ```csv 8 | firstName,lastName 9 | John,Doe 10 | ``` 11 | 12 | To decode from the given CSV string: 13 | 14 | ```kotlin 15 | @Serializable 16 | data class Names(val firstName: String, val lastName: String) 17 | 18 | CSVFormat.decodeFromString(Names.serializer(), csv) 19 | ``` 20 | 21 | And to encode: 22 | 23 | ```kotlin 24 | CSVFormat.encodeToString(Names.serializer(), Names("John", "Doe")) 25 | ``` 26 | 27 | ```csv 28 | firstName,lastName 29 | John,Doe 30 | ``` 31 | 32 | ### Quotes 33 | 34 | ```csv 35 | "lastName";"firstName" 36 | "Doe";"John" 37 | ``` 38 | 39 | To decode from the given CSV string with quotes and unordered attributes: 40 | 41 | ```kotlin 42 | @Serializable 43 | data class Names(val firstName: String, val lastName: String) 44 | 45 | CSVFormat { 46 | separator = ';' 47 | alwaysEmitQuotes = true 48 | }.decodeFromString(Names.serializer(), csv) 49 | ``` 50 | 51 | And to encode: 52 | 53 | ```kotlin 54 | CSVFormat { 55 | separator = ';' 56 | alwaysEmitQuotes = true 57 | }.encodeToString(Names.serializer(), Names("John", "Doe")) 58 | ``` 59 | 60 | ```csv 61 | "firstName";"lastName" 62 | "John";"Doe" 63 | ``` 64 | 65 | ## Limitations 66 | 67 | - Inner lists are not supported, eg. `data class NotSupported(val innerList: List)` 68 | - Maps are not supported. 69 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FailingPrimitiveDecoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.encoding.Decoder 5 | 6 | internal interface FailingPrimitiveDecoder : Decoder { 7 | override fun decodeBoolean() = 8 | error("Primitives are not supported due to missing length") 9 | 10 | override fun decodeByte() = 11 | error("Primitives are not supported due to missing length") 12 | 13 | override fun decodeChar() = 14 | error("Primitives are not supported due to missing length") 15 | 16 | override fun decodeDouble() = 17 | error("Primitives are not supported due to missing length") 18 | 19 | override fun decodeFloat() = 20 | error("Primitives are not supported due to missing length") 21 | 22 | override fun decodeInt() = 23 | error("Primitives are not supported due to missing length") 24 | 25 | override fun decodeLong() = 26 | error("Primitives are not supported due to missing length") 27 | 28 | @ExperimentalSerializationApi 29 | override fun decodeNull() = 30 | error("Primitives are not supported due to missing length") 31 | 32 | override fun decodeShort() = 33 | error("Primitives are not supported due to missing length") 34 | 35 | override fun decodeString() = 36 | error("Primitives are not supported due to missing length") 37 | } 38 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonMain/kotlin/app/softwork/serialization/csv/StatefulIterator.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | internal interface StatefulIterator : Iterator { 4 | val current: T? 5 | 6 | fun peek(): T? 7 | } 8 | 9 | internal fun Iterator.stateful(): StatefulIterator = object : StatefulIterator { 10 | override var current: T? = null 11 | private var peeked: T? = null 12 | 13 | override fun hasNext(): Boolean { 14 | if (peeked != null) { 15 | return true 16 | } else { 17 | val hasNext = this@stateful.hasNext() 18 | if (!hasNext) { 19 | current = null 20 | } 21 | return hasNext 22 | } 23 | } 24 | 25 | override fun next(): T { 26 | val peeked = peeked 27 | if (peeked == null) { 28 | val next = this@stateful.next() 29 | current = next 30 | return next 31 | } else { 32 | this.peeked = null 33 | current = peeked 34 | return peeked 35 | } 36 | } 37 | 38 | override fun peek(): T? { 39 | val peeked = peeked 40 | if (peeked != null) { 41 | return peeked 42 | } else if (this@stateful.hasNext()) { 43 | val next = this@stateful.next() 44 | this.peeked = next 45 | return next 46 | } else { 47 | return null 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthSealedDecoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.descriptors.SerialDescriptor 5 | import kotlinx.serialization.encoding.CompositeDecoder 6 | import kotlinx.serialization.encoding.Decoder 7 | import kotlinx.serialization.modules.SerializersModule 8 | 9 | @ExperimentalSerializationApi 10 | internal class FixedLengthSealedDecoder( 11 | private val classDiscriminator: SealedClassClassDiscriminator, 12 | private val originalDecoder: FixedLengthDecoder 13 | ) : Decoder by originalDecoder, CompositeDecoder by originalDecoder { 14 | override val serializersModule: SerializersModule = originalDecoder.serializersModule 15 | 16 | override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder { 17 | originalDecoder.beginStructure(descriptor) 18 | return this 19 | } 20 | 21 | override fun decodeStringElement(descriptor: SerialDescriptor, index: Int): String { 22 | return if (index == 0) { 23 | when (classDiscriminator) { 24 | is SealedClassClassDiscriminator.Length -> originalDecoder.decode(classDiscriminator.length).toString() 25 | is SealedClassClassDiscriminator.Property -> classDiscriminator.classDiscriminator 26 | } 27 | } else { 28 | originalDecoder.decodeStringElement(descriptor, index) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonTest/kotlin/app/softwork/serialization/csv/TestClasses.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import kotlin.jvm.JvmInline 6 | import kotlin.time.Instant 7 | 8 | @Serializable 9 | data class Foo(val bar: Int) 10 | 11 | @Serializable 12 | data class FooString(val bar: Int, val value: String, val foo: Int) 13 | 14 | @Serializable 15 | data class FooNamed(@SerialName("foo") val bar: Int) 16 | 17 | @Serializable 18 | data class FooNull(val bar: Int, val baz: Int?) 19 | 20 | @Serializable 21 | data class FooMultipleNull(val bar: Int, val baz1: Int?, val baz2: Int?, val baz3: Int?) 22 | 23 | @Serializable 24 | data class FooNullFirst(val baz: Int?, val bar: Int) 25 | 26 | @Serializable 27 | data class FooNested(val baz: Int?, val child: FooNullFirst, val foo: Int) 28 | 29 | @Serializable 30 | data class FooList(val baz: Int?, val child: List) 31 | 32 | @Serializable 33 | data class FooEnum(val baz: Int?, val foo: A) { 34 | @Serializable 35 | enum class A { 36 | One, Two, Three 37 | } 38 | } 39 | 40 | @Serializable 41 | @JvmInline 42 | value class FooInline(val foo: Double) 43 | 44 | @Serializable 45 | data class FooComplex(val bar: String?, val inline: FooInline, val enum: FooEnum.A, val instant: Instant) 46 | 47 | @Serializable 48 | sealed interface Sealed { 49 | @Serializable 50 | @SerialName("foo") 51 | data class Foo(val s: String) : Sealed 52 | 53 | @Serializable 54 | @SerialName("bar") 55 | data class Bar(val b: Int) : Sealed 56 | } 57 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FailingPrimitiveEncoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.encoding.Encoder 5 | 6 | internal interface FailingPrimitiveEncoder : Encoder { 7 | override fun encodeBoolean(value: Boolean) { 8 | error("Primitives are not supported due to missing length") 9 | } 10 | 11 | override fun encodeByte(value: Byte) { 12 | error("Primitives are not supported due to missing length") 13 | } 14 | 15 | override fun encodeChar(value: Char) { 16 | error("Primitives are not supported due to missing length") 17 | } 18 | 19 | override fun encodeDouble(value: Double) { 20 | error("Primitives are not supported due to missing length") 21 | } 22 | 23 | override fun encodeFloat(value: Float) { 24 | error("Primitives are not supported due to missing length") 25 | } 26 | 27 | override fun encodeInt(value: Int) { 28 | error("Primitives are not supported due to missing length") 29 | } 30 | 31 | override fun encodeLong(value: Long) { 32 | error("Primitives are not supported due to missing length") 33 | } 34 | 35 | @ExperimentalSerializationApi 36 | override fun encodeNull() { 37 | error("Primitives are not supported due to missing length") 38 | } 39 | 40 | override fun encodeShort(value: Short) { 41 | error("Primitives are not supported due to missing length") 42 | } 43 | 44 | override fun encodeString(value: String) { 45 | error("Primitives are not supported due to missing length") 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonTest/kotlin/app/softwork/serialization/csv/StatefulIteratorTest.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import kotlin.test.Test 4 | import kotlin.test.assertEquals 5 | 6 | class StatefulIteratorTest { 7 | 8 | @Test 9 | fun normal() { 10 | val iter = iterator { 11 | yield(1) 12 | yield(2) 13 | yield(3) 14 | yield(4) 15 | }.stateful() 16 | 17 | assertEquals(null, iter.current) 18 | 19 | assertEquals(1, iter.peek()) 20 | assertEquals(1, iter.next()) 21 | assertEquals(1, iter.current) 22 | 23 | assertEquals(2, iter.peek()) 24 | assertEquals(2, iter.peek()) 25 | assertEquals(2, iter.next()) 26 | assertEquals(2, iter.current) 27 | 28 | assertEquals(3, iter.peek()) 29 | assertEquals(3, iter.next()) 30 | assertEquals(3, iter.current) 31 | 32 | assertEquals(4, iter.next()) 33 | assertEquals(4, iter.current) 34 | 35 | assertEquals(null, iter.peek()) 36 | assertEquals(false, iter.hasNext()) 37 | assertEquals(null, iter.current) 38 | } 39 | 40 | @Test 41 | fun asList() { 42 | val iter = iterator { 43 | yield(1) 44 | yield(2) 45 | yield(3) 46 | }.stateful() 47 | 48 | assertEquals(listOf(1, 2, 3), iter.asSequence().toList()) 49 | } 50 | 51 | @Test 52 | fun empty() { 53 | val iter = iterator {}.stateful() 54 | 55 | assertEquals(null, iter.peek()) 56 | assertEquals(false, iter.hasNext()) 57 | 58 | assertEquals(listOf(), iter.asSequence().toList()) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthPrimitiveDecoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.descriptors.SerialDescriptor 5 | import kotlinx.serialization.encoding.Decoder 6 | import kotlinx.serialization.modules.SerializersModule 7 | 8 | @ExperimentalSerializationApi 9 | internal class FixedLengthPrimitiveDecoder( 10 | override val serializersModule: SerializersModule, 11 | private val data: CharSequence, 12 | private val ebcdic: Ebcdic? 13 | ) : Decoder { 14 | override fun beginStructure(descriptor: SerialDescriptor) = error("Not supported") 15 | 16 | override fun decodeBoolean() = data.toString().toBoolean() 17 | override fun decodeByte() = data.toString().toByte() 18 | override fun decodeChar() = data.single() 19 | override fun decodeDouble() = data.toString().toDouble() 20 | override fun decodeFloat() = data.toString().toFloat() 21 | override fun decodeInt() = ebcdic?.format?.toInt(data) ?: data.toString().toInt() 22 | override fun decodeLong(): Long = ebcdic?.format?.toLong(data) ?: data.toString().toLong() 23 | override fun decodeShort() = data.toString().toShort() 24 | override fun decodeString(): String = data.toString() 25 | 26 | override fun decodeEnum(enumDescriptor: SerialDescriptor) = enumDescriptor.getElementIndex(data.toString()) 27 | 28 | override fun decodeInline(descriptor: SerialDescriptor) = this 29 | 30 | @ExperimentalSerializationApi 31 | override fun decodeNotNullMark() = data.isNotBlank() 32 | 33 | @ExperimentalSerializationApi 34 | override fun decodeNull() = null 35 | } 36 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonMain/kotlin/app/softwork/serialization/csv/DescriptorChecks.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.descriptors.PolymorphicKind 5 | import kotlinx.serialization.descriptors.SerialDescriptor 6 | import kotlinx.serialization.descriptors.SerialKind 7 | import kotlinx.serialization.descriptors.StructureKind 8 | import kotlinx.serialization.descriptors.elementDescriptors 9 | 10 | @ExperimentalSerializationApi 11 | internal val SerialDescriptor.flatNames: Iterator 12 | get() = iterator { 13 | names(this@flatNames) 14 | } 15 | 16 | @ExperimentalSerializationApi 17 | private suspend fun SequenceScope.names(descriptor: SerialDescriptor) { 18 | for (i in 0 until descriptor.elementsCount) { 19 | val elementDescriptor = descriptor.getElementDescriptor(i) 20 | if (elementDescriptor.elementsCount == 0 || elementDescriptor.kind == SerialKind.ENUM) { 21 | yield(descriptor.getElementName(i)) 22 | } else { 23 | names(elementDescriptor) 24 | } 25 | } 26 | } 27 | 28 | @OptIn(ExperimentalSerializationApi::class) 29 | internal fun SerialDescriptor.checkForLists() { 30 | for (elementDescriptor in elementDescriptors) { 31 | require(elementDescriptor.kind !is StructureKind.LIST) { 32 | error("List is not yet supported") 33 | } 34 | require(elementDescriptor.kind !is StructureKind.MAP) { 35 | error("Map is not yet supported") 36 | } 37 | elementDescriptor.checkForLists() 38 | } 39 | } 40 | 41 | @OptIn(ExperimentalSerializationApi::class) 42 | internal fun SerialDescriptor.checkForPolymorphicClasses() { 43 | for (elementDescriptor in elementDescriptors) { 44 | require(elementDescriptor.kind !is PolymorphicKind) { 45 | "Polymorphic classes are not supported with encodeToString using encodeHeader." 46 | } 47 | elementDescriptor.checkForPolymorphicClasses() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /kotlin-js-store/wasm/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kotlinx-serialization-csv-flf", 3 | "version": "unspecified", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "kotlinx-serialization-csv-flf", 9 | "version": "unspecified", 10 | "workspaces": [ 11 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-csv", 12 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-csv-test", 13 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-flf", 14 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-flf-test" 15 | ], 16 | "devDependencies": {} 17 | }, 18 | "node_modules/kotlinx-serialization-csv-flf-kotlinx-serialization-csv": { 19 | "resolved": "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-csv", 20 | "link": true 21 | }, 22 | "node_modules/kotlinx-serialization-csv-flf-kotlinx-serialization-csv-test": { 23 | "resolved": "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-csv-test", 24 | "link": true 25 | }, 26 | "node_modules/kotlinx-serialization-csv-flf-kotlinx-serialization-flf": { 27 | "resolved": "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-flf", 28 | "link": true 29 | }, 30 | "node_modules/kotlinx-serialization-csv-flf-kotlinx-serialization-flf-test": { 31 | "resolved": "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-flf-test", 32 | "link": true 33 | }, 34 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-csv": { 35 | "version": "0.0.0-unspecified", 36 | "devDependencies": {} 37 | }, 38 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-csv-test": { 39 | "version": "0.0.0-unspecified", 40 | "devDependencies": {} 41 | }, 42 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-flf": { 43 | "version": "0.0.0-unspecified", 44 | "devDependencies": {} 45 | }, 46 | "packages/kotlinx-serialization-csv-flf-kotlinx-serialization-flf-test": { 47 | "version": "0.0.0-unspecified", 48 | "devDependencies": {} 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/jvmTest/kotlin/app/softwork/serialization/flf/JvmExtensionsTest.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import java.io.File 5 | import java.util.stream.Collectors 6 | import java.util.stream.Stream 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | 10 | @ExperimentalSerializationApi 11 | class JvmExtensionsTest { 12 | @Test 13 | fun sequences() { 14 | val file = File.createTempFile("foo", "bar") 15 | val data = sequenceOf("1", "2", "3") 16 | data.writeLines(file) 17 | data.appendLines(file) 18 | 19 | assertEquals(listOf("1", "2", "3", "1", "2", "3"), file.readLines()) 20 | } 21 | 22 | @Test 23 | fun appendWrite() { 24 | assertEquals( 25 | "11\n", 26 | buildString { 27 | append( 28 | Small.serializer(), 29 | Small("1") 30 | ) 31 | appendLine( 32 | Small.serializer(), 33 | Small("1") 34 | ) 35 | } 36 | ) 37 | } 38 | 39 | @Test 40 | fun decode() { 41 | assertEquals( 42 | listOf( 43 | Small("1"), 44 | Small("2"), 45 | Small("3"), 46 | ), 47 | "123".reader() 48 | .decode( 49 | deserializer = Small.serializer(), 50 | format = FixedLengthFormat.Default(lineSeparator = "") 51 | ).toList() 52 | ) 53 | 54 | assertEquals( 55 | listOf( 56 | Small("4"), 57 | Small("5"), 58 | Small("6"), 59 | ), 60 | "4\n5\n6\n".reader() 61 | .decode( 62 | deserializer = Small.serializer(), 63 | ).toList() 64 | ) 65 | } 66 | 67 | @Test 68 | fun stream() { 69 | val stream = Stream.of("a", "b") 70 | assertEquals(listOf(Small("a"), Small("b")), stream.decode(Small.serializer()).toList()) 71 | 72 | val parallelStream = Stream.of("a", "b").parallel() 73 | assertEquals( 74 | listOf("a", "b"), 75 | parallelStream.decodeStream(Small.serializer()).encodeStream(Small.serializer()).collect( 76 | Collectors.toList() 77 | ) 78 | ) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonTest/kotlin/app/softwork/serialization/flf/JsonTest.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.json.Json 5 | import kotlin.test.Test 6 | import kotlin.test.assertEquals 7 | 8 | @ExperimentalSerializationApi 9 | class JsonTest { 10 | private val prettyPrintJson = Json { prettyPrint = true } 11 | 12 | @Test 13 | fun interop() { 14 | val sampleFlf = """ 15 | ShortLong 004242.3 1970-01-01T00:00:00ZTwo 001foo4.2true000f41.118false0001000104.2-001 16 | """.trimIndent() 17 | val decode = FixedLengthFormat.decodeFromString( 18 | deserializer = Sample.serializer(), 19 | string = sampleFlf 20 | ) 21 | assertEquals( 22 | Sample.simple, 23 | decode 24 | ) 25 | val jsonString = prettyPrintJson.encodeToString(Sample.serializer(), decode) 26 | //language=JSON 27 | assertEquals( 28 | """ 29 | { 30 | "shortString": "Short", 31 | "longString": "Long", 32 | "int": 42, 33 | "double": 42.3, 34 | "nil": null, 35 | "date": "1970-01-01T00:00:00Z", 36 | "enum": "Two", 37 | "inline": 1, 38 | "inlineS": "foo", 39 | "inlineD": 4.2, 40 | "inlineB": true, 41 | "inlineL": 0, 42 | "inlineChar": "f", 43 | "inlineShort": 4, 44 | "inlineFloat": 1.1, 45 | "inlineByte": 1, 46 | "innerClass": { 47 | "s": 8 48 | }, 49 | "boolean": false, 50 | "byte": 1, 51 | "short": 1, 52 | "float": 4.2, 53 | "long": -1, 54 | "char": " " 55 | } 56 | """.trimIndent(), 57 | jsonString 58 | ) 59 | val sampleJson = Json.decodeFromString(Sample.serializer(), jsonString) 60 | assertEquals( 61 | Sample.simple, 62 | sampleJson 63 | ) 64 | val flfString = FixedLengthFormat.encodeToString( 65 | serializer = Sample.serializer(), 66 | value = sampleJson 67 | ) 68 | assertEquals( 69 | sampleFlf, 70 | flfString 71 | ) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthPrimitiveEncoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.descriptors.SerialDescriptor 5 | import kotlinx.serialization.encoding.Encoder 6 | import kotlinx.serialization.modules.SerializersModule 7 | 8 | @ExperimentalSerializationApi 9 | internal class FixedLengthPrimitiveEncoder( 10 | override val serializersModule: SerializersModule, 11 | private val length: Int, 12 | private val builder: StringBuilder, 13 | private val fillLeadingZero: Boolean, 14 | private val ebcdic: Ebcdic? 15 | ) : Encoder { 16 | private fun encode(value: String, length: Int) { 17 | require(value.length <= length) { "$value was longer as $length" } 18 | builder.append(value.padEnd(length)) 19 | } 20 | private fun encodeNumber(value: String, length: Int) { 21 | if (fillLeadingZero) { 22 | val sign = value.startsWith("-") 23 | if (sign) { 24 | encode("-" + value.drop(1).padStart(length - 1, '0'), length) 25 | } else { 26 | encode(value.padStart(length, '0'), length) 27 | } 28 | } else { 29 | encode(value, length) 30 | } 31 | } 32 | 33 | override fun beginStructure(descriptor: SerialDescriptor) = error("Not supported") 34 | 35 | override fun encodeBoolean(value: Boolean) { 36 | encode(value.toString(), length) 37 | } 38 | 39 | override fun encodeByte(value: Byte) { 40 | encodeNumber(value.toString(), length) 41 | } 42 | 43 | override fun encodeChar(value: Char) { 44 | encode(value.toString(), length) 45 | } 46 | 47 | override fun encodeDouble(value: Double) { 48 | encodeNumber(value.toString(), length) 49 | } 50 | 51 | override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) { 52 | val value = enumDescriptor.getElementName(index) 53 | encode(value, length) 54 | } 55 | 56 | override fun encodeFloat(value: Float) { 57 | encodeNumber(value.toString(), length) 58 | } 59 | 60 | override fun encodeInline(descriptor: SerialDescriptor) = this 61 | 62 | override fun encodeInt(value: Int) { 63 | val stringValue = ebcdic?.format?.toString(value) ?: value.toString() 64 | encodeNumber(stringValue.toString(), length) 65 | } 66 | 67 | override fun encodeLong(value: Long) { 68 | val stringValue = ebcdic?.format?.toString(value) ?: value.toString() 69 | encodeNumber(stringValue.toString(), length) 70 | } 71 | 72 | @ExperimentalSerializationApi 73 | override fun encodeNull() { 74 | encode("", length) 75 | } 76 | 77 | override fun encodeShort(value: Short) { 78 | encodeNumber(value.toString(), length) 79 | } 80 | 81 | override fun encodeString(value: String) { 82 | encode(value, length) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /detekt-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CyclomaticComplexMethod:CSVParser.kt$internal fun String.parse( separator: Char = ',', lineSeparator: String = "\n", ): StatefulIterator<CSVNode> 6 | CyclomaticComplexMethod:Ebcdic.kt$internal fun String.toSignedEBCDICZonedDecimal(positive: Boolean): String 7 | CyclomaticComplexMethod:Ebcdic.kt$private fun CharSequence.fromSignedEBCDICZonedDecimal(): Long 8 | LongMethod:CSVParser.kt$internal fun String.parse( separator: Char = ',', lineSeparator: String = "\n", ): StatefulIterator<CSVNode> 9 | LoopWithTooManyJumpStatements:CSVParser.kt$while 10 | MagicNumber:Ebcdic.kt$10 11 | MagicNumber:Ebcdic.kt$3 12 | MagicNumber:Ebcdic.kt$4 13 | MagicNumber:Ebcdic.kt$5 14 | MagicNumber:Ebcdic.kt$6 15 | MagicNumber:Ebcdic.kt$7 16 | MagicNumber:Ebcdic.kt$8 17 | MagicNumber:Ebcdic.kt$9 18 | MatchingDeclarationName:CSVParser.kt$CSVNode 19 | MaxLineLength:CSVEncoder.kt$CSVEncoderImpl$configuration.alwaysEmitQuotes || configuration.separator in valueToAppend || configuration.lineSeparator in valueToAppend 20 | MaxLineLength:CSVParser.kt$currentChar == lineSeparator.first() && substring(index until index + lineSeparator.length) == lineSeparator 21 | MaxLineLength:CsvEncoderTest.kt$CsvEncoderTest$expected = "bar;foo;enum;instant\r\n;42,42;Three;1970-01-01T00:00:00Z\r\nSomething;42,42;Three;1970-01-01T00:00:01Z\r\n;42,42;Three;1970-01-01T00:00:02Z" 22 | MaximumLineLength:CSVEncoder.kt$CSVEncoderImpl$ 23 | MaximumLineLength:CSVParser.kt$ 24 | MaximumLineLength:CsvEncoderTest.kt$CsvEncoderTest$ 25 | NestedBlockDepth:FixedLengthDecoder.kt$FixedLengthDecoder$@ExperimentalSerializationApi internal fun SerialDescriptor.hasInnerListLengthIndex(): Int? 26 | ReturnCount:CSVDecoder.kt$CSVDecoderImpl$override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder 27 | ReturnCount:CSVDecoder.kt$CSVDecoderImpl$override fun decodeElementIndex(descriptor: SerialDescriptor): Int 28 | ReturnCount:CSVParser.kt$@ExperimentalSerializationApi internal fun List<String>.isSequentially(descriptor: SerialDescriptor): Boolean 29 | ReturnCount:StatefulIterator.kt$<no name provided>$override fun peek(): T? 30 | TooManyFunctions:CSVDecoder.kt$CSVDecoderImpl : AbstractDecoderCSVDecoder 31 | TooManyFunctions:FixedLengthDecoder.kt$FixedLengthDecoder : FailingPrimitiveDecoderCompositeDecoder 32 | TooManyFunctions:FixedLengthEncoder.kt$FixedLengthEncoder : FailingPrimitiveEncoderCompositeEncoder 33 | TooManyFunctions:FixedLengthPrimitiveDecoder.kt$FixedLengthPrimitiveDecoder : Decoder 34 | TooManyFunctions:FixedLengthPrimitiveEncoder.kt$FixedLengthPrimitiveEncoder : Encoder 35 | 36 | 37 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH= 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonMain/kotlin/app/softwork/serialization/csv/CSVEncoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.descriptors.SerialDescriptor 5 | import kotlinx.serialization.encoding.AbstractEncoder 6 | import kotlinx.serialization.encoding.CompositeEncoder 7 | import kotlinx.serialization.encoding.Encoder 8 | import kotlinx.serialization.modules.SerializersModule 9 | 10 | public interface CSVEncoder : Encoder, CompositeEncoder { 11 | public val configuration: CSVConfiguration 12 | } 13 | 14 | @ExperimentalSerializationApi 15 | internal class CSVEncoderImpl( 16 | private val builder: StringBuilder, 17 | override val configuration: CSVConfiguration, 18 | ) : AbstractEncoder(), CSVEncoder { 19 | override val serializersModule: SerializersModule 20 | get() = configuration.serializersModule 21 | 22 | private var afterFirst = false 23 | private var level = 0 24 | 25 | override fun encodeValue(value: Any) { 26 | if (afterFirst) { 27 | builder.append(configuration.separator) 28 | } 29 | val valueToAppend = value.toString() 30 | val quote = 31 | configuration.alwaysEmitQuotes || configuration.separator in valueToAppend || configuration.lineSeparator in valueToAppend 32 | if (quote) { 33 | builder.append('"') 34 | builder.append(valueToAppend.escapeQuotes()) 35 | builder.append('"') 36 | } else { 37 | builder.append(valueToAppend) 38 | } 39 | afterFirst = true 40 | } 41 | 42 | override fun encodeDouble(value: Double) { 43 | encodeNumber(value) 44 | } 45 | 46 | override fun encodeFloat(value: Float) { 47 | encodeNumber(value) 48 | } 49 | 50 | private fun encodeNumber(value: Number) { 51 | when (configuration.numberFormat) { 52 | CSVFormat.NumberFormat.Dot -> encodeValue(value) 53 | CSVFormat.NumberFormat.Comma -> encodeValue(value.toString().replace(".", ",")) 54 | } 55 | } 56 | 57 | override fun encodeNull() { 58 | if (afterFirst) { 59 | builder.append(configuration.separator) 60 | } 61 | afterFirst = true 62 | } 63 | 64 | override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder { 65 | if (level == 0) { 66 | if (builder.isNotEmpty()) { 67 | builder.append(configuration.lineSeparator) 68 | } 69 | afterFirst = false 70 | } 71 | level++ 72 | return this 73 | } 74 | 75 | override fun beginCollection(descriptor: SerialDescriptor, collectionSize: Int): CompositeEncoder = this 76 | 77 | override fun endStructure(descriptor: SerialDescriptor) { 78 | level-- 79 | } 80 | 81 | override fun encodeInline(descriptor: SerialDescriptor): Encoder { 82 | if (level == 0) { 83 | builder.append(configuration.lineSeparator) 84 | afterFirst = false 85 | } 86 | return this 87 | } 88 | 89 | override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) { 90 | encodeValue(enumDescriptor.getElementName(index)) 91 | } 92 | } 93 | 94 | internal fun String.escapeQuotes(): String = replace("\"", "\"\"") 95 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/Ebcdic.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerialInfo 5 | import kotlin.math.absoluteValue 6 | 7 | @ExperimentalSerializationApi 8 | @SerialInfo 9 | @Target(AnnotationTarget.PROPERTY) 10 | public annotation class Ebcdic(val format: Format) { 11 | public enum class Format { 12 | 13 | /** 14 | * The integer is converted using each digit. 15 | * Each digit is stored binary using 4 bits (1 nibble). 16 | * ZonedDecimal uses 8 bits (1 byte) or 2 nibbles. 17 | * 18 | * The leading 4 bits (leading nibble) contain the sign: 19 | * 1111 (F) for unsigned digit, 1100 (C) for a positive and 1101 (D) for a negative one. 20 | * 21 | * The sign of the integer is only stored in the last digit. 22 | * 23 | * 1234 (unsigned) results into xF1F2F3F4. 24 | * +1234 (signed) results into xF1F2F3C4. 25 | * -1234 (signed) results into xF1F2F3D4. 26 | * 27 | * The hex value is stored in EBCDIC (IBM-1047). 28 | */ 29 | Zoned { 30 | override fun toInt(string: CharSequence): Int = toLong(string).toInt() 31 | 32 | override fun toLong(string: CharSequence): Long = 33 | string.fromSignedEBCDICZonedDecimal() 34 | 35 | override fun toString(value: Int): String { 36 | val positive = value >= 0 37 | val toString = value.absoluteValue.toString() 38 | return toString.toSignedEBCDICZonedDecimal(positive) 39 | } 40 | 41 | override fun toString(value: Long): String { 42 | val positive = value >= 0 43 | val toString = value.absoluteValue.toString() 44 | return toString.toSignedEBCDICZonedDecimal(positive) 45 | } 46 | }; 47 | 48 | internal abstract fun toInt(string: CharSequence): Int 49 | internal abstract fun toLong(string: CharSequence): Long 50 | 51 | internal abstract fun toString(value: Int): CharSequence 52 | internal abstract fun toString(value: Long): CharSequence 53 | } 54 | } 55 | 56 | internal fun String.toSignedEBCDICZonedDecimal(positive: Boolean): String { 57 | val last = when (last()) { 58 | '1' -> if (positive) 'A' else 'J' 59 | '2' -> if (positive) 'B' else 'K' 60 | '3' -> if (positive) 'C' else 'L' 61 | '4' -> if (positive) 'D' else 'M' 62 | '5' -> if (positive) 'E' else 'N' 63 | '6' -> if (positive) 'F' else 'O' 64 | '7' -> if (positive) 'G' else 'P' 65 | '8' -> if (positive) 'H' else 'Q' 66 | '9' -> if (positive) 'I' else 'R' 67 | '0' -> if (positive) '{' else '}' 68 | else -> error("No digit") 69 | } 70 | val start = subSequence(0, lastIndex) 71 | return "$start$last" 72 | } 73 | 74 | private fun CharSequence.fromSignedEBCDICZonedDecimal(): Long { 75 | var result = substring(0, lastIndex).toLongOrNull()?.times(10) ?: 0 76 | when (last()) { 77 | '{' -> {} // positive 0 78 | 'A' -> result += 1 79 | 'B' -> result += 2 80 | 'C' -> result += 3 81 | 'D' -> result += 4 82 | 'E' -> result += 5 83 | 'F' -> result += 6 84 | 'G' -> result += 7 85 | 'H' -> result += 8 86 | 'I' -> result += 9 87 | '}' -> { // negative 0 88 | result *= -1 89 | } 90 | 'J' -> { 91 | result += 1 92 | result *= -1 93 | } 94 | 95 | 'K' -> { 96 | result += 2 97 | result *= -1 98 | } 99 | 100 | 'L' -> { 101 | result += 3 102 | result *= -1 103 | } 104 | 105 | 'M' -> { 106 | result += 4 107 | result *= -1 108 | } 109 | 110 | 'N' -> { 111 | result += 5 112 | result *= -1 113 | } 114 | 115 | 'O' -> { 116 | result += 6 117 | result *= -1 118 | } 119 | 120 | 'P' -> { 121 | result += 7 122 | result *= -1 123 | } 124 | 125 | 'Q' -> { 126 | result += 8 127 | result *= -1 128 | } 129 | 130 | 'R' -> { 131 | result += 9 132 | result *= -1 133 | } 134 | } 135 | return result 136 | } 137 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/api/kotlinx-serialization-csv.api: -------------------------------------------------------------------------------- 1 | public final class app/softwork/serialization/csv/CSVConfiguration { 2 | public final fun getAlwaysEmitQuotes ()Z 3 | public final fun getIncludeHeader ()Z 4 | public final fun getLineSeparator ()Ljava/lang/String; 5 | public final fun getNumberFormat ()Lapp/softwork/serialization/csv/CSVFormat$NumberFormat; 6 | public final fun getSeparator ()C 7 | public final fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 8 | } 9 | 10 | public final class app/softwork/serialization/csv/CSVConfiguration$Builder { 11 | public fun ()V 12 | public final fun getAlwaysEmitQuotes ()Z 13 | public final fun getIncludeHeader ()Z 14 | public final fun getLineSeparator ()Ljava/lang/String; 15 | public final fun getNumberFormat ()Lapp/softwork/serialization/csv/CSVFormat$NumberFormat; 16 | public final fun getSeparator ()C 17 | public final fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 18 | public final fun setAlwaysEmitQuotes (Z)V 19 | public final fun setIncludeHeader (Z)V 20 | public final fun setLineSeparator (Ljava/lang/String;)V 21 | public final fun setNumberFormat (Lapp/softwork/serialization/csv/CSVFormat$NumberFormat;)V 22 | public final fun setSeparator (C)V 23 | public final fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V 24 | } 25 | 26 | public abstract interface class app/softwork/serialization/csv/CSVDecoder : kotlinx/serialization/encoding/CompositeDecoder, kotlinx/serialization/encoding/Decoder { 27 | public abstract fun getConfiguration ()Lapp/softwork/serialization/csv/CSVConfiguration; 28 | } 29 | 30 | public final class app/softwork/serialization/csv/CSVDecoder$DefaultImpls { 31 | public static fun decodeCollectionSize (Lapp/softwork/serialization/csv/CSVDecoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)I 32 | public static fun decodeNullableSerializableValue (Lapp/softwork/serialization/csv/CSVDecoder;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; 33 | public static fun decodeSequentially (Lapp/softwork/serialization/csv/CSVDecoder;)Z 34 | public static fun decodeSerializableValue (Lapp/softwork/serialization/csv/CSVDecoder;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; 35 | } 36 | 37 | public abstract interface class app/softwork/serialization/csv/CSVEncoder : kotlinx/serialization/encoding/CompositeEncoder, kotlinx/serialization/encoding/Encoder { 38 | public abstract fun getConfiguration ()Lapp/softwork/serialization/csv/CSVConfiguration; 39 | } 40 | 41 | public final class app/softwork/serialization/csv/CSVEncoder$DefaultImpls { 42 | public static fun beginCollection (Lapp/softwork/serialization/csv/CSVEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/CompositeEncoder; 43 | public static fun encodeNotNullMark (Lapp/softwork/serialization/csv/CSVEncoder;)V 44 | public static fun encodeNullableSerializableValue (Lapp/softwork/serialization/csv/CSVEncoder;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 45 | public static fun encodeSerializableValue (Lapp/softwork/serialization/csv/CSVEncoder;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 46 | public static fun shouldEncodeElementDefault (Lapp/softwork/serialization/csv/CSVEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z 47 | } 48 | 49 | public abstract class app/softwork/serialization/csv/CSVFormat : kotlinx/serialization/StringFormat { 50 | public static final field Default Lapp/softwork/serialization/csv/CSVFormat$Default; 51 | public synthetic fun (Lapp/softwork/serialization/csv/CSVConfiguration;Lkotlin/jvm/internal/DefaultConstructorMarker;)V 52 | public fun decodeFromString (Lkotlinx/serialization/DeserializationStrategy;Ljava/lang/String;)Ljava/lang/Object; 53 | public fun encodeToString (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ljava/lang/String; 54 | public final fun getConfiguration ()Lapp/softwork/serialization/csv/CSVConfiguration; 55 | public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 56 | } 57 | 58 | public final class app/softwork/serialization/csv/CSVFormat$Default : app/softwork/serialization/csv/CSVFormat { 59 | public final fun invoke (Lkotlin/jvm/functions/Function1;)Lapp/softwork/serialization/csv/CSVFormat; 60 | } 61 | 62 | public final class app/softwork/serialization/csv/CSVFormat$NumberFormat : java/lang/Enum { 63 | public static final field Comma Lapp/softwork/serialization/csv/CSVFormat$NumberFormat; 64 | public static final field Dot Lapp/softwork/serialization/csv/CSVFormat$NumberFormat; 65 | public static fun getEntries ()Lkotlin/enums/EnumEntries; 66 | public static fun valueOf (Ljava/lang/String;)Lapp/softwork/serialization/csv/CSVFormat$NumberFormat; 67 | public static fun values ()[Lapp/softwork/serialization/csv/CSVFormat$NumberFormat; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonTest/kotlin/app/softwork/serialization/flf/Sample.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerialName 5 | import kotlinx.serialization.Serializable 6 | import kotlin.jvm.JvmInline 7 | import kotlin.time.Instant 8 | 9 | @ExperimentalSerializationApi 10 | @Serializable 11 | data class Sample( 12 | @FixedLength(5) val shortString: String, 13 | @FixedLength(10) val longString: String, 14 | @FixedLength(4) val int: Int, 15 | @FixedLength(4) val double: Double, 16 | @FixedLength(4) val nil: Double?, 17 | @FixedLength(20) val date: Instant, 18 | @FixedLength(5) val enum: Testing, 19 | @FixedLength(3) val inline: Foo, 20 | @FixedLength(3) val inlineS: FooS, 21 | @FixedLength(3) val inlineD: FooD, 22 | @FixedLength(4) val inlineB: FooB, 23 | @FixedLength(3) val inlineL: FooL, 24 | @FixedLength(1) val inlineChar: FooChar, 25 | @FixedLength(1) val inlineShort: FooShort, 26 | @FixedLength(3) val inlineFloat: FooFloat, 27 | @FixedLength(1) val inlineByte: FooByte, 28 | val innerClass: Inner, 29 | 30 | @FixedLength(5) val boolean: Boolean, 31 | @FixedLength(4) val byte: Byte, 32 | @FixedLength(4) val short: Short, 33 | // https://youtrack.jetbrains.com/issue/KT-68948/Wasm-float-from-variable-is-printed-with-many-decimal-points 34 | @FixedLength(4) val float: Double, 35 | @FixedLength(4) val long: Long, 36 | @FixedLength(1) val char: Char 37 | ) { 38 | companion object { 39 | val simple = Sample( 40 | shortString = "Short", 41 | longString = "Long", 42 | int = 42, 43 | double = 42.3, 44 | nil = null, 45 | date = Instant.fromEpochSeconds(0L), 46 | enum = Testing.Two, 47 | inline = Foo(1), 48 | inlineS = FooS("foo"), 49 | inlineD = FooD(4.2), 50 | inlineB = FooB(true), 51 | inlineL = FooL(0L), 52 | inlineChar = FooChar('f'), 53 | inlineShort = FooShort(4.toShort()), 54 | inlineFloat = FooFloat(1.1), 55 | inlineByte = FooByte(1.toByte()), 56 | innerClass = Inner(8), 57 | boolean = false, 58 | byte = 1.toByte(), 59 | short = 1.toShort(), 60 | float = 4.2, 61 | long = -1L, 62 | char = ' ' 63 | ) 64 | } 65 | 66 | @Serializable 67 | enum class Testing { 68 | One, Two, Three 69 | } 70 | 71 | @Serializable 72 | data class Inner( 73 | @FixedLength(1) val s: Int 74 | ) 75 | 76 | @Serializable 77 | @JvmInline 78 | value class Foo(val int: Int) 79 | 80 | @Serializable 81 | @JvmInline 82 | value class FooS(val int: String) 83 | 84 | @Serializable 85 | @JvmInline 86 | value class FooD(val int: Double) 87 | 88 | @Serializable 89 | @JvmInline 90 | value class FooB(val int: Boolean) 91 | 92 | @Serializable 93 | @JvmInline 94 | value class FooL(val int: Long) 95 | 96 | @Serializable 97 | @JvmInline 98 | value class FooShort(val int: Short) 99 | 100 | @Serializable 101 | @JvmInline 102 | value class FooByte(val int: Byte) 103 | 104 | @Serializable 105 | @JvmInline 106 | value class FooChar(val int: Char) 107 | 108 | // https://youtrack.jetbrains.com/issue/KT-68948/Wasm-float-from-variable-is-printed-with-many-decimal-points 109 | @Serializable 110 | @JvmInline 111 | value class FooFloat(val int: Double) 112 | } 113 | 114 | @ExperimentalSerializationApi 115 | @Serializable 116 | data class Small( 117 | @FixedLength(1) val s: String? 118 | ) 119 | 120 | @Serializable 121 | data class Missing(val s: Int) 122 | 123 | @ExperimentalSerializationApi 124 | @Serializable 125 | data class InnerList( 126 | @FixedLength(1) val count: Int, 127 | @FixedLength(3) val foo: String, 128 | @FixedLengthList(serialName = "count") val s: List 129 | ) 130 | 131 | @ExperimentalSerializationApi 132 | @Serializable 133 | data class InnerListFailing( 134 | @FixedLength(3) val foo: String, 135 | @FixedLengthList(serialName = "count") val s: List, 136 | @FixedLength(1) val count: Int 137 | ) 138 | 139 | @ExperimentalSerializationApi 140 | @Serializable 141 | @FixedLengthSealedClassDiscriminatorLength(1) 142 | sealed class Seal { 143 | abstract val s: Int 144 | 145 | @SerialName("A") 146 | @ExperimentalSerializationApi 147 | @Serializable 148 | data class A( 149 | @FixedLength(2) 150 | val a: Int, 151 | @FixedLength(4) 152 | override val s: Int 153 | ) : Seal() 154 | 155 | @SerialName("B") 156 | @ExperimentalSerializationApi 157 | @Serializable 158 | data class B( 159 | @FixedLength(10) 160 | val b: String, 161 | @FixedLength(4) 162 | override val s: Int 163 | ) : Seal() 164 | } 165 | 166 | @ExperimentalSerializationApi 167 | @Serializable 168 | data class SealedWithProperty( 169 | @FixedLength(2) 170 | val type: String, 171 | @FixedLength(2) 172 | val s: Int, 173 | @FixedLengthSealedClassDiscriminator(serialName = "type") 174 | val sealed: Seal 175 | ) 176 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonMain/kotlin/app/softwork/serialization/csv/CSVFormat.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import app.softwork.serialization.csv.CSVFormat.NumberFormat 4 | import kotlinx.serialization.DeserializationStrategy 5 | import kotlinx.serialization.ExperimentalSerializationApi 6 | import kotlinx.serialization.SerializationStrategy 7 | import kotlinx.serialization.StringFormat 8 | import kotlinx.serialization.descriptors.StructureKind 9 | import kotlinx.serialization.modules.EmptySerializersModule 10 | import kotlinx.serialization.modules.SerializersModule 11 | import kotlin.native.concurrent.ThreadLocal 12 | 13 | /** 14 | * [RFC-4180](https://datatracker.ietf.org/doc/html/rfc4180) 15 | */ 16 | @ExperimentalSerializationApi 17 | public sealed class CSVFormat(public val configuration: CSVConfiguration) : StringFormat { 18 | 19 | override val serializersModule: SerializersModule get() = configuration.serializersModule 20 | 21 | public enum class NumberFormat { 22 | Dot, Comma, 23 | } 24 | 25 | internal class Custom internal constructor( 26 | configuration: CSVConfiguration 27 | ) : CSVFormat(configuration) 28 | 29 | @ThreadLocal 30 | public companion object Default : CSVFormat(CSVConfiguration.default) { 31 | public operator fun invoke(builder: CSVConfiguration.Builder.() -> Unit): CSVFormat = 32 | Custom(CSVConfiguration.Builder().apply(builder).build()) 33 | } 34 | 35 | override fun decodeFromString(deserializer: DeserializationStrategy, string: String): T { 36 | deserializer.descriptor.checkForLists() 37 | val parsed = string.parse(configuration.separator, configuration.lineSeparator) 38 | 39 | return if (configuration.includeHeader) { 40 | val headers = parsed.getHeader() 41 | val isSequentially = headers.isSequentially(deserializer.descriptor) 42 | deserializer.deserialize( 43 | decoder = CSVDecoderImpl( 44 | header = headers, 45 | nodes = parsed, 46 | configuration = configuration, 47 | decodesSequentially = isSequentially, 48 | level = if (deserializer.descriptor.kind is StructureKind.LIST) -1 else 0, 49 | ) 50 | ) 51 | } else { 52 | val decodesSequentially = deserializer.descriptor.kind !is StructureKind.LIST 53 | deserializer.deserialize( 54 | decoder = CSVDecoderImpl( 55 | header = emptyList(), 56 | nodes = parsed, 57 | configuration = configuration, 58 | decodesSequentially = decodesSequentially, 59 | level = if (deserializer.descriptor.kind is StructureKind.LIST) -1 else 0, 60 | ) 61 | ) 62 | } 63 | } 64 | 65 | override fun encodeToString(serializer: SerializationStrategy, value: T): String = buildString { 66 | serializer.descriptor.checkForLists() 67 | 68 | if (configuration.includeHeader) { 69 | serializer.descriptor.checkForPolymorphicClasses() 70 | for (header in serializer.descriptor.flatNames) { 71 | if (isNotEmpty()) { 72 | append(configuration.separator) 73 | } 74 | if (configuration.alwaysEmitQuotes) { 75 | append('"') 76 | append(header.escapeQuotes()) 77 | append('"') 78 | } else { 79 | append(header) 80 | } 81 | } 82 | } 83 | 84 | serializer.serialize( 85 | encoder = CSVEncoderImpl(this, configuration), 86 | value = value 87 | ) 88 | } 89 | } 90 | 91 | @OptIn(ExperimentalSerializationApi::class) 92 | public class CSVConfiguration internal constructor( 93 | public val separator: Char, 94 | public val lineSeparator: String, 95 | public val includeHeader: Boolean, 96 | public val alwaysEmitQuotes: Boolean, 97 | public val numberFormat: NumberFormat, 98 | public val serializersModule: SerializersModule, 99 | ) { 100 | internal companion object { 101 | internal val default: CSVConfiguration = CSVConfiguration( 102 | separator = ',', 103 | lineSeparator = "\n", 104 | includeHeader = true, 105 | alwaysEmitQuotes = false, 106 | numberFormat = NumberFormat.Dot, 107 | serializersModule = EmptySerializersModule(), 108 | ) 109 | } 110 | 111 | public class Builder { 112 | public var separator: Char = default.separator 113 | public var lineSeparator: String = default.lineSeparator 114 | public var includeHeader: Boolean = default.includeHeader 115 | public var alwaysEmitQuotes: Boolean = default.alwaysEmitQuotes 116 | public var numberFormat: NumberFormat = default.numberFormat 117 | public var serializersModule: SerializersModule = default.serializersModule 118 | 119 | internal fun build(): CSVConfiguration = CSVConfiguration( 120 | separator = separator, 121 | lineSeparator = lineSeparator, 122 | includeHeader = includeHeader, 123 | alwaysEmitQuotes = alwaysEmitQuotes, 124 | numberFormat = numberFormat, 125 | serializersModule = serializersModule, 126 | ) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonMain/kotlin/app/softwork/serialization/csv/CSVParser.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerializationException 5 | import kotlinx.serialization.descriptors.SerialDescriptor 6 | import kotlinx.serialization.descriptors.StructureKind 7 | import kotlin.jvm.JvmInline 8 | 9 | internal sealed interface CSVNode { 10 | @JvmInline 11 | value class Element(val value: String) : CSVNode 12 | data object NewLine : CSVNode 13 | } 14 | 15 | internal fun String.parse( 16 | separator: Char = ',', 17 | lineSeparator: String = "\n", 18 | ): StatefulIterator = iterator { 19 | var index = 0 20 | 21 | main@ while (true) { 22 | if (index >= length) { 23 | return@iterator 24 | } 25 | 26 | val start = index 27 | when (getOrNull(index)) { 28 | null -> return@iterator 29 | 30 | separator -> { 31 | yield(CSVNode.Element("")) 32 | index += 1 33 | } 34 | 35 | else -> { 36 | normal@ while (true) { 37 | val currentChar = getOrNull(index) 38 | when { 39 | currentChar == '"' -> { 40 | var indexOfClosingQuotes = index + 1 41 | escaping@ while (true) { 42 | val nextChar = getOrNull(indexOfClosingQuotes) 43 | when (nextChar) { 44 | '"' -> { 45 | if (indexOfClosingQuotes == lastIndex) { 46 | val text = substring(start + 1, indexOfClosingQuotes).replace( 47 | oldValue = "\"\"", 48 | newValue = "\"" 49 | ) 50 | val node = CSVNode.Element(text) 51 | yield(node) 52 | return@iterator 53 | } else { 54 | val following = get(indexOfClosingQuotes + 1) 55 | if (following == '"') { 56 | indexOfClosingQuotes += 1 57 | } else { 58 | index = indexOfClosingQuotes + 1 59 | break@escaping 60 | } 61 | } 62 | } 63 | 64 | null -> throw SerializationException( 65 | "Missing end of quotes at ${indexOfClosingQuotes - 1}" 66 | ) 67 | } 68 | indexOfClosingQuotes += 1 69 | } 70 | } 71 | 72 | currentChar == null -> { 73 | val node = CSVNode.Element(substring(start, index)) 74 | yield(node) 75 | break@main 76 | } 77 | 78 | currentChar == separator -> { 79 | yield(createNode(start, index)) 80 | index += 1 81 | break@normal 82 | } 83 | 84 | currentChar == lineSeparator.first() && substring(index until index + lineSeparator.length) == lineSeparator -> { 85 | yield(createNode(start, index)) 86 | index += lineSeparator.length 87 | yield(CSVNode.NewLine) 88 | break@normal 89 | } 90 | 91 | else -> index += 1 92 | } 93 | } 94 | } 95 | } 96 | } 97 | }.stateful() 98 | 99 | private fun String.createNode(start: Int, index: Int): CSVNode.Element { 100 | val text = if (get(start) == '"' && get(index - 1) == '"') { 101 | substring(start + 1, index - 1).replace(oldValue = "\"\"", newValue = "\"") 102 | } else { 103 | substring(start, index) 104 | } 105 | return CSVNode.Element(text) 106 | } 107 | 108 | internal fun Iterator.getHeader(): List = buildList { 109 | for (node in this@getHeader) { 110 | when (node) { 111 | is CSVNode.Element -> add(node.value) 112 | CSVNode.NewLine -> break 113 | } 114 | } 115 | } 116 | 117 | @ExperimentalSerializationApi 118 | internal fun List.isSequentially(descriptor: SerialDescriptor): Boolean { 119 | if (descriptor.kind is StructureKind.CLASS) { 120 | for ((index, expectedName) in descriptor.flatNames.withIndex()) { 121 | val actualName = getOrNull(index) 122 | if (actualName == null) { 123 | return false 124 | } 125 | if (actualName != expectedName) { 126 | return false 127 | } 128 | } 129 | 130 | return true 131 | } else { 132 | return false 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /gradle/build-logic/src/main/kotlin/mpp.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:OptIn(ExperimentalAbiValidation::class) 2 | 3 | import org.gradle.kotlin.dsl.invoke 4 | import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation 5 | 6 | plugins { 7 | kotlin("multiplatform") 8 | kotlin("plugin.serialization") 9 | id("maven-publish") 10 | id("signing") 11 | id("io.github.hfhbd.mavencentral") 12 | id("org.jetbrains.dokka") 13 | id("app.cash.licensee") 14 | } 15 | 16 | kotlin { 17 | jvmToolchain(8) 18 | 19 | explicitApi() 20 | compilerOptions { 21 | allWarningsAsErrors.set(true) 22 | progressiveMode.set(true) 23 | extraWarnings.set(true) 24 | 25 | optIn.add("kotlin.time.ExperimentalTime") 26 | } 27 | 28 | abiValidation { 29 | enabled.set(true) 30 | } 31 | 32 | jvm { 33 | val main = compilations.getByName("main") 34 | val jvm9 = compilations.create("9Main") { 35 | associateWith(main) 36 | } 37 | tasks.named(artifactsTaskName, Jar::class) { 38 | from(jvm9.output.allOutputs) { 39 | into("META-INF/versions/9") 40 | } 41 | manifest { 42 | manifest.attributes("Multi-Release" to true) 43 | } 44 | } 45 | } 46 | 47 | js { 48 | nodejs() 49 | } 50 | wasmJs { 51 | nodejs() 52 | } 53 | wasmWasi { 54 | nodejs() 55 | } 56 | 57 | // tier 1 58 | linuxX64() 59 | macosX64() 60 | macosArm64() 61 | iosSimulatorArm64() 62 | iosX64() 63 | 64 | // tier 2 65 | linuxArm64() 66 | watchosSimulatorArm64() 67 | watchosX64() 68 | watchosArm32() 69 | watchosArm64() 70 | tvosSimulatorArm64() 71 | tvosX64() 72 | tvosArm64() 73 | iosArm64() 74 | 75 | // tier 3 76 | androidNativeArm32() 77 | androidNativeArm64() 78 | androidNativeX86() 79 | androidNativeX64() 80 | mingwX64() 81 | watchosDeviceArm64() 82 | 83 | sourceSets { 84 | commonTest { 85 | dependencies { 86 | implementation(kotlin("test")) 87 | } 88 | } 89 | } 90 | } 91 | 92 | tasks.check { 93 | dependsOn(tasks.checkLegacyAbi) 94 | } 95 | 96 | tasks.named("compileJvm9MainJava") { 97 | javaCompiler.set(javaToolchains.compilerFor {}) 98 | options.release.set(9) 99 | } 100 | 101 | plugins.withType { 102 | the().downloadBaseUrl.set(null) 103 | } 104 | plugins.withType { 105 | the().downloadBaseUrl.set(null) 106 | } 107 | 108 | val emptyJar by tasks.registering(Jar::class) 109 | 110 | publishing { 111 | publications.withType(MavenPublication::class).configureEach { 112 | artifact(emptyJar) { 113 | classifier = "javadoc" 114 | } 115 | pom { 116 | name.set("app.softwork CSV and FLF kotlinx.serialization") 117 | description.set("A multiplatform Kotlin CSV and FLF kotlinx.serialization library") 118 | url.set("https://github.com/hfhbd/kotlinx-serialization-csv") 119 | licenses { 120 | license { 121 | name.set("Apache-2.0") 122 | url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") 123 | } 124 | } 125 | developers { 126 | developer { 127 | id.set("hfhbd") 128 | name.set("Philip Wedemann") 129 | email.set("mybztg+mavencentral@icloud.com") 130 | } 131 | } 132 | scm { 133 | connection.set("scm:git://github.com/hfhbd/kotlinx-serialization-csv.git") 134 | developerConnection.set("scm:git://github.com/hfhbd/kotlinx-serialization-csv.git") 135 | url.set("https://github.com/hfhbd/kotlinx-serialization-csv") 136 | } 137 | } 138 | } 139 | } 140 | 141 | signing { 142 | val signingKey = providers.gradleProperty("signingKey") 143 | if (signingKey.isPresent) { 144 | useInMemoryPgpKeys(signingKey.get(), providers.gradleProperty("signingPassword").get()) 145 | sign(publishing.publications) 146 | } 147 | } 148 | 149 | // https://youtrack.jetbrains.com/issue/KT-46466 150 | val signingTasks = tasks.withType() 151 | tasks.withType().configureEach { 152 | dependsOn(signingTasks) 153 | } 154 | 155 | licensee { 156 | allow("Apache-2.0") 157 | } 158 | 159 | dokka { 160 | val module = project.name 161 | dokkaSourceSets.configureEach { 162 | includes.from("README.md") 163 | reportUndocumented.set(true) 164 | val sourceSetName = name 165 | File("$module/src/$sourceSetName").takeIf { it.exists() }?.let { 166 | sourceLink { 167 | localDirectory.set(file("src/$sourceSetName/kotlin")) 168 | remoteUrl.set(uri("https://github.com/hfhbd/kotlinx-serialization-csv/tree/main/$module/src/$sourceSetName/kotlin")) 169 | remoteLineSuffix.set("#L") 170 | } 171 | } 172 | externalDocumentationLinks { 173 | register("kotlinx.serialization") { 174 | url("https://kotlinlang.org/api/kotlinx.serialization/") 175 | } 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonTest/kotlin/app/softwork/serialization/flf/EbcdicTest.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import app.softwork.serialization.flf.Ebcdic.Format.Zoned 4 | import kotlinx.serialization.ExperimentalSerializationApi 5 | import kotlinx.serialization.Serializable 6 | import kotlinx.serialization.json.Json 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | 10 | @ExperimentalSerializationApi 11 | class EbcdicTest { 12 | 13 | @Serializable 14 | data class Formatting( 15 | @Ebcdic(Zoned) 16 | @FixedLength(4) 17 | val positive: Int, 18 | 19 | @Ebcdic(Zoned) 20 | @FixedLength(4) 21 | val negative: Int, 22 | 23 | @FixedLength(4) 24 | val unsigned: UInt, 25 | 26 | @FixedLength(4) 27 | val normal: Int 28 | ) 29 | 30 | @Test 31 | fun encode() { 32 | val value = Formatting( 33 | positive = 42, 34 | negative = -42, 35 | unsigned = 42u, 36 | normal = 42 37 | ) 38 | 39 | assertEquals( 40 | """ 41 | |{"positive":42,"negative":-42,"unsigned":42,"normal":42} 42 | """.trimMargin(), 43 | Json.encodeToString( 44 | serializer = Formatting.serializer(), 45 | value = value 46 | ) 47 | ) 48 | 49 | assertEquals( 50 | expected = """ 51 | |004B004K00420042 52 | """.trimMargin(), 53 | actual = FixedLengthFormat.encodeToString( 54 | serializer = Formatting.serializer(), 55 | value = value 56 | ) 57 | ) 58 | } 59 | 60 | @Test 61 | fun decode() { 62 | val value = Formatting( 63 | positive = 42, 64 | negative = -42, 65 | unsigned = 42u, 66 | normal = 42 67 | ) 68 | 69 | assertEquals( 70 | value, 71 | Json.decodeFromString( 72 | deserializer = Formatting.serializer(), 73 | """ 74 | |{"positive":42,"negative":-42,"unsigned":42,"normal":42} 75 | """.trimMargin() 76 | ) 77 | ) 78 | 79 | assertEquals( 80 | expected = value, 81 | actual = FixedLengthFormat.decodeFromString( 82 | deserializer = Formatting.serializer(), 83 | """ 84 | |004B004K00420042 85 | """.trimMargin(), 86 | ) 87 | ) 88 | } 89 | 90 | @Test 91 | fun zonedToString() { 92 | assertEquals("123D", Zoned.toString(1234)) 93 | assertEquals("123M", Zoned.toString(-1234)) 94 | 95 | assertEquals("1N", Zoned.toString(-15)) 96 | assertEquals("150{", Zoned.toString(1500)) 97 | 98 | assertEquals("1M", Zoned.toString(-14)) 99 | assertEquals("140{", Zoned.toString(1400)) 100 | 101 | assertEquals("1L", Zoned.toString(-13)) 102 | assertEquals("130{", Zoned.toString(1300)) 103 | 104 | assertEquals("1K", Zoned.toString(-12)) 105 | assertEquals("120{", Zoned.toString(1200)) 106 | 107 | assertEquals("1J", Zoned.toString(-11)) 108 | assertEquals("110{", Zoned.toString(1100)) 109 | 110 | assertEquals("1}", Zoned.toString(-10)) 111 | assertEquals("100{", Zoned.toString(1000)) 112 | 113 | assertEquals("R", Zoned.toString(-9)) 114 | assertEquals("90{", Zoned.toString(900)) 115 | 116 | assertEquals("Q", Zoned.toString(-8)) 117 | assertEquals("80{", Zoned.toString(800)) 118 | 119 | assertEquals("P", Zoned.toString(-7)) 120 | assertEquals("70{", Zoned.toString(700)) 121 | 122 | assertEquals("O", Zoned.toString(-6)) 123 | assertEquals("60{", Zoned.toString(600)) 124 | 125 | assertEquals("N", Zoned.toString(-5)) 126 | assertEquals("50{", Zoned.toString(500)) 127 | 128 | assertEquals("M", Zoned.toString(-4)) 129 | assertEquals("40{", Zoned.toString(400)) 130 | 131 | assertEquals("L", Zoned.toString(-3)) 132 | assertEquals("30{", Zoned.toString(300)) 133 | 134 | assertEquals("K", Zoned.toString(-2)) 135 | assertEquals("20{", Zoned.toString(200)) 136 | 137 | assertEquals("J", Zoned.toString(-1)) 138 | assertEquals("10{", Zoned.toString(100)) 139 | 140 | assertEquals("{", Zoned.toString(0)) 141 | assertEquals("{", Zoned.toString(0L)) 142 | } 143 | 144 | @Test 145 | fun zonedFromString() { 146 | assertEquals(1234, Zoned.toInt("123D")) 147 | assertEquals(-1234, Zoned.toInt("123M")) 148 | 149 | assertEquals(-15, Zoned.toInt("1N")) 150 | assertEquals(1500, Zoned.toInt("150{")) 151 | 152 | assertEquals(-14, Zoned.toInt("1M")) 153 | assertEquals(1400, Zoned.toInt("140{")) 154 | 155 | assertEquals(-13, Zoned.toInt("1L")) 156 | assertEquals(1300, Zoned.toInt("130{")) 157 | 158 | assertEquals(-12, Zoned.toInt("1K")) 159 | assertEquals(1200, Zoned.toInt("120{")) 160 | 161 | assertEquals(-11, Zoned.toInt("1J")) 162 | assertEquals(1100, Zoned.toInt("110{")) 163 | 164 | assertEquals(-10, Zoned.toInt("1}")) 165 | assertEquals(1000, Zoned.toInt("100{")) 166 | 167 | assertEquals(-9, Zoned.toInt("R")) 168 | assertEquals(900, Zoned.toInt("90{")) 169 | 170 | assertEquals(-8, Zoned.toInt("Q")) 171 | assertEquals(800, Zoned.toInt("80{")) 172 | 173 | assertEquals(-7, Zoned.toInt("P")) 174 | assertEquals(700, Zoned.toInt("70{")) 175 | 176 | assertEquals(-6, Zoned.toInt("O")) 177 | assertEquals(600, Zoned.toInt("60{")) 178 | 179 | assertEquals(-5, Zoned.toInt("N")) 180 | assertEquals(500, Zoned.toInt("50{")) 181 | 182 | assertEquals(-4, Zoned.toInt("M")) 183 | assertEquals(400, Zoned.toInt("40{")) 184 | 185 | assertEquals(-3, Zoned.toInt("L")) 186 | assertEquals(300, Zoned.toInt("30{")) 187 | 188 | assertEquals(-2, Zoned.toInt("K")) 189 | assertEquals(200, Zoned.toInt("20{")) 190 | 191 | assertEquals(-1, Zoned.toInt("J")) 192 | assertEquals(100, Zoned.toInt("10{")) 193 | 194 | assertEquals(0, Zoned.toInt("{")) 195 | assertEquals(0, Zoned.toInt("}")) 196 | assertEquals(0L, Zoned.toLong("{")) 197 | assertEquals(0L, Zoned.toLong("}")) 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonMain/kotlin/app/softwork/serialization/csv/CSVDecoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import kotlinx.serialization.DeserializationStrategy 4 | import kotlinx.serialization.ExperimentalSerializationApi 5 | import kotlinx.serialization.SerializationException 6 | import kotlinx.serialization.descriptors.PolymorphicKind 7 | import kotlinx.serialization.descriptors.SerialDescriptor 8 | import kotlinx.serialization.descriptors.StructureKind 9 | import kotlinx.serialization.descriptors.elementNames 10 | import kotlinx.serialization.encoding.AbstractDecoder 11 | import kotlinx.serialization.encoding.CompositeDecoder 12 | import kotlinx.serialization.encoding.Decoder 13 | import kotlinx.serialization.modules.SerializersModule 14 | 15 | public interface CSVDecoder : Decoder, CompositeDecoder { 16 | public val configuration: CSVConfiguration 17 | } 18 | 19 | @ExperimentalSerializationApi 20 | internal class CSVDecoderImpl( 21 | private val header: List, 22 | private val nodes: StatefulIterator, 23 | override val configuration: CSVConfiguration, 24 | val decodesSequentially: Boolean, 25 | private val level: Int, 26 | ) : AbstractDecoder(), CSVDecoder { 27 | 28 | private var index = 0 29 | private var currentRow = 0 30 | 31 | override val serializersModule: SerializersModule get() = configuration.serializersModule 32 | 33 | override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder { 34 | when (descriptor.kind) { 35 | StructureKind.CLASS -> { 36 | val (nextHeaders, isSequentially) = if (configuration.includeHeader) { 37 | val nextHeaders = header.subList(index, header.size) 38 | nextHeaders to nextHeaders.isSequentially(descriptor) 39 | } else { 40 | header to true 41 | } 42 | return CSVDecoderImpl( 43 | header = nextHeaders, 44 | nodes = nodes, 45 | configuration = configuration, 46 | decodesSequentially = isSequentially, 47 | level = level + 1, 48 | ) 49 | } 50 | 51 | PolymorphicKind.SEALED -> { 52 | return CSVDecoderImpl( 53 | header = header, 54 | nodes = nodes, 55 | configuration = configuration, 56 | decodesSequentially = true, 57 | level = level, 58 | ) 59 | } 60 | 61 | else -> { 62 | return CSVDecoderImpl( 63 | header = header, 64 | nodes = nodes, 65 | configuration = configuration, 66 | decodesSequentially = false, 67 | level = level, 68 | ) 69 | } 70 | } 71 | } 72 | 73 | override fun decodeNotNullMark(): Boolean { 74 | val isNotNull = when (val nextValue = nodes.peek()) { 75 | is CSVNode.Element -> nextValue.value.isNotEmpty() 76 | CSVNode.NewLine -> false 77 | null -> false 78 | } 79 | return isNotNull 80 | } 81 | 82 | override tailrec fun endStructure(descriptor: SerialDescriptor) { 83 | val next = nodes.peek() 84 | when (next) { 85 | is CSVNode.Element -> { 86 | if (level == 0) { 87 | nodes.next() 88 | endStructure(descriptor) 89 | } 90 | } 91 | 92 | CSVNode.NewLine -> nodes.next() 93 | null -> {} 94 | } 95 | } 96 | 97 | override fun decodeNull(): Nothing? { 98 | when (nodes.peek()) { 99 | is CSVNode.Element -> nodes.next() 100 | CSVNode.NewLine -> Unit 101 | null -> Unit 102 | } 103 | index += 1 104 | return null 105 | } 106 | 107 | override fun decodeBoolean(): Boolean = decodeString().toBoolean() 108 | 109 | override fun decodeByte(): Byte = decodeString().toByte() 110 | 111 | override fun decodeShort(): Short = decodeString().toShort() 112 | 113 | override fun decodeInt(): Int { 114 | val s = decodeString() 115 | return s.toInt() 116 | } 117 | 118 | override fun decodeLong(): Long = decodeString().toLong() 119 | 120 | override fun decodeFloat(): Float = decodeNumber().toFloat() 121 | 122 | private fun decodeNumber(): String { 123 | val data = decodeString() 124 | return when (configuration.numberFormat) { 125 | CSVFormat.NumberFormat.Dot -> data 126 | CSVFormat.NumberFormat.Comma -> data.replace(",", ".") 127 | } 128 | } 129 | 130 | override fun decodeDouble(): Double = decodeNumber().toDouble() 131 | 132 | override fun decodeChar(): Char = decodeString().single() 133 | 134 | override fun decodeString(): String { 135 | index += 1 136 | return if (nodes.peek() == null) { 137 | "" 138 | } else { 139 | when (val nextNode = nodes.next()) { 140 | is CSVNode.Element -> nextNode.value 141 | CSVNode.NewLine -> throwUnknownValue() 142 | } 143 | } 144 | } 145 | 146 | private fun throwUnknownValue(): Nothing = throw SerializationException( 147 | "Missing value at the end of line ${currentRow + READABLE_LINE_NUMBER + HEADER_OFFSET}" 148 | ) 149 | 150 | override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = enumDescriptor.elementNames.indexOf(decodeString()) 151 | 152 | override fun decodeSequentially(): Boolean { 153 | val r = decodesSequentially 154 | return r 155 | } 156 | 157 | override fun decodeElementIndex(descriptor: SerialDescriptor): Int { 158 | if (descriptor.kind is StructureKind.LIST) { 159 | val nextValue = nodes.peek() 160 | return if (nextValue == null) { 161 | CompositeDecoder.DECODE_DONE 162 | } else { 163 | currentRow++ 164 | } 165 | } else { 166 | val headerName = header.getOrNull(index) ?: return CompositeDecoder.DECODE_DONE 167 | val index = descriptor.getElementIndex(headerName) 168 | if (index == CompositeDecoder.UNKNOWN_NAME) { 169 | throwUnknownValue() 170 | } 171 | return index 172 | } 173 | } 174 | 175 | override fun decodeNullableSerializableValue(deserializer: DeserializationStrategy): T? { 176 | return super.decodeNullableSerializableValue(deserializer) 177 | } 178 | } 179 | 180 | private const val READABLE_LINE_NUMBER = 1 181 | private const val HEADER_OFFSET = 1 182 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/jvmMain/kotlin/app/softwork/serialization/flf/SequenceWriteLines.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.DeserializationStrategy 4 | import kotlinx.serialization.ExperimentalSerializationApi 5 | import kotlinx.serialization.SerializationStrategy 6 | import java.io.File 7 | import java.io.FileOutputStream 8 | import java.nio.CharBuffer 9 | import java.nio.charset.Charset 10 | import java.util.Spliterators.AbstractSpliterator 11 | import java.util.function.Consumer 12 | import java.util.stream.Stream 13 | import java.util.stream.StreamSupport 14 | import kotlin.streams.asSequence 15 | 16 | @JvmOverloads 17 | public fun Sequence.appendLines(file: File, charset: Charset = Charsets.UTF_8, lineSeparator: String = "\n") { 18 | FileOutputStream(file, true).bufferedWriter(charset).use { writer -> 19 | for (line in this) { 20 | writer.write(line) 21 | writer.write(lineSeparator) 22 | } 23 | } 24 | } 25 | 26 | @JvmOverloads 27 | public fun Sequence.writeLines(file: File, charset: Charset = Charsets.UTF_8, lineSeparator: String = "\n") { 28 | FileOutputStream(file, false).bufferedWriter(charset).use { writer -> 29 | for (line in this) { 30 | writer.write(line) 31 | writer.write(lineSeparator) 32 | } 33 | } 34 | } 35 | 36 | @ExperimentalSerializationApi 37 | @JvmOverloads 38 | public fun Readable.decode( 39 | deserializer: DeserializationStrategy, 40 | format: FixedLengthFormat = FixedLengthFormat 41 | ): Iterable { 42 | deserializer.descriptor.checkForMaps() 43 | 44 | return Iterable { 45 | var afterInit = false 46 | generateSequence { 47 | try { 48 | deserializer.deserialize( 49 | FixedLengthDecoder({ 50 | if (afterInit) { 51 | val length = format.lineSeparator.length 52 | if (length > 0) { 53 | if (read(CharBuffer.allocate(length)) != length) { 54 | throw NoMoreDataException() 55 | } 56 | } 57 | } 58 | afterInit = true 59 | }, { length -> 60 | val buffer = CharBuffer.allocate(length) 61 | val got = read(buffer) 62 | if (got != length) { 63 | throw NoMoreDataException() 64 | } 65 | buffer.position(0) 66 | buffer 67 | }, format.serializersModule, -1) 68 | ) 69 | } catch (_: NoMoreDataException) { 70 | null 71 | } 72 | }.iterator() 73 | } 74 | } 75 | 76 | private class NoMoreDataException : Exception() 77 | 78 | @ExperimentalSerializationApi 79 | @JvmOverloads 80 | public fun Stream.decode( 81 | deserializer: DeserializationStrategy, 82 | format: FixedLengthFormat = FixedLengthFormat 83 | ): Iterable { 84 | return Iterable { asSequence().decode(deserializer, format).iterator() } 85 | } 86 | 87 | @ExperimentalSerializationApi 88 | @JvmOverloads 89 | public fun Stream.encode( 90 | serializer: SerializationStrategy, 91 | format: FixedLengthFormat = FixedLengthFormat 92 | ): Iterable { 93 | return Iterable { asSequence().encode(serializer, format).iterator() } 94 | } 95 | 96 | @ExperimentalSerializationApi 97 | @JvmOverloads 98 | public fun Stream.decodeStream( 99 | deserializer: DeserializationStrategy, 100 | format: FixedLengthFormat = FixedLengthFormat 101 | ): Stream { 102 | deserializer.descriptor.checkForMaps() 103 | val parallel = isParallel 104 | val split = spliterator() 105 | return StreamSupport.stream( 106 | object : AbstractSpliterator( 107 | split.estimateSize(), 108 | split.characteristics().and(NONNULL) 109 | ) { 110 | var currentRow: String? = null 111 | val decoder = FixedLengthDecoder( 112 | {}, 113 | { currentRow!! }, 114 | format.serializersModule, 115 | size = exactSizeIfKnown.toIntOrNull() ?: -1 116 | ) 117 | 118 | override fun tryAdvance(action: Consumer): Boolean { 119 | return split.tryAdvance { 120 | currentRow = it 121 | val t = deserializer.deserialize(decoder) 122 | action.accept(t) 123 | } 124 | } 125 | 126 | fun Long.toIntOrNull(): Int? { 127 | return if (this < Int.MIN_VALUE || this > Int.MAX_VALUE) { 128 | null 129 | } else { 130 | this.toInt() 131 | } 132 | } 133 | }, 134 | parallel 135 | ).onClose(::close) 136 | } 137 | 138 | @ExperimentalSerializationApi 139 | @JvmOverloads 140 | public fun Stream.encodeStream( 141 | serializer: SerializationStrategy, 142 | format: FixedLengthFormat = FixedLengthFormat 143 | ): Stream { 144 | serializer.descriptor.checkForMaps() 145 | val parallel = isParallel 146 | val split = spliterator() 147 | return StreamSupport.stream( 148 | object : AbstractSpliterator( 149 | split.estimateSize(), 150 | split.characteristics().and(NONNULL) 151 | ) { 152 | val currentRow = StringBuilder() 153 | val encoder = FixedLengthEncoder( 154 | currentRow, 155 | format.serializersModule, 156 | lineSeparator = "", 157 | format.fillLeadingZeros 158 | ) 159 | 160 | override fun tryAdvance(action: Consumer): Boolean { 161 | return split.tryAdvance { 162 | serializer.serialize(encoder, it) 163 | action.accept(currentRow.toString()) 164 | currentRow.setLength(0) 165 | } 166 | } 167 | }, 168 | parallel 169 | ).onClose(::close) 170 | } 171 | 172 | @ExperimentalSerializationApi 173 | @JvmOverloads 174 | public fun Appendable.append( 175 | serializer: SerializationStrategy, 176 | value: T, 177 | format: FixedLengthFormat = FixedLengthFormat 178 | ) { 179 | append(format.encodeToString(serializer, value)) 180 | } 181 | 182 | @ExperimentalSerializationApi 183 | @JvmOverloads 184 | public fun Appendable.appendLine( 185 | serializer: SerializationStrategy, 186 | value: T, 187 | format: FixedLengthFormat = FixedLengthFormat 188 | ) { 189 | appendLine(format.encodeToString(serializer, value)) 190 | } 191 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthEncoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.SerializationStrategy 5 | import kotlinx.serialization.descriptors.PolymorphicKind 6 | import kotlinx.serialization.descriptors.SerialDescriptor 7 | import kotlinx.serialization.descriptors.StructureKind 8 | import kotlinx.serialization.encoding.CompositeEncoder 9 | import kotlinx.serialization.encoding.Encoder 10 | import kotlinx.serialization.modules.SerializersModule 11 | 12 | @ExperimentalSerializationApi 13 | public class FixedLengthEncoder( 14 | private val builder: StringBuilder, 15 | override val serializersModule: SerializersModule, 16 | private val lineSeparator: String, 17 | private val fillLeadingZero: Boolean 18 | ) : FailingPrimitiveEncoder, CompositeEncoder { 19 | 20 | private var level = 0 21 | private var afterFirst = false 22 | 23 | private fun maybeAddLine() { 24 | if (level == 0 && afterFirst) { 25 | builder.append(lineSeparator) 26 | } 27 | } 28 | 29 | internal fun encode(value: String, length: Int) { 30 | require(value.length <= length) { "$value was longer as $length" } 31 | builder.append(value.padEnd(length)) 32 | afterFirst = true 33 | } 34 | 35 | private fun encodeNumber(value: String, length: Int) { 36 | if (fillLeadingZero) { 37 | val sign = value.startsWith("-") 38 | if (sign) { 39 | encode("-" + value.drop(1).padStart(length - 1, '0'), length) 40 | } else { 41 | encode(value.padStart(length, '0'), length) 42 | } 43 | } else { 44 | encode(value, length) 45 | } 46 | } 47 | 48 | override fun encodeBooleanElement(descriptor: SerialDescriptor, index: Int, value: Boolean) { 49 | encode(value.toString(), descriptor.fixedLength(index)) 50 | } 51 | 52 | override fun encodeByteElement(descriptor: SerialDescriptor, index: Int, value: Byte) { 53 | encodeNumber(value.toString(), descriptor.fixedLength(index)) 54 | } 55 | 56 | override fun encodeCharElement(descriptor: SerialDescriptor, index: Int, value: Char) { 57 | encode(value.toString(), descriptor.fixedLength(index)) 58 | } 59 | 60 | override fun encodeDoubleElement(descriptor: SerialDescriptor, index: Int, value: Double) { 61 | encodeNumber(value.toString(), descriptor.fixedLength(index)) 62 | } 63 | 64 | override fun encodeFloatElement(descriptor: SerialDescriptor, index: Int, value: Float) { 65 | encodeNumber(value.toString(), descriptor.fixedLength(index)) 66 | } 67 | 68 | override fun encodeInlineElement( 69 | descriptor: SerialDescriptor, 70 | index: Int 71 | ): Encoder = encodeInline(descriptor.getElementDescriptor(index)) 72 | 73 | override fun encodeIntElement(descriptor: SerialDescriptor, index: Int, value: Int) { 74 | val stringValue = descriptor.ebcdic(index)?.format?.toString(value) ?: value.toString() 75 | encodeNumber(stringValue.toString(), descriptor.fixedLength(index)) 76 | } 77 | 78 | override fun encodeLongElement(descriptor: SerialDescriptor, index: Int, value: Long) { 79 | val stringValue = descriptor.ebcdic(index)?.format?.toString(value) ?: value.toString() 80 | encodeNumber(stringValue.toString(), descriptor.fixedLength(index)) 81 | } 82 | 83 | @ExperimentalSerializationApi 84 | override fun encodeNullableSerializableElement( 85 | descriptor: SerialDescriptor, 86 | index: Int, 87 | serializer: SerializationStrategy, 88 | value: T? 89 | ) { 90 | val encoder = FixedLengthPrimitiveEncoder( 91 | serializersModule, 92 | descriptor.fixedLength(index), 93 | builder, 94 | fillLeadingZero, 95 | descriptor.ebcdic(index) 96 | ) 97 | if (value == null) { 98 | encoder.encodeNull() 99 | } else { 100 | serializer.serialize(encoder, value) 101 | } 102 | } 103 | 104 | override fun encodeSerializableElement( 105 | descriptor: SerialDescriptor, 106 | index: Int, 107 | serializer: SerializationStrategy, 108 | value: T 109 | ) { 110 | val isInnerClass = level != 0 && serializer.descriptor.kind is StructureKind.CLASS && 111 | !serializer.descriptor.isInline 112 | if (serializer.descriptor.kind is PolymorphicKind.SEALED) { 113 | var length: Int? = serializer.descriptor.fixedLengthType 114 | for (anno in descriptor.getElementAnnotations(index)) { 115 | if (anno is FixedLengthSealedClassDiscriminator) { 116 | length = null 117 | break 118 | } 119 | } 120 | serializer.serialize(FixedLengthSealedEncoder(length, this), value) 121 | } else if ( 122 | descriptor.kind is StructureKind.LIST || 123 | serializer.descriptor.kind is StructureKind.LIST || 124 | isInnerClass 125 | ) { 126 | serializer.serialize(this, value) 127 | } else { 128 | serializer.serialize( 129 | FixedLengthPrimitiveEncoder( 130 | serializersModule, 131 | descriptor.fixedLength(index), 132 | builder, 133 | fillLeadingZero, 134 | descriptor.ebcdic(index) 135 | ), 136 | value 137 | ) 138 | } 139 | } 140 | 141 | override fun encodeShortElement(descriptor: SerialDescriptor, index: Int, value: Short) { 142 | encodeNumber(value.toString(), descriptor.fixedLength(index)) 143 | } 144 | 145 | override fun encodeStringElement(descriptor: SerialDescriptor, index: Int, value: String) { 146 | encode(value, descriptor.fixedLength(index)) 147 | } 148 | 149 | override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder { 150 | maybeAddLine() 151 | level++ 152 | return this 153 | } 154 | 155 | override fun beginCollection(descriptor: SerialDescriptor, collectionSize: Int): CompositeEncoder = this 156 | override fun endStructure(descriptor: SerialDescriptor) { 157 | level-- 158 | } 159 | 160 | override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) { 161 | val value = enumDescriptor.getElementName(index) 162 | encode(value, enumDescriptor.fixedLength(index)) 163 | } 164 | 165 | override fun encodeInline(descriptor: SerialDescriptor): Encoder { 166 | maybeAddLine() 167 | val fixedLength = descriptor.fixedLength 168 | return FixedLengthPrimitiveEncoder(serializersModule, fixedLength, builder, fillLeadingZero, descriptor.ebcdic) 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthFormat.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.DeserializationStrategy 4 | import kotlinx.serialization.ExperimentalSerializationApi 5 | import kotlinx.serialization.SerializationStrategy 6 | import kotlinx.serialization.StringFormat 7 | import kotlinx.serialization.descriptors.SerialDescriptor 8 | import kotlinx.serialization.descriptors.StructureKind 9 | import kotlinx.serialization.descriptors.elementDescriptors 10 | import kotlinx.serialization.modules.EmptySerializersModule 11 | import kotlinx.serialization.modules.SerializersModule 12 | import kotlin.jvm.JvmOverloads 13 | import kotlin.math.min 14 | 15 | /** 16 | * [Fixed Length Files](https://www.ibm.com/docs/en/psfa/latest?topic=format-fixed-length-files) 17 | */ 18 | @ExperimentalSerializationApi 19 | public sealed class FixedLengthFormat( 20 | override val serializersModule: SerializersModule, 21 | public val lineSeparator: String, 22 | internal val fillLeadingZeros: Boolean 23 | ) : StringFormat { 24 | 25 | private class Custom( 26 | serializersModule: SerializersModule, 27 | lineSeparator: String, 28 | fillLeadingZeros: Boolean 29 | ) : FixedLengthFormat(serializersModule, lineSeparator, fillLeadingZeros) 30 | 31 | public companion object Default : FixedLengthFormat( 32 | serializersModule = EmptySerializersModule(), 33 | lineSeparator = "\n", 34 | fillLeadingZeros = true 35 | ) { 36 | @JvmOverloads 37 | public operator fun invoke( 38 | lineSeparator: String = "\n", 39 | fillLeadingZeros: Boolean = true, 40 | serializersModule: SerializersModule = EmptySerializersModule(), 41 | ): FixedLengthFormat = Custom(serializersModule, lineSeparator, fillLeadingZeros) 42 | } 43 | 44 | override fun decodeFromString(deserializer: DeserializationStrategy, string: String): T { 45 | deserializer.descriptor.checkForMaps() 46 | val data = string.split(lineSeparator) 47 | var index = 0 48 | var currentRowIndex = -1 49 | var currentRow: String? = null 50 | return deserializer.deserialize( 51 | FixedLengthDecoder({ 52 | currentRowIndex++ 53 | currentRow = data[currentRowIndex] 54 | index = 0 55 | }, { length -> 56 | currentRow!!.substring(index, min(index + length, currentRow!!.length)).also { 57 | index += length 58 | } 59 | }, serializersModule, data.size) 60 | ) 61 | } 62 | 63 | public fun decodeAsSequence(deserializer: DeserializationStrategy, input: Sequence): Sequence { 64 | deserializer.descriptor.checkForMaps() 65 | return sequence { 66 | val iterator = input.iterator() 67 | if (!iterator.hasNext()) { 68 | return@sequence 69 | } 70 | var currentRow: String? = null 71 | var index = 0 72 | val decoder = FixedLengthDecoder({ 73 | currentRow = iterator.next() 74 | index = 0 75 | }, { length -> 76 | val r = currentRow!!.substring(index, min(index + length, currentRow!!.length)) 77 | index += length 78 | r 79 | }, serializersModule, size = -1) 80 | while (iterator.hasNext()) { 81 | yield(deserializer.deserialize(decoder)) 82 | } 83 | } 84 | } 85 | 86 | override fun encodeToString(serializer: SerializationStrategy, value: T): String = buildString { 87 | serializer.descriptor.checkForMaps() 88 | serializer.serialize(FixedLengthEncoder(this, serializersModule, lineSeparator, fillLeadingZeros), value) 89 | } 90 | 91 | public fun encodeAsSequence(serializer: SerializationStrategy, value: Sequence): Sequence { 92 | serializer.descriptor.checkForMaps() 93 | return sequence { 94 | val iterator = value.iterator() 95 | if (!iterator.hasNext()) { 96 | return@sequence 97 | } 98 | 99 | val stringBuilder = StringBuilder() 100 | val encoder = FixedLengthEncoder(stringBuilder, serializersModule, lineSeparator = "", fillLeadingZeros) 101 | while (iterator.hasNext()) { 102 | serializer.serialize(encoder, iterator.next()) 103 | yield(stringBuilder.toString()) 104 | stringBuilder.setLength(0) 105 | } 106 | } 107 | } 108 | } 109 | 110 | @ExperimentalSerializationApi 111 | @JvmOverloads 112 | public fun Sequence.encode( 113 | serializationStrategy: SerializationStrategy, 114 | format: FixedLengthFormat = FixedLengthFormat 115 | ): Sequence = format.encodeAsSequence(serializationStrategy, this) 116 | 117 | @ExperimentalSerializationApi 118 | @JvmOverloads 119 | public fun Sequence.decode( 120 | deserializationStrategy: DeserializationStrategy, 121 | format: FixedLengthFormat = FixedLengthFormat 122 | ): Sequence = format.decodeAsSequence(deserializationStrategy, this) 123 | 124 | @ExperimentalSerializationApi 125 | internal fun SerialDescriptor.fixedLength(index: Int): Int { 126 | for (anno in getElementAnnotations(index)) { 127 | if (anno is FixedLength) { 128 | return anno.length 129 | } 130 | } 131 | error("$serialName.${getElementName(index)} not annotated with @FixedLength") 132 | } 133 | 134 | @ExperimentalSerializationApi 135 | internal val SerialDescriptor.fixedLength: Int 136 | get() { 137 | for (anno in annotations) { 138 | if (anno is FixedLength) return anno.length 139 | } 140 | error("$serialName not annotated with @FixedLength") 141 | } 142 | 143 | @ExperimentalSerializationApi 144 | internal val SerialDescriptor.hasSealedTypeProperty: Boolean 145 | get() { 146 | for (index in 0 until elementsCount) { 147 | for (anno in getElementAnnotations(index)) { 148 | if (anno is FixedLengthSealedClassDiscriminator) { 149 | return true 150 | } 151 | } 152 | } 153 | return false 154 | } 155 | 156 | @ExperimentalSerializationApi 157 | internal val SerialDescriptor.fixedLengthType: Int 158 | get() { 159 | for (anno in annotations) { 160 | if (anno is FixedLengthSealedClassDiscriminatorLength) { 161 | return anno.length 162 | } 163 | } 164 | error("$serialName not annotated with @FixedLengthSealedType") 165 | } 166 | 167 | @ExperimentalSerializationApi 168 | internal val SerialDescriptor.fixedLengthList: String 169 | get() { 170 | for (anno in annotations) { 171 | if (anno is FixedLengthList) { 172 | return anno.serialName 173 | } 174 | } 175 | error("$serialName not annotated with @FixedLengthList") 176 | } 177 | 178 | @ExperimentalSerializationApi 179 | internal fun SerialDescriptor.checkForMaps() { 180 | for (descriptor in elementDescriptors) { 181 | if (descriptor.kind is StructureKind.MAP) { 182 | error("Map is not yet supported: ${descriptor.serialName}") 183 | } 184 | descriptor.checkForMaps() 185 | } 186 | } 187 | 188 | @ExperimentalSerializationApi 189 | internal fun SerialDescriptor.ebcdic(index: Int): Ebcdic? { 190 | for (anno in getElementAnnotations(index)) { 191 | if (anno is Ebcdic) { 192 | return anno 193 | } 194 | } 195 | return null 196 | } 197 | 198 | @ExperimentalSerializationApi 199 | internal val SerialDescriptor.ebcdic: Ebcdic? 200 | get() { 201 | for (anno in annotations) { 202 | if (anno is Ebcdic) { 203 | return anno 204 | } 205 | } 206 | return null 207 | } 208 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonTest/kotlin/app/softwork/serialization/flf/FlfEncoderTest.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import app.softwork.serialization.flf.Seal.A 4 | import app.softwork.serialization.flf.Seal.B 5 | import kotlinx.serialization.ExperimentalSerializationApi 6 | import kotlinx.serialization.builtins.ListSerializer 7 | import kotlinx.serialization.encodeToString 8 | import kotlin.test.Test 9 | import kotlin.test.assertEquals 10 | import kotlin.test.assertFailsWith 11 | import kotlin.time.Instant 12 | 13 | @ExperimentalSerializationApi 14 | class FlfEncoderTest { 15 | 16 | @Test 17 | fun normal() { 18 | val flf = FixedLengthFormat.encodeToString( 19 | serializer = Sample.serializer(), 20 | value = Sample.simple 21 | ) 22 | assertEquals( 23 | expected = """ 24 | ShortLong 004242.3 1970-01-01T00:00:00ZTwo 001foo4.2true000f41.118false0001000104.2-001 25 | """.trimIndent(), 26 | actual = flf 27 | ) 28 | } 29 | 30 | @Test 31 | fun list() { 32 | val flf = FixedLengthFormat.encodeToString( 33 | serializer = ListSerializer(Sample.serializer()), 34 | value = List(3) { 35 | Sample( 36 | shortString = "Short", 37 | longString = "Long", 38 | int = it, 39 | double = 42.3, 40 | nil = null, 41 | date = Instant.fromEpochSeconds(0L), 42 | enum = Sample.Testing.Two, 43 | inline = Sample.Foo(it), 44 | inlineS = Sample.FooS("foo"), 45 | inlineD = Sample.FooD(4.2), 46 | inlineB = Sample.FooB(true), 47 | inlineL = Sample.FooL(0L), 48 | inlineChar = Sample.FooChar('f'), 49 | inlineShort = Sample.FooShort(4.toShort()), 50 | inlineFloat = Sample.FooFloat(1.1), 51 | inlineByte = Sample.FooByte(1.toByte()), 52 | innerClass = Sample.Inner(8), 53 | boolean = false, 54 | byte = 1.toByte(), 55 | short = 1.toShort(), 56 | float = 4.2, 57 | long = -1L, 58 | char = ' ' 59 | ) 60 | } 61 | ) 62 | assertEquals( 63 | expected = """ 64 | ShortLong 000042.3 1970-01-01T00:00:00ZTwo 000foo4.2true000f41.118false0001000104.2-001 65 | ShortLong 000142.3 1970-01-01T00:00:00ZTwo 001foo4.2true000f41.118false0001000104.2-001 66 | ShortLong 000242.3 1970-01-01T00:00:00ZTwo 002foo4.2true000f41.118false0001000104.2-001 67 | """.trimIndent(), 68 | actual = flf 69 | ) 70 | } 71 | 72 | @Test 73 | fun sequence() { 74 | val flf = generateSequence(0) { it + 1 }.map { 75 | Sample( 76 | shortString = "Short", 77 | longString = "Long", 78 | int = it, 79 | double = 42.3, 80 | nil = null, 81 | date = Instant.fromEpochSeconds(0L), 82 | enum = Sample.Testing.Two, 83 | inline = Sample.Foo(it), 84 | inlineS = Sample.FooS("foo"), 85 | inlineD = Sample.FooD(4.2), 86 | inlineB = Sample.FooB(true), 87 | inlineL = Sample.FooL(0L), 88 | inlineChar = Sample.FooChar('f'), 89 | inlineShort = Sample.FooShort(4.toShort()), 90 | inlineFloat = Sample.FooFloat(1.1), 91 | inlineByte = Sample.FooByte(1.toByte()), 92 | innerClass = Sample.Inner(8), 93 | boolean = false, 94 | byte = 1.toByte(), 95 | short = 1.toShort(), 96 | float = 4.2, 97 | long = -1L, 98 | char = ' ' 99 | ) 100 | }.take(3).constrainOnce() 101 | 102 | assertEquals( 103 | expected = listOf( 104 | "ShortLong 000042.3 1970-01-01T00:00:00ZTwo 000foo4.2true000f41.118false0001000104.2-001 ", 105 | "ShortLong 000142.3 1970-01-01T00:00:00ZTwo 001foo4.2true000f41.118false0001000104.2-001 ", 106 | "ShortLong 000242.3 1970-01-01T00:00:00ZTwo 002foo4.2true000f41.118false0001000104.2-001 " 107 | ), 108 | actual = flf.encode(Sample.serializer()).toList() 109 | ) 110 | 111 | val constrainOnce = assertFailsWith { 112 | flf.encode(Sample.serializer()).count() 113 | } 114 | assertEquals("This sequence can be consumed only once.", constrainOnce.message!!) 115 | } 116 | 117 | @Test 118 | fun primitives() { 119 | assertFailsWith { 120 | FixedLengthFormat.encodeToString(1) 121 | } 122 | assertFailsWith { 123 | FixedLengthFormat.encodeToString(true) 124 | } 125 | assertFailsWith { 126 | FixedLengthFormat.encodeToString("") 127 | } 128 | assertFailsWith { 129 | FixedLengthFormat.encodeToString(1.0) 130 | } 131 | assertFailsWith { 132 | FixedLengthFormat.encodeToString(1.0f) 133 | } 134 | assertFailsWith { 135 | FixedLengthFormat.encodeToString(1.toByte()) 136 | } 137 | assertFailsWith { 138 | FixedLengthFormat.encodeToString(1.toChar()) 139 | } 140 | assertFailsWith { 141 | FixedLengthFormat.encodeToString(1L) 142 | } 143 | assertFailsWith { 144 | FixedLengthFormat.encodeToString(1.toShort()) 145 | } 146 | assertFailsWith { 147 | FixedLengthFormat.encodeToString(null as Int?) 148 | } 149 | } 150 | 151 | @Test 152 | fun tooSmall() { 153 | assertFailsWith { 154 | FixedLengthFormat.encodeToString(Small("Too long")) 155 | } 156 | } 157 | 158 | @Test 159 | fun tooSmallNull() { 160 | assertEquals(" ", FixedLengthFormat.encodeToString(Small(null))) 161 | } 162 | 163 | @Test 164 | fun missingFixedLength() { 165 | assertFailsWith { 166 | FixedLengthFormat.encodeToString(Missing.serializer(), Missing(42)) 167 | } 168 | } 169 | 170 | @Test 171 | fun innerList() { 172 | val flf = FixedLengthFormat.encodeToString( 173 | InnerList.serializer(), 174 | InnerList( 175 | 2, 176 | "foo", 177 | listOf( 178 | A(42, 1), 179 | B("foo", 2) 180 | ) 181 | ) 182 | ) 183 | assertEquals( 184 | expected = """ 185 | 2fooA420001Bfoo 0002 186 | """.trimIndent(), 187 | actual = flf 188 | ) 189 | } 190 | 191 | @Test 192 | fun sealed() { 193 | val flf = FixedLengthFormat.encodeToString( 194 | serializer = ListSerializer(Seal.serializer()), 195 | value = listOf( 196 | A(42, 1), 197 | B("foo", 2) 198 | ) 199 | ) 200 | assertEquals( 201 | expected = """ 202 | A420001 203 | Bfoo 0002 204 | """.trimIndent(), 205 | actual = flf 206 | ) 207 | } 208 | 209 | @Test 210 | fun sealedProperty() { 211 | val flf = FixedLengthFormat.encodeToString( 212 | serializer = ListSerializer(SealedWithProperty.serializer()), 213 | value = listOf( 214 | SealedWithProperty(A.serializer().descriptor.serialName, 42, A(42, 1)), 215 | SealedWithProperty(B.serializer().descriptor.serialName, 42, B("foo", 2)) 216 | ) 217 | ) 218 | assertEquals( 219 | expected = """ 220 | A 42420001 221 | B 42foo 0002 222 | """.trimIndent(), 223 | actual = flf 224 | ) 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonMain/kotlin/app/softwork/serialization/flf/FixedLengthDecoder.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.DeserializationStrategy 4 | import kotlinx.serialization.ExperimentalSerializationApi 5 | import kotlinx.serialization.descriptors.PolymorphicKind 6 | import kotlinx.serialization.descriptors.SerialDescriptor 7 | import kotlinx.serialization.descriptors.StructureKind 8 | import kotlinx.serialization.descriptors.elementNames 9 | import kotlinx.serialization.encoding.CompositeDecoder 10 | import kotlinx.serialization.encoding.Decoder 11 | import kotlinx.serialization.modules.SerializersModule 12 | 13 | @ExperimentalSerializationApi 14 | public class FixedLengthDecoder( 15 | private val nextRow: () -> Unit, 16 | private val next: (Int) -> CharSequence, 17 | override val serializersModule: SerializersModule, 18 | private val size: Int 19 | ) : FailingPrimitiveDecoder, CompositeDecoder { 20 | private var level = 0 21 | private var lengthElementIndex: Int? = null 22 | private var currentLength: Int? = null 23 | 24 | private val sealedClassClassDiscriminators = mutableMapOf() 25 | 26 | internal fun decode(length: Int, trim: Boolean = true): CharSequence { 27 | val data = next(length) 28 | return if (trim) data.trim() else data 29 | } 30 | 31 | override fun decodeElementIndex(descriptor: SerialDescriptor): Nothing = 32 | error("Never called, because decodeSequentially returns true") 33 | 34 | override fun decodeFloatElement(descriptor: SerialDescriptor, index: Int): Float = 35 | decode(descriptor.fixedLength(index)).toString().toFloat() 36 | 37 | override fun decodeInlineElement(descriptor: SerialDescriptor, index: Int): Decoder = 38 | decodeInline(descriptor.getElementDescriptor(index)) 39 | 40 | override fun decodeIntElement(descriptor: SerialDescriptor, index: Int): Int { 41 | val decoded = decode(descriptor.fixedLength(index)) 42 | return (descriptor.ebcdic(index)?.format?.toInt(decoded) ?: decoded.toString().toInt()).also { 43 | if (index == lengthElementIndex) { 44 | currentLength = it 45 | } 46 | } 47 | } 48 | 49 | override fun decodeLongElement(descriptor: SerialDescriptor, index: Int): Long { 50 | val decoded = decode(descriptor.fixedLength(index)) 51 | return descriptor.ebcdic(index)?.format?.toLong(decoded) ?: decoded.toString().toLong() 52 | } 53 | 54 | @ExperimentalSerializationApi 55 | override fun decodeNullableSerializableElement( 56 | descriptor: SerialDescriptor, 57 | index: Int, 58 | deserializer: DeserializationStrategy, 59 | previousValue: T? 60 | ): T? { 61 | val data = decode(descriptor.fixedLength(index)) 62 | val decoder = FixedLengthPrimitiveDecoder( 63 | serializersModule, 64 | data, 65 | ebcdic = descriptor.ebcdic(index) 66 | ) 67 | return if (data.isBlank()) { 68 | decoder.decodeNull() 69 | } else { 70 | deserializer.deserialize(decoder) 71 | } 72 | } 73 | 74 | override fun decodeSequentially(): Boolean = true 75 | 76 | override fun decodeSerializableElement( 77 | descriptor: SerialDescriptor, 78 | index: Int, 79 | deserializer: DeserializationStrategy, 80 | previousValue: T? 81 | ): T { 82 | val isInnerClass = level != 0 && deserializer.descriptor.kind is StructureKind.CLASS && 83 | !deserializer.descriptor.isInline 84 | return if (deserializer.descriptor.kind is PolymorphicKind.SEALED) { 85 | var property: String? = null 86 | for (anno in descriptor.getElementAnnotations(index)) { 87 | if (anno is FixedLengthSealedClassDiscriminator) { 88 | property = anno.serialName 89 | break 90 | } 91 | } 92 | val typeLength = if (property != null) { 93 | val classDiscriminator = sealedClassClassDiscriminators[property]!! 94 | SealedClassClassDiscriminator.Property(classDiscriminator) 95 | } else { 96 | SealedClassClassDiscriminator.Length(deserializer.descriptor.fixedLengthType) 97 | } 98 | deserializer.deserialize(FixedLengthSealedDecoder(typeLength, this)) 99 | } else if ( 100 | descriptor.kind is StructureKind.LIST || 101 | deserializer.descriptor.kind is StructureKind.LIST || 102 | isInnerClass 103 | ) { 104 | deserializer.deserialize(this) 105 | } else { 106 | val data = decode(descriptor.fixedLength(index)) 107 | deserializer.deserialize(FixedLengthPrimitiveDecoder(serializersModule, data, descriptor.ebcdic(index))) 108 | } 109 | } 110 | 111 | @ExperimentalSerializationApi 112 | override fun decodeNullableSerializableValue(deserializer: DeserializationStrategy): T? { 113 | val isNullabilitySupported = deserializer.descriptor.isNullable 114 | val length = deserializer.descriptor.fixedLength 115 | val value = next(length) 116 | return if (isNullabilitySupported || value.isNotBlank()) decodeSerializableValue(deserializer) else decodeNull() 117 | } 118 | 119 | override fun decodeShortElement(descriptor: SerialDescriptor, index: Int): Short = 120 | decode(descriptor.fixedLength(index)).toString().toShort() 121 | 122 | override fun decodeStringElement(descriptor: SerialDescriptor, index: Int): String { 123 | val value = decode(descriptor.fixedLength(index)).toString() 124 | if (descriptor.hasSealedTypeProperty) { 125 | sealedClassClassDiscriminators[descriptor.getElementName(index)] = value 126 | } 127 | return value 128 | } 129 | 130 | override fun endStructure(descriptor: SerialDescriptor) { 131 | level -= 1 132 | } 133 | 134 | override fun decodeBooleanElement(descriptor: SerialDescriptor, index: Int): Boolean = 135 | decode(descriptor.fixedLength(index)).toString().toBoolean() 136 | 137 | override fun decodeByteElement(descriptor: SerialDescriptor, index: Int): Byte = 138 | decode(descriptor.fixedLength(index)).toString().toByte() 139 | 140 | override fun decodeCharElement(descriptor: SerialDescriptor, index: Int): Char = 141 | decode(descriptor.fixedLength(index), trim = false).single() 142 | 143 | override fun decodeCollectionSize(descriptor: SerialDescriptor): Int = when (level) { 144 | 0 -> size 145 | else -> currentLength ?: error("${descriptor.fixedLengthList} was not seen before this list: $descriptor") 146 | } 147 | 148 | override fun decodeDoubleElement(descriptor: SerialDescriptor, index: Int): Double = 149 | decode(descriptor.fixedLength(index)).toString().toDouble() 150 | 151 | override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder { 152 | val hasInnerList = descriptor.hasInnerListLengthIndex() 153 | if (hasInnerList != null) { 154 | lengthElementIndex = hasInnerList 155 | } 156 | if (descriptor.kind !is StructureKind.LIST) { 157 | if (level == 0) { 158 | nextRow() 159 | } 160 | level += 1 161 | } 162 | return this 163 | } 164 | 165 | override fun decodeEnum(enumDescriptor: SerialDescriptor): Int { 166 | val fixedLength = enumDescriptor.fixedLength 167 | return enumDescriptor.elementNames.indexOf(decode(enumDescriptor.fixedLength(fixedLength))) 168 | } 169 | 170 | override fun decodeInline(descriptor: SerialDescriptor): Decoder { 171 | val fixedLength = descriptor.fixedLength 172 | val data = decode(fixedLength) 173 | return FixedLengthPrimitiveDecoder(serializersModule, data, descriptor.ebcdic) 174 | } 175 | 176 | @ExperimentalSerializationApi 177 | override fun decodeNotNullMark(): Nothing = 178 | error("Never called, because decodeNullableSerializableValue is overridden.") 179 | 180 | @ExperimentalSerializationApi 181 | internal fun SerialDescriptor.hasInnerListLengthIndex(): Int? { 182 | for (element in elementNames) { 183 | val index = getElementIndex(element) 184 | val descriptor = getElementDescriptor(index) 185 | if (descriptor.kind is StructureKind.LIST) { 186 | for (anno in getElementAnnotations(index)) { 187 | if (anno is FixedLengthList) { 188 | return getElementIndex(anno.serialName) 189 | } 190 | } 191 | error("$serialName not annotated with @FixedLengthList") 192 | } 193 | } 194 | return null 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/src/commonTest/kotlin/app/softwork/serialization/flf/FlfDecoderTest.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.flf 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.builtins.ListSerializer 5 | import kotlinx.serialization.builtins.nullable 6 | import kotlinx.serialization.builtins.serializer 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | import kotlin.test.assertFailsWith 10 | import kotlin.time.Instant 11 | 12 | @ExperimentalSerializationApi 13 | class FlfDecoderTest { 14 | 15 | @Test 16 | fun normal() { 17 | val flf = """ 18 | ShortLong 42 42.3 1970-01-01T00:00:00ZTwo 1 foo4.2true0 f41.118false1 1 4.2 -1 19 | """.trimIndent() 20 | 21 | assertEquals( 22 | expected = Sample.simple, 23 | actual = FixedLengthFormat.decodeFromString(Sample.serializer(), flf) 24 | ) 25 | } 26 | 27 | @Test 28 | fun list() { 29 | val flf = """ 30 | ShortLong 0 42.3 1970-01-01T00:00:00ZTwo 0 foo4.0true0 f41.018false1 1 4.0 -1 31 | ShortLong 1 42.3 1970-01-01T00:00:00ZTwo 1 foo4.0true0 f41.018false1 1 4.0 -1 32 | ShortLong 2 42.3 1970-01-01T00:00:00ZTwo 2 foo4.0true0 f41.018false1 1 4.0 -1 33 | """.trimIndent() 34 | 35 | assertEquals( 36 | expected = List(3) { 37 | Sample( 38 | shortString = "Short", 39 | longString = "Long", 40 | int = it, 41 | double = 42.3, 42 | nil = null, 43 | date = Instant.fromEpochSeconds(0L), 44 | enum = Sample.Testing.Two, 45 | inline = Sample.Foo(it), 46 | inlineS = Sample.FooS("foo"), 47 | inlineD = Sample.FooD(4.0), 48 | inlineB = Sample.FooB(true), 49 | inlineL = Sample.FooL(0L), 50 | inlineChar = Sample.FooChar('f'), 51 | inlineShort = Sample.FooShort(4.toShort()), 52 | inlineFloat = Sample.FooFloat(1.0), 53 | inlineByte = Sample.FooByte(1.toByte()), 54 | innerClass = Sample.Inner(8), 55 | boolean = false, 56 | byte = 1.toByte(), 57 | short = 1.toShort(), 58 | float = 4.0, 59 | long = -1L, 60 | char = ' ' 61 | ) 62 | }, 63 | actual = FixedLengthFormat.decodeFromString(ListSerializer(Sample.serializer()), flf) 64 | ) 65 | } 66 | 67 | @Test 68 | fun sequence() { 69 | val flf = sequence { 70 | yield("ShortLong 0 42.3 1970-01-01T00:00:00ZTwo 0 foo4.0true0 f41.018false1 1 4.0 -1 ") 71 | yield("ShortLong 1 42.3 1970-01-01T00:00:00ZTwo 1 foo4.0true0 f41.018false1 1 4.0 -1 ") 72 | yield("ShortLong 2 42.3 1970-01-01T00:00:00ZTwo 2 foo4.0true0 f41.018false1 1 4.0 -1 ") 73 | }.constrainOnce() 74 | val actual = flf.decode(Sample.serializer()) 75 | 76 | assertEquals( 77 | expected = List(3) { 78 | Sample( 79 | shortString = "Short", 80 | longString = "Long", 81 | int = it, 82 | double = 42.3, 83 | nil = null, 84 | date = Instant.fromEpochSeconds(0L), 85 | enum = Sample.Testing.Two, 86 | inline = Sample.Foo(it), 87 | inlineS = Sample.FooS("foo"), 88 | inlineD = Sample.FooD(4.0), 89 | inlineB = Sample.FooB(true), 90 | inlineL = Sample.FooL(0L), 91 | inlineChar = Sample.FooChar('f'), 92 | inlineShort = Sample.FooShort(4.toShort()), 93 | inlineFloat = Sample.FooFloat(1.0), 94 | inlineByte = Sample.FooByte(1.toByte()), 95 | innerClass = Sample.Inner(8), 96 | boolean = false, 97 | byte = 1.toByte(), 98 | short = 1.toShort(), 99 | float = 4.0, 100 | long = -1L, 101 | char = ' ' 102 | ) 103 | }, 104 | actual = actual.toList() 105 | ) 106 | 107 | val constrainOnce = assertFailsWith { 108 | flf.decode(Sample.serializer()).count() 109 | } 110 | assertEquals("This sequence can be consumed only once.", constrainOnce.message!!) 111 | } 112 | 113 | @Test 114 | fun primitives() { 115 | assertFailsWith { 116 | FixedLengthFormat.decodeFromString(Int.serializer(), "") 117 | } 118 | assertFailsWith { 119 | FixedLengthFormat.decodeFromString(Boolean.serializer(), "") 120 | } 121 | assertFailsWith { 122 | FixedLengthFormat.decodeFromString(String.serializer(), "") 123 | } 124 | assertFailsWith { 125 | FixedLengthFormat.decodeFromString(Double.serializer(), "") 126 | } 127 | assertFailsWith { 128 | FixedLengthFormat.decodeFromString(Float.serializer(), "") 129 | } 130 | assertFailsWith { 131 | FixedLengthFormat.decodeFromString(Byte.serializer(), "") 132 | } 133 | assertFailsWith { 134 | FixedLengthFormat.decodeFromString(Char.serializer(), "") 135 | } 136 | assertFailsWith { 137 | FixedLengthFormat.decodeFromString(Long.serializer(), "") 138 | } 139 | assertFailsWith { 140 | FixedLengthFormat.decodeFromString(Short.serializer(), "") 141 | } 142 | assertFailsWith { 143 | FixedLengthFormat.decodeFromString(Int.serializer().nullable, "") 144 | } 145 | } 146 | 147 | @Test 148 | fun missingFixedLength() { 149 | assertFailsWith { 150 | FixedLengthFormat.decodeFromString(Missing.serializer(), "") 151 | } 152 | } 153 | 154 | @Test 155 | fun enumTest() { 156 | assertFailsWith { 157 | FixedLengthFormat.decodeFromString(Sample.Testing.serializer(), "One") 158 | } 159 | } 160 | 161 | @Test 162 | fun inlineTest() { 163 | assertFailsWith { 164 | FixedLengthFormat.decodeFromString(Sample.FooShort.serializer(), "1") 165 | } 166 | } 167 | 168 | @Test 169 | fun sealed() { 170 | val flf = """ 171 | A421 172 | Bfoo 2 173 | """.trimIndent() 174 | 175 | assertEquals( 176 | expected = listOf( 177 | Seal.A(42, 1), 178 | Seal.B("foo", 2) 179 | ), 180 | actual = FixedLengthFormat.decodeFromString(ListSerializer(Seal.serializer()), flf) 181 | ) 182 | } 183 | 184 | @Test 185 | fun innerList() { 186 | val flf = """ 187 | 2fooA421 Bfoo 2 188 | """.trimIndent() 189 | assertEquals( 190 | expected = InnerList( 191 | 2, 192 | "foo", 193 | listOf( 194 | Seal.A(42, 1), 195 | Seal.B("foo", 2) 196 | ) 197 | ), 198 | actual = FixedLengthFormat.decodeFromString(InnerList.serializer(), flf) 199 | ) 200 | } 201 | 202 | @Test 203 | fun innerListFailing() { 204 | val flf = """ 205 | fooA421 Bfoo 2 2 206 | """.trimIndent() 207 | assertFailsWith { 208 | FixedLengthFormat.decodeFromString(InnerListFailing.serializer(), flf) 209 | } 210 | } 211 | 212 | @Test 213 | fun sealedProperty() { 214 | val flf = FixedLengthFormat.decodeFromString( 215 | deserializer = ListSerializer(SealedWithProperty.serializer()), 216 | string = """ 217 | A 42421 218 | B 42foo 2 219 | """.trimIndent() 220 | ) 221 | assertEquals( 222 | expected = listOf( 223 | SealedWithProperty(Seal.A.serializer().descriptor.serialName, 42, Seal.A(42, 1)), 224 | SealedWithProperty(Seal.B.serializer().descriptor.serialName, 42, Seal.B("foo", 2)) 225 | ), 226 | actual = flf 227 | ) 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/src/commonTest/kotlin/app/softwork/serialization/csv/CsvEncoderTest.kt: -------------------------------------------------------------------------------- 1 | package app.softwork.serialization.csv 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.builtins.ListSerializer 5 | import kotlin.test.Test 6 | import kotlin.test.assertEquals 7 | import kotlin.test.assertFailsWith 8 | import kotlin.time.Instant 9 | 10 | @ExperimentalSerializationApi 11 | class CsvEncoderTest { 12 | 13 | @Test 14 | fun normal() { 15 | val csv = CSVFormat.encodeToString(Foo.serializer(), Foo(bar = 42)) 16 | assertEquals( 17 | expected = """ 18 | bar 19 | 42 20 | """.trimIndent(), 21 | actual = csv 22 | ) 23 | } 24 | 25 | @Test 26 | fun named() { 27 | val csv = CSVFormat.encodeToString(FooNamed.serializer(), FooNamed(bar = 42)) 28 | assertEquals( 29 | expected = """ 30 | foo 31 | 42 32 | """.trimIndent(), 33 | actual = csv 34 | ) 35 | } 36 | 37 | @Test 38 | fun nullableSecond() { 39 | val csv = CSVFormat.encodeToString(FooNull.serializer(), FooNull(bar = 42, baz = null)) 40 | assertEquals( 41 | expected = """ 42 | bar,baz 43 | 42, 44 | """.trimIndent(), 45 | actual = csv 46 | ) 47 | } 48 | 49 | @Test 50 | fun nullableFirst() { 51 | val csv = CSVFormat.encodeToString(FooNullFirst.serializer(), FooNullFirst(baz = null, bar = 42)) 52 | assertEquals( 53 | expected = """ 54 | baz,bar 55 | ,42 56 | """.trimIndent(), 57 | actual = csv 58 | ) 59 | } 60 | 61 | @Test 62 | fun nested() { 63 | val csv = CSVFormat.encodeToString( 64 | serializer = FooNested.serializer(), 65 | value = FooNested( 66 | baz = 42, 67 | child = FooNullFirst(baz = null, bar = 42), 68 | foo = 1 69 | ) 70 | ) 71 | assertEquals( 72 | expected = """ 73 | baz,baz,bar,foo 74 | 42,,42,1 75 | """.trimIndent(), 76 | actual = csv 77 | ) 78 | } 79 | 80 | @Test 81 | fun nestedList() { 82 | assertFailsWith { 83 | val csv = CSVFormat.encodeToString( 84 | serializer = FooList.serializer(), 85 | value = FooList( 86 | baz = 42, 87 | child = listOf( 88 | FooNullFirst(baz = null, bar = 1), 89 | FooNullFirst(baz = null, bar = 2) 90 | ) 91 | ) 92 | ) 93 | assertEquals( 94 | expected = """ 95 | baz,baz,bar,baz,bar 96 | 42,,1,,2 97 | """.trimIndent(), 98 | actual = csv 99 | ) 100 | } 101 | } 102 | 103 | @Test 104 | fun list() { 105 | val csv = CSVFormat.encodeToString( 106 | serializer = ListSerializer(elementSerializer = FooNested.serializer()), 107 | value = List(size = 3) { 108 | FooNested( 109 | baz = 42, 110 | child = FooNullFirst(baz = null, bar = it), 111 | foo = it * 10 112 | ) 113 | } 114 | ) 115 | 116 | assertEquals( 117 | expected = """ 118 | baz,baz,bar,foo 119 | 42,,0,0 120 | 42,,1,10 121 | 42,,2,20 122 | """.trimIndent(), 123 | actual = csv 124 | ) 125 | } 126 | 127 | @Test 128 | fun emptyListTest() { 129 | val csv = CSVFormat.encodeToString(ListSerializer(FooNested.serializer()), emptyList()) 130 | 131 | assertEquals( 132 | expected = """ 133 | baz,baz,bar,foo 134 | """.trimIndent(), 135 | actual = csv 136 | ) 137 | } 138 | 139 | @Test 140 | fun enumTest() { 141 | val csv = CSVFormat.encodeToString( 142 | serializer = FooEnum.serializer(), 143 | value = FooEnum( 144 | baz = null, 145 | foo = FooEnum.A.One 146 | ) 147 | ) 148 | 149 | assertEquals( 150 | expected = """ 151 | baz,foo 152 | ,One 153 | """.trimIndent(), 154 | actual = csv 155 | ) 156 | } 157 | 158 | @Test 159 | fun inlineTest() { 160 | val csv = CSVFormat.encodeToString(FooInline.serializer(), FooInline(42.42)) 161 | 162 | assertEquals( 163 | expected = """ 164 | foo 165 | 42.42 166 | """.trimIndent(), 167 | actual = csv 168 | ) 169 | } 170 | 171 | @Test 172 | fun complexTest() { 173 | val csv = CSVFormat.encodeToString( 174 | serializer = ListSerializer(FooComplex.serializer()), 175 | value = List(size = 3) { 176 | FooComplex( 177 | bar = if (it == 1) "Something" else null, 178 | inline = FooInline(42.42), 179 | enum = FooEnum.A.Three, 180 | instant = Instant.fromEpochSeconds(it.toLong()) 181 | ) 182 | } 183 | ) 184 | 185 | assertEquals( 186 | expected = """ 187 | bar,foo,enum,instant 188 | ,42.42,Three,1970-01-01T00:00:00Z 189 | Something,42.42,Three,1970-01-01T00:00:01Z 190 | ,42.42,Three,1970-01-01T00:00:02Z 191 | """.trimIndent(), 192 | actual = csv 193 | ) 194 | } 195 | 196 | @Test 197 | fun custom() { 198 | val csv = CSVFormat { 199 | separator = ';' 200 | lineSeparator = "\r\n" 201 | }.encodeToString( 202 | FooNull.serializer(), 203 | FooNull(bar = 42, baz = null) 204 | ) 205 | 206 | assertEquals( 207 | expected = "bar;baz\r\n42;", 208 | actual = csv 209 | ) 210 | } 211 | 212 | @Test 213 | fun numberFormatTest() { 214 | val csv = CSVFormat { 215 | separator = ';' 216 | lineSeparator = "\r\n" 217 | numberFormat = CSVFormat.NumberFormat.Comma 218 | }.encodeToString( 219 | serializer = ListSerializer(FooComplex.serializer()), 220 | value = List(size = 3) { 221 | FooComplex( 222 | bar = if (it == 1) "Something" else null, 223 | inline = FooInline(42.42), 224 | enum = FooEnum.A.Three, 225 | instant = Instant.fromEpochSeconds(it.toLong()) 226 | ) 227 | } 228 | ) 229 | 230 | assertEquals( 231 | expected = "bar;foo;enum;instant\r\n;42,42;Three;1970-01-01T00:00:00Z\r\nSomething;42,42;Three;1970-01-01T00:00:01Z\r\n;42,42;Three;1970-01-01T00:00:02Z", 232 | actual = csv 233 | ) 234 | } 235 | 236 | @Test 237 | fun checkForPolymorphicClasses() { 238 | assertFailsWith { 239 | CSVFormat.encodeToString(ListSerializer(Sealed.serializer()), emptyList()) 240 | } 241 | } 242 | 243 | @Test 244 | fun customList() { 245 | val csv = CSVFormat { 246 | separator = ';' 247 | lineSeparator = "\r\n" 248 | includeHeader = false 249 | }.encodeToString( 250 | ListSerializer(Sealed.serializer()), 251 | listOf( 252 | Sealed.Foo("Hello ;from\r\nWorld"), 253 | Sealed.Bar(42) 254 | ) 255 | ) 256 | 257 | assertEquals( 258 | expected = "foo;\"Hello ;from\r\nWorld\"\r\nbar;42", 259 | actual = csv 260 | ) 261 | } 262 | 263 | @Test 264 | fun alwaysQuote() { 265 | val csv = CSVFormat { 266 | alwaysEmitQuotes = true 267 | }.encodeToString( 268 | ListSerializer(FooString.serializer()), 269 | listOf( 270 | FooString(42, "ff\"", 42), 271 | FooString(42, "newLine\nff", 42), 272 | ) 273 | ) 274 | 275 | assertEquals( 276 | expected = "\"bar\",\"value\",\"foo\"\n\"42\",\"ff\"\"\",\"42\"\n\"42\",\"newLine\nff\",\"42\"", 277 | actual = csv 278 | ) 279 | } 280 | 281 | @Test 282 | fun alwaysQuoteWithoutHeader() { 283 | val csv = CSVFormat { 284 | alwaysEmitQuotes = true 285 | includeHeader = false 286 | }.encodeToString( 287 | ListSerializer(Sealed.serializer()), 288 | listOf(Sealed.Foo("Hello from\nWorld"), Sealed.Bar(42)) 289 | ) 290 | 291 | assertEquals( 292 | expected = "\"foo\",\"Hello from\nWorld\"\n\"bar\",\"42\"", 293 | actual = csv 294 | ) 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /kotlinx-serialization-csv/api/kotlinx-serialization-csv.klib.api: -------------------------------------------------------------------------------- 1 | // Klib ABI Dump 2 | // Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] 3 | // Rendering settings: 4 | // - Signature version: 2 5 | // - Show manifest properties: true 6 | // - Show declarations: true 7 | 8 | // Library unique name: 9 | abstract interface app.softwork.serialization.csv/CSVDecoder : kotlinx.serialization.encoding/CompositeDecoder, kotlinx.serialization.encoding/Decoder { // app.softwork.serialization.csv/CSVDecoder|null[0] 10 | abstract val configuration // app.softwork.serialization.csv/CSVDecoder.configuration|{}configuration[0] 11 | abstract fun (): app.softwork.serialization.csv/CSVConfiguration // app.softwork.serialization.csv/CSVDecoder.configuration.|(){}[0] 12 | } 13 | 14 | abstract interface app.softwork.serialization.csv/CSVEncoder : kotlinx.serialization.encoding/CompositeEncoder, kotlinx.serialization.encoding/Encoder { // app.softwork.serialization.csv/CSVEncoder|null[0] 15 | abstract val configuration // app.softwork.serialization.csv/CSVEncoder.configuration|{}configuration[0] 16 | abstract fun (): app.softwork.serialization.csv/CSVConfiguration // app.softwork.serialization.csv/CSVEncoder.configuration.|(){}[0] 17 | } 18 | 19 | final class app.softwork.serialization.csv/CSVConfiguration { // app.softwork.serialization.csv/CSVConfiguration|null[0] 20 | final val alwaysEmitQuotes // app.softwork.serialization.csv/CSVConfiguration.alwaysEmitQuotes|{}alwaysEmitQuotes[0] 21 | final fun (): kotlin/Boolean // app.softwork.serialization.csv/CSVConfiguration.alwaysEmitQuotes.|(){}[0] 22 | final val includeHeader // app.softwork.serialization.csv/CSVConfiguration.includeHeader|{}includeHeader[0] 23 | final fun (): kotlin/Boolean // app.softwork.serialization.csv/CSVConfiguration.includeHeader.|(){}[0] 24 | final val lineSeparator // app.softwork.serialization.csv/CSVConfiguration.lineSeparator|{}lineSeparator[0] 25 | final fun (): kotlin/String // app.softwork.serialization.csv/CSVConfiguration.lineSeparator.|(){}[0] 26 | final val numberFormat // app.softwork.serialization.csv/CSVConfiguration.numberFormat|{}numberFormat[0] 27 | final fun (): app.softwork.serialization.csv/CSVFormat.NumberFormat // app.softwork.serialization.csv/CSVConfiguration.numberFormat.|(){}[0] 28 | final val separator // app.softwork.serialization.csv/CSVConfiguration.separator|{}separator[0] 29 | final fun (): kotlin/Char // app.softwork.serialization.csv/CSVConfiguration.separator.|(){}[0] 30 | final val serializersModule // app.softwork.serialization.csv/CSVConfiguration.serializersModule|{}serializersModule[0] 31 | final fun (): kotlinx.serialization.modules/SerializersModule // app.softwork.serialization.csv/CSVConfiguration.serializersModule.|(){}[0] 32 | 33 | final class Builder { // app.softwork.serialization.csv/CSVConfiguration.Builder|null[0] 34 | constructor () // app.softwork.serialization.csv/CSVConfiguration.Builder.|(){}[0] 35 | 36 | final var alwaysEmitQuotes // app.softwork.serialization.csv/CSVConfiguration.Builder.alwaysEmitQuotes|{}alwaysEmitQuotes[0] 37 | final fun (): kotlin/Boolean // app.softwork.serialization.csv/CSVConfiguration.Builder.alwaysEmitQuotes.|(){}[0] 38 | final fun (kotlin/Boolean) // app.softwork.serialization.csv/CSVConfiguration.Builder.alwaysEmitQuotes.|(kotlin.Boolean){}[0] 39 | final var includeHeader // app.softwork.serialization.csv/CSVConfiguration.Builder.includeHeader|{}includeHeader[0] 40 | final fun (): kotlin/Boolean // app.softwork.serialization.csv/CSVConfiguration.Builder.includeHeader.|(){}[0] 41 | final fun (kotlin/Boolean) // app.softwork.serialization.csv/CSVConfiguration.Builder.includeHeader.|(kotlin.Boolean){}[0] 42 | final var lineSeparator // app.softwork.serialization.csv/CSVConfiguration.Builder.lineSeparator|{}lineSeparator[0] 43 | final fun (): kotlin/String // app.softwork.serialization.csv/CSVConfiguration.Builder.lineSeparator.|(){}[0] 44 | final fun (kotlin/String) // app.softwork.serialization.csv/CSVConfiguration.Builder.lineSeparator.|(kotlin.String){}[0] 45 | final var numberFormat // app.softwork.serialization.csv/CSVConfiguration.Builder.numberFormat|{}numberFormat[0] 46 | final fun (): app.softwork.serialization.csv/CSVFormat.NumberFormat // app.softwork.serialization.csv/CSVConfiguration.Builder.numberFormat.|(){}[0] 47 | final fun (app.softwork.serialization.csv/CSVFormat.NumberFormat) // app.softwork.serialization.csv/CSVConfiguration.Builder.numberFormat.|(app.softwork.serialization.csv.CSVFormat.NumberFormat){}[0] 48 | final var separator // app.softwork.serialization.csv/CSVConfiguration.Builder.separator|{}separator[0] 49 | final fun (): kotlin/Char // app.softwork.serialization.csv/CSVConfiguration.Builder.separator.|(){}[0] 50 | final fun (kotlin/Char) // app.softwork.serialization.csv/CSVConfiguration.Builder.separator.|(kotlin.Char){}[0] 51 | final var serializersModule // app.softwork.serialization.csv/CSVConfiguration.Builder.serializersModule|{}serializersModule[0] 52 | final fun (): kotlinx.serialization.modules/SerializersModule // app.softwork.serialization.csv/CSVConfiguration.Builder.serializersModule.|(){}[0] 53 | final fun (kotlinx.serialization.modules/SerializersModule) // app.softwork.serialization.csv/CSVConfiguration.Builder.serializersModule.|(kotlinx.serialization.modules.SerializersModule){}[0] 54 | } 55 | } 56 | 57 | sealed class app.softwork.serialization.csv/CSVFormat : kotlinx.serialization/StringFormat { // app.softwork.serialization.csv/CSVFormat|null[0] 58 | final val configuration // app.softwork.serialization.csv/CSVFormat.configuration|{}configuration[0] 59 | final fun (): app.softwork.serialization.csv/CSVConfiguration // app.softwork.serialization.csv/CSVFormat.configuration.|(){}[0] 60 | open val serializersModule // app.softwork.serialization.csv/CSVFormat.serializersModule|{}serializersModule[0] 61 | open fun (): kotlinx.serialization.modules/SerializersModule // app.softwork.serialization.csv/CSVFormat.serializersModule.|(){}[0] 62 | 63 | open fun <#A1: kotlin/Any?> decodeFromString(kotlinx.serialization/DeserializationStrategy<#A1>, kotlin/String): #A1 // app.softwork.serialization.csv/CSVFormat.decodeFromString|decodeFromString(kotlinx.serialization.DeserializationStrategy<0:0>;kotlin.String){0§}[0] 64 | open fun <#A1: kotlin/Any?> encodeToString(kotlinx.serialization/SerializationStrategy<#A1>, #A1): kotlin/String // app.softwork.serialization.csv/CSVFormat.encodeToString|encodeToString(kotlinx.serialization.SerializationStrategy<0:0>;0:0){0§}[0] 65 | 66 | final enum class NumberFormat : kotlin/Enum { // app.softwork.serialization.csv/CSVFormat.NumberFormat|null[0] 67 | enum entry Comma // app.softwork.serialization.csv/CSVFormat.NumberFormat.Comma|null[0] 68 | enum entry Dot // app.softwork.serialization.csv/CSVFormat.NumberFormat.Dot|null[0] 69 | 70 | final val entries // app.softwork.serialization.csv/CSVFormat.NumberFormat.entries|#static{}entries[0] 71 | final fun (): kotlin.enums/EnumEntries // app.softwork.serialization.csv/CSVFormat.NumberFormat.entries.|#static(){}[0] 72 | 73 | final fun valueOf(kotlin/String): app.softwork.serialization.csv/CSVFormat.NumberFormat // app.softwork.serialization.csv/CSVFormat.NumberFormat.valueOf|valueOf#static(kotlin.String){}[0] 74 | final fun values(): kotlin/Array // app.softwork.serialization.csv/CSVFormat.NumberFormat.values|values#static(){}[0] 75 | } 76 | 77 | final object Default : app.softwork.serialization.csv/CSVFormat { // app.softwork.serialization.csv/CSVFormat.Default|null[0] 78 | final fun invoke(kotlin/Function1): app.softwork.serialization.csv/CSVFormat // app.softwork.serialization.csv/CSVFormat.Default.invoke|invoke(kotlin.Function1){}[0] 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH="\\\"\\\"" 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | if ! command -v java >/dev/null 2>&1 137 | then 138 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 139 | 140 | Please set the JAVA_HOME variable in your environment to match the 141 | location of your Java installation." 142 | fi 143 | fi 144 | 145 | # Increase the maximum file descriptors if we can. 146 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 147 | case $MAX_FD in #( 148 | max*) 149 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 150 | # shellcheck disable=SC2039,SC3045 151 | MAX_FD=$( ulimit -H -n ) || 152 | warn "Could not query maximum file descriptor limit" 153 | esac 154 | case $MAX_FD in #( 155 | '' | soft) :;; #( 156 | *) 157 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 158 | # shellcheck disable=SC2039,SC3045 159 | ulimit -n "$MAX_FD" || 160 | warn "Could not set maximum file descriptor limit to $MAX_FD" 161 | esac 162 | fi 163 | 164 | # Collect all arguments for the java command, stacking in reverse order: 165 | # * args from the command line 166 | # * the main class name 167 | # * -classpath 168 | # * -D...appname settings 169 | # * --module-path (only if needed) 170 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 171 | 172 | # For Cygwin or MSYS, switch paths to Windows format before running java 173 | if "$cygwin" || "$msys" ; then 174 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 175 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 176 | 177 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 178 | 179 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 180 | for arg do 181 | if 182 | case $arg in #( 183 | -*) false ;; # don't mess with options #( 184 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 185 | [ -e "$t" ] ;; #( 186 | *) false ;; 187 | esac 188 | then 189 | arg=$( cygpath --path --ignore --mixed "$arg" ) 190 | fi 191 | # Roll the args list around exactly as many times as the number of 192 | # args, so each arg winds up back in the position where it started, but 193 | # possibly modified. 194 | # 195 | # NB: a `for` loop captures its iteration list before it begins, so 196 | # changing the positional parameters here affects neither the number of 197 | # iterations, nor the values presented in `arg`. 198 | shift # remove old arg 199 | set -- "$@" "$arg" # push replacement arg 200 | done 201 | fi 202 | 203 | 204 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 205 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 206 | 207 | # Collect all arguments for the java command: 208 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 209 | # and any embedded shellness will be escaped. 210 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 211 | # treated as '${Hostname}' itself on the command line. 212 | 213 | set -- \ 214 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 215 | -classpath "$CLASSPATH" \ 216 | -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ 217 | "$@" 218 | 219 | # Stop when "xargs" is not available. 220 | if ! command -v xargs >/dev/null 2>&1 221 | then 222 | die "xargs is not available" 223 | fi 224 | 225 | # Use "xargs" to parse quoted args. 226 | # 227 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 228 | # 229 | # In Bash we could simply go: 230 | # 231 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 232 | # set -- "${ARGS[@]}" "$@" 233 | # 234 | # but POSIX shell has neither arrays nor command substitution, so instead we 235 | # post-process each arg (as a line of input to sed) to backslash-escape any 236 | # character that might be a shell metacharacter, then use eval to reverse 237 | # that process (while maintaining the separation between arguments), and wrap 238 | # the whole thing up as a single "set" statement. 239 | # 240 | # This will of course break if any of these variables contains a newline or 241 | # an unmatched quote. 242 | # 243 | 244 | eval "set -- $( 245 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 246 | xargs -n1 | 247 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 248 | tr '\n' ' ' 249 | )" '"$@"' 250 | 251 | exec "$JAVACMD" "$@" 252 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/api/kotlinx-serialization-flf.api: -------------------------------------------------------------------------------- 1 | public abstract interface annotation class app/softwork/serialization/flf/Ebcdic : java/lang/annotation/Annotation { 2 | public abstract fun format ()Lapp/softwork/serialization/flf/Ebcdic$Format; 3 | } 4 | 5 | public final class app/softwork/serialization/flf/Ebcdic$Format : java/lang/Enum { 6 | public static final field Zoned Lapp/softwork/serialization/flf/Ebcdic$Format; 7 | public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V 8 | public static fun getEntries ()Lkotlin/enums/EnumEntries; 9 | public static fun valueOf (Ljava/lang/String;)Lapp/softwork/serialization/flf/Ebcdic$Format; 10 | public static fun values ()[Lapp/softwork/serialization/flf/Ebcdic$Format; 11 | } 12 | 13 | public final synthetic class app/softwork/serialization/flf/Ebcdic$Impl : app/softwork/serialization/flf/Ebcdic { 14 | public fun (Lapp/softwork/serialization/flf/Ebcdic$Format;)V 15 | public final synthetic fun format ()Lapp/softwork/serialization/flf/Ebcdic$Format; 16 | } 17 | 18 | public abstract interface annotation class app/softwork/serialization/flf/FixedLength : java/lang/annotation/Annotation { 19 | public abstract fun length ()I 20 | } 21 | 22 | public final synthetic class app/softwork/serialization/flf/FixedLength$Impl : app/softwork/serialization/flf/FixedLength { 23 | public fun (I)V 24 | public final synthetic fun length ()I 25 | } 26 | 27 | public final class app/softwork/serialization/flf/FixedLengthDecoder : app/softwork/serialization/flf/FailingPrimitiveDecoder, kotlinx/serialization/encoding/CompositeDecoder { 28 | public fun (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlinx/serialization/modules/SerializersModule;I)V 29 | public fun beginStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/CompositeDecoder; 30 | public fun decodeBoolean ()Ljava/lang/Void; 31 | public synthetic fun decodeBoolean ()Z 32 | public fun decodeBooleanElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z 33 | public synthetic fun decodeByte ()B 34 | public fun decodeByte ()Ljava/lang/Void; 35 | public fun decodeByteElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)B 36 | public synthetic fun decodeChar ()C 37 | public fun decodeChar ()Ljava/lang/Void; 38 | public fun decodeCharElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)C 39 | public fun decodeCollectionSize (Lkotlinx/serialization/descriptors/SerialDescriptor;)I 40 | public synthetic fun decodeDouble ()D 41 | public fun decodeDouble ()Ljava/lang/Void; 42 | public fun decodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)D 43 | public synthetic fun decodeElementIndex (Lkotlinx/serialization/descriptors/SerialDescriptor;)I 44 | public fun decodeElementIndex (Lkotlinx/serialization/descriptors/SerialDescriptor;)Ljava/lang/Void; 45 | public fun decodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;)I 46 | public synthetic fun decodeFloat ()F 47 | public fun decodeFloat ()Ljava/lang/Void; 48 | public fun decodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)F 49 | public fun decodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Decoder; 50 | public fun decodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Decoder; 51 | public synthetic fun decodeInt ()I 52 | public fun decodeInt ()Ljava/lang/Void; 53 | public fun decodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)I 54 | public synthetic fun decodeLong ()J 55 | public fun decodeLong ()Ljava/lang/Void; 56 | public fun decodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)J 57 | public fun decodeNotNullMark ()Ljava/lang/Void; 58 | public synthetic fun decodeNotNullMark ()Z 59 | public fun decodeNull ()Ljava/lang/Void; 60 | public fun decodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object; 61 | public fun decodeNullableSerializableValue (Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; 62 | public fun decodeSequentially ()Z 63 | public fun decodeSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object; 64 | public fun decodeSerializableValue (Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; 65 | public fun decodeShort ()Ljava/lang/Void; 66 | public synthetic fun decodeShort ()S 67 | public fun decodeShortElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)S 68 | public synthetic fun decodeString ()Ljava/lang/String; 69 | public fun decodeString ()Ljava/lang/Void; 70 | public fun decodeStringElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Ljava/lang/String; 71 | public fun endStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)V 72 | public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 73 | } 74 | 75 | public final class app/softwork/serialization/flf/FixedLengthEncoder : app/softwork/serialization/flf/FailingPrimitiveEncoder, kotlinx/serialization/encoding/CompositeEncoder { 76 | public fun (Ljava/lang/StringBuilder;Lkotlinx/serialization/modules/SerializersModule;Ljava/lang/String;Z)V 77 | public fun beginCollection (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/CompositeEncoder; 78 | public fun beginStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/CompositeEncoder; 79 | public fun encodeBoolean (Z)V 80 | public fun encodeBooleanElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IZ)V 81 | public fun encodeByte (B)V 82 | public fun encodeByteElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IB)V 83 | public fun encodeChar (C)V 84 | public fun encodeCharElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IC)V 85 | public fun encodeDouble (D)V 86 | public fun encodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ID)V 87 | public fun encodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;I)V 88 | public fun encodeFloat (F)V 89 | public fun encodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IF)V 90 | public fun encodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Encoder; 91 | public fun encodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Encoder; 92 | public fun encodeInt (I)V 93 | public fun encodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;II)V 94 | public fun encodeLong (J)V 95 | public fun encodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IJ)V 96 | public fun encodeNotNullMark ()V 97 | public fun encodeNull ()V 98 | public fun encodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 99 | public fun encodeNullableSerializableValue (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 100 | public fun encodeSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 101 | public fun encodeSerializableValue (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 102 | public fun encodeShort (S)V 103 | public fun encodeShortElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IS)V 104 | public fun encodeString (Ljava/lang/String;)V 105 | public fun encodeStringElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/String;)V 106 | public fun endStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)V 107 | public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 108 | public fun shouldEncodeElementDefault (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z 109 | } 110 | 111 | public abstract class app/softwork/serialization/flf/FixedLengthFormat : kotlinx/serialization/StringFormat { 112 | public static final field Default Lapp/softwork/serialization/flf/FixedLengthFormat$Default; 113 | public synthetic fun (Lkotlinx/serialization/modules/SerializersModule;Ljava/lang/String;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V 114 | public final fun decodeAsSequence (Lkotlinx/serialization/DeserializationStrategy;Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; 115 | public fun decodeFromString (Lkotlinx/serialization/DeserializationStrategy;Ljava/lang/String;)Ljava/lang/Object; 116 | public final fun encodeAsSequence (Lkotlinx/serialization/SerializationStrategy;Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; 117 | public fun encodeToString (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ljava/lang/String; 118 | public final fun getLineSeparator ()Ljava/lang/String; 119 | public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 120 | } 121 | 122 | public final class app/softwork/serialization/flf/FixedLengthFormat$Default : app/softwork/serialization/flf/FixedLengthFormat { 123 | public final fun invoke ()Lapp/softwork/serialization/flf/FixedLengthFormat; 124 | public final fun invoke (Ljava/lang/String;)Lapp/softwork/serialization/flf/FixedLengthFormat; 125 | public final fun invoke (Ljava/lang/String;Z)Lapp/softwork/serialization/flf/FixedLengthFormat; 126 | public final fun invoke (Ljava/lang/String;ZLkotlinx/serialization/modules/SerializersModule;)Lapp/softwork/serialization/flf/FixedLengthFormat; 127 | public static synthetic fun invoke$default (Lapp/softwork/serialization/flf/FixedLengthFormat$Default;Ljava/lang/String;ZLkotlinx/serialization/modules/SerializersModule;ILjava/lang/Object;)Lapp/softwork/serialization/flf/FixedLengthFormat; 128 | } 129 | 130 | public final class app/softwork/serialization/flf/FixedLengthFormatKt { 131 | public static final fun decode (Lkotlin/sequences/Sequence;Lkotlinx/serialization/DeserializationStrategy;)Lkotlin/sequences/Sequence; 132 | public static final fun decode (Lkotlin/sequences/Sequence;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;)Lkotlin/sequences/Sequence; 133 | public static synthetic fun decode$default (Lkotlin/sequences/Sequence;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)Lkotlin/sequences/Sequence; 134 | public static final fun encode (Lkotlin/sequences/Sequence;Lkotlinx/serialization/SerializationStrategy;)Lkotlin/sequences/Sequence; 135 | public static final fun encode (Lkotlin/sequences/Sequence;Lkotlinx/serialization/SerializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;)Lkotlin/sequences/Sequence; 136 | public static synthetic fun encode$default (Lkotlin/sequences/Sequence;Lkotlinx/serialization/SerializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)Lkotlin/sequences/Sequence; 137 | } 138 | 139 | public abstract interface annotation class app/softwork/serialization/flf/FixedLengthList : java/lang/annotation/Annotation { 140 | public abstract fun serialName ()Ljava/lang/String; 141 | } 142 | 143 | public final synthetic class app/softwork/serialization/flf/FixedLengthList$Impl : app/softwork/serialization/flf/FixedLengthList { 144 | public fun (Ljava/lang/String;)V 145 | public final synthetic fun serialName ()Ljava/lang/String; 146 | } 147 | 148 | public abstract interface annotation class app/softwork/serialization/flf/FixedLengthSealedClassDiscriminator : java/lang/annotation/Annotation { 149 | public abstract fun serialName ()Ljava/lang/String; 150 | } 151 | 152 | public final synthetic class app/softwork/serialization/flf/FixedLengthSealedClassDiscriminator$Impl : app/softwork/serialization/flf/FixedLengthSealedClassDiscriminator { 153 | public fun (Ljava/lang/String;)V 154 | public final synthetic fun serialName ()Ljava/lang/String; 155 | } 156 | 157 | public abstract interface annotation class app/softwork/serialization/flf/FixedLengthSealedClassDiscriminatorLength : java/lang/annotation/Annotation { 158 | public abstract fun length ()I 159 | } 160 | 161 | public final synthetic class app/softwork/serialization/flf/FixedLengthSealedClassDiscriminatorLength$Impl : app/softwork/serialization/flf/FixedLengthSealedClassDiscriminatorLength { 162 | public fun (I)V 163 | public final synthetic fun length ()I 164 | } 165 | 166 | public final class app/softwork/serialization/flf/SequenceWriteLinesKt { 167 | public static final fun append (Ljava/lang/Appendable;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 168 | public static final fun append (Ljava/lang/Appendable;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lapp/softwork/serialization/flf/FixedLengthFormat;)V 169 | public static synthetic fun append$default (Ljava/lang/Appendable;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)V 170 | public static final fun appendLine (Ljava/lang/Appendable;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V 171 | public static final fun appendLine (Ljava/lang/Appendable;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lapp/softwork/serialization/flf/FixedLengthFormat;)V 172 | public static synthetic fun appendLine$default (Ljava/lang/Appendable;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)V 173 | public static final fun appendLines (Lkotlin/sequences/Sequence;Ljava/io/File;)V 174 | public static final fun appendLines (Lkotlin/sequences/Sequence;Ljava/io/File;Ljava/nio/charset/Charset;)V 175 | public static final fun appendLines (Lkotlin/sequences/Sequence;Ljava/io/File;Ljava/nio/charset/Charset;Ljava/lang/String;)V 176 | public static synthetic fun appendLines$default (Lkotlin/sequences/Sequence;Ljava/io/File;Ljava/nio/charset/Charset;Ljava/lang/String;ILjava/lang/Object;)V 177 | public static final fun decode (Ljava/lang/Readable;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Iterable; 178 | public static final fun decode (Ljava/lang/Readable;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;)Ljava/lang/Iterable; 179 | public static final fun decode (Ljava/util/stream/Stream;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Iterable; 180 | public static final fun decode (Ljava/util/stream/Stream;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;)Ljava/lang/Iterable; 181 | public static synthetic fun decode$default (Ljava/lang/Readable;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)Ljava/lang/Iterable; 182 | public static synthetic fun decode$default (Ljava/util/stream/Stream;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)Ljava/lang/Iterable; 183 | public static final fun decodeStream (Ljava/util/stream/Stream;Lkotlinx/serialization/DeserializationStrategy;)Ljava/util/stream/Stream; 184 | public static final fun decodeStream (Ljava/util/stream/Stream;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;)Ljava/util/stream/Stream; 185 | public static synthetic fun decodeStream$default (Ljava/util/stream/Stream;Lkotlinx/serialization/DeserializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)Ljava/util/stream/Stream; 186 | public static final fun encode (Ljava/util/stream/Stream;Lkotlinx/serialization/SerializationStrategy;)Ljava/lang/Iterable; 187 | public static final fun encode (Ljava/util/stream/Stream;Lkotlinx/serialization/SerializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;)Ljava/lang/Iterable; 188 | public static synthetic fun encode$default (Ljava/util/stream/Stream;Lkotlinx/serialization/SerializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)Ljava/lang/Iterable; 189 | public static final fun encodeStream (Ljava/util/stream/Stream;Lkotlinx/serialization/SerializationStrategy;)Ljava/util/stream/Stream; 190 | public static final fun encodeStream (Ljava/util/stream/Stream;Lkotlinx/serialization/SerializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;)Ljava/util/stream/Stream; 191 | public static synthetic fun encodeStream$default (Ljava/util/stream/Stream;Lkotlinx/serialization/SerializationStrategy;Lapp/softwork/serialization/flf/FixedLengthFormat;ILjava/lang/Object;)Ljava/util/stream/Stream; 192 | public static final fun writeLines (Lkotlin/sequences/Sequence;Ljava/io/File;)V 193 | public static final fun writeLines (Lkotlin/sequences/Sequence;Ljava/io/File;Ljava/nio/charset/Charset;)V 194 | public static final fun writeLines (Lkotlin/sequences/Sequence;Ljava/io/File;Ljava/nio/charset/Charset;Ljava/lang/String;)V 195 | public static synthetic fun writeLines$default (Lkotlin/sequences/Sequence;Ljava/io/File;Ljava/nio/charset/Charset;Ljava/lang/String;ILjava/lang/Object;)V 196 | } 197 | 198 | -------------------------------------------------------------------------------- /kotlinx-serialization-flf/api/kotlinx-serialization-flf.klib.api: -------------------------------------------------------------------------------- 1 | // Klib ABI Dump 2 | // Targets: [androidNativeArm32, androidNativeArm64, androidNativeX64, androidNativeX86, iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64] 3 | // Rendering settings: 4 | // - Signature version: 2 5 | // - Show manifest properties: true 6 | // - Show declarations: true 7 | 8 | // Library unique name: 9 | open annotation class app.softwork.serialization.flf/Ebcdic : kotlin/Annotation { // app.softwork.serialization.flf/Ebcdic|null[0] 10 | constructor (app.softwork.serialization.flf/Ebcdic.Format) // app.softwork.serialization.flf/Ebcdic.|(app.softwork.serialization.flf.Ebcdic.Format){}[0] 11 | 12 | final val format // app.softwork.serialization.flf/Ebcdic.format|{}format[0] 13 | final fun (): app.softwork.serialization.flf/Ebcdic.Format // app.softwork.serialization.flf/Ebcdic.format.|(){}[0] 14 | 15 | abstract enum class Format : kotlin/Enum { // app.softwork.serialization.flf/Ebcdic.Format|null[0] 16 | enum entry Zoned // app.softwork.serialization.flf/Ebcdic.Format.Zoned|null[0] 17 | 18 | final val entries // app.softwork.serialization.flf/Ebcdic.Format.entries|#static{}entries[0] 19 | final fun (): kotlin.enums/EnumEntries // app.softwork.serialization.flf/Ebcdic.Format.entries.|#static(){}[0] 20 | 21 | final fun valueOf(kotlin/String): app.softwork.serialization.flf/Ebcdic.Format // app.softwork.serialization.flf/Ebcdic.Format.valueOf|valueOf#static(kotlin.String){}[0] 22 | final fun values(): kotlin/Array // app.softwork.serialization.flf/Ebcdic.Format.values|values#static(){}[0] 23 | } 24 | } 25 | 26 | open annotation class app.softwork.serialization.flf/FixedLength : kotlin/Annotation { // app.softwork.serialization.flf/FixedLength|null[0] 27 | constructor (kotlin/Int) // app.softwork.serialization.flf/FixedLength.|(kotlin.Int){}[0] 28 | 29 | final val length // app.softwork.serialization.flf/FixedLength.length|{}length[0] 30 | final fun (): kotlin/Int // app.softwork.serialization.flf/FixedLength.length.|(){}[0] 31 | } 32 | 33 | open annotation class app.softwork.serialization.flf/FixedLengthList : kotlin/Annotation { // app.softwork.serialization.flf/FixedLengthList|null[0] 34 | constructor (kotlin/String) // app.softwork.serialization.flf/FixedLengthList.|(kotlin.String){}[0] 35 | 36 | final val serialName // app.softwork.serialization.flf/FixedLengthList.serialName|{}serialName[0] 37 | final fun (): kotlin/String // app.softwork.serialization.flf/FixedLengthList.serialName.|(){}[0] 38 | } 39 | 40 | open annotation class app.softwork.serialization.flf/FixedLengthSealedClassDiscriminator : kotlin/Annotation { // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminator|null[0] 41 | constructor (kotlin/String) // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminator.|(kotlin.String){}[0] 42 | 43 | final val serialName // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminator.serialName|{}serialName[0] 44 | final fun (): kotlin/String // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminator.serialName.|(){}[0] 45 | } 46 | 47 | open annotation class app.softwork.serialization.flf/FixedLengthSealedClassDiscriminatorLength : kotlin/Annotation { // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminatorLength|null[0] 48 | constructor (kotlin/Int) // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminatorLength.|(kotlin.Int){}[0] 49 | 50 | final val length // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminatorLength.length|{}length[0] 51 | final fun (): kotlin/Int // app.softwork.serialization.flf/FixedLengthSealedClassDiscriminatorLength.length.|(){}[0] 52 | } 53 | 54 | final class app.softwork.serialization.flf/FixedLengthDecoder : app.softwork.serialization.flf/FailingPrimitiveDecoder, kotlinx.serialization.encoding/CompositeDecoder { // app.softwork.serialization.flf/FixedLengthDecoder|null[0] 55 | constructor (kotlin/Function0, kotlin/Function1, kotlinx.serialization.modules/SerializersModule, kotlin/Int) // app.softwork.serialization.flf/FixedLengthDecoder.|(kotlin.Function0;kotlin.Function1;kotlinx.serialization.modules.SerializersModule;kotlin.Int){}[0] 56 | 57 | final val serializersModule // app.softwork.serialization.flf/FixedLengthDecoder.serializersModule|{}serializersModule[0] 58 | final fun (): kotlinx.serialization.modules/SerializersModule // app.softwork.serialization.flf/FixedLengthDecoder.serializersModule.|(){}[0] 59 | 60 | final fun <#A1: kotlin/Any> decodeNullableSerializableElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlinx.serialization/DeserializationStrategy<#A1?>, #A1?): #A1? // app.softwork.serialization.flf/FixedLengthDecoder.decodeNullableSerializableElement|decodeNullableSerializableElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlinx.serialization.DeserializationStrategy<0:0?>;0:0?){0§}[0] 61 | final fun <#A1: kotlin/Any> decodeNullableSerializableValue(kotlinx.serialization/DeserializationStrategy<#A1?>): #A1? // app.softwork.serialization.flf/FixedLengthDecoder.decodeNullableSerializableValue|decodeNullableSerializableValue(kotlinx.serialization.DeserializationStrategy<0:0?>){0§}[0] 62 | final fun <#A1: kotlin/Any?> decodeSerializableElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlinx.serialization/DeserializationStrategy<#A1>, #A1?): #A1 // app.softwork.serialization.flf/FixedLengthDecoder.decodeSerializableElement|decodeSerializableElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlinx.serialization.DeserializationStrategy<0:0>;0:0?){0§}[0] 63 | final fun beginStructure(kotlinx.serialization.descriptors/SerialDescriptor): kotlinx.serialization.encoding/CompositeDecoder // app.softwork.serialization.flf/FixedLengthDecoder.beginStructure|beginStructure(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 64 | final fun decodeBooleanElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Boolean // app.softwork.serialization.flf/FixedLengthDecoder.decodeBooleanElement|decodeBooleanElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 65 | final fun decodeByteElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Byte // app.softwork.serialization.flf/FixedLengthDecoder.decodeByteElement|decodeByteElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 66 | final fun decodeCharElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Char // app.softwork.serialization.flf/FixedLengthDecoder.decodeCharElement|decodeCharElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 67 | final fun decodeCollectionSize(kotlinx.serialization.descriptors/SerialDescriptor): kotlin/Int // app.softwork.serialization.flf/FixedLengthDecoder.decodeCollectionSize|decodeCollectionSize(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 68 | final fun decodeDoubleElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Double // app.softwork.serialization.flf/FixedLengthDecoder.decodeDoubleElement|decodeDoubleElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 69 | final fun decodeElementIndex(kotlinx.serialization.descriptors/SerialDescriptor): kotlin/Nothing // app.softwork.serialization.flf/FixedLengthDecoder.decodeElementIndex|decodeElementIndex(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 70 | final fun decodeEnum(kotlinx.serialization.descriptors/SerialDescriptor): kotlin/Int // app.softwork.serialization.flf/FixedLengthDecoder.decodeEnum|decodeEnum(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 71 | final fun decodeFloatElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Float // app.softwork.serialization.flf/FixedLengthDecoder.decodeFloatElement|decodeFloatElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 72 | final fun decodeInline(kotlinx.serialization.descriptors/SerialDescriptor): kotlinx.serialization.encoding/Decoder // app.softwork.serialization.flf/FixedLengthDecoder.decodeInline|decodeInline(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 73 | final fun decodeInlineElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlinx.serialization.encoding/Decoder // app.softwork.serialization.flf/FixedLengthDecoder.decodeInlineElement|decodeInlineElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 74 | final fun decodeIntElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Int // app.softwork.serialization.flf/FixedLengthDecoder.decodeIntElement|decodeIntElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 75 | final fun decodeLongElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Long // app.softwork.serialization.flf/FixedLengthDecoder.decodeLongElement|decodeLongElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 76 | final fun decodeNotNullMark(): kotlin/Nothing // app.softwork.serialization.flf/FixedLengthDecoder.decodeNotNullMark|decodeNotNullMark(){}[0] 77 | final fun decodeSequentially(): kotlin/Boolean // app.softwork.serialization.flf/FixedLengthDecoder.decodeSequentially|decodeSequentially(){}[0] 78 | final fun decodeShortElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/Short // app.softwork.serialization.flf/FixedLengthDecoder.decodeShortElement|decodeShortElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 79 | final fun decodeStringElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlin/String // app.softwork.serialization.flf/FixedLengthDecoder.decodeStringElement|decodeStringElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 80 | final fun endStructure(kotlinx.serialization.descriptors/SerialDescriptor) // app.softwork.serialization.flf/FixedLengthDecoder.endStructure|endStructure(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 81 | } 82 | 83 | final class app.softwork.serialization.flf/FixedLengthEncoder : app.softwork.serialization.flf/FailingPrimitiveEncoder, kotlinx.serialization.encoding/CompositeEncoder { // app.softwork.serialization.flf/FixedLengthEncoder|null[0] 84 | constructor (kotlin.text/StringBuilder, kotlinx.serialization.modules/SerializersModule, kotlin/String, kotlin/Boolean) // app.softwork.serialization.flf/FixedLengthEncoder.|(kotlin.text.StringBuilder;kotlinx.serialization.modules.SerializersModule;kotlin.String;kotlin.Boolean){}[0] 85 | 86 | final val serializersModule // app.softwork.serialization.flf/FixedLengthEncoder.serializersModule|{}serializersModule[0] 87 | final fun (): kotlinx.serialization.modules/SerializersModule // app.softwork.serialization.flf/FixedLengthEncoder.serializersModule.|(){}[0] 88 | 89 | final fun <#A1: kotlin/Any> encodeNullableSerializableElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlinx.serialization/SerializationStrategy<#A1>, #A1?) // app.softwork.serialization.flf/FixedLengthEncoder.encodeNullableSerializableElement|encodeNullableSerializableElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlinx.serialization.SerializationStrategy<0:0>;0:0?){0§}[0] 90 | final fun <#A1: kotlin/Any?> encodeSerializableElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlinx.serialization/SerializationStrategy<#A1>, #A1) // app.softwork.serialization.flf/FixedLengthEncoder.encodeSerializableElement|encodeSerializableElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlinx.serialization.SerializationStrategy<0:0>;0:0){0§}[0] 91 | final fun beginCollection(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlinx.serialization.encoding/CompositeEncoder // app.softwork.serialization.flf/FixedLengthEncoder.beginCollection|beginCollection(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 92 | final fun beginStructure(kotlinx.serialization.descriptors/SerialDescriptor): kotlinx.serialization.encoding/CompositeEncoder // app.softwork.serialization.flf/FixedLengthEncoder.beginStructure|beginStructure(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 93 | final fun encodeBooleanElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Boolean) // app.softwork.serialization.flf/FixedLengthEncoder.encodeBooleanElement|encodeBooleanElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Boolean){}[0] 94 | final fun encodeByteElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Byte) // app.softwork.serialization.flf/FixedLengthEncoder.encodeByteElement|encodeByteElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Byte){}[0] 95 | final fun encodeCharElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Char) // app.softwork.serialization.flf/FixedLengthEncoder.encodeCharElement|encodeCharElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Char){}[0] 96 | final fun encodeDoubleElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Double) // app.softwork.serialization.flf/FixedLengthEncoder.encodeDoubleElement|encodeDoubleElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Double){}[0] 97 | final fun encodeEnum(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int) // app.softwork.serialization.flf/FixedLengthEncoder.encodeEnum|encodeEnum(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 98 | final fun encodeFloatElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Float) // app.softwork.serialization.flf/FixedLengthEncoder.encodeFloatElement|encodeFloatElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Float){}[0] 99 | final fun encodeInline(kotlinx.serialization.descriptors/SerialDescriptor): kotlinx.serialization.encoding/Encoder // app.softwork.serialization.flf/FixedLengthEncoder.encodeInline|encodeInline(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 100 | final fun encodeInlineElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int): kotlinx.serialization.encoding/Encoder // app.softwork.serialization.flf/FixedLengthEncoder.encodeInlineElement|encodeInlineElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int){}[0] 101 | final fun encodeIntElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Int) // app.softwork.serialization.flf/FixedLengthEncoder.encodeIntElement|encodeIntElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Int){}[0] 102 | final fun encodeLongElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Long) // app.softwork.serialization.flf/FixedLengthEncoder.encodeLongElement|encodeLongElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Long){}[0] 103 | final fun encodeShortElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/Short) // app.softwork.serialization.flf/FixedLengthEncoder.encodeShortElement|encodeShortElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.Short){}[0] 104 | final fun encodeStringElement(kotlinx.serialization.descriptors/SerialDescriptor, kotlin/Int, kotlin/String) // app.softwork.serialization.flf/FixedLengthEncoder.encodeStringElement|encodeStringElement(kotlinx.serialization.descriptors.SerialDescriptor;kotlin.Int;kotlin.String){}[0] 105 | final fun endStructure(kotlinx.serialization.descriptors/SerialDescriptor) // app.softwork.serialization.flf/FixedLengthEncoder.endStructure|endStructure(kotlinx.serialization.descriptors.SerialDescriptor){}[0] 106 | } 107 | 108 | sealed class app.softwork.serialization.flf/FixedLengthFormat : kotlinx.serialization/StringFormat { // app.softwork.serialization.flf/FixedLengthFormat|null[0] 109 | final val lineSeparator // app.softwork.serialization.flf/FixedLengthFormat.lineSeparator|{}lineSeparator[0] 110 | final fun (): kotlin/String // app.softwork.serialization.flf/FixedLengthFormat.lineSeparator.|(){}[0] 111 | open val serializersModule // app.softwork.serialization.flf/FixedLengthFormat.serializersModule|{}serializersModule[0] 112 | open fun (): kotlinx.serialization.modules/SerializersModule // app.softwork.serialization.flf/FixedLengthFormat.serializersModule.|(){}[0] 113 | 114 | final fun <#A1: kotlin/Any?> decodeAsSequence(kotlinx.serialization/DeserializationStrategy<#A1>, kotlin.sequences/Sequence): kotlin.sequences/Sequence<#A1> // app.softwork.serialization.flf/FixedLengthFormat.decodeAsSequence|decodeAsSequence(kotlinx.serialization.DeserializationStrategy<0:0>;kotlin.sequences.Sequence){0§}[0] 115 | final fun <#A1: kotlin/Any?> encodeAsSequence(kotlinx.serialization/SerializationStrategy<#A1>, kotlin.sequences/Sequence<#A1>): kotlin.sequences/Sequence // app.softwork.serialization.flf/FixedLengthFormat.encodeAsSequence|encodeAsSequence(kotlinx.serialization.SerializationStrategy<0:0>;kotlin.sequences.Sequence<0:0>){0§}[0] 116 | open fun <#A1: kotlin/Any?> decodeFromString(kotlinx.serialization/DeserializationStrategy<#A1>, kotlin/String): #A1 // app.softwork.serialization.flf/FixedLengthFormat.decodeFromString|decodeFromString(kotlinx.serialization.DeserializationStrategy<0:0>;kotlin.String){0§}[0] 117 | open fun <#A1: kotlin/Any?> encodeToString(kotlinx.serialization/SerializationStrategy<#A1>, #A1): kotlin/String // app.softwork.serialization.flf/FixedLengthFormat.encodeToString|encodeToString(kotlinx.serialization.SerializationStrategy<0:0>;0:0){0§}[0] 118 | 119 | final object Default : app.softwork.serialization.flf/FixedLengthFormat { // app.softwork.serialization.flf/FixedLengthFormat.Default|null[0] 120 | final fun invoke(kotlin/String = ..., kotlin/Boolean = ..., kotlinx.serialization.modules/SerializersModule = ...): app.softwork.serialization.flf/FixedLengthFormat // app.softwork.serialization.flf/FixedLengthFormat.Default.invoke|invoke(kotlin.String;kotlin.Boolean;kotlinx.serialization.modules.SerializersModule){}[0] 121 | } 122 | } 123 | 124 | final fun <#A: kotlin/Any?> (kotlin.sequences/Sequence<#A>).app.softwork.serialization.flf/encode(kotlinx.serialization/SerializationStrategy<#A>, app.softwork.serialization.flf/FixedLengthFormat = ...): kotlin.sequences/Sequence // app.softwork.serialization.flf/encode|encode@kotlin.sequences.Sequence<0:0>(kotlinx.serialization.SerializationStrategy<0:0>;app.softwork.serialization.flf.FixedLengthFormat){0§}[0] 125 | final fun <#A: kotlin/Any?> (kotlin.sequences/Sequence).app.softwork.serialization.flf/decode(kotlinx.serialization/DeserializationStrategy<#A>, app.softwork.serialization.flf/FixedLengthFormat = ...): kotlin.sequences/Sequence<#A> // app.softwork.serialization.flf/decode|decode@kotlin.sequences.Sequence(kotlinx.serialization.DeserializationStrategy<0:0>;app.softwork.serialization.flf.FixedLengthFormat){0§}[0] 126 | --------------------------------------------------------------------------------