From d372cdcea3b3a0ba4b49180695c4e6b0e2d074a5 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Mon, 19 Aug 2024 00:34:03 +0200 Subject: Increase the samba implemetation With the exception of openDir, largely untested. --- libs/samba/src/main/cpp/jni.hpp | 43 +++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'libs/samba/src/main/cpp/jni.hpp') 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 #include +#include #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&) = delete; - Ref& operator=(const Ref&) = 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 { LocalRef(JNIEnv* env, T ptr): Ref(env, ptr) {} ~LocalRef() override { free(); } + LocalRef(LocalRef &&ref) noexcept : Ref(ref.env_, ref.release()) {} + + LocalRef& operator=(const Ref& other) = delete; + protected: T release_to_local() override { return this->ptr_; } void del() override { free(); } @@ -71,6 +76,8 @@ class ParamRef : public Ref { ParamRef(JNIEnv* env, T ptr) : Ref(env, ptr) {} ~ParamRef() override = default; + ParamRef& operator=(const Ref& other) = delete; + protected: T release_to_local() override { if (this->ptr_) @@ -83,11 +90,18 @@ class ParamRef : public Ref { template class GlobalRef : public Ref { public: - GlobalRef(JNIEnv* env, T ptr) : Ref(env, ptr ? env->NewGlobalRef(ptr) : 0) {} - explicit GlobalRef(const Ref& other) : Ref(other.env_, other ? other.env_->NewGlobalRef(other.ptr_) : 0) {} + GlobalRef(JNIEnv* env, T ptr) : Ref(env, ptr ? static_cast(env->NewGlobalRef(static_cast(ptr))) : 0) {} + explicit GlobalRef(const Ref& other) : Ref(other.env(), other ? static_cast(other.env()->NewGlobalRef(static_cast(other.get()))) : 0) {} ~GlobalRef() override { free(); } + GlobalRef& operator=(const Ref& other) { + free(); + this->env_ = other.env(); + this->ptr_ = other ? static_cast(this->env_->NewGlobalRef(static_cast(other.get()))) : 0; + return *this; + } + protected: T release_to_local() override { if (this->ptr_) { @@ -117,19 +131,32 @@ LocalRef FindClass(JNIEnv *env, const char *name); LocalRef ExceptionOccurred(JNIEnv* env); -template -LocalRef CallObjectMethod(JNIEnv* env, const Ref& object, jmethodID method) { - return {env, static_cast(env->CallObjectMethod(object.get(), method))}; +template +LocalRef CallObjectMethod(JNIEnv* env, const Ref& object, jmethodID method, Params... params) { + return {env, static_cast(env->CallObjectMethod(object.get(), method, params...))}; +} + +template +LocalRef CallStaticObjectMethod(JNIEnv* env, const Ref& clazz, jmethodID method, Params... params) { + return {env, static_cast(env->CallStaticObjectMethod(clazz.get(), method, params...))}; } std::string StringToUTF8(JNIEnv* env, const Ref& str); LocalRef UTF8ToString(JNIEnv* env, const std::string& str); +LocalRef CreateArray(JNIEnv* env, const Ref& element_class, std::vector> objects); + namespace internal { template -void _abort_if_null(const char* file, int line, JNIEnv* env, const jni::Ref& ref) { +inline void _abort_if_null(const char* file, int line, JNIEnv* env, const jni::Ref& 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); -- cgit v1.2.3-70-g09d2