diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2024-08-19 00:34:03 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2024-08-19 00:34:03 +0200 |
| commit | d372cdcea3b3a0ba4b49180695c4e6b0e2d074a5 (patch) | |
| tree | f3442d2a56afd362d172cef096c878a5e7311066 /libs/samba/src/main/cpp/jni.hpp | |
| parent | b0d90f32974f6473552d8b1bf5387f9fc4995970 (diff) | |
Increase the samba implemetation
With the exception of openDir, largely untested.
Diffstat (limited to 'libs/samba/src/main/cpp/jni.hpp')
| -rw-r--r-- | libs/samba/src/main/cpp/jni.hpp | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/libs/samba/src/main/cpp/jni.hpp b/libs/samba/src/main/cpp/jni.hpp index 90ca011..450fa71 100644 --- a/libs/samba/src/main/cpp/jni.hpp +++ b/libs/samba/src/main/cpp/jni.hpp @@ -3,6 +3,7 @@ #include <jni.h> #include <string> +#include <vector> #define ABORT_IF_NOT_OK(x) (::jni::internal::_abort_if_not_ok(__FILE__, __LINE__, (x))) #define ABORT_IF_NULL(env, x) (::jni::internal::_abort_if_null(__FILE__, __LINE__, (env), (x))) @@ -21,8 +22,8 @@ class Ref { public: constexpr Ref() : env_(nullptr), ptr_(0) {} Ref(const Ref<T>&) = delete; - Ref<T>& operator=(const Ref<T>&) = delete; + [[nodiscard]] JNIEnv* env() const { return env_; } [[nodiscard]] T get() const { return ptr_; } [[nodiscard]] T release() { auto ret = release_to_local(); @@ -44,7 +45,7 @@ class Ref { virtual T release_to_local() = 0; virtual void del() = 0; - JNIEnv* const env_; + JNIEnv* env_; T ptr_; }; @@ -54,6 +55,10 @@ class LocalRef : public Ref<T> { LocalRef(JNIEnv* env, T ptr): Ref<T>(env, ptr) {} ~LocalRef() override { free(); } + LocalRef(LocalRef<T> &&ref) noexcept : Ref<T>(ref.env_, ref.release()) {} + + LocalRef& operator=(const Ref<T>& other) = delete; + protected: T release_to_local() override { return this->ptr_; } void del() override { free(); } @@ -71,6 +76,8 @@ class ParamRef : public Ref<T> { ParamRef(JNIEnv* env, T ptr) : Ref<T>(env, ptr) {} ~ParamRef() override = default; + ParamRef& operator=(const Ref<T>& other) = delete; + protected: T release_to_local() override { if (this->ptr_) @@ -83,11 +90,18 @@ class ParamRef : public Ref<T> { template<class T> class GlobalRef : public Ref<T> { public: - GlobalRef(JNIEnv* env, T ptr) : Ref<T>(env, ptr ? env->NewGlobalRef(ptr) : 0) {} - explicit GlobalRef(const Ref<T>& other) : Ref<T>(other.env_, other ? other.env_->NewGlobalRef(other.ptr_) : 0) {} + GlobalRef(JNIEnv* env, T ptr) : Ref<T>(env, ptr ? static_cast<T>(env->NewGlobalRef(static_cast<jobject>(ptr))) : 0) {} + explicit GlobalRef(const Ref<T>& other) : Ref<T>(other.env(), other ? static_cast<T>(other.env()->NewGlobalRef(static_cast<jobject>(other.get()))) : 0) {} ~GlobalRef() override { free(); } + GlobalRef& operator=(const Ref<T>& other) { + free(); + this->env_ = other.env(); + this->ptr_ = other ? static_cast<T>(this->env_->NewGlobalRef(static_cast<jobject>(other.get()))) : 0; + return *this; + } + protected: T release_to_local() override { if (this->ptr_) { @@ -117,19 +131,32 @@ LocalRef<jclass> FindClass(JNIEnv *env, const char *name); LocalRef<jthrowable> ExceptionOccurred(JNIEnv* env); -template<typename Out, typename In> -LocalRef<Out> CallObjectMethod(JNIEnv* env, const Ref<In>& object, jmethodID method) { - return {env, static_cast<Out>(env->CallObjectMethod(object.get(), method))}; +template<typename Out, typename In, typename... Params> +LocalRef<Out> CallObjectMethod(JNIEnv* env, const Ref<In>& object, jmethodID method, Params... params) { + return {env, static_cast<Out>(env->CallObjectMethod(object.get(), method, params...))}; +} + +template<typename Out, typename... Params> +LocalRef<Out> CallStaticObjectMethod(JNIEnv* env, const Ref<jclass>& clazz, jmethodID method, Params... params) { + return {env, static_cast<Out>(env->CallStaticObjectMethod(clazz.get(), method, params...))}; } std::string StringToUTF8(JNIEnv* env, const Ref<jstring>& str); LocalRef<jstring> UTF8ToString(JNIEnv* env, const std::string& str); +LocalRef<jobjectArray> CreateArray(JNIEnv* env, const Ref<jclass>& element_class, std::vector<LocalRef<jobject>> objects); + namespace internal { template<typename T> -void _abort_if_null(const char* file, int line, JNIEnv* env, const jni::Ref<T>& ref) { +inline void _abort_if_null(const char* file, int line, JNIEnv* env, const jni::Ref<T>& ref) { + if (ref) [[likely]] return; + + _abort_with_exception(file, line, env); +} + +inline void _abort_if_null(const char* file, int line, JNIEnv* env, jmethodID ref) { if (ref) [[likely]] return; _abort_with_exception(file, line, env); |
