JNI: make it safe to iterate over or convert an invalid QJniArray

This is expected behavior for default-constructed containers.

Also add the missing isEmpty() member function to QJniArrayBase.

Change-Id: I23111f6906ef5476567272cb23746fec962afa35
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit e5516191b25d70ee9d6e87246d932fa559ef0b59)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Volker Hilsheimer 2024-06-06 14:16:42 +02:00 committed by Qt Cherry-pick Bot
parent 78784065a8
commit b2f8a7b6a8
2 changed files with 33 additions and 2 deletions

View File

@ -106,6 +106,7 @@ public:
template <typename T = jobject>
T object() const { return m_object.object<T>(); }
bool isValid() const { return m_object.isValid(); }
bool isEmpty() const { return size() == 0; }
size_type size() const
{
@ -310,6 +311,7 @@ public:
return res;
}
}
auto toContainer() const
{
JNIEnv *env = jniEnv();
@ -328,11 +330,15 @@ public:
} else if constexpr (std::is_same_v<T, jbyte>) {
const qsizetype bytecount = size();
QByteArray res(bytecount, Qt::Initialization::Uninitialized);
env->GetByteArrayRegion(object<jbyteArray>(),
0, bytecount, reinterpret_cast<jbyte *>(res.data()));
if (!isEmpty()) {
env->GetByteArrayRegion(object<jbyteArray>(),
0, bytecount, reinterpret_cast<jbyte *>(res.data()));
}
return res;
} else {
QList<T> res;
if (isEmpty())
return res;
res.resize(size());
if constexpr (std::is_same_v<T, jchar>) {
env->GetCharArrayRegion(object<jcharArray>(),

View File

@ -17,6 +17,7 @@ public:
private slots:
void construct();
void invalidArraysAreEmpty();
void size();
void operators();
};
@ -126,6 +127,30 @@ void tst_QJniArray::construct()
}
}
void tst_QJniArray::invalidArraysAreEmpty()
{
QJniArray<jchar> invalid;
QVERIFY(!invalid.isValid());
QCOMPARE(invalid.object(), nullptr);
QVERIFY(invalid.isEmpty());
QCOMPARE(invalid.begin(), invalid.end());
QCOMPARE(invalid.rbegin(), invalid.rend());
QList<jchar> data;
// safe to iterate
for (const auto &e : invalid)
data.emplace_back(e);
QVERIFY(data.empty());
// safe to convert
data = invalid.toContainer();
QVERIFY(data.empty());
// unsafe to access
// auto element = invalid.at(0);
}
void tst_QJniArray::size()
{
QJniArray<jint> array;