summaryrefslogtreecommitdiff
path: root/runtime/jvmMain/src/kotlinx/serialization/Serialization.kt
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/jvmMain/src/kotlinx/serialization/Serialization.kt')
-rw-r--r--runtime/jvmMain/src/kotlinx/serialization/Serialization.kt74
1 files changed, 74 insertions, 0 deletions
diff --git a/runtime/jvmMain/src/kotlinx/serialization/Serialization.kt b/runtime/jvmMain/src/kotlinx/serialization/Serialization.kt
new file mode 100644
index 00000000..0c30ad87
--- /dev/null
+++ b/runtime/jvmMain/src/kotlinx/serialization/Serialization.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2018 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package kotlinx.serialization
+
+import kotlin.reflect.KClass
+
+@Suppress("UNCHECKED_CAST")
+@ImplicitReflectionSerializer
+actual fun <T: Any> KClass<T>.compiledSerializer(): KSerializer<T>? = this.java.invokeSerializerGetter()
+
+actual fun String.toUtf8Bytes() = this.toByteArray(Charsets.UTF_8)
+actual fun stringFromUtf8Bytes(bytes: ByteArray) = String(bytes, Charsets.UTF_8)
+
+actual fun <E: Enum<E>> enumFromName(enumClass: KClass<E>, value: String): E = java.lang.Enum.valueOf(enumClass.java, value)
+actual fun <E: Enum<E>> enumFromOrdinal(enumClass: KClass<E>, ordinal: Int): E = enumClass.java.enumConstants[ordinal]
+
+actual fun <E: Enum<E>> KClass<E>.enumClassName(): String = this.java.canonicalName ?: ""
+actual fun <E : Enum<E>> KClass<E>.enumMembers(): Array<E> = this.java.enumConstants
+
+@Suppress("UNCHECKED_CAST")
+actual fun <T: Any, E: T?> ArrayList<E>.toNativeArray(eClass: KClass<T>): Array<E> = toArray(java.lang.reflect.Array.newInstance(eClass.java, size) as Array<E>)
+
+@Suppress("UNCHECKED_CAST")
+@ImplicitReflectionSerializer
+internal fun <T> Class<T>.invokeSerializerGetter(vararg args: KSerializer<Any>): KSerializer<T>? {
+ var serializer: KSerializer<T>? = null
+
+ // Search for serializer defined on companion object.
+ val companion = declaredFields.singleOrNull { it.name == "Companion" }?.apply { isAccessible = true }?.get(null)
+ if (companion != null) {
+ serializer = companion.javaClass.methods
+ .find { method ->
+ method.name == "serializer" && method.parameterTypes.size == args.size && method.parameterTypes.all { it == KSerializer::class.java }
+ }
+ ?.invoke(companion, *args) as? KSerializer<T>
+ }
+
+ // Search for default serializer in case no serializer is defined on companion object.
+ if (serializer == null) {
+ serializer =
+ declaredClasses.singleOrNull { it.simpleName == ("\$serializer") }
+ ?.getField("INSTANCE")?.get(null) as? KSerializer<T>
+ }
+
+ return serializer
+}
+
+/**
+ * Checks if an [this@isInstanceOf] is an instance of a given [kclass].
+ *
+ * This check is a replacement for [KClass.isInstance] because
+ * on JVM it requires kotlin-reflect.jar in classpath
+ * (see https://youtrack.jetbrains.com/issue/KT-14720).
+ *
+ * On JS and Native, this function delegates to aforementioned
+ * [KClass.isInstance] since it is supported there out-of-the box;
+ * on JVM, it falls back to java.lang.Class.isInstance which causes
+ * difference when applied to function types with big arity.
+ */
+internal actual fun Any.isInstanceOf(kclass: KClass<*>): Boolean = kclass.java.isInstance(this)