90 lines
2.7 KiB
Kotlin
90 lines
2.7 KiB
Kotlin
package ru.dbotthepony.kstarbound.io.json
|
|
|
|
import com.google.common.collect.Interner
|
|
import com.google.gson.JsonArray
|
|
import com.google.gson.JsonElement
|
|
import com.google.gson.JsonNull
|
|
import com.google.gson.JsonObject
|
|
import com.google.gson.JsonPrimitive
|
|
import com.google.gson.TypeAdapter
|
|
import com.google.gson.internal.LazilyParsedNumber
|
|
import com.google.gson.internal.bind.TypeAdapters
|
|
import com.google.gson.stream.JsonReader
|
|
import com.google.gson.stream.JsonToken
|
|
import com.google.gson.stream.JsonWriter
|
|
|
|
class InternedJsonElementAdapter(val stringInterner: Interner<String>) : TypeAdapter<JsonElement>() {
|
|
override fun write(out: JsonWriter, value: JsonElement?) {
|
|
return TypeAdapters.JSON_ELEMENT.write(out, value)
|
|
}
|
|
|
|
override fun read(`in`: JsonReader): JsonElement? {
|
|
return when (val p = `in`.peek()) {
|
|
JsonToken.STRING -> JsonPrimitive(stringInterner.intern(`in`.nextString()))
|
|
JsonToken.NUMBER -> JsonPrimitive(LazilyParsedNumber(`in`.nextString()))
|
|
JsonToken.BOOLEAN -> if (`in`.nextBoolean()) TRUE else FALSE
|
|
JsonToken.NULL -> JsonNull.INSTANCE
|
|
JsonToken.BEGIN_ARRAY -> arrays.read(`in`)
|
|
JsonToken.BEGIN_OBJECT -> objects.read(`in`)
|
|
else -> throw IllegalArgumentException(p.toString())
|
|
}
|
|
}
|
|
|
|
val objects = object : TypeAdapter<JsonObject>() {
|
|
override fun write(out: JsonWriter, value: JsonObject?) {
|
|
return TypeAdapters.JSON_ELEMENT.write(out, value)
|
|
}
|
|
|
|
override fun read(`in`: JsonReader): JsonObject? {
|
|
if (`in`.peek() == JsonToken.NULL)
|
|
return null
|
|
|
|
val output = JsonObject()
|
|
`in`.beginObject()
|
|
while (`in`.hasNext()) { output.add(stringInterner.intern(`in`.nextName()), this@InternedJsonElementAdapter.read(`in`)) }
|
|
`in`.endObject()
|
|
return output
|
|
}
|
|
}
|
|
|
|
val arrays = object : TypeAdapter<JsonArray>() {
|
|
override fun write(out: JsonWriter, value: JsonArray?) {
|
|
return TypeAdapters.JSON_ELEMENT.write(out, value)
|
|
}
|
|
|
|
override fun read(`in`: JsonReader): JsonArray? {
|
|
if (`in`.peek() == JsonToken.NULL)
|
|
return null
|
|
|
|
val output = JsonArray()
|
|
`in`.beginArray()
|
|
while (`in`.hasNext()) { output.add(this@InternedJsonElementAdapter.read(`in`)) }
|
|
`in`.endArray()
|
|
return output
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
val TRUE = JsonPrimitive(true)
|
|
val FALSE = JsonPrimitive(false)
|
|
|
|
fun of(value: Boolean) = if (value) TRUE else FALSE
|
|
}
|
|
}
|
|
|
|
class InternedStringAdapter(val stringInterner: Interner<String>) : TypeAdapter<String>() {
|
|
override fun write(out: JsonWriter, value: String?) {
|
|
out.value(value)
|
|
}
|
|
|
|
override fun read(`in`: JsonReader): String? {
|
|
if (`in`.peek() == JsonToken.NULL)
|
|
return null
|
|
|
|
if (`in`.peek() == JsonToken.BOOLEAN)
|
|
return `in`.nextBoolean().toString()
|
|
|
|
return stringInterner.intern(`in`.nextString())
|
|
}
|
|
}
|