summaryrefslogtreecommitdiff
path: root/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt
diff options
context:
space:
mode:
Diffstat (limited to 'formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt')
-rw-r--r--formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt96
1 files changed, 20 insertions, 76 deletions
diff --git a/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt b/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt
index 3b83299c..329e309d 100644
--- a/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt
+++ b/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt
@@ -12,7 +12,7 @@ import java.io.*
* 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.
+ * @throws [IOException] If an I/O error occurs and stream cannot be written to.
*/
@ExperimentalSerializationApi
public fun <T> Json.encodeToStream(
@@ -20,16 +20,11 @@ public fun <T> Json.encodeToStream(
value: T,
stream: OutputStream
) {
- val result = JsonToWriterStringBuilder(stream)
+ val writer = JsonToJavaStreamWriter(stream)
try {
- val encoder = StreamingJsonEncoder(
- result, this,
- WriteMode.OBJ,
- arrayOfNulls(WriteMode.values().size)
- )
- encoder.encodeSerializableValue(serializer, value)
+ encodeByWriter(this, writer, serializer, value)
} finally {
- result.release()
+ writer.release()
}
}
@@ -37,7 +32,7 @@ public fun <T> Json.encodeToStream(
* 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.
+ * @throws [IOException] If an I/O error occurs and stream cannot be written to.
*/
@ExperimentalSerializationApi
public inline fun <reified T> Json.encodeToStream(
@@ -53,18 +48,20 @@ public inline fun <reified T> Json.encodeToStream(
* 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.
+ * @throws [IllegalArgumentException] if the decoded input cannot be represented as a valid instance of type [T]
+ * @throws [IOException] If an I/O error occurs and stream cannot be read from.
*/
@ExperimentalSerializationApi
public fun <T> Json.decodeFromStream(
deserializer: DeserializationStrategy<T>,
stream: InputStream
): T {
- val lexer = ReaderJsonLexer(stream)
- val input = StreamingJsonDecoder(this, WriteMode.OBJ, lexer, deserializer.descriptor)
- val result = input.decodeSerializableValue(deserializer)
- lexer.expectEof()
- return result
+ val reader = JavaStreamSerialReader(stream)
+ try {
+ return decodeByReader(this, deserializer, reader)
+ } finally {
+ reader.release()
+ }
}
/**
@@ -75,65 +72,13 @@ public fun <T> Json.decodeFromStream(
* 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.
+ * @throws [IllegalArgumentException] if the decoded input cannot be represented as a valid instance of type [T]
+ * @throws [IOException] If an I/O error occurs and stream cannot be read from.
*/
@ExperimentalSerializationApi
public inline fun <reified T> Json.decodeFromStream(stream: InputStream): T =
decodeFromStream(serializersModule.serializer(), stream)
-/**
- * Description of [decodeToSequence]'s JSON input shape.
- *
- * The sequence represents a stream of objects parsed one by one;
- * [DecodeSequenceMode] defines a separator between these objects.
- * Typically, these objects are not separated by meaningful characters ([WHITESPACE_SEPARATED]),
- * or the whole stream is a large array of objects separated with commas ([ARRAY_WRAPPED]).
- */
-@ExperimentalSerializationApi
-public enum class DecodeSequenceMode {
- /**
- * Declares that objects in the input stream are separated by whitespace characters.
- *
- * The stream is read as multiple JSON objects separated by any number of whitespace characters between objects. Starting and trailing whitespace characters are also permitted.
- * Each individual object is parsed lazily, when it is requested from the resulting sequence.
- *
- * Whitespace character is either ' ', '\n', '\r' or '\t'.
- *
- * Example of `WHITESPACE_SEPARATED` stream content:
- * ```
- * """{"key": "value"}{"key": "value2"} {"key2": "value2"}"""
- * ```
- */
- WHITESPACE_SEPARATED,
-
- /**
- * Declares that objects in the input stream are wrapped in the JSON array.
- * Each individual object in the array is parsed lazily when it is requested from the resulting sequence.
- *
- * The stream is read as multiple JSON objects wrapped into a JSON array.
- * The stream must start with an array start character `[` and end with an array end character `]`,
- * otherwise, [JsonDecodingException] is thrown.
- *
- * Example of `ARRAY_WRAPPED` stream content:
- * ```
- * """[{"key": "value"}, {"key": "value2"},{"key2": "value2"}]"""
- * ```
- */
- ARRAY_WRAPPED,
-
- /**
- * Declares that parser itself should select between [WHITESPACE_SEPARATED] and [ARRAY_WRAPPED] modes.
- * The selection is performed by looking on the first meaningful character of the stream.
- *
- * In most cases, auto-detection is sufficient to correctly parse an input.
- * If the input is _whitespace-separated stream of the arrays_, parser could select an incorrect mode,
- * for that [DecodeSequenceMode] must be specified explicitly.
- *
- * Example of an exceptional case:
- * `[1, 2, 3] [4, 5, 6]\n[7, 8, 9]`
- */
- AUTO_DETECT;
-}
/**
* Transforms the given [stream] into lazily deserialized sequence of elements of type [T] using UTF-8 encoding and [deserializer].
@@ -148,7 +93,8 @@ public enum class DecodeSequenceMode {
* 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.
+ * @throws [IllegalArgumentException] if the decoded input cannot be represented as a valid instance of type [T]
+ * @throws [IOException] If an I/O error occurs and stream cannot be read from.
*/
@ExperimentalSerializationApi
public fun <T> Json.decodeToSequence(
@@ -156,9 +102,7 @@ public fun <T> Json.decodeToSequence(
deserializer: DeserializationStrategy<T>,
format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT
): Sequence<T> {
- val lexer = ReaderJsonLexer(stream)
- val iter = JsonIterator(format, this, lexer, deserializer)
- return Sequence { iter }.constrainOnce()
+ return decodeToSequenceByReader(this, JavaStreamSerialReader(stream), deserializer, format)
}
/**
@@ -174,11 +118,11 @@ public fun <T> Json.decodeToSequence(
* 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.
+ * @throws [IllegalArgumentException] if the decoded input cannot be represented as a valid instance of type [T]
+ * @throws [IOException] If an I/O error occurs and stream cannot be read from.
*/
@ExperimentalSerializationApi
public inline fun <reified T> Json.decodeToSequence(
stream: InputStream,
format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT
): Sequence<T> = decodeToSequence(stream, serializersModule.serializer(), format)
-