diff --git a/kotlin-native/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt b/kotlin-native/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt index f99ac1fb915..e9bc4b35316 100644 --- a/kotlin-native/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt +++ b/kotlin-native/Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt @@ -21,9 +21,22 @@ import java.io.File import java.nio.file.Files import java.nio.file.Paths -internal fun decodeFromUtf8(bytes: ByteArray) = String(bytes) +private fun decodeFromUtf8(bytes: ByteArray) = String(bytes) internal fun encodeToUtf8(str: String) = str.toByteArray() +internal fun CPointer.toKStringFromUtf8Impl(): String { + val nativeBytes = this + + var length = 0 + while (nativeBytes[length] != 0.toByte()) { + ++length + } + + val bytes = ByteArray(length) + nativeMemUtils.getByteArray(nativeBytes.pointed, bytes, length) + return decodeFromUtf8(bytes) +} + fun bitsToFloat(bits: Int): Float = java.lang.Float.intBitsToFloat(bits) fun bitsToDouble(bits: Long): Double = java.lang.Double.longBitsToDouble(bits) diff --git a/kotlin-native/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt b/kotlin-native/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt index a4e83f74b40..0f74241fe7e 100644 --- a/kotlin-native/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt +++ b/kotlin-native/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt @@ -507,18 +507,7 @@ public val String.utf32: CValues /** * @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string. */ -public fun CPointer.toKStringFromUtf8(): String { - val nativeBytes = this - - var length = 0 - while (nativeBytes[length] != 0.toByte()) { - ++length - } - - val bytes = ByteArray(length) - nativeMemUtils.getByteArray(nativeBytes.pointed, bytes, length) - return decodeFromUtf8(bytes) -} +public fun CPointer.toKStringFromUtf8(): String = this.toKStringFromUtf8Impl() /** * @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string. diff --git a/kotlin-native/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt b/kotlin-native/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt index 846bd3650f4..ccf17aca9e6 100644 --- a/kotlin-native/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt +++ b/kotlin-native/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt @@ -20,9 +20,11 @@ import kotlin.native.internal.Intrinsic import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType -internal fun decodeFromUtf8(bytes: ByteArray): String = bytes.decodeToString() internal fun encodeToUtf8(str: String): ByteArray = str.encodeToByteArray() +@SymbolName("Kotlin_CString_toKStringFromUtf8Impl") +internal external fun CPointer.toKStringFromUtf8Impl(): String + @TypedIntrinsic(IntrinsicType.INTEROP_BITS_TO_FLOAT) external fun bitsToFloat(bits: Int): Float diff --git a/kotlin-native/runtime/src/main/cpp/Interop.cpp b/kotlin-native/runtime/src/main/cpp/Interop.cpp index 4b6c2909110..e37f1931f1d 100644 --- a/kotlin-native/runtime/src/main/cpp/Interop.cpp +++ b/kotlin-native/runtime/src/main/cpp/Interop.cpp @@ -17,8 +17,10 @@ #include #include #include +#include #include "Alloc.h" +#include "KString.h" #include "Memory.h" #include "MemorySharedRefs.hpp" #include "Types.h" @@ -42,4 +44,8 @@ OBJ_GETTER(Kotlin_Interop_derefStablePointer, KNativePtr pointer) { RETURN_OBJ(holder->ref()); } +OBJ_GETTER(Kotlin_CString_toKStringFromUtf8Impl, const char* cstring) { + RETURN_RESULT_OF(StringFromUtf8Buffer, cstring, strlen(cstring)); +} + } diff --git a/kotlin-native/runtime/src/main/cpp/KString.cpp b/kotlin-native/runtime/src/main/cpp/KString.cpp index 63b37549675..f9579a50720 100644 --- a/kotlin-native/runtime/src/main/cpp/KString.cpp +++ b/kotlin-native/runtime/src/main/cpp/KString.cpp @@ -511,6 +511,13 @@ OBJ_GETTER(Kotlin_ByteArray_unsafeStringFromUtf8, KConstRef thiz, KInt start, KI RETURN_RESULT_OF(utf8ToUtf16, rawString, size); } +OBJ_GETTER(StringFromUtf8Buffer, const char* start, size_t size) { + if (size == 0) { + RETURN_RESULT_OF0(TheEmptyString); + } + RETURN_RESULT_OF(utf8ToUtf16, start, size); +} + OBJ_GETTER(Kotlin_String_unsafeStringToUtf8, KString thiz, KInt start, KInt size) { RETURN_RESULT_OF(unsafeUtf16ToUtf8Impl, thiz, start, size); } diff --git a/kotlin-native/runtime/src/main/cpp/KString.h b/kotlin-native/runtime/src/main/cpp/KString.h index eaf8139ae6f..e970d449af1 100644 --- a/kotlin-native/runtime/src/main/cpp/KString.h +++ b/kotlin-native/runtime/src/main/cpp/KString.h @@ -31,6 +31,8 @@ OBJ_GETTER(CreateStringFromUtf8, const char* utf8, uint32_t lengthBytes); char* CreateCStringFromString(KConstRef kstring); void DisposeCString(char* cstring); +OBJ_GETTER(StringFromUtf8Buffer, const char* start, size_t size); + #ifdef __cplusplus } #endif