diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2024-07-22 23:06:16 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2024-07-23 00:04:58 +0200 |
| commit | 09bc93ed756361d396890c389b01315cdb5e32fd (patch) | |
| tree | 3a2718a2b5a3584a489d009a532526239f6b45a5 /libs/samba/src/main/cpp/jni.cpp | |
| parent | 42564c71cfb70c28831c662a3b6bf4084e079353 (diff) | |
Add initial code for samba implementation based on libsmb2
Diffstat (limited to 'libs/samba/src/main/cpp/jni.cpp')
| -rw-r--r-- | libs/samba/src/main/cpp/jni.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/libs/samba/src/main/cpp/jni.cpp b/libs/samba/src/main/cpp/jni.cpp new file mode 100644 index 0000000..be13df7 --- /dev/null +++ b/libs/samba/src/main/cpp/jni.cpp @@ -0,0 +1,100 @@ +#include "jni.hpp" + +#include <android/log.h> + +namespace { + +JavaVM *g_vm; + +const char *_jni_error(jint err) { + switch (err) { + case JNI_OK: + return "OK"; + case JNI_ERR: + return "Unknown error"; + case JNI_EDETACHED: + return "Thread detached from the VM"; + case JNI_EVERSION: + return "JNI version error"; + case JNI_ENOMEM: + return "Not enough memory"; + case JNI_EEXIST: + return "VM already created"; + case JNI_EINVAL: + return "Invalid arguments"; + default: + return "Unexpected error"; + } +} + +} // namespace + +namespace jni { + +namespace internal { + +void _abort_if_not_ok(const char *file, int line, jint ret) { + if (ret == JNI_OK) [[likely]] return; + __android_log_assert(nullptr, "jni", "JNI error: %s", _jni_error(ret)); +} + +void _abort_with_exception(const char* file, int line, JNIEnv* env) { + auto throwable = jni::ExceptionOccurred(env); + env->ExceptionClear(); + if (throwable) { + auto throwable_class = jni::FindClass(env, "java/lang/Throwable"); + if (throwable_class) { + auto throwable_toString = env->GetMethodID(throwable_class.get(), + "toString", + "()Ljava/lang/String;"); + if (throwable_toString) { + auto description = jni::CallObjectMethod<jstring>(env, throwable, + throwable_toString); + auto str = jni::StringToUTF8(env, description); + __android_log_assert(nullptr, "jni", "JNI error: %s", str.c_str()); + } + } + env->ExceptionClear(); + __android_log_assert(nullptr, "jni", + "Unexpected NULL but no exception"); + } +} + +} // namespace internal + +JNIEnv* AttachCurrentThread() { + JNIEnv* env; + auto ret = g_vm->AttachCurrentThread(&env, nullptr); + ABORT_IF_NOT_OK(ret); + return env; +} + +JNIEnv* OnLoad(JavaVM* vm) { + void* v_env; + auto ret = vm->GetEnv(&v_env, JNI_VERSION); + ABORT_IF_NOT_OK(ret); + return reinterpret_cast<JNIEnv*>(v_env); +} + +LocalRef<jclass> FindClass(JNIEnv *env, const char *name) { + return {env, env->FindClass(name)}; +} + +LocalRef<jthrowable> ExceptionOccurred(JNIEnv* env) { + return {env, env->ExceptionOccurred()}; +} + +std::string StringToUTF8(JNIEnv* env, const Ref<jstring>& str) { + if (!str) return "null"; + auto len = env->GetStringUTFLength(str.get()); + std::string ret(len, ' '); + env->GetStringUTFRegion(str.get(), 0, len, ret.data()); + // This returns modified UTF-8 encoding, don't care. + return ret; +} + +LocalRef<jstring> UTF8ToString(JNIEnv* env, const std::string& str) { + return {env, env->NewStringUTF(str.c_str())}; +} + +} // namespace jni |
