2019-10-08 14:52:01 +00:00
|
|
|
#ifndef LOKINET_JNI_COMMON_HPP
|
|
|
|
#define LOKINET_JNI_COMMON_HPP
|
|
|
|
|
|
|
|
#include <jni.h>
|
2020-09-22 19:04:15 +00:00
|
|
|
#include <string_view>
|
2019-10-08 14:52:01 +00:00
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
/// visit string as native bytes
|
2019-10-09 12:40:40 +00:00
|
|
|
/// jvm uses some unholy encoding internally so we convert it to utf-8
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T, typename V>
|
2019-10-08 14:52:01 +00:00
|
|
|
static T
|
|
|
|
VisitStringAsStringView(JNIEnv* env, jobject str, V visit)
|
|
|
|
{
|
|
|
|
const jclass stringClass = env->GetObjectClass(str);
|
2020-04-07 18:38:56 +00:00
|
|
|
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
|
2019-10-08 14:52:01 +00:00
|
|
|
|
|
|
|
const jstring charsetName = env->NewStringUTF("UTF-8");
|
2020-04-07 18:38:56 +00:00
|
|
|
const jbyteArray stringJbytes = (jbyteArray)env->CallObjectMethod(str, getBytes, charsetName);
|
2019-10-08 14:52:01 +00:00
|
|
|
env->DeleteLocalRef(charsetName);
|
|
|
|
|
2019-10-09 12:40:40 +00:00
|
|
|
const size_t length = env->GetArrayLength(stringJbytes);
|
2020-04-07 18:38:56 +00:00
|
|
|
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
|
2019-10-08 14:52:01 +00:00
|
|
|
|
2020-09-22 19:04:15 +00:00
|
|
|
T result = visit(std::string_view((const char*)pBytes, length));
|
2019-10-08 14:52:01 +00:00
|
|
|
|
|
|
|
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
|
|
|
|
env->DeleteLocalRef(stringJbytes);
|
|
|
|
|
|
|
|
return std::move(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// cast jni buffer to T *
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T>
|
2019-10-08 14:52:01 +00:00
|
|
|
static T*
|
|
|
|
FromBuffer(JNIEnv* env, jobject o)
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (o == nullptr)
|
2019-10-08 14:52:01 +00:00
|
|
|
return nullptr;
|
2020-04-07 18:38:56 +00:00
|
|
|
return static_cast<T*>(env->GetDirectBufferAddress(o));
|
2019-10-08 14:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// get T * from object member called membername
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T>
|
2019-10-08 14:52:01 +00:00
|
|
|
static T*
|
|
|
|
FromObjectMember(JNIEnv* env, jobject self, const char* membername)
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
jclass cl = env->GetObjectClass(self);
|
|
|
|
jfieldID name = env->GetFieldID(cl, membername, "Ljava/nio/Buffer;");
|
2019-10-08 14:52:01 +00:00
|
|
|
jobject buffer = env->GetObjectField(self, name);
|
2020-04-07 18:38:56 +00:00
|
|
|
return FromBuffer<T>(env, buffer);
|
2019-10-08 14:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// visit object string member called membername as bytes
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T, typename V>
|
2019-10-08 14:52:01 +00:00
|
|
|
static T
|
2020-04-07 18:38:56 +00:00
|
|
|
VisitObjectMemberStringAsStringView(JNIEnv* env, jobject self, const char* membername, V v)
|
2019-10-08 14:52:01 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
jclass cl = env->GetObjectClass(self);
|
2019-10-08 14:52:01 +00:00
|
|
|
jfieldID name = env->GetFieldID(cl, membername, "Ljava/lang/String;");
|
2020-04-07 18:38:56 +00:00
|
|
|
jobject str = env->GetObjectField(self, name);
|
|
|
|
return VisitStringAsStringView<T, V>(env, str, v);
|
2019-10-08 14:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// get object member int called membername
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Int_t>
|
2019-10-09 12:40:40 +00:00
|
|
|
Int_t
|
|
|
|
GetObjectMemberAsInt(JNIEnv* env, jobject self, const char* membername)
|
2019-10-08 14:52:01 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
jclass cl = env->GetObjectClass(self);
|
2019-10-08 14:52:01 +00:00
|
|
|
jfieldID name = env->GetFieldID(cl, membername, "I");
|
2019-10-09 12:40:40 +00:00
|
|
|
return env->GetIntField(self, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// get implementation on jni type
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T>
|
2019-10-09 12:40:40 +00:00
|
|
|
T*
|
|
|
|
GetImpl(JNIEnv* env, jobject self)
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
return FromObjectMember<T>(env, self, "impl");
|
2019-10-08 14:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|