Search code examples
jsonkotlindeserialization

JSON decoding from stream in Kotlin


I have a server set up to send messages over a local host port. I am trying to decode the serialized json messages sent by the server and get this error.

Error decoding message: kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 55: Expected EOF after parsing, but had   instead at path: $
JSON input: .....mber":13,"Timestamp":5769784}                               .....

The Racer State messages are formatted in JSON as follows: { “SensorId”: “value”, “RacerBibNumber” : “value”, “Timestamp” : “value” }, where the value’s are character string representations of the field values. I have also tried changing my RacerStatus Class to take String instead of Int but to a similar error. Am I missing something here? The symbol that is missing in the error was not able to be copied over so I know it's not UTF-8.

I have also added

val inputString = bytes.toString(Charsets.UTF_8)
println("Received input: $inputString")

This gets Received input: {"SensorId":0,"RacerBibNumber":5254,"Timestamp":3000203}
with a bunch of extraneous symbols at the end.

data class RacerStatus(
    var SensorId: Int,
    var RacerBibNumber: Int,
    var Timestamp: Int
) {


    fun encode(): ByteArray {
        return Json.encodeToString(serializer(), this).toByteArray()
    }

    companion object {
        fun decode(bytes: ByteArray): RacerStatus {
            print(bytes[0])

            try {
                val mstream = ByteArrayInputStream(bytes)
                return Json.decodeFromStream<RacerStatus>(mstream)
            } catch (e: SerializationException) {
                println("Error decoding message: $e")
                return RacerStatus(0, 0, 0)
            }

//            return Json.decodeFromString(serializer(), mstream.readBytes().toString())
        }
    }
}

Solution

  • So I found an answer to my question. I added a regex to include just the json components I know my json contains.

    val str = bytes.toString(Charsets.UTF_8)
    val re = Regex("[^A-Za-z0-9{}:,\"\"]")
                    return Json.decodeFromString<RacerStatus>(re.replace(str,""))
    

    I thought that Charsets.UTF_8 would remove the misc characters but it did not. Is there a more intiuative solution? Also is there a regex that would cover all possible values in json?