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) : TypeAdapter() { 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() { 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() { 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) : TypeAdapter() { 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()) } }