commonMain.kotlinx.serialization.internal.Platform.common.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-jupyter-script-classpath-shadowed Show documentation
Show all versions of kotlin-jupyter-script-classpath-shadowed Show documentation
Kotlin Jupyter kernel script classpath with all dependencies inside one artifact
/*
* Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
@file:OptIn(ExperimentalSerializationApi::class)
package kotlinx.serialization.internal
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlin.native.concurrent.*
import kotlin.reflect.*
internal object InternalHexConverter {
private const val hexCode = "0123456789ABCDEF"
fun parseHexBinary(s: String): ByteArray {
val len = s.length
require(len % 2 == 0) { "HexBinary string must be even length" }
val bytes = ByteArray(len / 2)
var i = 0
while (i < len) {
val h = hexToInt(s[i])
val l = hexToInt(s[i + 1])
require(!(h == -1 || l == -1)) { "Invalid hex chars: ${s[i]}${s[i + 1]}" }
bytes[i / 2] = ((h shl 4) + l).toByte()
i += 2
}
return bytes
}
private fun hexToInt(ch: Char): Int = when (ch) {
in '0'..'9' -> ch - '0'
in 'A'..'F' -> ch - 'A' + 10
in 'a'..'f' -> ch - 'a' + 10
else -> -1
}
fun printHexBinary(data: ByteArray, lowerCase: Boolean = false): String {
val r = StringBuilder(data.size * 2)
for (b in data) {
r.append(hexCode[b.toInt() shr 4 and 0xF])
r.append(hexCode[b.toInt() and 0xF])
}
return if (lowerCase) r.toString().lowercase() else r.toString()
}
fun toHexString(n: Int): String {
val arr = ByteArray(4)
for (i in 0 until 4) {
arr[i] = (n shr (24 - i * 8)).toByte()
}
return printHexBinary(arr, true).trimStart('0').takeIf { it.isNotEmpty() } ?: "0"
}
}
@OptIn(ExperimentalSerializationApi::class)
internal fun SerialDescriptor.cachedSerialNames(): Set {
if (this is CachedNames) return serialNames
val result = HashSet(elementsCount)
for (i in 0 until elementsCount) {
result += getElementName(i)
}
return result
}
private val EMPTY_DESCRIPTOR_ARRAY: Array = arrayOf()
/**
* Same as [toTypedArray], but uses special empty array constant, if [this]
* is null or empty.
*/
internal fun List?.compactArray(): Array =
takeUnless { it.isNullOrEmpty() }?.toTypedArray() ?: EMPTY_DESCRIPTOR_ARRAY
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
@PublishedApi
internal inline fun KSerializer<*>.cast(): KSerializer = this as KSerializer
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
@PublishedApi
internal inline fun SerializationStrategy<*>.cast(): SerializationStrategy = this as SerializationStrategy
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
@PublishedApi
internal inline fun DeserializationStrategy<*>.cast(): DeserializationStrategy =
this as DeserializationStrategy
internal fun KClass<*>.serializerNotRegistered(): Nothing {
throw SerializationException(notRegisteredMessage())
}
internal fun KClass<*>.notRegisteredMessage(): String = notRegisteredMessage(simpleName ?: "")
internal fun notRegisteredMessage(className: String): String = "Serializer for class '$className' is not found.\n" +
"Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.\n"
internal expect fun KClass<*>.platformSpecificSerializerNotRegistered(): Nothing
@Suppress("UNCHECKED_CAST")
internal fun KType.kclass() = when (val t = classifier) {
is KClass<*> -> t
is KTypeParameter -> {
// If you are going to change this error message, please also actualize the message in the compiler intrinsics here:
// Kotlin/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializationJvmIrIntrinsicSupport.kt#argumentTypeOrGenerateException
throw IllegalArgumentException(
"Captured type parameter $t from generic non-reified function. " +
"Such functionality cannot be supported because $t is erased, either specify serializer explicitly or make " +
"calling function inline with reified $t."
)
}
else -> throw IllegalArgumentException("Only KClass supported as classifier, got $t")
} as KClass
// If you are going to change this error message, please also actualize the message in the compiler intrinsics here:
// Kotlin/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializationJvmIrIntrinsicSupport.kt#argumentTypeOrGenerateException
internal fun KTypeProjection.typeOrThrow(): KType = requireNotNull(type) { "Star projections in type arguments are not allowed, but had $type" }
/**
* Constructs KSerializer> by given KSerializer, KSerializer, ...
* via reflection (on JVM) or compiler+plugin intrinsic `SerializerFactory` (on Native)
*/
internal expect fun KClass.constructSerializerForGivenTypeArgs(vararg args: KSerializer): KSerializer?
/**
* Checks whether given KType and its corresponding KClass represent a reference array
*/
internal expect fun isReferenceArray(rootClass: KClass): Boolean
/**
* Array.get that checks indices on JS
*/
internal expect fun Array.getChecked(index: Int): T
/**
* Array.get that checks indices on JS
*/
internal expect fun BooleanArray.getChecked(index: Int): Boolean
internal expect fun KClass.compiledSerializerImpl(): KSerializer?
/**
* Create serializers cache for non-parametrized and non-contextual serializers.
* The activity and type of cache is determined for a specific platform and a specific environment.
*/
internal expect fun createCache(factory: (KClass<*>) -> KSerializer?): SerializerCache
/**
* Create serializers cache for parametrized and non-contextual serializers. Parameters also non-contextual.
* The activity and type of cache is determined for a specific platform and a specific environment.
*/
internal expect fun createParametrizedCache(factory: (KClass, List) -> KSerializer?): ParametrizedSerializerCache
internal expect fun ArrayList.toNativeArrayImpl(eClass: KClass): Array
internal inline fun Iterable.elementsHashCodeBy(selector: (T) -> K): Int {
return fold(1) { hash, element -> 31 * hash + selector(element).hashCode() }
}
/**
* Cache class for non-parametrized and non-contextual serializers.
*/
internal interface SerializerCache {
/**
* Returns cached serializer or `null` if serializer not found.
*/
fun get(key: KClass): KSerializer?
}
/**
* Cache class for parametrized and non-contextual serializers.
*/
internal interface ParametrizedSerializerCache {
/**
* Returns successful result with cached serializer or `null` if root serializer not found.
* If no serializer was found for the parameters, then result contains an exception.
*/
fun get(key: KClass, types: List = emptyList()): Result?>
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy