Release GPS2Audio v2.5.44 POI category fix
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
package de.waypointaudio.license
|
||||
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* v2.5.20 — Kanonische JSON-Serialisierung, kompatibel zum Python-Tool
|
||||
* (`canonical_json_bytes`):
|
||||
* - Keys lexikografisch sortiert.
|
||||
* - Trennzeichen ohne Whitespace: "," / ":".
|
||||
* - `ensure_ascii=False` ⇒ Unicode-Strings werden nicht escapet, ausser den
|
||||
* minimal nötigen JSON-Escapes (`\"`, `\\`, Steuerzeichen < 0x20).
|
||||
* - `null` für JSON-Null; `JSONObject.NULL` und Kotlin-`null` gleich behandelt.
|
||||
*
|
||||
* Diese kanonische Form ist die Eingabe für die ECDSA-P256-SHA256-Signatur.
|
||||
*/
|
||||
internal object CanonicalJson {
|
||||
|
||||
fun encode(value: Any?): String {
|
||||
val sb = StringBuilder()
|
||||
appendValue(sb, value)
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun appendValue(sb: StringBuilder, value: Any?) {
|
||||
when {
|
||||
value == null || value === JSONObject.NULL -> sb.append("null")
|
||||
value is Boolean -> sb.append(if (value) "true" else "false")
|
||||
value is Number -> appendNumber(sb, value)
|
||||
value is String -> appendString(sb, value)
|
||||
value is JSONObject -> appendObject(sb, value)
|
||||
value is JSONArray -> appendArray(sb, value)
|
||||
else -> appendString(sb, value.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun appendObject(sb: StringBuilder, obj: JSONObject) {
|
||||
val keys = obj.keys().asSequence().toList().sorted()
|
||||
sb.append('{')
|
||||
for ((index, key) in keys.withIndex()) {
|
||||
if (index > 0) sb.append(',')
|
||||
appendString(sb, key)
|
||||
sb.append(':')
|
||||
appendValue(sb, obj.opt(key))
|
||||
}
|
||||
sb.append('}')
|
||||
}
|
||||
|
||||
private fun appendArray(sb: StringBuilder, arr: JSONArray) {
|
||||
sb.append('[')
|
||||
for (i in 0 until arr.length()) {
|
||||
if (i > 0) sb.append(',')
|
||||
appendValue(sb, arr.opt(i))
|
||||
}
|
||||
sb.append(']')
|
||||
}
|
||||
|
||||
private fun appendNumber(sb: StringBuilder, n: Number) {
|
||||
when (n) {
|
||||
is Int, is Long, is Short, is Byte -> sb.append(n.toString())
|
||||
is Double -> {
|
||||
if (n.isNaN() || n.isInfinite()) {
|
||||
sb.append("null")
|
||||
} else if (n == n.toLong().toDouble()) {
|
||||
sb.append(n.toLong().toString())
|
||||
} else {
|
||||
sb.append(n.toString())
|
||||
}
|
||||
}
|
||||
is Float -> appendNumber(sb, n.toDouble())
|
||||
else -> sb.append(n.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun appendString(sb: StringBuilder, s: String) {
|
||||
sb.append('"')
|
||||
for (c in s) {
|
||||
when (c.code) {
|
||||
0x22 -> sb.append("\\\"")
|
||||
0x5C -> sb.append("\\\\")
|
||||
0x08 -> sb.append("\\b")
|
||||
0x0C -> sb.append("\\f")
|
||||
0x0A -> sb.append("\\n")
|
||||
0x0D -> sb.append("\\r")
|
||||
0x09 -> sb.append("\\t")
|
||||
else -> {
|
||||
val code = c.code
|
||||
if (code < 0x20) {
|
||||
sb.append("\\u%04x".format(code))
|
||||
} else {
|
||||
sb.append(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append('"')
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user