JNI: establish API symmetry across QJniObject and QJniArray
We implicitly support QString, QStringList, and QByteArray, as well as C++ types that are equivalent to JNI primitive types (such as bool for jboolean, or int for jint) in QJniObject and some QJniArray APIs. Make this symmetrical for QJniArray::to/fromContainer. Add more compile- and run-time time test coverage. Change-Id: I8cc84e6181a93f889282d2d3f0a05207416c4dbe Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> (cherry picked from commit d9dd8c4986373789b8bd250d0c2b36b660fe210f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
eedbcad7a4
commit
708b84be11
@ -132,42 +132,43 @@ public:
|
|||||||
"QJniArray::fromContainer", "Container is too large for a Java array");
|
"QJniArray::fromContainer", "Container is too large for a Java array");
|
||||||
|
|
||||||
using ElementType = typename std::remove_reference_t<Container>::value_type;
|
using ElementType = typename std::remove_reference_t<Container>::value_type;
|
||||||
if constexpr (std::disjunction_v<std::is_same<ElementType, jobject>,
|
if constexpr (std::is_base_of_v<std::remove_pointer_t<jobject>,
|
||||||
std::is_same<ElementType, QJniObject>,
|
std::remove_pointer_t<ElementType>>) {
|
||||||
std::is_same<ElementType, QString>,
|
|
||||||
std::is_base_of<QtJniTypes::JObjectBase, ElementType>
|
|
||||||
>) {
|
|
||||||
return makeObjectArray(std::forward<Container>(container));
|
return makeObjectArray(std::forward<Container>(container));
|
||||||
} else if constexpr (std::is_same_v<ElementType, jfloat>) {
|
} else if constexpr (std::disjunction_v<std::is_same<ElementType, QJniObject>,
|
||||||
|
std::is_same<ElementType, QString>,
|
||||||
|
std::is_base_of<QtJniTypes::JObjectBase, ElementType>
|
||||||
|
>) {
|
||||||
|
return QJniArray<ElementType>(makeObjectArray(std::forward<Container>(container)));
|
||||||
|
} else if constexpr (QtJniTypes::sameTypeForJni<ElementType, jfloat>) {
|
||||||
return makeArray<jfloat>(std::forward<Container>(container), &JNIEnv::NewFloatArray,
|
return makeArray<jfloat>(std::forward<Container>(container), &JNIEnv::NewFloatArray,
|
||||||
&JNIEnv::SetFloatArrayRegion);
|
&JNIEnv::SetFloatArrayRegion);
|
||||||
} else if constexpr (std::is_same_v<ElementType, jdouble>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<ElementType, jdouble>) {
|
||||||
return makeArray<jdouble>(std::forward<Container>(container), &JNIEnv::NewDoubleArray,
|
return makeArray<jdouble>(std::forward<Container>(container), &JNIEnv::NewDoubleArray,
|
||||||
&JNIEnv::SetDoubleArrayRegion);
|
&JNIEnv::SetDoubleArrayRegion);
|
||||||
} else if constexpr (std::disjunction_v<std::is_same<ElementType, jboolean>,
|
} else if constexpr (QtJniTypes::sameTypeForJni<ElementType, jboolean>) {
|
||||||
std::is_same<ElementType, bool>>) {
|
|
||||||
return makeArray<jboolean>(std::forward<Container>(container), &JNIEnv::NewBooleanArray,
|
return makeArray<jboolean>(std::forward<Container>(container), &JNIEnv::NewBooleanArray,
|
||||||
&JNIEnv::SetBooleanArrayRegion);
|
&JNIEnv::SetBooleanArrayRegion);
|
||||||
} else if constexpr (std::disjunction_v<std::is_same<ElementType, jbyte>,
|
} else if constexpr (QtJniTypes::sameTypeForJni<ElementType, jbyte>
|
||||||
std::is_same<ElementType, char>>) {
|
|| std::is_same_v<ElementType, char>) {
|
||||||
return makeArray<jbyte>(std::forward<Container>(container), &JNIEnv::NewByteArray,
|
return makeArray<jbyte>(std::forward<Container>(container), &JNIEnv::NewByteArray,
|
||||||
&JNIEnv::SetByteArrayRegion);
|
&JNIEnv::SetByteArrayRegion);
|
||||||
} else if constexpr (std::disjunction_v<std::is_same<ElementType, jchar>,
|
} else if constexpr (std::disjunction_v<std::is_same<ElementType, jchar>,
|
||||||
std::is_same<ElementType, QChar>>) {
|
std::is_same<ElementType, QChar>>) {
|
||||||
return makeArray<jchar>(std::forward<Container>(container), &JNIEnv::NewCharArray,
|
return makeArray<jchar>(std::forward<Container>(container), &JNIEnv::NewCharArray,
|
||||||
&JNIEnv::SetCharArrayRegion);
|
&JNIEnv::SetCharArrayRegion);
|
||||||
} else if constexpr (std::is_same_v<ElementType, jshort>
|
} else if constexpr (QtJniTypes::sameTypeForJni<ElementType, jshort>) {
|
||||||
|| sizeof(ElementType) == sizeof(jshort)) {
|
|
||||||
return makeArray<jshort>(std::forward<Container>(container), &JNIEnv::NewShortArray,
|
return makeArray<jshort>(std::forward<Container>(container), &JNIEnv::NewShortArray,
|
||||||
&JNIEnv::SetShortArrayRegion);
|
&JNIEnv::SetShortArrayRegion);
|
||||||
} else if constexpr (std::is_same_v<ElementType, jint>
|
} else if constexpr (QtJniTypes::sameTypeForJni<ElementType, jint>) {
|
||||||
|| sizeof(ElementType) == sizeof(jint)) {
|
|
||||||
return makeArray<jint>(std::forward<Container>(container), &JNIEnv::NewIntArray,
|
return makeArray<jint>(std::forward<Container>(container), &JNIEnv::NewIntArray,
|
||||||
&JNIEnv::SetIntArrayRegion);
|
&JNIEnv::SetIntArrayRegion);
|
||||||
} else if constexpr (std::is_same_v<ElementType, jlong>
|
} else if constexpr (QtJniTypes::sameTypeForJni<ElementType, jlong>) {
|
||||||
|| sizeof(ElementType) == sizeof(jlong)) {
|
|
||||||
return makeArray<jlong>(std::forward<Container>(container), &JNIEnv::NewLongArray,
|
return makeArray<jlong>(std::forward<Container>(container), &JNIEnv::NewLongArray,
|
||||||
&JNIEnv::SetLongArrayRegion);
|
&JNIEnv::SetLongArrayRegion);
|
||||||
|
} else {
|
||||||
|
static_assert(QtPrivate::type_dependent_false<ElementType>(),
|
||||||
|
"Don't know how to make QJniArray for this element type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +206,8 @@ class QJniArray : public QJniArrayBase
|
|||||||
template <typename E> struct ToContainerHelper { using type = QList<E>; };
|
template <typename E> struct ToContainerHelper { using type = QList<E>; };
|
||||||
template <> struct ToContainerHelper<jstring> { using type = QStringList; };
|
template <> struct ToContainerHelper<jstring> { using type = QStringList; };
|
||||||
template <> struct ToContainerHelper<jbyte> { using type = QByteArray; };
|
template <> struct ToContainerHelper<jbyte> { using type = QByteArray; };
|
||||||
|
template <> struct ToContainerHelper<char> { using type = QByteArray; };
|
||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
using ToContainerType = typename ToContainerHelper<E>::type;
|
using ToContainerType = typename ToContainerHelper<E>::type;
|
||||||
|
|
||||||
@ -255,21 +258,23 @@ public:
|
|||||||
{
|
{
|
||||||
if constexpr (std::is_convertible_v<jobject, T>)
|
if constexpr (std::is_convertible_v<jobject, T>)
|
||||||
return object<jobjectArray>();
|
return object<jobjectArray>();
|
||||||
else if constexpr (std::is_same_v<T, jbyte>)
|
else if constexpr (std::is_same_v<T, QString>)
|
||||||
|
return object<jobjectArray>();
|
||||||
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jbyte>)
|
||||||
return object<jbyteArray>();
|
return object<jbyteArray>();
|
||||||
else if constexpr (std::is_same_v<T, jchar>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jchar>)
|
||||||
return object<jcharArray>();
|
return object<jcharArray>();
|
||||||
else if constexpr (std::is_same_v<T, jboolean>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jboolean>)
|
||||||
return object<jbooleanArray>();
|
return object<jbooleanArray>();
|
||||||
else if constexpr (std::is_same_v<T, jshort>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jshort>)
|
||||||
return object<jshortArray>();
|
return object<jshortArray>();
|
||||||
else if constexpr (std::is_same_v<T, jint>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jint>)
|
||||||
return object<jintArray>();
|
return object<jintArray>();
|
||||||
else if constexpr (std::is_same_v<T, jlong>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jlong>)
|
||||||
return object<jlongArray>();
|
return object<jlongArray>();
|
||||||
else if constexpr (std::is_same_v<T, jfloat>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jfloat>)
|
||||||
return object<jfloatArray>();
|
return object<jfloatArray>();
|
||||||
else if constexpr (std::is_same_v<T, jdouble>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jdouble>)
|
||||||
return object<jdoubleArray>();
|
return object<jdoubleArray>();
|
||||||
else
|
else
|
||||||
return object<jarray>();
|
return object<jarray>();
|
||||||
@ -299,26 +304,33 @@ public:
|
|||||||
return T::fromLocalRef(element);
|
return T::fromLocalRef(element);
|
||||||
else
|
else
|
||||||
return T{element};
|
return T{element};
|
||||||
|
} else if constexpr (std::is_same_v<QString, T>) {
|
||||||
|
jstring string = static_cast<jstring>(env->GetObjectArrayElement(arrayObject(), i));
|
||||||
|
const auto length = env->GetStringLength(string);
|
||||||
|
QString res(length, Qt::Uninitialized);
|
||||||
|
env->GetStringRegion(string, 0, length, reinterpret_cast<jchar *>(res.data()));
|
||||||
|
env->DeleteLocalRef(string);
|
||||||
|
return res;
|
||||||
} else if constexpr (std::is_base_of_v<std::remove_pointer_t<jobject>, std::remove_pointer_t<T>>) {
|
} else if constexpr (std::is_base_of_v<std::remove_pointer_t<jobject>, std::remove_pointer_t<T>>) {
|
||||||
// jstring, jclass etc
|
// jstring, jclass etc
|
||||||
return static_cast<T>(env->GetObjectArrayElement(object<jobjectArray>(), i));
|
return static_cast<T>(env->GetObjectArrayElement(object<jobjectArray>(), i));
|
||||||
} else {
|
} else {
|
||||||
T res = {};
|
T res = {};
|
||||||
if constexpr (std::is_same_v<T, jbyte>)
|
if constexpr (QtJniTypes::sameTypeForJni<T, jbyte>)
|
||||||
env->GetByteArrayRegion(object<jbyteArray>(), i, 1, &res);
|
env->GetByteArrayRegion(object<jbyteArray>(), i, 1, &res);
|
||||||
else if constexpr (std::is_same_v<T, jchar>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jchar>)
|
||||||
env->GetCharArrayRegion(object<jcharArray>(), i, 1, &res);
|
env->GetCharArrayRegion(object<jcharArray>(), i, 1, &res);
|
||||||
else if constexpr (std::is_same_v<T, jboolean>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jboolean>)
|
||||||
env->GetBooleanArrayRegion(object<jbooleanArray>(), i, 1, &res);
|
env->GetBooleanArrayRegion(object<jbooleanArray>(), i, 1, &res);
|
||||||
else if constexpr (std::is_same_v<T, jshort>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jshort>)
|
||||||
env->GetShortArrayRegion(object<jshortArray>(), i, 1, &res);
|
env->GetShortArrayRegion(object<jshortArray>(), i, 1, &res);
|
||||||
else if constexpr (std::is_same_v<T, jint>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jint>)
|
||||||
env->GetIntArrayRegion(object<jintArray>(), i, 1, &res);
|
env->GetIntArrayRegion(object<jintArray>(), i, 1, &res);
|
||||||
else if constexpr (std::is_same_v<T, jlong>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jlong>)
|
||||||
env->GetLongArrayRegion(object<jlongArray>(), i, 1, &res);
|
env->GetLongArrayRegion(object<jlongArray>(), i, 1, &res);
|
||||||
else if constexpr (std::is_same_v<T, jfloat>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jfloat>)
|
||||||
env->GetFloatArrayRegion(object<jfloatArray>(), i, 1, &res);
|
env->GetFloatArrayRegion(object<jfloatArray>(), i, 1, &res);
|
||||||
else if constexpr (std::is_same_v<T, jdouble>)
|
else if constexpr (QtJniTypes::sameTypeForJni<T, jdouble>)
|
||||||
env->GetDoubleArrayRegion(object<jdoubleArray>(), i, 1, &res);
|
env->GetDoubleArrayRegion(object<jdoubleArray>(), i, 1, &res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -336,36 +348,40 @@ public:
|
|||||||
|
|
||||||
container.reserve(sz);
|
container.reserve(sz);
|
||||||
if constexpr (std::is_same_v<typename ContainerType::value_type, QString>) {
|
if constexpr (std::is_same_v<typename ContainerType::value_type, QString>) {
|
||||||
for (auto element : *this)
|
for (auto element : *this) {
|
||||||
container.emplace_back(QJniObject(element).toString());
|
if constexpr (std::is_same_v<decltype(element), QString>)
|
||||||
|
container.emplace_back(element);
|
||||||
|
else
|
||||||
|
container.emplace_back(QJniObject(element).toString());
|
||||||
|
}
|
||||||
} else if constexpr (std::is_base_of_v<std::remove_pointer_t<jobject>, std::remove_pointer_t<T>>) {
|
} else if constexpr (std::is_base_of_v<std::remove_pointer_t<jobject>, std::remove_pointer_t<T>>) {
|
||||||
for (auto element : *this)
|
for (auto element : *this)
|
||||||
container.emplace_back(element);
|
container.emplace_back(element);
|
||||||
} else if constexpr (QJniArrayBase::isContiguousContainer<ContainerType>) {
|
} else if constexpr (QJniArrayBase::isContiguousContainer<ContainerType>) {
|
||||||
container.resize(sz);
|
container.resize(sz);
|
||||||
if constexpr (std::is_same_v<T, jbyte>) {
|
if constexpr (QtJniTypes::sameTypeForJni<T, jbyte>) {
|
||||||
env->GetByteArrayRegion(object<jbyteArray>(),
|
env->GetByteArrayRegion(object<jbyteArray>(),
|
||||||
0, sz,
|
0, sz,
|
||||||
reinterpret_cast<jbyte *>(container.data()));
|
reinterpret_cast<jbyte *>(container.data()));
|
||||||
} else if constexpr (std::is_same_v<T, jchar>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<T, jchar>) {
|
||||||
env->GetCharArrayRegion(object<jcharArray>(),
|
env->GetCharArrayRegion(object<jcharArray>(),
|
||||||
0, sz, container.data());
|
0, sz, container.data());
|
||||||
} else if constexpr (std::is_same_v<T, jboolean>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<T, jboolean>) {
|
||||||
env->GetBooleanArrayRegion(object<jbooleanArray>(),
|
env->GetBooleanArrayRegion(object<jbooleanArray>(),
|
||||||
0, sz, container.data());
|
0, sz, container.data());
|
||||||
} else if constexpr (std::is_same_v<T, jshort>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<T, jshort>) {
|
||||||
env->GetShortArrayRegion(object<jshortArray>(),
|
env->GetShortArrayRegion(object<jshortArray>(),
|
||||||
0, sz, container.data());
|
0, sz, container.data());
|
||||||
} else if constexpr (std::is_same_v<T, jint>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<T, jint>) {
|
||||||
env->GetIntArrayRegion(object<jintArray>(),
|
env->GetIntArrayRegion(object<jintArray>(),
|
||||||
0, sz, container.data());
|
0, sz, container.data());
|
||||||
} else if constexpr (std::is_same_v<T, jlong>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<T, jlong>) {
|
||||||
env->GetLongArrayRegion(object<jlongArray>(),
|
env->GetLongArrayRegion(object<jlongArray>(),
|
||||||
0, sz, container.data());
|
0, sz, container.data());
|
||||||
} else if constexpr (std::is_same_v<T, jfloat>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<T, jfloat>) {
|
||||||
env->GetFloatArrayRegion(object<jfloatArray>(),
|
env->GetFloatArrayRegion(object<jfloatArray>(),
|
||||||
0, sz, container.data());
|
0, sz, container.data());
|
||||||
} else if constexpr (std::is_same_v<T, jdouble>) {
|
} else if constexpr (QtJniTypes::sameTypeForJni<T, jdouble>) {
|
||||||
env->GetDoubleArrayRegion(object<jdoubleArray>(),
|
env->GetDoubleArrayRegion(object<jdoubleArray>(),
|
||||||
0, sz, container.data());
|
0, sz, container.data());
|
||||||
} else {
|
} else {
|
||||||
|
@ -165,8 +165,14 @@
|
|||||||
\li QJniArray<jbyte>
|
\li QJniArray<jbyte>
|
||||||
\li QByteArray
|
\li QByteArray
|
||||||
\row
|
\row
|
||||||
|
\li QJniArray<char>
|
||||||
|
\li QByteArray
|
||||||
|
\row
|
||||||
\li QJniArray<jstring>
|
\li QJniArray<jstring>
|
||||||
\li QStringList
|
\li QStringList
|
||||||
|
\row
|
||||||
|
\li QJniArray<QString>
|
||||||
|
\li QStringList
|
||||||
\endtable
|
\endtable
|
||||||
//! [type-mapping]
|
//! [type-mapping]
|
||||||
|
|
||||||
|
@ -76,21 +76,61 @@ VERIFY_RETURN_FOR_TYPE(QList<jdouble>, QList<jdouble>);
|
|||||||
VERIFY_RETURN_FOR_TYPE(QList<double>, QList<double>);
|
VERIFY_RETURN_FOR_TYPE(QList<double>, QList<double>);
|
||||||
|
|
||||||
VERIFY_RETURN_FOR_TYPE(QString, QString);
|
VERIFY_RETURN_FOR_TYPE(QString, QString);
|
||||||
|
VERIFY_RETURN_FOR_TYPE(QJniArray<QString>, QJniArray<QString>);
|
||||||
|
|
||||||
VERIFY_RETURN_FOR_TYPE(List, List);
|
VERIFY_RETURN_FOR_TYPE(List, List);
|
||||||
VERIFY_RETURN_FOR_TYPE(List[], QJniArray<List>);
|
VERIFY_RETURN_FOR_TYPE(List[], QJniArray<List>);
|
||||||
VERIFY_RETURN_FOR_TYPE(QJniArray<List>, QJniArray<List>);
|
VERIFY_RETURN_FOR_TYPE(QJniArray<List>, QJniArray<List>);
|
||||||
|
|
||||||
#define VERIFY_CONTAINER_FOR_TYPE(In, Out) \
|
#define VERIFY_CONTAINER_FOR_TYPE(In, Out) \
|
||||||
static_assert(std::is_same_v<decltype(std::declval<In>().toContainer()), Out>)
|
static_assert(std::is_same_v<decltype(std::declval<In>().toContainer()), Out>);
|
||||||
|
|
||||||
|
#define VERIFY_ARRAY_FOR_CONTAINER(In, Out) \
|
||||||
|
static_assert(std::is_same_v<decltype(QJniArrayBase::fromContainer(std::declval<In>())), Out>);
|
||||||
|
|
||||||
|
// primitive types, both JNI and C++ equivalent types
|
||||||
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jchar>, QList<jchar>);
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jchar>, QList<jchar>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jchar>, QJniArray<jchar>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jint>, QList<jint>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jint>, QJniArray<jint>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<int>, QList<int>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<int>, QJniArray<int>);
|
||||||
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jfloat>, QList<jfloat>);
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jfloat>, QList<jfloat>);
|
||||||
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jbyte>, QByteArray);
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jfloat>, QJniArray<jfloat>);
|
||||||
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jstring>, QStringList);
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<float>, QList<float>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<float>, QJniArray<float>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jdouble>, QList<jdouble>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jdouble>, QJniArray<jdouble>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<double>, QList<double>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<double>, QJniArray<double>);
|
||||||
|
|
||||||
|
// jobject and derivatives
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jobject>, QList<jobject>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jobject>, QJniArray<jobject>);
|
||||||
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jclass>, QList<jclass>);
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jclass>, QList<jclass>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jclass>, QJniArray<jclass>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jthrowable>, QList<jthrowable>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jthrowable>, QJniArray<jthrowable>);
|
||||||
|
|
||||||
|
// QJniObject-ish classes
|
||||||
VERIFY_CONTAINER_FOR_TYPE(QJniArray<QJniObject>, QList<QJniObject>);
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<QJniObject>, QList<QJniObject>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<QJniObject>, QJniArray<QJniObject>);
|
||||||
VERIFY_CONTAINER_FOR_TYPE(QJniArray<List>, QList<List>);
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<List>, QList<List>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<List>, QJniArray<List>);
|
||||||
|
|
||||||
|
// Special case: jbyte, (u)char, and QByteArray
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jbyte>, QByteArray);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QByteArray, QJniArray<jbyte>);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jbyte>, QJniArray<jbyte>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<char>, QByteArray);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<char>, QJniArray<jbyte>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<uchar>, QList<uchar>);
|
||||||
|
|
||||||
|
// Special case: jstring, QString, and QStringList
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<jstring>, QStringList);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QStringList, QJniArray<QString>);
|
||||||
|
VERIFY_CONTAINER_FOR_TYPE(QJniArray<QString>, QStringList);
|
||||||
|
VERIFY_ARRAY_FOR_CONTAINER(QList<jstring>, QJniArray<jstring>);
|
||||||
|
|
||||||
void tst_QJniArray::construct()
|
void tst_QJniArray::construct()
|
||||||
{
|
{
|
||||||
@ -101,6 +141,8 @@ void tst_QJniArray::construct()
|
|||||||
strings << QString::number(i);
|
strings << QString::number(i);
|
||||||
QJniArray<QString> list(strings);
|
QJniArray<QString> list(strings);
|
||||||
QCOMPARE(list.size(), 10000);
|
QCOMPARE(list.size(), 10000);
|
||||||
|
QCOMPARE(list.at(500), QString::number(500));
|
||||||
|
QCOMPARE(list.toContainer(), strings);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
QJniArray bytes = QJniArrayBase::fromContainer(QByteArray("abc"));
|
QJniArray bytes = QJniArrayBase::fromContainer(QByteArray("abc"));
|
||||||
|
@ -152,6 +152,11 @@ public class QtJniObjectTestClass
|
|||||||
public Object[] reverseObjectArray(Object[] array)
|
public Object[] reverseObjectArray(Object[] array)
|
||||||
{ return staticReverseObjectArray(array); }
|
{ return staticReverseObjectArray(array); }
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
public static String[] staticStringArrayMethod()
|
||||||
|
{ String[] array = { "First", "Second", "Third" }; return array; }
|
||||||
|
public String[] stringArrayMethod() { return staticStringArrayMethod(); }
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
public static boolean[] staticBooleanArrayMethod()
|
public static boolean[] staticBooleanArrayMethod()
|
||||||
{ boolean[] array = { true, true, true }; return array; }
|
{ boolean[] array = { true, true, true }; return array; }
|
||||||
|
@ -1563,6 +1563,26 @@ void tst_QJniObject::templateApiCheck()
|
|||||||
QCOMPARE(QJniObject::fromLocalRef(reverse.at(2)).toString(), u"one"_s);
|
QCOMPARE(QJniObject::fromLocalRef(reverse.at(2)).toString(), u"one"_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jstringArray ------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
const QStringList strings{"First", "Second", "Third"};
|
||||||
|
const auto array = TestClass::callStaticMethod<QJniArray<QtJniTypes::String>>("staticStringArrayMethod");
|
||||||
|
QVERIFY(array.isValid());
|
||||||
|
QCOMPARE(array.size(), 3);
|
||||||
|
QCOMPARE(array.at(0).toString(), strings.first());
|
||||||
|
QCOMPARE(array.toContainer<QStringList>(), strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// jstringArray via implicit QString support -------------------------------------------------
|
||||||
|
{
|
||||||
|
const QStringList strings{"First", "Second", "Third"};
|
||||||
|
const auto array = TestClass::callStaticMethod<QJniArray<QString>>("staticStringArrayMethod");
|
||||||
|
QVERIFY(array.isValid());
|
||||||
|
QCOMPARE(array.size(), 3);
|
||||||
|
QCOMPARE(array.at(0), strings.first());
|
||||||
|
QCOMPARE(array.toContainer(), strings);
|
||||||
|
}
|
||||||
|
|
||||||
// jbooleanArray ------------------------------------------------------------------------------
|
// jbooleanArray ------------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
QJniObject res = QJniObject::callStaticObjectMethod<jbooleanArray>(testClassName,
|
QJniObject res = QJniObject::callStaticObjectMethod<jbooleanArray>(testClassName,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user