commonMain.kotlinx.serialization.json.internal.StringOps.kt Maven / Gradle / Ivy
/*
* Copyright 2017-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.serialization.json.internal
import kotlin.native.concurrent.SharedImmutable
private fun toHexChar(i: Int) : Char {
val d = i and 0xf
return if (d < 10) (d + '0'.toInt()).toChar()
else (d - 10 + 'a'.toInt()).toChar()
}
/*
* Even though the actual size of this array is 92, it has to be the power of two, otherwise
* JVM cannot perform advanced range-check elimination and vectorization in printQuoted
*/
@SharedImmutable
private val ESCAPE_CHARS: Array = arrayOfNulls(128).apply {
for (c in 0..0x1f) {
val c1 = toHexChar(c shr 12)
val c2 = toHexChar(c shr 8)
val c3 = toHexChar(c shr 4)
val c4 = toHexChar(c)
this[c] = "\\u$c1$c2$c3$c4"
}
this['"'.toInt()] = "\\\""
this['\\'.toInt()] = "\\\\"
this['\t'.toInt()] = "\\t"
this['\b'.toInt()] = "\\b"
this['\n'.toInt()] = "\\n"
this['\r'.toInt()] = "\\r"
this[0x0c] = "\\f"
}
internal fun StringBuilder.printQuoted(value: String) {
append(STRING)
var lastPos = 0
val length = value.length
for (i in 0 until length) {
val c = value[i].toInt()
// Do not replace this constant with C2ESC_MAX (which is smaller than ESCAPE_CHARS size),
// otherwise JIT won't eliminate range check and won't vectorize this loop
if (c >= ESCAPE_CHARS.size) continue // no need to escape
val esc = ESCAPE_CHARS[c] ?: continue
append(value, lastPos, i) // flush prev
append(esc)
lastPos = i + 1
}
append(value, lastPos, length)
append(STRING)
}
/**
* Returns `true` if the contents of this string is equal to the word "true", ignoring case, `false` if content equals "false",
* and throws [IllegalStateException] otherwise.
*/
internal fun String.toBooleanStrict(): Boolean = toBooleanStrictOrNull() ?: throw IllegalStateException("$this does not represent a Boolean")
/**
* Returns `true` if the contents of this string is equal to the word "true", ignoring case, `false` if content equals "false",
* and returns `null` otherwise.
*/
internal fun String.toBooleanStrictOrNull(): Boolean? = when {
this.equals("true", ignoreCase = true) -> true
this.equals("false", ignoreCase = true) -> false
else -> null
}
internal fun shouldBeQuoted(str: String): Boolean {
if (str == NULL) return true
for (ch in str) {
if (charToTokenClass(ch) != TC_OTHER) return true
}
return false
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy