Unverified Commit d90660e8 authored by Nikolay Igotti's avatar Nikolay Igotti Committed by GitHub

Provide mechanisms to return strings (#324)

parent 7939fb15
package org.jetbrains.skia package org.jetbrains.skia
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.Managed
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skia.impl.NativePointer
class ManagedString internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR) { class ManagedString internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR) {
companion object { companion object {
...@@ -20,7 +17,10 @@ class ManagedString internal constructor(ptr: NativePointer) : Managed(ptr, _Fin ...@@ -20,7 +17,10 @@ class ManagedString internal constructor(ptr: NativePointer) : Managed(ptr, _Fin
override fun toString(): String { override fun toString(): String {
return try { return try {
Stats.onNativeCall() Stats.onNativeCall()
_nToString(_ptr) val size = _nStringSize(_ptr)
withResult(ByteArray(size)) {
_nStringData(_ptr, it, size)
}.decodeToString()
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -61,8 +61,11 @@ private external fun ManagedString_nGetFinalizer(): NativePointer ...@@ -61,8 +61,11 @@ private external fun ManagedString_nGetFinalizer(): NativePointer
@ExternalSymbolName("org_jetbrains_skia_ManagedString__1nMake") @ExternalSymbolName("org_jetbrains_skia_ManagedString__1nMake")
private external fun _nMake(s: String?): NativePointer private external fun _nMake(s: String?): NativePointer
@ExternalSymbolName("org_jetbrains_skia_ManagedString__1nToString") @ExternalSymbolName("org_jetbrains_skia_ManagedString__nStringSize")
private external fun _nToString(ptr: NativePointer): String private external fun _nStringSize(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_ManagedString__nStringData")
private external fun _nStringData(ptr: NativePointer, result: InteropPointer, size: Int): String
@ExternalSymbolName("org_jetbrains_skia_ManagedString__1nInsert") @ExternalSymbolName("org_jetbrains_skia_ManagedString__1nInsert")
private external fun _nInsert(ptr: NativePointer, offset: Int, s: String?) private external fun _nInsert(ptr: NativePointer, offset: Int, s: String?)
......
package org.jetbrains.skia.impl package org.jetbrains.skia.impl
import org.jetbrains.skia.ManagedString
expect class NativePointer expect class NativePointer
expect class InteropPointer expect class InteropPointer
...@@ -106,6 +108,12 @@ inline fun withResult(result: NativePointerArray, block: (InteropPointer) -> Uni ...@@ -106,6 +108,12 @@ inline fun withResult(result: NativePointerArray, block: (InteropPointer) -> Uni
result result
} }
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
inline fun withStringResult(block: () -> NativePointer): String {
val string = ManagedString(block())
return string.toString()
}
interface ArrayInteropDecoder<T> { interface ArrayInteropDecoder<T> {
fun getArrayElement(array: InteropPointer, index: Int): T fun getArrayElement(array: InteropPointer, index: Int): T
fun getArraySize(array: InteropPointer): Int fun getArraySize(array: InteropPointer): Int
......
package org.jetbrains.skia
import org.jetbrains.skia.impl.withStringResult
import org.jetbrains.skiko.tests.nativeStringByIndex
import kotlin.test.Test
import kotlin.test.assertEquals
class ManagedStringTest {
@Test
fun basicTest() {
val s1 = withStringResult {
nativeStringByIndex(0)
}
assertEquals("Hello", s1)
val s2 = withStringResult {
nativeStringByIndex(1)
}
assertEquals("Привет", s2)
val s3 = withStringResult {
nativeStringByIndex(2)
}
assertEquals("你好", s3)
}
}
...@@ -2,6 +2,8 @@ package org.jetbrains.skiko.tests ...@@ -2,6 +2,8 @@ package org.jetbrains.skiko.tests
import org.jetbrains.skia.ExternalSymbolName import org.jetbrains.skia.ExternalSymbolName
import org.jetbrains.skia.impl.* import org.jetbrains.skia.impl.*
import kotlin.test.Test
import kotlin.test.assertEquals
class TestHelpers { class TestHelpers {
...@@ -54,3 +56,8 @@ private external fun _nFillIntArrayOf5(interopPointer: InteropPointer) ...@@ -54,3 +56,8 @@ private external fun _nFillIntArrayOf5(interopPointer: InteropPointer)
@ExternalSymbolName("org_jetbrains_skiko_tests_TestHelpers__1nFillDoubleArrayOf5") @ExternalSymbolName("org_jetbrains_skiko_tests_TestHelpers__1nFillDoubleArrayOf5")
private external fun _nFillDoubleArrayOf5(interopPointer: InteropPointer) private external fun _nFillDoubleArrayOf5(interopPointer: InteropPointer)
@ExternalSymbolName("org_jetbrains_skiko_tests_TestHelpers__nStringByIndex")
private external fun _nStringByIndex(index: Int): NativePointer
internal fun nativeStringByIndex(index: Int): NativePointer = _nStringByIndex(index)
\ No newline at end of file
...@@ -110,7 +110,7 @@ class InteropScopeTests { ...@@ -110,7 +110,7 @@ class InteropScopeTests {
it + 1 it + 1
}.map { }.map {
val charArray = CharArray(2) val charArray = CharArray(2)
(npa[it] as InteropPointer).fromInterop(charArray) npa[it].fromInterop(charArray)
charArray.concatToString() charArray.concatToString()
}.take(3).toList().toTypedArray() }.take(3).toList().toTypedArray()
......
...@@ -17,10 +17,20 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ManagedStringKt__1nMa ...@@ -17,10 +17,20 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ManagedStringKt__1nMa
return reinterpret_cast<jlong>(text); return reinterpret_cast<jlong>(text);
} }
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_ManagedStringKt__1nToString extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_ManagedStringKt__1nStringSize
(JNIEnv* env, jclass jclass, jlong ptr) { (JNIEnv* env, jclass jclass, jlong ptr) {
SkString* instance = reinterpret_cast<SkString*>(static_cast<uintptr_t>(ptr)); SkString* instance = reinterpret_cast<SkString*>(static_cast<uintptr_t>(ptr));
return javaString(env, *instance); return instance->size();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_ManagedStringKt__1nStringData
(JNIEnv* env, jclass jclass, jlong ptr, jbyteArray array, jint size) {
SkString* instance = reinterpret_cast<SkString*>(static_cast<uintptr_t>(ptr));
jbyte* bytes = env->GetByteArrayElements(array, NULL);
if (bytes != nullptr) {
memcpy(bytes, instance->c_str(), size);
env->ReleaseByteArrayElements(array, bytes, 0);
}
} }
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_ManagedStringKt__1nInsert extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_ManagedStringKt__1nInsert
......
#include <jni.h> #include <jni.h>
#include "SkString.h"
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__1nFillByteArrayOf5 extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__1nFillByteArrayOf5
(JNIEnv* env, jclass jclass, jbyteArray jbarray) { (JNIEnv* env, jclass jclass, jbyteArray jbarray) {
jbyte *result_bytes = env->GetByteArrayElements(jbarray, NULL); jbyte *result_bytes = env->GetByteArrayElements(jbarray, NULL);
...@@ -11,7 +13,6 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__ ...@@ -11,7 +13,6 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__
env->ReleaseByteArrayElements(jbarray, result_bytes, 0); env->ReleaseByteArrayElements(jbarray, result_bytes, 0);
} }
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__1nFillFloatArrayOf5 extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__1nFillFloatArrayOf5
(JNIEnv* env, jclass jclass, jfloatArray jfarray) { (JNIEnv* env, jclass jclass, jfloatArray jfarray) {
jfloat *result_float = env->GetFloatArrayElements(jfarray, NULL); jfloat *result_float = env->GetFloatArrayElements(jfarray, NULL);
...@@ -55,3 +56,18 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__ ...@@ -55,3 +56,18 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__
result_double[4] = 10000000.9991; result_double[4] = 10000000.9991;
env->ReleaseDoubleArrayElements(jdarray, result_double, 0); env->ReleaseDoubleArrayElements(jdarray, result_double, 0);
} }
static inline jlong ptrToJlong(void* ptr) {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_tests_TestHelpersKt__1nStringByIndex
(JNIEnv* env, jclass jclass, jint index) {
switch (index) {
case 0: return ptrToJlong(new SkString("Hello"));
case 1: return ptrToJlong(new SkString("Привет"));
case 2: return ptrToJlong(new SkString("你好"));
default: return 0;
}
}
...@@ -19,20 +19,17 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_ManagedString__1nMake ...@@ -19,20 +19,17 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_ManagedString__1nMake
return reinterpret_cast<KNativePointer>(text); return reinterpret_cast<KNativePointer>(text);
} }
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_ManagedString__1nToString SKIKO_EXPORT KInt org_jetbrains_skia_ManagedString__nStringSize
(KNativePointer ptr) { (KNativePointer ptr) {
TODO("implement org_jetbrains_skia_ManagedString__1nToString"); SkString* instance = reinterpret_cast<SkString*>(ptr);
return instance->size();
} }
#if 0
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_ManagedString__1nToString
(KNativePointer ptr) {
SkString* instance = reinterpret_cast<SkString*>((ptr));
return javaString(env, *instance);
}
#endif
SKIKO_EXPORT void org_jetbrains_skia_ManagedString__nStringData
(KNativePointer ptr, KByte* bytes, KInt size) {
SkString* instance = reinterpret_cast<SkString*>(ptr);
memcpy(bytes, instance->c_str(), size);
}
SKIKO_EXPORT void org_jetbrains_skia_ManagedString__1nInsert SKIKO_EXPORT void org_jetbrains_skia_ManagedString__1nInsert
(KNativePointer ptr, KInt offset, KInteropPointer s) { (KNativePointer ptr, KInt offset, KInteropPointer s) {
......
...@@ -45,3 +45,12 @@ SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nFillDoubleArrayOf5(KN ...@@ -45,3 +45,12 @@ SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nFillDoubleArrayOf5(KN
doubles[3] = 3.1415; doubles[3] = 3.1415;
doubles[4] = 10000000.9991; doubles[4] = 10000000.9991;
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_tests_TestHelpers__nStringByIndex(KInt index) {
switch (index) {
case 0: return new SkString("Hello");
case 1: return new SkString("Привет");
case 2: return new SkString("你好");
default: TODO("unknown");
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment