summaryrefslogtreecommitdiff
path: root/libs/samba/src/main/cpp/jni.hpp
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2024-08-19 00:34:03 +0200
committerJoel Klinghed <the_jk@spawned.biz>2024-08-19 00:34:03 +0200
commitd372cdcea3b3a0ba4b49180695c4e6b0e2d074a5 (patch)
treef3442d2a56afd362d172cef096c878a5e7311066 /libs/samba/src/main/cpp/jni.hpp
parentb0d90f32974f6473552d8b1bf5387f9fc4995970 (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.hpp43
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);