diff options
Diffstat (limited to 'formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt')
-rw-r--r-- | formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt | 96 |
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) - |