#pragma once #include #include #include /// visit string as native bytes /// jvm uses some unholy encoding internally so we convert it to utf-8 template static T VisitStringAsStringView(JNIEnv* env, jobject str, V visit) { const jclass stringClass = env->GetObjectClass(str); const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B"); const jstring charsetName = env->NewStringUTF("UTF-8"); const jbyteArray stringJbytes = (jbyteArray)env->CallObjectMethod(str, getBytes, charsetName); env->DeleteLocalRef(charsetName); const size_t length = env->GetArrayLength(stringJbytes); jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL); T result = visit(std::string_view((const char*)pBytes, length)); env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT); env->DeleteLocalRef(stringJbytes); return result; } /// cast jni buffer to T * template static T* FromBuffer(JNIEnv* env, jobject o) { if (o == nullptr) return nullptr; return static_cast(env->GetDirectBufferAddress(o)); } /// get T * from object member called membername template static T* FromObjectMember(JNIEnv* env, jobject self, const char* membername) { jclass cl = env->GetObjectClass(self); jfieldID name = env->GetFieldID(cl, membername, "Ljava/nio/ByteBuffer;"); jobject buffer = env->GetObjectField(self, name); return FromBuffer(env, buffer); } /// visit object string member called membername as bytes template static T VisitObjectMemberStringAsStringView(JNIEnv* env, jobject self, const char* membername, V v) { jclass cl = env->GetObjectClass(self); jfieldID name = env->GetFieldID(cl, membername, "Ljava/lang/String;"); jobject str = env->GetObjectField(self, name); return VisitStringAsStringView(env, str, v); } /// get object member int called membername template Int_t GetObjectMemberAsInt(JNIEnv* env, jobject self, const char* membername) { jclass cl = env->GetObjectClass(self); jfieldID name = env->GetFieldID(cl, membername, "I"); return env->GetIntField(self, name); } /// get implementation on jni type template T* GetImpl(JNIEnv* env, jobject self) { return FromObjectMember(env, self, "impl"); }