mirror of
https://github.com/tateisu/SubwayTooter
synced 2025-02-10 09:00:36 +01:00
fix Emojipadia.json
This commit is contained in:
parent
a6c677a5c6
commit
8298a6f49c
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
|||||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
|
||||||
package jp.juggler.subwaytooter.emoji
|
package jp.juggler.subwaytooter.emoji
|
||||||
|
|
||||||
import java.io.*
|
import java.io.*
|
||||||
@ -6,9 +7,9 @@ import java.math.BigDecimal
|
|||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
|
||||||
class JsonException : RuntimeException {
|
class JsonException : RuntimeException {
|
||||||
constructor(message : String?) : super(message)
|
constructor(message: String?) : super(message)
|
||||||
constructor(message : String?, cause : Throwable?) : super(message, cause)
|
constructor(message: String?, cause: Throwable?) : super(message, cause)
|
||||||
constructor(cause : Throwable) : super(cause.message, cause)
|
constructor(cause: Throwable) : super(cause.message, cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val char0 = '\u0000'
|
private const val char0 = '\u0000'
|
||||||
@ -16,22 +17,22 @@ private const val char0 = '\u0000'
|
|||||||
// Tests if the value should be tried as a decimal.
|
// Tests if the value should be tried as a decimal.
|
||||||
// It makes no test if there are actual digits.
|
// It makes no test if there are actual digits.
|
||||||
// return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
|
// return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
|
||||||
private fun String.isDecimalNotation() : Boolean =
|
private fun String.isDecimalNotation(): Boolean =
|
||||||
indexOf('.') > - 1 ||
|
indexOf('.') > -1 ||
|
||||||
indexOf('e') > - 1 ||
|
indexOf('e') > -1 ||
|
||||||
indexOf('E') > - 1 ||
|
indexOf('E') > -1 ||
|
||||||
this == "-0"
|
this == "-0"
|
||||||
|
|
||||||
private fun String.stringToNumber() : Number {
|
private fun String.stringToNumber(): Number {
|
||||||
val initial = this.firstOrNull()
|
val initial = this.firstOrNull()
|
||||||
if(initial != null && (initial in '0'..'9' || initial == '-')) {
|
if (initial != null && (initial in '0'..'9' || initial == '-')) {
|
||||||
val length = this.length
|
val length = this.length
|
||||||
when {
|
when {
|
||||||
isDecimalNotation() -> return if(length > 14) {
|
isDecimalNotation() -> return if (length > 14) {
|
||||||
BigDecimal(this)
|
BigDecimal(this)
|
||||||
} else {
|
} else {
|
||||||
val d = this.toDouble()
|
val d = this.toDouble()
|
||||||
if(d.isInfinite() || d.isNaN()) {
|
if (d.isInfinite() || d.isNaN()) {
|
||||||
// if we can't parse it as a double, go up to BigDecimal
|
// if we can't parse it as a double, go up to BigDecimal
|
||||||
// this is probably due to underflow like 4.32e-678
|
// this is probably due to underflow like 4.32e-678
|
||||||
// or overflow like 4.65e5324. The size of the string is small
|
// or overflow like 4.65e5324. The size of the string is small
|
||||||
@ -65,13 +66,13 @@ private fun String.stringToNumber() : Number {
|
|||||||
throw NumberFormatException("val [$this] is not a valid number.")
|
throw NumberFormatException("val [$this] is not a valid number.")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Any?.asNumber(defaultValue : Number) : Number =
|
private fun Any?.asNumber(defaultValue: Number): Number =
|
||||||
when(this) {
|
when (this) {
|
||||||
null -> defaultValue
|
null -> defaultValue
|
||||||
is Number -> this
|
is Number -> this
|
||||||
else -> try {
|
else -> try {
|
||||||
toString().stringToNumber()
|
toString().stringToNumber()
|
||||||
} catch(e : Exception) {
|
} catch (e: Exception) {
|
||||||
defaultValue
|
defaultValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,18 +80,18 @@ private fun Any?.asNumber(defaultValue : Number) : Number =
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class JsonArray : ArrayList<Any?> {
|
class JsonArray : ArrayList<Any?> {
|
||||||
|
|
||||||
constructor(capacity : Int = 10) : super(capacity)
|
constructor(capacity: Int = 10) : super(capacity)
|
||||||
constructor(collection : Collection<*>) : super(collection)
|
constructor(collection: Collection<*>) : super(collection)
|
||||||
constructor(array : Array<*>) : super(array.toList())
|
constructor(array: Array<*>) : super(array.toList())
|
||||||
|
|
||||||
fun toString(indentFactor : Int) : String {
|
fun toString(indentFactor: Int): String {
|
||||||
val sw = StringWriter()
|
val sw = StringWriter()
|
||||||
synchronized(sw.buffer) {
|
synchronized(sw.buffer) {
|
||||||
return sw.writeJsonValue(indentFactor, 0, this).toString()
|
return sw.writeJsonValue(indentFactor, 0, this).toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() : String = toString(0)
|
override fun toString(): String = toString(0)
|
||||||
|
|
||||||
fun objectList() = mapNotNull { it.cast<JsonObject>() }
|
fun objectList() = mapNotNull { it.cast<JsonObject>() }
|
||||||
|
|
||||||
@ -102,38 +103,38 @@ class JsonArray : ArrayList<Any?> {
|
|||||||
addAll(this@JsonArray.mapNotNull { this.asNumber(0f).toFloat() })
|
addAll(this@JsonArray.mapNotNull { this.asNumber(0f).toFloat() })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun string(key : Int) : String? = this[key]?.toString()
|
fun string(key: Int): String? = this[key]?.toString()
|
||||||
fun boolean(key : Int) : Boolean? = JsonObject.castBoolean(this[key])
|
fun boolean(key: Int): Boolean? = JsonObject.castBoolean(this[key])
|
||||||
fun int(key : Int) : Int? = JsonObject.castInt(this[key])
|
fun int(key: Int): Int? = JsonObject.castInt(this[key])
|
||||||
fun long(key : Int) : Long? = JsonObject.castLong(this[key])
|
fun long(key: Int): Long? = JsonObject.castLong(this[key])
|
||||||
fun float(key : Int) : Float? = JsonObject.castFloat(this[key])
|
fun float(key: Int): Float? = JsonObject.castFloat(this[key])
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
fun double(key : Int) : Double? = JsonObject.castDouble(this[key])
|
fun double(key: Int): Double? = JsonObject.castDouble(this[key])
|
||||||
|
|
||||||
fun jsonObject(key : Int) = this[key].cast<JsonObject>()
|
fun jsonObject(key: Int) = this[key].cast<JsonObject>()
|
||||||
fun jsonArray(key : Int) = this[key].cast<JsonArray>()
|
fun jsonArray(key: Int) = this[key].cast<JsonArray>()
|
||||||
|
|
||||||
fun optString(key : Int, defVal : String = "") = string(key) ?: defVal
|
fun optString(key: Int, defVal: String = "") = string(key) ?: defVal
|
||||||
fun optBoolean(key : Int, defVal : Boolean = false) = boolean(key) ?: defVal
|
fun optBoolean(key: Int, defVal: Boolean = false) = boolean(key) ?: defVal
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun optInt(key : Int, defVal : Int = 0) = int(key) ?: defVal
|
fun optInt(key: Int, defVal: Int = 0) = int(key) ?: defVal
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun optLong(key : Int, defVal : Long = 0L) = long(key) ?: defVal
|
fun optLong(key: Int, defVal: Long = 0L) = long(key) ?: defVal
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun optFloat(key : Int, defVal : Float = 0f) = float(key) ?: defVal
|
fun optFloat(key: Int, defVal: Float = 0f) = float(key) ?: defVal
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun optDouble(key : Int, defVal : Double = 0.0) = double(key) ?: defVal
|
fun optDouble(key: Int, defVal: Double = 0.0) = double(key) ?: defVal
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun notEmptyOrThrow(key : Int) = notEmptyOrThrow(key.toString(), string(key))
|
fun notEmptyOrThrow(key: Int) = notEmptyOrThrow(key.toString(), string(key))
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun isNull(key : Int) = this[key] == null
|
fun isNull(key: Int) = this[key] == null
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order/38218582#38218582
|
// https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order/38218582#38218582
|
||||||
@ -146,16 +147,16 @@ class JsonObject : LinkedHashMap<String, Any?>() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun castBoolean(o : Any?) : Boolean? =
|
fun castBoolean(o: Any?): Boolean? =
|
||||||
when(o) {
|
when (o) {
|
||||||
null -> null
|
null -> null
|
||||||
is Boolean -> o
|
is Boolean -> o
|
||||||
is Int -> o != 0
|
is Int -> o != 0
|
||||||
is Long -> o != 0L
|
is Long -> o != 0L
|
||||||
is Float -> ! (o.isFinite() && o == 0f)
|
is Float -> !(o.isFinite() && o == 0f)
|
||||||
is Double -> ! (o.isFinite() && o == 0.0)
|
is Double -> !(o.isFinite() && o == 0.0)
|
||||||
|
|
||||||
is String -> when(o) {
|
is String -> when (o) {
|
||||||
"", "0", "false", "False" -> false
|
"", "0", "false", "False" -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
@ -166,74 +167,74 @@ class JsonObject : LinkedHashMap<String, Any?>() {
|
|||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun castLong(o : Any?) : Long? =
|
fun castLong(o: Any?): Long? =
|
||||||
when(o) {
|
when (o) {
|
||||||
is Long -> o
|
is Long -> o
|
||||||
is Number -> o.toLong()
|
is Number -> o.toLong()
|
||||||
|
|
||||||
is String -> try {
|
is String -> try {
|
||||||
o.stringToNumber().toLong()
|
o.stringToNumber().toLong()
|
||||||
} catch(_ : NumberFormatException) {
|
} catch (_: NumberFormatException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null // may null or JsonObject.NULL or object,array,boolean
|
else -> null // may null or JsonObject.NULL or object,array,boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
fun castInt(o : Any?) : Int? =
|
fun castInt(o: Any?): Int? =
|
||||||
when(o) {
|
when (o) {
|
||||||
|
|
||||||
is Int -> o
|
is Int -> o
|
||||||
|
|
||||||
is Number -> try {
|
is Number -> try {
|
||||||
o.toInt()
|
o.toInt()
|
||||||
} catch(_ : NumberFormatException) {
|
} catch (_: NumberFormatException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
is String -> try {
|
is String -> try {
|
||||||
o.stringToNumber().toInt()
|
o.stringToNumber().toInt()
|
||||||
} catch(_ : NumberFormatException) {
|
} catch (_: NumberFormatException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null // may null or JsonObject.NULL or object,array,boolean
|
else -> null // may null or JsonObject.NULL or object,array,boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
fun castDouble(o : Any?) : Double? =
|
fun castDouble(o: Any?): Double? =
|
||||||
when(o) {
|
when (o) {
|
||||||
|
|
||||||
is Double -> o
|
is Double -> o
|
||||||
|
|
||||||
is Number -> try {
|
is Number -> try {
|
||||||
o.toDouble()
|
o.toDouble()
|
||||||
} catch(_ : NumberFormatException) {
|
} catch (_: NumberFormatException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
is String -> try {
|
is String -> try {
|
||||||
o.stringToNumber().toDouble()
|
o.stringToNumber().toDouble()
|
||||||
} catch(_ : NumberFormatException) {
|
} catch (_: NumberFormatException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null // may null or JsonObject.NULL or object,array,boolean
|
else -> null // may null or JsonObject.NULL or object,array,boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
fun castFloat(o : Any?) : Float? =
|
fun castFloat(o: Any?): Float? =
|
||||||
when(o) {
|
when (o) {
|
||||||
|
|
||||||
is Float -> o
|
is Float -> o
|
||||||
|
|
||||||
is Number -> try {
|
is Number -> try {
|
||||||
o.toFloat()
|
o.toFloat()
|
||||||
} catch(_ : NumberFormatException) {
|
} catch (_: NumberFormatException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
is String -> try {
|
is String -> try {
|
||||||
o.stringToNumber().toFloat()
|
o.stringToNumber().toFloat()
|
||||||
} catch(_ : NumberFormatException) {
|
} catch (_: NumberFormatException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,81 +242,82 @@ class JsonObject : LinkedHashMap<String, Any?>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toString(indentFactor : Int) : String {
|
fun toString(indentFactor: Int): String {
|
||||||
val sw = StringWriter()
|
val sw = StringWriter()
|
||||||
synchronized(sw.buffer) {
|
synchronized(sw.buffer) {
|
||||||
return sw.writeJsonValue(indentFactor, 0, this).toString()
|
return sw.writeJsonValue(indentFactor, 0, this).toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() : String = toString(0)
|
override fun toString(): String = toString(0)
|
||||||
|
|
||||||
fun string(key : String) : String? = this[key]?.toString()
|
fun string(key: String): String? = this[key]?.toString()
|
||||||
fun boolean(key : String) : Boolean? = castBoolean(this[key])
|
fun boolean(key: String): Boolean? = castBoolean(this[key])
|
||||||
fun int(key : String) : Int? = castInt(this[key])
|
fun int(key: String): Int? = castInt(this[key])
|
||||||
fun long(key : String) : Long? = castLong(this[key])
|
fun long(key: String): Long? = castLong(this[key])
|
||||||
fun float(key : String) : Float? = castFloat(this[key])
|
fun float(key: String): Float? = castFloat(this[key])
|
||||||
fun double(key : String) : Double? = castDouble(this[key])
|
fun double(key: String): Double? = castDouble(this[key])
|
||||||
fun jsonObject(name : String) = this[name].cast<JsonObject>()
|
fun jsonObject(name: String) = this[name].cast<JsonObject>()
|
||||||
fun jsonArray(name : String) = this[name].cast<JsonArray>()
|
fun jsonArray(name: String) = this[name].cast<JsonArray>()
|
||||||
|
|
||||||
fun stringArrayList(name : String) : ArrayList<String>? =
|
fun stringArrayList(name: String): ArrayList<String>? =
|
||||||
jsonArray(name)?.stringArrayList()?.notEmpty()
|
jsonArray(name)?.stringArrayList()?.notEmpty()
|
||||||
|
|
||||||
fun objectList(name : String) : List<JsonObject>? =
|
fun objectList(name: String): List<JsonObject>? =
|
||||||
jsonArray(name)?.objectList()?.notEmpty()
|
jsonArray(name)?.objectList()?.notEmpty()
|
||||||
|
|
||||||
fun floatArrayList(name : String) : ArrayList<Float>? =
|
fun floatArrayList(name: String): ArrayList<Float>? =
|
||||||
jsonArray(name)?.floatArrayList()?.notEmpty()
|
jsonArray(name)?.floatArrayList()?.notEmpty()
|
||||||
|
|
||||||
fun optString(name : String, defVal : String = "") = string(name) ?: defVal
|
fun optString(name: String, defVal: String = "") = string(name) ?: defVal
|
||||||
fun optBoolean(name : String, defVal : Boolean = false) = boolean(name) ?: defVal
|
fun optBoolean(name: String, defVal: Boolean = false) = boolean(name) ?: defVal
|
||||||
fun optInt(name : String, defVal : Int = 0) = int(name) ?: defVal
|
fun optInt(name: String, defVal: Int = 0) = int(name) ?: defVal
|
||||||
fun optLong(name : String, defVal : Long = 0L) = long(name) ?: defVal
|
fun optLong(name: String, defVal: Long = 0L) = long(name) ?: defVal
|
||||||
fun optFloat(name : String, defVal : Float = 0f) = float(name) ?: defVal
|
fun optFloat(name: String, defVal: Float = 0f) = float(name) ?: defVal
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun optDouble(name : String, defVal : Double = 0.0) = double(name) ?: defVal
|
fun optDouble(name: String, defVal: Double = 0.0) = double(name) ?: defVal
|
||||||
|
|
||||||
|
fun stringOrThrow(name: String) = notEmptyOrThrow(name, string(name))
|
||||||
|
|
||||||
fun stringOrThrow(name : String) = notEmptyOrThrow(name, string(name))
|
|
||||||
// fun isNull(name : String) = this[name] == null
|
// fun isNull(name : String) = this[name] == null
|
||||||
fun putNotNull(name : String, value : Any?) {
|
fun putNotNull(name: String, value: Any?) {
|
||||||
if(value != null) put(name, value)
|
if (value != null) put(name, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class JsonTokenizer(reader : Reader) {
|
class JsonTokenizer(reader: Reader) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private fun String.toStringOrNumber() : Any {
|
private fun String.toStringOrNumber(): Any {
|
||||||
/*
|
/*
|
||||||
* If it might be a number, try converting it. If a number cannot be
|
* If it might be a number, try converting it. If a number cannot be
|
||||||
* produced, then the value will just be a string.
|
* produced, then the value will just be a string.
|
||||||
*/
|
*/
|
||||||
val initial = this.firstOrNull()
|
val initial = this.firstOrNull()
|
||||||
if(initial != null && (initial in '0' .. '9' || initial == '-')) {
|
if (initial != null && (initial in '0'..'9' || initial == '-')) {
|
||||||
try { // if we want full Big Number support the contents of this
|
try { // if we want full Big Number support the contents of this
|
||||||
// `try` block can be replaced with:
|
// `try` block can be replaced with:
|
||||||
// return stringToNumber(string);
|
// return stringToNumber(string);
|
||||||
if(isDecimalNotation()) {
|
if (isDecimalNotation()) {
|
||||||
val d = toDouble()
|
val d = toDouble()
|
||||||
if(! d.isInfinite() && ! d.isNaN()) {
|
if (!d.isInfinite() && !d.isNaN()) {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val longValue = toLong()
|
val longValue = toLong()
|
||||||
if(longValue.toString() == this) {
|
if (longValue.toString() == this) {
|
||||||
try {
|
try {
|
||||||
val intValue = longValue.toInt()
|
val intValue = longValue.toInt()
|
||||||
if(intValue.toLong() == longValue) return intValue
|
if (intValue.toLong() == longValue) return intValue
|
||||||
} catch(_ : Throwable) {
|
} catch (_: Throwable) {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
return longValue
|
return longValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(ignore : Exception) {
|
} catch (ignore: Exception) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
@ -323,7 +325,7 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// constructor(inputStream : InputStream) : this(InputStreamReader(inputStream))
|
// constructor(inputStream : InputStream) : this(InputStreamReader(inputStream))
|
||||||
constructor(s : String) : this(StringReader(s))
|
constructor(s: String) : this(StringReader(s))
|
||||||
|
|
||||||
/** current read character position on the current line. */
|
/** current read character position on the current line. */
|
||||||
private var character = 1L
|
private var character = 1L
|
||||||
@ -341,7 +343,7 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
private var previous = char0
|
private var previous = char0
|
||||||
|
|
||||||
/** Reader for the input. */
|
/** Reader for the input. */
|
||||||
private val reader = if(reader.markSupported()) reader else BufferedReader(reader)
|
private val reader = if (reader.markSupported()) reader else BufferedReader(reader)
|
||||||
|
|
||||||
/** flag to indicate that a previous character was requested. */
|
/** flag to indicate that a previous character was requested. */
|
||||||
private var usePrevious = false
|
private var usePrevious = false
|
||||||
@ -357,7 +359,7 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* or if already at the start of the string
|
* or if already at the start of the string
|
||||||
*/
|
*/
|
||||||
private fun back() {
|
private fun back() {
|
||||||
if(usePrevious || index <= 0) {
|
if (usePrevious || index <= 0) {
|
||||||
throw JsonException("Stepping back two steps is not supported")
|
throw JsonException("Stepping back two steps is not supported")
|
||||||
}
|
}
|
||||||
decrementIndexes()
|
decrementIndexes()
|
||||||
@ -369,12 +371,12 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* Decrements the indexes for the [.back] method based on the previous character read.
|
* Decrements the indexes for the [.back] method based on the previous character read.
|
||||||
*/
|
*/
|
||||||
private fun decrementIndexes() {
|
private fun decrementIndexes() {
|
||||||
index --
|
index--
|
||||||
if(previous == '\r' || previous == '\n') {
|
if (previous == '\r' || previous == '\n') {
|
||||||
line --
|
line--
|
||||||
character = characterPreviousLine
|
character = characterPreviousLine
|
||||||
} else if(character > 0) {
|
} else if (character > 0) {
|
||||||
character --
|
character--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,8 +385,8 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
*
|
*
|
||||||
* @return true if at the end of the file and we didn't step back
|
* @return true if at the end of the file and we didn't step back
|
||||||
*/
|
*/
|
||||||
private fun end() : Boolean {
|
private fun end(): Boolean {
|
||||||
return eof && ! usePrevious
|
return eof && !usePrevious
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
@ -421,18 +423,18 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* @return The next character, or 0 if past the end of the source string.
|
* @return The next character, or 0 if past the end of the source string.
|
||||||
* @throws JsonException Thrown if there is an error reading the source string.
|
* @throws JsonException Thrown if there is an error reading the source string.
|
||||||
*/
|
*/
|
||||||
private operator fun next() : Char {
|
private operator fun next(): Char {
|
||||||
val c : Char
|
val c: Char
|
||||||
if(usePrevious) {
|
if (usePrevious) {
|
||||||
usePrevious = false
|
usePrevious = false
|
||||||
c = previous
|
c = previous
|
||||||
} else {
|
} else {
|
||||||
val i = try {
|
val i = try {
|
||||||
reader.read()
|
reader.read()
|
||||||
} catch(exception : IOException) {
|
} catch (exception: IOException) {
|
||||||
throw JsonException(exception)
|
throw JsonException(exception)
|
||||||
}
|
}
|
||||||
if(i <= 0) { // End of stream
|
if (i <= 0) { // End of stream
|
||||||
eof = true
|
eof = true
|
||||||
return char0
|
return char0
|
||||||
}
|
}
|
||||||
@ -448,26 +450,26 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* read and the character passed as the current character.
|
* read and the character passed as the current character.
|
||||||
* @param c the current character read.
|
* @param c the current character read.
|
||||||
*/
|
*/
|
||||||
private fun incrementIndexes(c : Char) {
|
private fun incrementIndexes(c: Char) {
|
||||||
if(c == char0) return
|
if (c == char0) return
|
||||||
index ++
|
index++
|
||||||
when(c) {
|
when (c) {
|
||||||
'\r' -> {
|
'\r' -> {
|
||||||
line ++
|
line++
|
||||||
characterPreviousLine = character
|
characterPreviousLine = character
|
||||||
character = 0
|
character = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
'\n' -> {
|
'\n' -> {
|
||||||
if(previous != '\r') {
|
if (previous != '\r') {
|
||||||
line ++
|
line++
|
||||||
characterPreviousLine = character
|
characterPreviousLine = character
|
||||||
}
|
}
|
||||||
character = 0
|
character = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
character ++
|
character++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -502,15 +504,15 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* Substring bounds error if there are not
|
* Substring bounds error if there are not
|
||||||
* n characters remaining in the source string.
|
* n characters remaining in the source string.
|
||||||
*/
|
*/
|
||||||
private fun next(@Suppress("SameParameterValue") n : Int) : String {
|
private fun next(@Suppress("SameParameterValue") n: Int): String {
|
||||||
if(n == 0) {
|
if (n == 0) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
val chars = CharArray(n)
|
val chars = CharArray(n)
|
||||||
var pos = 0
|
var pos = 0
|
||||||
while(pos < n) {
|
while (pos < n) {
|
||||||
chars[pos] = this.next()
|
chars[pos] = this.next()
|
||||||
if(end()) {
|
if (end()) {
|
||||||
throw this.syntaxError("Substring bounds error")
|
throw this.syntaxError("Substring bounds error")
|
||||||
}
|
}
|
||||||
pos += 1
|
pos += 1
|
||||||
@ -523,10 +525,10 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* @throws JsonException Thrown if there is an error reading the source string.
|
* @throws JsonException Thrown if there is an error reading the source string.
|
||||||
* @return A character, or 0 if there are no more characters.
|
* @return A character, or 0 if there are no more characters.
|
||||||
*/
|
*/
|
||||||
private fun nextClean() : Char {
|
private fun nextClean(): Char {
|
||||||
while(true) {
|
while (true) {
|
||||||
val c = this.next()
|
val c = this.next()
|
||||||
if(c == char0 || c > ' ') {
|
if (c == char0 || c > ' ') {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -543,11 +545,11 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* @return A String.
|
* @return A String.
|
||||||
* @throws JsonException Unterminated string.
|
* @throws JsonException Unterminated string.
|
||||||
*/
|
*/
|
||||||
private fun nextString(quote : Char) : String {
|
private fun nextString(quote: Char): String {
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
while(true) {
|
while (true) {
|
||||||
var c : Char = this.next()
|
var c: Char = this.next()
|
||||||
when(c) {
|
when (c) {
|
||||||
char0, '\n', '\r' ->
|
char0, '\n', '\r' ->
|
||||||
throw this.syntaxError("Unterminated string")
|
throw this.syntaxError("Unterminated string")
|
||||||
|
|
||||||
@ -556,7 +558,7 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
|
|
||||||
'\\' -> {
|
'\\' -> {
|
||||||
c = this.next()
|
c = this.next()
|
||||||
when(c) {
|
when (c) {
|
||||||
'b' -> sb.append('\b')
|
'b' -> sb.append('\b')
|
||||||
't' -> sb.append('\t')
|
't' -> sb.append('\t')
|
||||||
'n' -> sb.append('\n')
|
'n' -> sb.append('\n')
|
||||||
@ -564,7 +566,7 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
'r' -> sb.append('\r')
|
'r' -> sb.append('\r')
|
||||||
'u' -> try {
|
'u' -> try {
|
||||||
sb.append(this.next(4).toInt(16).toChar())
|
sb.append(this.next(4).toInt(16).toChar())
|
||||||
} catch(e : NumberFormatException) {
|
} catch (e: NumberFormatException) {
|
||||||
throw syntaxError("Illegal escape.", e)
|
throw syntaxError("Illegal escape.", e)
|
||||||
}
|
}
|
||||||
'"', '\'', '\\', '/' -> sb.append(c)
|
'"', '\'', '\\', '/' -> sb.append(c)
|
||||||
@ -628,10 +630,10 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
*
|
*
|
||||||
* @return An object.
|
* @return An object.
|
||||||
*/
|
*/
|
||||||
fun nextValue() : Any? {
|
fun nextValue(): Any? {
|
||||||
var c = nextClean()
|
var c = nextClean()
|
||||||
val string : String
|
val string: String
|
||||||
when(c) {
|
when (c) {
|
||||||
'"', '\'' -> return nextString(c)
|
'"', '\'' -> return nextString(c)
|
||||||
|
|
||||||
'{' -> {
|
'{' -> {
|
||||||
@ -653,15 +655,15 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* formatting character.
|
* formatting character.
|
||||||
*/
|
*/
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
while(c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
|
while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
|
||||||
sb.append(c)
|
sb.append(c)
|
||||||
c = this.next()
|
c = this.next()
|
||||||
}
|
}
|
||||||
if(! eof) {
|
if (!eof) {
|
||||||
back()
|
back()
|
||||||
}
|
}
|
||||||
string = sb.toString().trim { it <= ' ' }
|
string = sb.toString().trim { it <= ' ' }
|
||||||
if("" == string) {
|
if ("" == string) {
|
||||||
throw syntaxError("Missing value")
|
throw syntaxError("Missing value")
|
||||||
}
|
}
|
||||||
return with(string) {
|
return with(string) {
|
||||||
@ -718,7 +720,7 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* @param message The error message.
|
* @param message The error message.
|
||||||
* @return A JsonException object, suitable for throwing
|
* @return A JsonException object, suitable for throwing
|
||||||
*/
|
*/
|
||||||
private fun syntaxError(message : String) : JsonException {
|
private fun syntaxError(message: String): JsonException {
|
||||||
return JsonException(message + this.toString())
|
return JsonException(message + this.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,8 +732,8 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
* @return A JsonException object, suitable for throwing
|
* @return A JsonException object, suitable for throwing
|
||||||
*/
|
*/
|
||||||
private fun syntaxError(
|
private fun syntaxError(
|
||||||
@Suppress("SameParameterValue") message : String,
|
@Suppress("SameParameterValue") message: String,
|
||||||
causedBy : Throwable?
|
causedBy: Throwable?
|
||||||
) = JsonException(message + toString(), causedBy)
|
) = JsonException(message + toString(), causedBy)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -739,17 +741,17 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
*
|
*
|
||||||
* @return " at {index} [character {character} line {line}]"
|
* @return " at {index} [character {character} line {line}]"
|
||||||
*/
|
*/
|
||||||
override fun toString() : String =
|
override fun toString(): String =
|
||||||
" at $index [character $character line $line]"
|
" at $index [character $character line $line]"
|
||||||
|
|
||||||
private fun parseInto(dst : JsonObject) : JsonObject {
|
private fun parseInto(dst: JsonObject): JsonObject {
|
||||||
|
|
||||||
if(nextClean() != '{')
|
if (nextClean() != '{')
|
||||||
throw syntaxError("A JsonObject text must begin with '{'")
|
throw syntaxError("A JsonObject text must begin with '{'")
|
||||||
|
|
||||||
while(true) {
|
while (true) {
|
||||||
var c : Char = nextClean()
|
var c: Char = nextClean()
|
||||||
val key : String = when(c) {
|
val key: String = when (c) {
|
||||||
char0 ->
|
char0 ->
|
||||||
throw syntaxError("A JsonObject text must end with '}'")
|
throw syntaxError("A JsonObject text must end with '}'")
|
||||||
'}' ->
|
'}' ->
|
||||||
@ -762,21 +764,21 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
}
|
}
|
||||||
// The key is followed by ':'.
|
// The key is followed by ':'.
|
||||||
c = nextClean()
|
c = nextClean()
|
||||||
if(c != ':')
|
if (c != ':')
|
||||||
throw syntaxError("Expected a ':' after a key")
|
throw syntaxError("Expected a ':' after a key")
|
||||||
|
|
||||||
// Use syntaxError(..) to include error location
|
// Use syntaxError(..) to include error location
|
||||||
// Check if key exists
|
// Check if key exists
|
||||||
|
|
||||||
// key already exists
|
// key already exists
|
||||||
if(dst.contains(key))
|
if (dst.contains(key))
|
||||||
throw syntaxError("Duplicate key \"$key\"")
|
throw syntaxError("Duplicate key \"$key\"")
|
||||||
|
|
||||||
// Only add value if non-null
|
// Only add value if non-null
|
||||||
dst[key] = nextValue()
|
dst[key] = nextValue()
|
||||||
when(nextClean()) {
|
when (nextClean()) {
|
||||||
';', ',' -> {
|
';', ',' -> {
|
||||||
if(nextClean() == '}') {
|
if (nextClean() == '}') {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
back()
|
back()
|
||||||
@ -788,11 +790,11 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseInto(dst : JsonArray) : JsonArray {
|
private fun parseInto(dst: JsonArray): JsonArray {
|
||||||
if(nextClean() != '[')
|
if (nextClean() != '[')
|
||||||
throw syntaxError("A JsonArray text must start with '['")
|
throw syntaxError("A JsonArray text must start with '['")
|
||||||
|
|
||||||
when(nextClean()) {
|
when (nextClean()) {
|
||||||
// array is unclosed. No ']' found, instead EOF
|
// array is unclosed. No ']' found, instead EOF
|
||||||
char0 -> throw syntaxError("Expected a ',' or ']'")
|
char0 -> throw syntaxError("Expected a ',' or ']'")
|
||||||
// empty array
|
// empty array
|
||||||
@ -800,18 +802,18 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
back()
|
back()
|
||||||
while(true) {
|
while (true) {
|
||||||
if(nextClean() == ',') {
|
if (nextClean() == ',') {
|
||||||
back()
|
back()
|
||||||
dst.add(null)
|
dst.add(null)
|
||||||
} else {
|
} else {
|
||||||
back()
|
back()
|
||||||
dst.add(nextValue())
|
dst.add(nextValue())
|
||||||
}
|
}
|
||||||
when(nextClean()) {
|
when (nextClean()) {
|
||||||
char0 -> throw syntaxError("Expected a ',' or ']'")
|
char0 -> throw syntaxError("Expected a ',' or ']'")
|
||||||
']' -> return dst
|
']' -> return dst
|
||||||
',' -> when(nextClean()) {
|
',' -> when (nextClean()) {
|
||||||
// array is unclosed. No ']' found, instead EOF
|
// array is unclosed. No ']' found, instead EOF
|
||||||
char0 -> throw syntaxError("Expected a ',' or ']'")
|
char0 -> throw syntaxError("Expected a ',' or ']'")
|
||||||
']' -> return dst
|
']' -> return dst
|
||||||
@ -827,21 +829,24 @@ class JsonTokenizer(reader : Reader) {
|
|||||||
|
|
||||||
private val reNumber = """-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?""".toRegex()
|
private val reNumber = """-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?""".toRegex()
|
||||||
|
|
||||||
private fun Writer.writeQuote(string : String) : Writer {
|
private fun Writer.writeQuote(string: String): Writer {
|
||||||
if(string.isEmpty()) {
|
if (string.isEmpty()) {
|
||||||
write("\"\"")
|
write("\"\"")
|
||||||
} else {
|
} else {
|
||||||
append('"')
|
append('"')
|
||||||
var previousChar : Char = char0
|
var previousChar: Char = char0
|
||||||
for(c in string) {
|
for (c in string) {
|
||||||
when(c) {
|
when (c) {
|
||||||
'\\', '"' -> {
|
'\\', '"' -> {
|
||||||
append('\\')
|
append('\\')
|
||||||
append(c)
|
append(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't escape some characters those used in many emoji
|
||||||
|
'\u200d', '\u20e3', '\u203c', '\u2049' -> append(c)
|
||||||
|
|
||||||
'/' -> {
|
'/' -> {
|
||||||
if(previousChar == '<') append('\\')
|
if (previousChar == '<') append('\\')
|
||||||
append(c)
|
append(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,7 +860,7 @@ private fun Writer.writeQuote(string : String) : Writer {
|
|||||||
in '\u0080' until '\u00a0',
|
in '\u0080' until '\u00a0',
|
||||||
in '\u2000' until '\u2100' -> {
|
in '\u2000' until '\u2100' -> {
|
||||||
write("\\u")
|
write("\\u")
|
||||||
val hexCode : String = Integer.toHexString(c.toInt())
|
val hexCode: String = Integer.toHexString(c.toInt())
|
||||||
write("0000", 0, 4 - hexCode.length)
|
write("0000", 0, 4 - hexCode.length)
|
||||||
write(hexCode)
|
write(hexCode)
|
||||||
}
|
}
|
||||||
@ -869,60 +874,60 @@ private fun Writer.writeQuote(string : String) : Writer {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Number.toJsonString() : String {
|
private fun Number.toJsonString(): String {
|
||||||
|
|
||||||
when(this) {
|
when (this) {
|
||||||
is Double -> if(isInfinite() || isNaN())
|
is Double -> if (isInfinite() || isNaN())
|
||||||
throw JsonException("JSON does not allow non-finite numbers.")
|
throw JsonException("JSON does not allow non-finite numbers.")
|
||||||
is Float -> if(isInfinite() || isNaN())
|
is Float -> if (isInfinite() || isNaN())
|
||||||
throw JsonException("JSON does not allow non-finite numbers.")
|
throw JsonException("JSON does not allow non-finite numbers.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shave off trailing zeros and decimal point, if possible.
|
// Shave off trailing zeros and decimal point, if possible.
|
||||||
var string = toString()
|
var string = toString()
|
||||||
if(string.indexOf('.') > 0 &&
|
if (string.indexOf('.') > 0 &&
|
||||||
string.indexOf('e') < 0 &&
|
string.indexOf('e') < 0 &&
|
||||||
string.indexOf('E') < 0
|
string.indexOf('E') < 0
|
||||||
) {
|
) {
|
||||||
while(string.endsWith("0")) {
|
while (string.endsWith("0")) {
|
||||||
string = string.substring(0, string.length - 1)
|
string = string.substring(0, string.length - 1)
|
||||||
}
|
}
|
||||||
if(string.endsWith(".")) {
|
if (string.endsWith(".")) {
|
||||||
string = string.substring(0, string.length - 1)
|
string = string.substring(0, string.length - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string
|
return string
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Writer.indent(indentFactor : Int, indent : Int) : Writer {
|
private fun Writer.indent(indentFactor: Int, indent: Int): Writer {
|
||||||
if(indentFactor > 0) {
|
if (indentFactor > 0) {
|
||||||
append('\n')
|
append('\n')
|
||||||
for(i in 0 until indent) append(' ')
|
for (i in 0 until indent) append(' ')
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Writer.writeCollection(indentFactor : Int, indent : Int, src : Collection<*>) : Writer =
|
private fun Writer.writeCollection(indentFactor: Int, indent: Int, src: Collection<*>): Writer =
|
||||||
try {
|
try {
|
||||||
append('[')
|
append('[')
|
||||||
when(src.size) {
|
when (src.size) {
|
||||||
0 -> {
|
0 -> {
|
||||||
}
|
}
|
||||||
|
|
||||||
1 -> try {
|
1 -> try {
|
||||||
writeJsonValue(indentFactor, indent, src.iterator().next())
|
writeJsonValue(indentFactor, indent, src.iterator().next())
|
||||||
} catch(e : Exception) {
|
} catch (e: Exception) {
|
||||||
throw JsonException("Unable to write JsonArray value at index: 0", e)
|
throw JsonException("Unable to write JsonArray value at index: 0", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val newIndent = indent + indentFactor
|
val newIndent = indent + indentFactor
|
||||||
for((index, value) in src.withIndex()) {
|
for ((index, value) in src.withIndex()) {
|
||||||
if(index > 0) append(',')
|
if (index > 0) append(',')
|
||||||
indent(indentFactor, newIndent)
|
indent(indentFactor, newIndent)
|
||||||
try {
|
try {
|
||||||
writeJsonValue(indentFactor, newIndent, value)
|
writeJsonValue(indentFactor, newIndent, value)
|
||||||
} catch(ex : Exception) {
|
} catch (ex: Exception) {
|
||||||
throw JsonException("Unable to write JsonArray value at index: $index", ex)
|
throw JsonException("Unable to write JsonArray value at index: $index", ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -931,33 +936,33 @@ private fun Writer.writeCollection(indentFactor : Int, indent : Int, src : Colle
|
|||||||
}
|
}
|
||||||
append(']')
|
append(']')
|
||||||
this
|
this
|
||||||
} catch(e : IOException) {
|
} catch (e: IOException) {
|
||||||
throw JsonException(e)
|
throw JsonException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Writer.writeArray(indentFactor : Int, indent : Int, src : Any) : Writer =
|
private fun Writer.writeArray(indentFactor: Int, indent: Int, src: Any): Writer =
|
||||||
try {
|
try {
|
||||||
append('[')
|
append('[')
|
||||||
when(val size = java.lang.reflect.Array.getLength(src)) {
|
when (val size = java.lang.reflect.Array.getLength(src)) {
|
||||||
0 -> {
|
0 -> {
|
||||||
}
|
}
|
||||||
|
|
||||||
1 -> try {
|
1 -> try {
|
||||||
val value = java.lang.reflect.Array.get(src, 0)
|
val value = java.lang.reflect.Array.get(src, 0)
|
||||||
writeJsonValue(indentFactor, indent, value)
|
writeJsonValue(indentFactor, indent, value)
|
||||||
} catch(e : Exception) {
|
} catch (e: Exception) {
|
||||||
throw JsonException("Unable to write JsonArray value at index: 0", e)
|
throw JsonException("Unable to write JsonArray value at index: 0", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val newIndent = indent + indentFactor
|
val newIndent = indent + indentFactor
|
||||||
for(index in 0 until size) {
|
for (index in 0 until size) {
|
||||||
if(index > 0) append(',')
|
if (index > 0) append(',')
|
||||||
indent(indentFactor, newIndent)
|
indent(indentFactor, newIndent)
|
||||||
try {
|
try {
|
||||||
val value = java.lang.reflect.Array.get(src, index)
|
val value = java.lang.reflect.Array.get(src, index)
|
||||||
writeJsonValue(indentFactor, newIndent, value)
|
writeJsonValue(indentFactor, newIndent, value)
|
||||||
} catch(ex : Exception) {
|
} catch (ex: Exception) {
|
||||||
throw JsonException("Unable to write JsonArray value at index: $index", ex)
|
throw JsonException("Unable to write JsonArray value at index: $index", ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -966,14 +971,14 @@ private fun Writer.writeArray(indentFactor : Int, indent : Int, src : Any) : Wri
|
|||||||
}
|
}
|
||||||
append(']')
|
append(']')
|
||||||
this
|
this
|
||||||
} catch(e : IOException) {
|
} catch (e: IOException) {
|
||||||
throw JsonException(e)
|
throw JsonException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Writer.writeMap(indentFactor : Int, indent : Int, src : Map<*, *>) : Writer =
|
private fun Writer.writeMap(indentFactor: Int, indent: Int, src: Map<*, *>): Writer =
|
||||||
try {
|
try {
|
||||||
append('{')
|
append('{')
|
||||||
when(src.size) {
|
when (src.size) {
|
||||||
0 -> {
|
0 -> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,10 +986,10 @@ private fun Writer.writeMap(indentFactor : Int, indent : Int, src : Map<*, *>) :
|
|||||||
val entry = src.entries.first()
|
val entry = src.entries.first()
|
||||||
writeJsonValue(indentFactor, indent, entry.key)
|
writeJsonValue(indentFactor, indent, entry.key)
|
||||||
append(':')
|
append(':')
|
||||||
if(indentFactor > 0) append(' ')
|
if (indentFactor > 0) append(' ')
|
||||||
try {
|
try {
|
||||||
writeJsonValue(indentFactor, indent, entry.value)
|
writeJsonValue(indentFactor, indent, entry.value)
|
||||||
} catch(ex : Throwable) {
|
} catch (ex: Throwable) {
|
||||||
throw JsonException(
|
throw JsonException(
|
||||||
"Unable to write JsonObject value for key: ${entry.key}",
|
"Unable to write JsonObject value for key: ${entry.key}",
|
||||||
ex
|
ex
|
||||||
@ -995,15 +1000,15 @@ private fun Writer.writeMap(indentFactor : Int, indent : Int, src : Map<*, *>) :
|
|||||||
else -> {
|
else -> {
|
||||||
val newIndent = indent + indentFactor
|
val newIndent = indent + indentFactor
|
||||||
var needsComma = false
|
var needsComma = false
|
||||||
for(entry in src.entries) {
|
for (entry in src.entries) {
|
||||||
if(needsComma) append(',')
|
if (needsComma) append(',')
|
||||||
indent(indentFactor, newIndent)
|
indent(indentFactor, newIndent)
|
||||||
writeJsonValue(indentFactor, newIndent, entry.key)
|
writeJsonValue(indentFactor, newIndent, entry.key)
|
||||||
append(':')
|
append(':')
|
||||||
if(indentFactor > 0) append(' ')
|
if (indentFactor > 0) append(' ')
|
||||||
try {
|
try {
|
||||||
writeJsonValue(indentFactor, newIndent, entry.value)
|
writeJsonValue(indentFactor, newIndent, entry.value)
|
||||||
} catch(ex : Exception) {
|
} catch (ex: Exception) {
|
||||||
throw JsonException(
|
throw JsonException(
|
||||||
"Unable to write JsonObject value for key: ${entry.key}",
|
"Unable to write JsonObject value for key: ${entry.key}",
|
||||||
ex
|
ex
|
||||||
@ -1016,15 +1021,15 @@ private fun Writer.writeMap(indentFactor : Int, indent : Int, src : Map<*, *>) :
|
|||||||
}
|
}
|
||||||
append('}')
|
append('}')
|
||||||
this
|
this
|
||||||
} catch(e : IOException) {
|
} catch (e: IOException) {
|
||||||
throw JsonException(e)
|
throw JsonException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Writer.writeJsonValue(
|
fun Writer.writeJsonValue(
|
||||||
indentFactor : Int,
|
indentFactor: Int,
|
||||||
indent : Int,
|
indent: Int,
|
||||||
value : Any?
|
value: Any?
|
||||||
) : Writer {
|
): Writer {
|
||||||
when {
|
when {
|
||||||
value == null -> write("null")
|
value == null -> write("null")
|
||||||
|
|
||||||
@ -1032,7 +1037,7 @@ fun Writer.writeJsonValue(
|
|||||||
|
|
||||||
value is Number -> {
|
value is Number -> {
|
||||||
val sv = value.toJsonString()
|
val sv = value.toJsonString()
|
||||||
if(reNumber.matches(sv)) {
|
if (reNumber.matches(sv)) {
|
||||||
write(sv)
|
write(sv)
|
||||||
} else {
|
} else {
|
||||||
// not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
|
// not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
|
||||||
@ -1057,8 +1062,8 @@ fun Writer.writeJsonValue(
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
fun notEmptyOrThrow(name : String, value : String?) =
|
fun notEmptyOrThrow(name: String, value: String?) =
|
||||||
if(value?.isNotEmpty() == true) value else throw RuntimeException("$name is empty")
|
if (value?.isNotEmpty() == true) value else throw RuntimeException("$name is empty")
|
||||||
|
|
||||||
// return null if the json value is "null"
|
// return null if the json value is "null"
|
||||||
fun String.decodeJsonValue() = JsonTokenizer(this).nextValue()
|
fun String.decodeJsonValue() = JsonTokenizer(this).nextValue()
|
||||||
@ -1071,30 +1076,30 @@ fun String.decodeJsonValue() = JsonTokenizer(this).nextValue()
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun String.decodeJsonObject() = decodeJsonValue() !!.castNotNull<JsonObject>()
|
fun String.decodeJsonObject() = decodeJsonValue()!!.castNotNull<JsonObject>()
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun String.decodeJsonArray() = decodeJsonValue() !!.castNotNull<JsonArray>()
|
fun String.decodeJsonArray() = decodeJsonValue()!!.castNotNull<JsonArray>()
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun Array<*>.toJsonArray() : JsonArray = JsonArray(this)
|
fun Array<*>.toJsonArray(): JsonArray = JsonArray(this)
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun List<*>.toJsonArray() = JsonArray(this)
|
fun List<*>.toJsonArray() = JsonArray(this)
|
||||||
|
|
||||||
inline fun jsonObject(initializer : JsonObject.() -> Unit) =
|
inline fun jsonObject(initializer: JsonObject.() -> Unit) =
|
||||||
JsonObject().apply { initializer() }
|
JsonObject().apply { initializer() }
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
inline fun jsonArray(initializer : JsonArray.() -> Unit) =
|
inline fun jsonArray(initializer: JsonArray.() -> Unit) =
|
||||||
JsonArray().apply { initializer() }
|
JsonArray().apply { initializer() }
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun jsonArray(vararg args : String) = JsonArray(args)
|
fun jsonArray(vararg args: String) = JsonArray(args)
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun jsonObject(vararg args : Pair<String, *>) = JsonObject().apply {
|
fun jsonObject(vararg args: Pair<String, *>) = JsonObject().apply {
|
||||||
for(pair in args) {
|
for (pair in args) {
|
||||||
put(pair.first, pair.second)
|
put(pair.first, pair.second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user