Commit 67305c78 authored by Volker Krause's avatar Volker Krause
Browse files

Implement JNI array creation

Of very limited use so far, we cannot write to them yet.
parent ca419f90
......@@ -97,6 +97,13 @@ private Q_SLOTS:
}
#endif
}
void testArrayCreate()
{
auto a1 = Jni::Array<jshort>(10);
auto a2 = Jni::Array<java::lang::String>(5);
auto a3 = Jni::Array<java::lang::String>(3, QStringLiteral("test"));
}
};
QTEST_GUILESS_MAIN(JniArrayTest)
......
......@@ -12,6 +12,7 @@
class QAndroidJniEnvironment
{
public:
inline jclass findClass(const char *) { return nullptr; }
inline operator JNIEnv*() const { return &m_env; }
inline JNIEnv* operator->() { return &m_env; }
......
......@@ -53,8 +53,11 @@ struct JNIEnv
{
inline bool ExceptionCheck() { return false; }
inline void ExceptionClear() {}
inline int GetArrayLength(jobjectArray) { return m_arrayLength; }
inline jobjectArray NewObjectArray(jsize, jclass, jobject) { return nullptr; }
inline jobject GetObjectArrayElement(jobjectArray, int index) { return reinterpret_cast<jobject>(index); }
inline void SetObjectArrayElement(jobjectArray, jsize, jobject) {}
inline jbooleanArray NewBooleanArray(jsize) { return nullptr; }
inline jbyteArray NewByteArray (jsize) { return nullptr; }
......
......@@ -7,6 +7,7 @@
#ifndef KANDROIDEXTRAS_JNIARRAY_H
#define KANDROIDEXTRAS_JNIARRAY_H
#include "jniargument.h"
#include "jnireturnvalue.h"
#include "jnitypetraits.h"
......@@ -150,29 +151,34 @@ protected:
template <typename T, bool is_basic>
class ArrayImpl {};
// array wrapper for basic types
// array wrapper for primitive types
template <typename T>
class ArrayImpl<T, true> : public ArrayImplBase<T>
{
public:
ArrayImpl(const QAndroidJniObject &array)
inline ArrayImpl(const QAndroidJniObject &array)
: ArrayImplBase<T>(array)
{
if (!array.isValid()) {
return;
}
// ### do this on demand?
QAndroidJniEnvironment env;
m_data = ArrayImplBase<T>::_t::getArrayElements(env, this->handle(), nullptr);
getArrayElements();
}
~ArrayImpl()
/** Create a new array with @p size elements. */
inline explicit ArrayImpl(jsize size)
{
QAndroidJniEnvironment env;
ArrayImplBase<T>::_t::releaseArrayElements(env, this->handle(), m_data, JNI_ABORT);
ArrayImplBase<T>::m_array = QAndroidJniObject::fromLocalRef(ArrayImplBase<T>::_t::newArray(env, size));
getArrayElements();
}
ArrayImpl() = default;
ArrayImpl(const ArrayImpl&) = delete; // ### ref count m_data and allow copying?
ArrayImpl(ArrayImpl&&) = default;
~ArrayImpl()
{
QAndroidJniEnvironment env;
ArrayImplBase<T>::_t::releaseArrayElements(env, this->handle(), m_data, JNI_ABORT);
}
T operator[](jsize index) const
{
......@@ -183,15 +189,41 @@ public:
T* end() const { return m_data + ArrayImplBase<T>::size(); }
private:
inline void getArrayElements()
{
if (!ArrayImplBase<T>::m_array.isValid()) {
return;
}
QAndroidJniEnvironment env;
m_data = ArrayImplBase<T>::_t::getArrayElements(env, this->handle(), nullptr);
}
T *m_data = nullptr;
};
// array wrapper for non-based types
// array wrapper for non-primitive types
template <typename T>
class ArrayImpl<T, false> : public ArrayImplBase<T>
{
public:
using ArrayImplBase<T>::ArrayImplBase;
/** Create a new array with @p size elements initialized with @p value. */
explicit inline ArrayImpl(jsize size, typename Internal::argument<T>::type value)
{
QAndroidJniEnvironment env;
auto clazz = env.findClass(Jni::typeName<T>());
ArrayImplBase<T>::m_array = QAndroidJniObject::fromLocalRef(env->NewObjectArray(size, clazz, Internal::argument<T>::toCallArgument(value)));
}
/** Create a new array with @p size null elements. */
explicit inline ArrayImpl(jsize size, std::nullptr_t = nullptr)
{
QAndroidJniEnvironment env;
auto clazz = env.findClass(Jni::typeName<T>());
ArrayImplBase<T>::m_array = QAndroidJniObject::fromLocalRef(env->NewObjectArray(size, clazz, nullptr));
}
ArrayImpl() = default;
ArrayImpl(const ArrayImpl&) = default;
ArrayImpl(ArrayImpl&&) = default;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment