Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
849 additions
and
244 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
public final class kotlinx/serialization/json/OkioStreamsKt { | ||
public static final fun decodeFromOkio (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/DeserializationStrategy;Lokio/BufferedSource;)Ljava/lang/Object; | ||
public static final fun decodeOkioToSequence (Lkotlinx/serialization/json/Json;Lokio/BufferedSource;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;)Lkotlin/sequences/Sequence; | ||
public static synthetic fun decodeOkioToSequence$default (Lkotlinx/serialization/json/Json;Lokio/BufferedSource;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;ILjava/lang/Object;)Lkotlin/sequences/Sequence; | ||
public static final fun encodeToOkio (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lokio/BufferedSink;)V | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
import Java9Modularity.configureJava9ModuleInfo | ||
|
||
plugins { | ||
kotlin("multiplatform") | ||
kotlin("plugin.serialization") | ||
} | ||
|
||
apply(from = rootProject.file("gradle/native-targets.gradle")) | ||
apply(from = rootProject.file("gradle/configure-source-sets.gradle")) | ||
|
||
kotlin { | ||
sourceSets { | ||
val commonMain by getting { | ||
dependencies { | ||
api(project(":kotlinx-serialization-core")) | ||
api(project(":kotlinx-serialization-json")) | ||
compileOnly("com.squareup.okio:okio-multiplatform:3.0.0-alpha.9") | ||
} | ||
} | ||
val commonTest by getting { | ||
dependencies { | ||
implementation("com.squareup.okio:okio-multiplatform:3.0.0-alpha.9") | ||
} | ||
} | ||
} | ||
} | ||
|
||
project.configureJava9ModuleInfo() |
120 changes: 120 additions & 0 deletions
120
formats/json-okio/commonMain/src/kotlinx/serialization/json/OkioStreams.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package kotlinx.serialization.json | ||
|
||
import kotlinx.serialization.* | ||
import kotlinx.serialization.json.internal.* | ||
import kotlinx.serialization.json.internal.JsonToOkioStreamWriter | ||
import kotlinx.serialization.json.internal.decodeToSequence | ||
import okio.BufferedSink | ||
import okio.BufferedSource | ||
|
||
/** | ||
* Serializes the [value] with [serializer] into a [stream] using JSON format and UTF-8 encoding. | ||
* | ||
* @throws [SerializationException] if the given value cannot be serialized to JSON. | ||
* @throws [IOException] If an I/O error occurs and stream can't be written to. | ||
*/ | ||
@ExperimentalSerializationApi | ||
public fun <T> Json.encodeToOkio( | ||
serializer: SerializationStrategy<T>, | ||
value: T, | ||
target: BufferedSink | ||
) { | ||
val writer = JsonToOkioStreamWriter(target) | ||
try { | ||
encodeByWriter(writer, serializer, value) | ||
} finally { | ||
writer.release() | ||
} | ||
} | ||
|
||
/** | ||
* Serializes given [value] to [stream] using UTF-8 encoding and serializer retrieved from the reified type parameter. | ||
* | ||
* @throws [SerializationException] if the given value cannot be serialized to JSON. | ||
* @throws [IOException] If an I/O error occurs and stream can't be written to. | ||
*/ | ||
@ExperimentalSerializationApi | ||
public inline fun <reified T> Json.encodeToOkio( | ||
value: T, | ||
target: BufferedSink | ||
): Unit = | ||
encodeToOkio(serializersModule.serializer(), value, target) | ||
|
||
|
||
|
||
/** | ||
* Deserializes JSON from [source] using UTF-8 encoding to a value of type [T] using [deserializer]. | ||
* | ||
* Note that this functions expects that exactly one object would be present in the stream | ||
* and throws an exception if there are any dangling bytes after an object. | ||
* | ||
* @throws [SerializationException] if the given JSON input cannot be deserialized to the value of type [T]. | ||
* @throws [IOException] If an I/O error occurs and stream can't be read from. | ||
*/ | ||
@ExperimentalSerializationApi | ||
public fun <T> Json.decodeFromOkio( | ||
deserializer: DeserializationStrategy<T>, | ||
source: BufferedSource | ||
): T { | ||
return decodeByReader(deserializer, OkioSerialReader(source)) | ||
} | ||
|
||
/** | ||
* Deserializes the contents of given [source] to the value of type [T] using UTF-8 encoding and | ||
* deserializer retrieved from the reified type parameter. | ||
* | ||
* Note that this functions expects that exactly one object would be present in the stream | ||
* and throws an exception if there are any dangling bytes after an object. | ||
* | ||
* @throws [SerializationException] if the given JSON input cannot be deserialized to the value of type [T]. | ||
* @throws [IOException] If an I/O error occurs and stream can't be read from. | ||
*/ | ||
@ExperimentalSerializationApi | ||
public inline fun <reified T> Json.decodeFromOkio(source: BufferedSource): T = | ||
decodeFromOkio(serializersModule.serializer(), source) | ||
|
||
|
||
/** | ||
* Transforms the given [source] into lazily deserialized sequence of elements of type [T] using UTF-8 encoding and [deserializer]. | ||
* Unlike [decodeFromStream], [source] is allowed to have more than one element, separated as [format] declares. | ||
* | ||
* Elements must all be of type [T]. | ||
* Elements are parsed lazily when resulting [Sequence] is evaluated. | ||
* Resulting sequence is tied to the stream and can be evaluated only once. | ||
* | ||
* **Resource caution:** this method neither closes the [source] when the parsing is finished nor provides a method to close it manually. | ||
* It is a caller responsibility to hold a reference to a stream and close it. Moreover, because stream is parsed lazily, | ||
* closing it before returned sequence is evaluated completely will result in [IOException] from decoder. | ||
* | ||
* @throws [SerializationException] if the given JSON input cannot be deserialized to the value of type [T]. | ||
* @throws [IOException] If an I/O error occurs and stream can't be read from. | ||
*/ | ||
@ExperimentalSerializationApi | ||
public fun <T> Json.decodeOkioToSequence( | ||
source: BufferedSource, | ||
deserializer: DeserializationStrategy<T>, | ||
format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT | ||
): Sequence<T> { | ||
return decodeToSequence(OkioSerialReader(source), deserializer, format) | ||
} | ||
|
||
/** | ||
* Transforms the given [source] into lazily deserialized sequence of elements of type [T] using UTF-8 encoding and deserializer retrieved from the reified type parameter. | ||
* Unlike [decodeFromStream], [source] is allowed to have more than one element, separated as [format] declares. | ||
* | ||
* Elements must all be of type [T]. | ||
* Elements are parsed lazily when resulting [Sequence] is evaluated. | ||
* Resulting sequence is tied to the stream and constrained to be evaluated only once. | ||
* | ||
* **Resource caution:** this method does not close [source] when the parsing is finished neither provides method to close it manually. | ||
* It is a caller responsibility to hold a reference to a stream and close it. Moreover, because stream is parsed lazily, | ||
* closing it before returned sequence is evaluated fully would result in [IOException] from decoder. | ||
* | ||
* @throws [SerializationException] if the given JSON input cannot be deserialized to the value of type [T]. | ||
* @throws [IOException] If an I/O error occurs and stream can't be read from. | ||
*/ | ||
@ExperimentalSerializationApi | ||
public inline fun <reified T> Json.decodeOkioToSequence( | ||
source: BufferedSource, | ||
format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT | ||
): Sequence<T> = decodeOkioToSequence(source, serializersModule.serializer(), format) |
50 changes: 50 additions & 0 deletions
50
formats/json-okio/commonMain/src/kotlinx/serialization/json/internal/OkioJsonStreams.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package kotlinx.serialization.json.internal | ||
|
||
import okio.* | ||
|
||
internal class JsonToOkioStreamWriter(private val target: BufferedSink) : JsonWriter { | ||
override fun writeLong(value: Long) { | ||
write(value.toString()) | ||
} | ||
|
||
override fun writeChar(char: Char) { | ||
target.writeUtf8CodePoint(char.code) | ||
} | ||
|
||
override fun write(text: String) { | ||
target.writeUtf8(text) | ||
} | ||
|
||
override fun writeQuoted(text: String) { | ||
target.writeUtf8CodePoint('"'.code) | ||
var lastPos = 0 | ||
for (i in text.indices) { | ||
val c = text[i].code | ||
if (c < ESCAPE_STRINGS.size && ESCAPE_STRINGS[c] != null) { | ||
target.writeUtf8(text, lastPos, i) // flush prev | ||
target.writeUtf8(ESCAPE_STRINGS[c]!!) | ||
lastPos = i + 1 | ||
} | ||
} | ||
|
||
if (lastPos != 0) target.writeUtf8(text, lastPos, text.length) | ||
else target.writeUtf8(text) | ||
target.writeUtf8CodePoint('"'.code) | ||
} | ||
|
||
override fun release() { | ||
target.flush() | ||
} | ||
} | ||
|
||
internal class OkioSerialReader(private val source: BufferedSource): SerialReader { | ||
override fun read(buffer: CharArray, bufferOffset: Int, count: Int): Int { | ||
var i = 0 | ||
while (i < count && !source.exhausted()) { | ||
buffer[i] = source.readUtf8CodePoint().toChar() | ||
i++ | ||
} | ||
return if (i > 0) i else -1 | ||
} | ||
} | ||
|
54 changes: 54 additions & 0 deletions
54
formats/json-okio/commonTest/src/kotlinx/serialization/json/TestTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package kotlinx.serialization.json | ||
|
||
import kotlinx.serialization.KSerializer | ||
import kotlinx.serialization.Serializable | ||
import okio.* | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
import kotlin.test.assertFalse | ||
import kotlin.test.assertTrue | ||
|
||
|
||
class TestTest { | ||
private val strLen = 1024 * 2 + 42 | ||
|
||
@Serializable | ||
data class StringHolder(val data: String) | ||
|
||
@Test | ||
fun testParsesStringsLongerThanBuffer() { | ||
val str = "a".repeat(strLen) | ||
val input = """{"data":"$str"}""" | ||
assertEquals(input, Json.encodeViaOkio(StringHolder.serializer(), StringHolder(str))) | ||
} | ||
@Test | ||
fun test2() { | ||
val str = "a".repeat(strLen) | ||
|
||
val buffer = Buffer() | ||
|
||
Json.encodeToOkio(StringHolder.serializer(), StringHolder(str), buffer) | ||
|
||
val result = Json.decodeFromOkio(StringHolder.serializer(), buffer) | ||
|
||
assertEquals(StringHolder(str), result) | ||
} | ||
@Test | ||
fun test4() { | ||
val str = "a".repeat(strLen) | ||
|
||
val buffer = Buffer() | ||
|
||
Json.encodeToOkio(StringHolder(str), buffer) | ||
Json.decodeOkioToSequence(buffer, StringHolder.serializer()) | ||
} | ||
} | ||
|
||
fun <T> Json.encodeViaOkio(serializer: KSerializer<T>, value: T): String { | ||
val limited = Buffer() | ||
|
||
encodeToOkio(serializer, value, limited) | ||
|
||
return limited.readUtf8() | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.