summaryrefslogtreecommitdiff
path: root/runtime/commonMain/src/kotlinx/serialization/json/internal/JsonParser.kt
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/commonMain/src/kotlinx/serialization/json/internal/JsonParser.kt')
-rw-r--r--runtime/commonMain/src/kotlinx/serialization/json/internal/JsonParser.kt61
1 files changed, 61 insertions, 0 deletions
diff --git a/runtime/commonMain/src/kotlinx/serialization/json/internal/JsonParser.kt b/runtime/commonMain/src/kotlinx/serialization/json/internal/JsonParser.kt
new file mode 100644
index 00000000..34fc4c79
--- /dev/null
+++ b/runtime/commonMain/src/kotlinx/serialization/json/internal/JsonParser.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.json.internal
+
+import kotlinx.serialization.json.*
+
+internal class JsonParser(private val reader: JsonReader) {
+
+ private fun readObject(): JsonElement {
+ reader.requireTokenClass(TC_BEGIN_OBJ) { "Expected start of object" }
+ reader.nextToken()
+ val result: MutableMap<String, JsonElement> = linkedMapOf()
+ while (true) {
+ if (reader.tokenClass == TC_COMMA) reader.nextToken()
+ if (!reader.canBeginValue) break
+ val key = reader.takeString()
+ reader.requireTokenClass(TC_COLON) { "Expected ':'" }
+ reader.nextToken()
+ val elem = read()
+ result[key] = elem
+ }
+ reader.requireTokenClass(TC_END_OBJ) { "Expected end of object" }
+ reader.nextToken()
+ return JsonObject(result)
+ }
+
+ private fun readValue(isString: Boolean): JsonElement {
+ val str = reader.takeString()
+ return JsonLiteral(str, isString)
+ }
+
+ private fun readArray(): JsonElement {
+ reader.requireTokenClass(TC_BEGIN_LIST) { "Expected start of array" }
+ reader.nextToken()
+ val result: MutableList<JsonElement> = arrayListOf()
+ while (true) {
+ if (reader.tokenClass == TC_COMMA) reader.nextToken()
+ if (!reader.canBeginValue) break
+ val elem = read()
+ result.add(elem)
+ }
+ reader.requireTokenClass(TC_END_LIST) { "Expected end of array" }
+ reader.nextToken()
+ return JsonArray(result)
+ }
+
+ fun read(): JsonElement {
+ if (!reader.canBeginValue) fail(reader.currentPosition, "Can't begin reading value from here")
+ val tc = reader.tokenClass
+ return when (tc) {
+ TC_NULL -> JsonNull.also { reader.nextToken() }
+ TC_STRING -> readValue(isString = true)
+ TC_OTHER -> readValue(isString = false)
+ TC_BEGIN_OBJ -> readObject()
+ TC_BEGIN_LIST -> readArray()
+ else -> fail(reader.currentPosition, "Can't begin reading element")
+ }
+ }
+}