Fix QDataStream::operator<<(const char *) to handle 64-bit length
The operator was not converted to using a new streaming version, so it supported only 32-bit length. Fix it and add a manual test for serialization/deserialization of large c-style strings. Amends fd48ce0b73c74dafd5db27bc1f2752ef665df7ef Change-Id: I83704edec021d400b992de810feba5da52d5ffe1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 0aaf7092cd077eb07e62d3742293f146c65c9630) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
cc1476c608
commit
635be3cdf1
@ -1344,13 +1344,9 @@ QDataStream &QDataStream::operator<<(double f)
|
||||
|
||||
QDataStream &QDataStream::operator<<(const char *s)
|
||||
{
|
||||
if (!s) {
|
||||
*this << (quint32)0;
|
||||
return *this;
|
||||
}
|
||||
int len = int(qstrlen(s)) + 1; // also write null terminator
|
||||
*this << (quint32)len; // write length specifier
|
||||
writeRawData(s, len);
|
||||
// Include null terminator, unless s itself is null
|
||||
const qint64 len = s ? qint64(qstrlen(s)) + 1 : 0;
|
||||
writeBytes(s, len);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QScopeGuard>
|
||||
#include <QSet>
|
||||
#include <QTest>
|
||||
|
||||
@ -32,6 +33,7 @@ private slots:
|
||||
void stream_bigQSet();
|
||||
void stream_bigQMap();
|
||||
void stream_bigQHash();
|
||||
void stream_bigCString();
|
||||
};
|
||||
|
||||
void tst_QDataStream::initTestCase()
|
||||
@ -161,6 +163,54 @@ void tst_QDataStream::stream_bigQHash()
|
||||
stream_big<QHash<qsizetype, qsizetype>>();
|
||||
}
|
||||
|
||||
void tst_QDataStream::stream_bigCString()
|
||||
{
|
||||
if constexpr (sizeof(void*) == sizeof(int))
|
||||
QSKIP("This test is 64-bit only.");
|
||||
|
||||
QFETCH_GLOBAL(const QDataStream::Version, streamVersion);
|
||||
constexpr qint64 GiB = 1024 * 1024 * 1024;
|
||||
constexpr qint64 BaseSize = 4 * GiB + 1;
|
||||
std::string input;
|
||||
qDebug("Creating an array with %lld entries", BaseSize);
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
try {
|
||||
input.resize(BaseSize, 'a');
|
||||
} catch (const std::bad_alloc &) {
|
||||
QSKIP("Could not allocate 4 Gi + 2 entries.");
|
||||
}
|
||||
qDebug("Created dataset in %lld ms", timer.elapsed());
|
||||
QByteArray ba;
|
||||
QDataStream inputstream(&ba, QIODevice::WriteOnly);
|
||||
inputstream.setVersion(streamVersion);
|
||||
timer.start();
|
||||
try {
|
||||
inputstream << input.data();
|
||||
} catch (const std::bad_alloc &) {
|
||||
QSKIP("Not enough memory to copy into QDataStream.");
|
||||
}
|
||||
qDebug("Streamed into QDataStream in %lld ms", timer.elapsed());
|
||||
if (streamVersion < QDataStream::Qt_6_7) {
|
||||
// old versions do not support data size more than 4 GiB
|
||||
QCOMPARE(inputstream.status(), QDataStream::SizeLimitExceeded);
|
||||
QVERIFY(ba.isEmpty());
|
||||
} else {
|
||||
char *output = nullptr;
|
||||
auto cleanup = qScopeGuard([&output] { delete [] output; });
|
||||
QDataStream outputstream(ba);
|
||||
timer.start();
|
||||
try {
|
||||
outputstream >> output;
|
||||
} catch (const std::bad_alloc &) {
|
||||
QSKIP("Not enough memory to copy out of QDataStream.");
|
||||
}
|
||||
qDebug("Streamed out of QDataStream in %lld ms", timer.elapsed());
|
||||
QCOMPARE(qstrlen(output), input.size());
|
||||
QVERIFY(memcmp(input.data(), output, BaseSize + 1) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDataStream)
|
||||
|
||||
#include "tst_manualqdatastream.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user