|
|
@ -1,15 +1,20 @@ |
|
|
|
package io.legado.app.utils |
|
|
|
package io.legado.app.utils |
|
|
|
|
|
|
|
|
|
|
|
import com.google.gson.Gson |
|
|
|
import com.google.gson.* |
|
|
|
import com.google.gson.GsonBuilder |
|
|
|
import com.google.gson.internal.LinkedTreeMap |
|
|
|
import com.google.gson.JsonSyntaxException |
|
|
|
|
|
|
|
import com.google.gson.reflect.TypeToken |
|
|
|
import com.google.gson.reflect.TypeToken |
|
|
|
import org.jetbrains.anko.attempt |
|
|
|
import org.jetbrains.anko.attempt |
|
|
|
import java.lang.reflect.ParameterizedType |
|
|
|
import java.lang.reflect.ParameterizedType |
|
|
|
import java.lang.reflect.Type |
|
|
|
import java.lang.reflect.Type |
|
|
|
|
|
|
|
import kotlin.math.ceil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val GSON: Gson by lazy { |
|
|
|
val GSON: Gson by lazy { |
|
|
|
GsonBuilder() |
|
|
|
GsonBuilder() |
|
|
|
|
|
|
|
.registerTypeAdapter( |
|
|
|
|
|
|
|
object : TypeToken<Map<String?, Any?>?>() {}.type, |
|
|
|
|
|
|
|
MapDeserializerDoubleAsIntFix() |
|
|
|
|
|
|
|
) |
|
|
|
.disableHtmlEscaping() |
|
|
|
.disableHtmlEscaping() |
|
|
|
.setPrettyPrinting() |
|
|
|
.setPrettyPrinting() |
|
|
|
.create() |
|
|
|
.create() |
|
|
@ -40,3 +45,68 @@ class ParameterizedTypeImpl(private val clazz: Class<*>) : ParameterizedType { |
|
|
|
|
|
|
|
|
|
|
|
override fun getActualTypeArguments(): Array<Type> = arrayOf(clazz) |
|
|
|
override fun getActualTypeArguments(): Array<Type> = arrayOf(clazz) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 修复Int变为Double的问题 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
class MapDeserializerDoubleAsIntFix : |
|
|
|
|
|
|
|
JsonDeserializer<Map<String, Any>?> { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Throws(JsonParseException::class) |
|
|
|
|
|
|
|
override fun deserialize( |
|
|
|
|
|
|
|
jsonElement: JsonElement, |
|
|
|
|
|
|
|
type: Type, |
|
|
|
|
|
|
|
jsonDeserializationContext: JsonDeserializationContext |
|
|
|
|
|
|
|
): Map<String, Any>? { |
|
|
|
|
|
|
|
@Suppress("unchecked_cast") |
|
|
|
|
|
|
|
return read(jsonElement) as? Map<String, Any> |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun read(`in`: JsonElement): Any? { |
|
|
|
|
|
|
|
when { |
|
|
|
|
|
|
|
`in`.isJsonArray -> { |
|
|
|
|
|
|
|
val list: MutableList<Any?> = ArrayList() |
|
|
|
|
|
|
|
val arr = `in`.asJsonArray |
|
|
|
|
|
|
|
for (anArr in arr) { |
|
|
|
|
|
|
|
list.add(read(anArr)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return list |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
`in`.isJsonObject -> { |
|
|
|
|
|
|
|
val map: MutableMap<String, Any?> = |
|
|
|
|
|
|
|
LinkedTreeMap() |
|
|
|
|
|
|
|
val obj = `in`.asJsonObject |
|
|
|
|
|
|
|
val entitySet = |
|
|
|
|
|
|
|
obj.entrySet() |
|
|
|
|
|
|
|
for ((key, value) in entitySet) { |
|
|
|
|
|
|
|
map[key] = read(value) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return map |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
`in`.isJsonPrimitive -> { |
|
|
|
|
|
|
|
val prim = `in`.asJsonPrimitive |
|
|
|
|
|
|
|
when { |
|
|
|
|
|
|
|
prim.isBoolean -> { |
|
|
|
|
|
|
|
return prim.asBoolean |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
prim.isString -> { |
|
|
|
|
|
|
|
return prim.asString |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
prim.isNumber -> { |
|
|
|
|
|
|
|
val num: Number = prim.asNumber |
|
|
|
|
|
|
|
// here you can handle double int/long values |
|
|
|
|
|
|
|
// and return any type you want |
|
|
|
|
|
|
|
// this solution will transform 3.0 float to long values |
|
|
|
|
|
|
|
return if (ceil(num.toDouble()) == num.toLong().toDouble()) { |
|
|
|
|
|
|
|
num.toLong() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
num.toDouble() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |