summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/serialization')
-rw-r--r--src/corelib/serialization/qcborarray.h1
-rw-r--r--src/corelib/serialization/qcborcommon.h10
-rw-r--r--src/corelib/serialization/qcbormap.h7
-rw-r--r--src/corelib/serialization/qcborstream.cpp356
-rw-r--r--src/corelib/serialization/qcborvalue.cpp505
-rw-r--r--src/corelib/serialization/qcborvalue.h24
-rw-r--r--src/corelib/serialization/qdatastream.cpp28
-rw-r--r--src/corelib/serialization/qdatastream.h20
-rw-r--r--src/corelib/serialization/qjson.cpp1
-rw-r--r--src/corelib/serialization/qjson_p.h18
-rw-r--r--src/corelib/serialization/qjsonarray.cpp16
-rw-r--r--src/corelib/serialization/qjsonarray.h8
-rw-r--r--src/corelib/serialization/qjsoncbor.cpp9
-rw-r--r--src/corelib/serialization/qjsondocument.cpp16
-rw-r--r--src/corelib/serialization/qjsondocument.h6
-rw-r--r--src/corelib/serialization/qjsonobject.h6
-rw-r--r--src/corelib/serialization/qjsonparser.cpp1
-rw-r--r--src/corelib/serialization/qjsonvalue.h8
-rw-r--r--src/corelib/serialization/qtextstream.cpp142
-rw-r--r--src/corelib/serialization/qtextstream.h25
-rw-r--r--src/corelib/serialization/qtextstream_p.h6
-rw-r--r--src/corelib/serialization/qxmlstream.cpp50
-rw-r--r--src/corelib/serialization/qxmlstream.g18
-rw-r--r--src/corelib/serialization/qxmlstream.h32
-rw-r--r--src/corelib/serialization/qxmlstream_p.h14
25 files changed, 838 insertions, 489 deletions
diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h
index d96342cfa6..e06544f245 100644
--- a/src/corelib/serialization/qcborarray.h
+++ b/src/corelib/serialization/qcborarray.h
@@ -272,6 +272,7 @@ private:
void detach(qsizetype reserve = 0);
friend QCborValue;
+ friend QCborValueRef;
explicit QCborArray(QCborContainerPrivate &dd) noexcept;
QExplicitlySharedDataPointer<QCborContainerPrivate> d;
};
diff --git a/src/corelib/serialization/qcborcommon.h b/src/corelib/serialization/qcborcommon.h
index 0147f85de8..3dfe50cd09 100644
--- a/src/corelib/serialization/qcborcommon.h
+++ b/src/corelib/serialization/qcborcommon.h
@@ -138,6 +138,16 @@ QDataStream &operator<<(QDataStream &ds, QCborSimpleType st);
QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st);
#endif
+inline uint qHash(QCborSimpleType tag, uint seed = 0)
+{
+ return qHash(quint8(tag), seed);
+}
+
+inline uint qHash(QCborTag tag, uint seed = 0)
+{
+ return qHash(quint64(tag), seed);
+}
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QCborTag)
diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h
index 0eb163a0a8..4aea901eef 100644
--- a/src/corelib/serialization/qcbormap.h
+++ b/src/corelib/serialization/qcbormap.h
@@ -118,6 +118,8 @@ public:
QCborValueRef item; // points to the value
friend class Iterator;
friend class QCborMap;
+ friend class QCborValue;
+ friend class QCborValueRef;
ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
public:
typedef std::random_access_iterator_tag iterator_category;
@@ -171,7 +173,7 @@ public:
: QCborMap()
{
detach(args.size());
- for (auto pair : args)
+ for (const auto &pair : args)
insert(pair.first, pair.second);
}
~QCborMap();
@@ -323,9 +325,10 @@ public:
QJsonObject toJsonObject() const;
private:
+ friend class QCborValue;
+ friend class QCborValueRef;
void detach(qsizetype reserve = 0);
- friend QCborValue;
explicit QCborMap(QCborContainerPrivate &dd) noexcept;
QExplicitlySharedDataPointer<QCborContainerPrivate> d;
};
diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp
index 38b809158a..1392b4d8d6 100644
--- a/src/corelib/serialization/qcborstream.cpp
+++ b/src/corelib/serialization/qcborstream.cpp
@@ -101,6 +101,16 @@ static CborError _cbor_value_dup_string(const CborValue *, void **, size_t *, Cb
Q_UNREACHABLE();
return CborErrorInternalError;
}
+static CborError cbor_value_get_half_float_as_float(const CborValue *, float *)
+{
+ Q_UNREACHABLE();
+ return CborErrorInternalError;
+}
+static CborError cbor_encode_float_as_half_float(CborEncoder *, float)
+{
+ Q_UNREACHABLE();
+ return CborErrorInternalError;
+}
QT_WARNING_POP
Q_DECLARE_TYPEINFO(CborEncoder, Q_PRIMITIVE_TYPE);
@@ -213,9 +223,7 @@ QDebug operator<<(QDebug dbg, QCborSimpleType st)
For example, the following creates a QCborValue containing a byte array
tagged with a tag 2.
- \code
- QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9));
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 0
\sa QCborKnownTags, QCborStreamWriter::append(QCborTag),
QCborStreamReader::isTag(), QCborStreamReader::toTag(),
@@ -422,7 +430,7 @@ QDebug operator<<(QDebug dbg, QCborKnownTags tag)
\value IllegalSimpleType The CBOR stream contains a Simple Type encoded incorrectly (data is
corrupt and the error is not recoverable).
\value InvalidUtf8String The CBOR stream contains a text string that does not decode properly
- as UTF (data is corrupt and the error is not recoverable).
+ as UTF-8 (data is corrupt and the error is not recoverable).
\value DataTooLarge CBOR string, map or array is too big and cannot be parsed by Qt
(internal limitation, but the error is not recoverable).
\value NestingTooDeep Too many levels of arrays or maps encountered while processing the
@@ -431,6 +439,24 @@ QDebug operator<<(QDebug dbg, QCborKnownTags tag)
support (internal limitation, but the error is not recoverable).
*/
+// Convert from CborError to QCborError.
+//
+// Centralized in a function in case we need to make more adjustments in the
+// future.
+static QCborError fromCborError(CborError err)
+{
+ return { QCborError::Code(int(err)) };
+}
+
+// Convert to CborError from QCborError.
+//
+// Centralized in a function in case we need to make more adjustments in the
+// future.
+static CborError toCborError(QCborError c)
+{
+ return CborError(int(c.c));
+}
+
/*!
\variable QCborError::c
\internal
@@ -501,8 +527,8 @@ QString QCborError::toString() const
return QStringLiteral("Internal limitation: unsupported type");
}
- // get the error from TinyCBOR
- CborError err = CborError(int(c));
+ // get the error string from TinyCBOR
+ CborError err = toCborError(*this);
return QString::fromLatin1(cbor_error_string(err));
}
@@ -546,25 +572,7 @@ QString QCborError::toString() const
}
\enddiv
- \code
- writer.startMap(4); // 4 elements in the map
-
- writer.append(QLatin1String("label"));
- writer.append(QLatin1String("journald"));
-
- writer.append(QLatin1String("autoDetect"));
- writer.append(false);
-
- writer.append(QLatin1String("condition"));
- writer.append(QLatin1String("libs.journald"));
-
- writer.append(QLatin1String("output"));
- writer.startArray(1);
- writer.append(QLatin1String("privateFeature"));
- writer.endArray();
-
- writer.endMap();
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 1
\section1 CBOR support
@@ -747,12 +755,7 @@ static CborError qt_cbor_encoder_write_callback(void *self, const void *data, si
The following example writes an empty map to a file:
- \code
- QFile f("output", QIODevice::WriteOnly);
- QCborStreamWriter writer(&f);
- writer.startMap(0);
- writer.endMap();
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 2
QCborStreamWriter does not take ownership of \a device.
@@ -771,15 +774,7 @@ QCborStreamWriter::QCborStreamWriter(QIODevice *device)
The following example writes a number to a byte array then returns
it.
- \code
- QByteArray encodedNumber(qint64 value)
- {
- QByteArray ba;
- QCborStreamWriter writer(&ba);
- writer.append(value);
- return ba;
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 3
QCborStreamWriter does not take ownership of \a data.
*/
@@ -837,11 +832,7 @@ QIODevice *QCborStreamWriter::device() const
Unsigned Integer value. In the following example, we write the values 0,
2\sup{32} and \c UINT64_MAX:
- \code
- writer.append(0U);
- writer.append(Q_UINT64_C(4294967296));
- writer.append(std::numeric_limits<quint64>::max());
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 4
\sa QCborStreamReader::isUnsignedInteger(), QCborStreamReader::toUnsignedInteger()
*/
@@ -858,12 +849,7 @@ void QCborStreamWriter::append(quint64 u)
sign of the parameter. In the following example, we write the values 0, -1,
2\sup{32} and \c INT64_MAX:
- \code
- writer.append(0);
- writer.append(-1);
- writer.append(Q_INT64_C(4294967296));
- writer.append(std::numeric_limits<qint64>::max());
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 5
\sa QCborStreamReader::isInteger(), QCborStreamReader::toInteger()
*/
@@ -881,11 +867,7 @@ void QCborStreamWriter::append(qint64 i)
equivalent to 2\sup{64} (that is, -18,446,744,073,709,551,616).
In the following example, we write the values -1, -2\sup{32} and INT64_MIN:
- \code
- writer.append(QCborNegativeInteger(1));
- writer.append(QCborNegativeInteger(Q_INT64_C(4294967296)));
- writer.append(QCborNegativeInteger(-quint64(std::numeric_limits<qint64>::min())));
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 6
Note how this function can be used to encode numbers that cannot fit a
standard computer's 64-bit signed integer like \l qint64. That is, if \a n
@@ -911,14 +893,7 @@ void QCborStreamWriter::append(QCborNegativeInteger n)
The following example will load and append the contents of a file to the
stream:
- \code
- void writeFile(QCborStreamWriter &writer, const QString &fileName)
- {
- QFile f(fileName);
- if (f.open(QIODevice::ReadOnly))
- writer.append(f.readAll());
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 7
As the example shows, unlike JSON, CBOR requires no escaping for binary
content.
@@ -936,9 +911,7 @@ void QCborStreamWriter::append(QCborNegativeInteger n)
The following example appends a simple string to the stream:
- \code
- writer.append(QLatin1String("Hello, World"));
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 8
\b{Performance note}: CBOR requires that all Text Strings be encoded in
UTF-8, so this function will iterate over the characters in the string to
@@ -971,12 +944,7 @@ void QCborStreamWriter::append(QLatin1String str)
The following example writes an arbitrary QString to the stream:
- \code
- void writeString(QCborStreamWriter &writer, const QString &str)
- {
- writer.append(str);
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 9
\sa QCborStreamReader::isString(), QCborStreamReader::readString()
*/
@@ -995,13 +963,7 @@ void QCborStreamWriter::append(QStringView str)
In the following example, we append a CBOR Tag 36 (Regular Expression) and a
QRegularExpression's pattern to the stream:
- \code
- void writeRxPattern(QCborStreamWriter &writer, const QRegularExpression &rx)
- {
- writer.append(QCborTag(36));
- writer.append(rx.pattern());
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 10
\sa QCborStreamReader::isTag(), QCborStreamReader::toTag()
*/
@@ -1021,13 +983,7 @@ void QCborStreamWriter::append(QCborTag tag)
integer representing the current time to the stream, obtained using the \c
time() function:
- \code
- void writeCurrentTime(QCborStreamWriter &writer)
- {
- writer.append(QCborKnownTags::UnixTime_t);
- writer.append(time(nullptr));
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 11
\sa QCborStreamReader::isTag(), QCborStreamReader::toTag()
*/
@@ -1039,10 +995,7 @@ void QCborStreamWriter::append(QCborTag tag)
Type value. In the following example, we write the simple type for Null as
well as for type 32, which Qt has no support for.
- \code
- writer.append(QCborSimpleType::Null);
- writer.append(QCborSimpleType(32));
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 12
\note Using Simple Types for which there is no specification can lead to
validation errors by the remote receiver. In addition, simple type values 24
@@ -1063,16 +1016,7 @@ void QCborStreamWriter::append(QCborSimpleType st)
a C++ \tt float to \c qfloat16 if there's no loss of precision and append it, or
instead append the \tt float.
- \code
- void writeFloat(QCborStreamWriter &writer, float f)
- {
- qfloat16 f16 = f;
- if (qIsNaN(f) || f16 == f)
- writer.append(f16);
- else
- writer.append(f);
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 13
\sa QCborStreamReader::isFloat16(), QCborStreamReader::toFloat16()
*/
@@ -1089,16 +1033,7 @@ void QCborStreamWriter::append(qfloat16 f)
a C++ \tt double to \tt float if there's no loss of precision and append it, or
instead append the \tt double.
- \code
- void writeFloat(QCborStreamWriter &writer, double d)
- {
- float f = d;
- if (qIsNaN(d) || d == f)
- writer.append(f);
- else
- writer.append(d);
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 14
\sa QCborStreamReader::isFloat(), QCborStreamReader::toFloat()
*/
@@ -1120,25 +1055,7 @@ void QCborStreamWriter::append(float f)
which is expected to be taken into account by the system FPU or floating
point emulation directly.
- \code
- void writeDouble(QCborStreamWriter &writer, double d)
- {
- float f;
- if (qIsNaN(d)) {
- writer.append(qfloat16(qQNaN()));
- } else if (qIsInf(d)) {
- writer.append(d < 0 ? -qInf() : qInf());
- } else if ((f = d) == d) {
- qfloat16 f16 = f;
- if (f16 == f)
- writer.append(f16);
- else
- writer.append(f);
- } else {
- writer.append(d);
- }
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 15
Determining if a double can be converted to an integral with no loss of
precision is left as an exercise to the reader.
@@ -1216,9 +1133,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len)
value or a CBOR True value. This function is equivalent to (and implemented
as):
- \code
- writer.append(b ? QCborSimpleType::True : QCborSimpleType::False);
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 16
\sa appendNull(), appendUndefined(),
QCborStreamReader::isBool(), QCborStreamReader::toBool()
@@ -1231,9 +1146,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len)
Appends a CBOR Null value to the stream. This function is equivalent to (and
implemented as): The parameter is ignored.
- \code
- writer.append(QCborSimpleType::Null);
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 17
\sa appendNull(), append(QCborSimpleType), QCborStreamReader::isNull()
*/
@@ -1244,9 +1157,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len)
Appends a CBOR Null value to the stream. This function is equivalent to (and
implemented as):
- \code
- writer.append(QCborSimpleType::Null);
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 18
\sa append(std::nullptr_t), append(QCborSimpleType), QCborStreamReader::isNull()
*/
@@ -1257,9 +1168,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len)
Appends a CBOR Undefined value to the stream. This function is equivalent to (and
implemented as):
- \code
- writer.append(QCborSimpleType::Undefined);
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 19
\sa append(QCborSimpleType), QCborStreamReader::isUndefined()
*/
@@ -1276,15 +1185,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len)
The following example appends elements from the linked list of strings
passed as input:
- \code
- void appendList(QCborStreamWriter &writer, const QLinkedList<QString> &list)
- {
- writer.startArray();
- for (const QString &s : list)
- writer.append(s);
- writer.endArray();
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 20
\sa startArray(quint64), endArray(), startMap(), QCborStreamReader::isArray(),
QCborStreamReader::isLengthKnown()
@@ -1309,15 +1210,7 @@ void QCborStreamWriter::startArray()
The following example appends all strings found in the \l QStringList passed as input:
- \code
- void appendList(QCborStreamWriter &writer, const QStringList &list)
- {
- writer.startArray(list.size());
- for (const QString &s : list)
- writer.append(s);
- writer.endArray();
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 21
\b{Size limitations}: The parameter to this function is quint64, which would
seem to allow up to 2\sup{64}-1 elements in the array. However, both
@@ -1365,17 +1258,7 @@ bool QCborStreamWriter::endArray()
The following example appends elements from the linked list of int and
string pairs passed as input:
- \code
- void appendMap(QCborStreamWriter &writer, const QLinkedList<QPair<int, QString>> &list)
- {
- writer.startMap();
- for (const auto pair : list) {
- writer.append(pair.first)
- writer.append(pair.second);
- }
- writer.endMap();
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 22
\sa startMap(quint64), endMap(), startArray(), QCborStreamReader::isMap(),
QCborStreamReader::isLengthKnown()
@@ -1400,17 +1283,7 @@ void QCborStreamWriter::startMap()
The following example appends all strings found in the \l QMap passed as input:
- \code
- void appendMap(QCborStreamWriter &writer, const QMap<int, QString> &map)
- {
- writer.startMap(map.size());
- for (auto it = map.begin(); it != map.end(); ++it) {
- writer.append(it.key());
- writer.append(it.value());
- }
- writer.endMap();
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 23
\b{Size limitations}: The parameter to this function is quint64, which would
seem to allow up to 2\sup{64}-1 pairs in the map. However, both
@@ -1491,33 +1364,7 @@ bool QCborStreamWriter::endMap()
So a processor function typically looks like this:
- \code
- void handleStream(QCborStreamReader &reader)
- {
- switch (reader.type())
- case QCborStreamReader::UnsignedInteger:
- case QCborStreamReader::NegativeInteger:
- case QCborStreamReader::SimpleType:
- case QCborStreamReader::Float16:
- case QCborStreamReader::Float:
- case QCborStreamReader::Double:
- handleFixedWidth(reader);
- reader.next();
- break;
- case QCborStreamReader::ByteArray:
- case QCborStreamReader::String:
- handleString(reader);
- break;
- case QCborStreamReader::Array:
- case QCborStreamReader::Map:
- reader.enterContainer();
- while (reader.lastError() == QCborError::NoError)
- handleStream(reader);
- if (reader.lastError() == QCborError::NoError)
- reader.leaveContainer();
- }
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 24
\section1 CBOR support
@@ -1619,12 +1466,14 @@ bool QCborStreamWriter::endMap()
*/
/*!
- \variable Container QCborStreamReader::StringResult::data
+ \variable QCborStreamReader::StringResult::data
+
Contains the actual data from the string if \l status is \c Ok.
*/
/*!
- \variable QCborStreamReader::StringResultCode QCborStreamReader::StringResult::status
+ \variable QCborStreamReader::StringResult::status
+
Contains the status of the attempt of reading the string from the stream.
*/
@@ -1733,20 +1582,7 @@ bool QCborStreamWriter::endMap()
The following example pre-allocates a QVariantList given the array's size
for more efficient decoding:
- \code
- QVariantList populateFromCbor(QCborStreamReader &reader)
- {
- QVariantList list;
- if (reader.isLengthKnown())
- list.reserve(reader.length());
-
- reader.enterContainer();
- while (reader.lastError() == QCborError::NoError && reader.hasNext())
- list.append(readOneElement(reader));
- if (reader.lastError() == QCborError::NoError)
- reader.leaveContainer();
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 25
\note The code above does not validate that the length is a sensible value.
If the input stream reports that the length is 1 billion elements, the above
@@ -1770,22 +1606,7 @@ bool QCborStreamWriter::endMap()
The following example pre-allocates a QVariantMap given the map's size
for more efficient decoding:
- \code
- QVariantMap populateFromCbor(QCborStreamReader &reader)
- {
- QVariantMap map;
- if (reader.isLengthKnown())
- map.reserve(reader.length());
-
- reader.enterContainer();
- while (reader.lastError() == QCborError::NoError && reader.hasNext()) {
- QString key = readElementAsString(reader);
- map.insert(key, readOneElement(reader));
- }
- if (reader.lastError() == QCborError::NoError)
- reader.leaveContainer();
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 26
The example above uses a function called \c readElementAsString to read the
map's keys and obtain a string. That is because CBOR maps may contain any
@@ -2004,6 +1825,8 @@ public:
preread();
if (CborError err = cbor_parser_init_reader(nullptr, &parser, &currentElement, this))
handleError(err);
+ else
+ lastError = { QCborError::NoError };
}
char *bufferPtr()
@@ -2044,8 +1867,7 @@ public:
if (err != CborErrorUnexpectedEOF)
corrupt = true;
- // our error codes are the same (for now)
- lastError = { QCborError::Code(err) };
+ lastError = fromCborError(err);
}
void updateBufferAfterString(qsizetype offset, qsizetype size)
@@ -2155,7 +1977,7 @@ inline void QCborStreamReader::preparse()
// for negative integer and we don't have separate types for Boolean,
// Null and Undefined).
if (type_ == CborBooleanType || type_ == CborNullType || type_ == CborUndefinedType) {
- type_ = SimpleType;
+ type_ = CborSimpleType;
value64 = quint8(d->buffer.at(d->bufferStart)) - CborSimpleType;
} else {
// Using internal TinyCBOR API!
@@ -2718,23 +2540,7 @@ bool QCborStreamReader::leaveContainer()
always loop around calling this function, even if isLengthKnown() has
is true. The typical use of this function is as follows:
- \code
- QString decodeString(QCborStreamReader &reader)
- {
- QString result;
- auto r = reader.readString();
- while (r.code == QCborStreamReader::Ok) {
- result += r.data;
- r = reader.readString();
- }
-
- if (r.code == QCborStreamReader::Error) {
- // handle error condition
- result.clear();
- }
- return result;
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 27
This function does not perform any type conversions, including from integers
or from byte arrays. Therefore, it may only be called if isString() returned
@@ -2770,23 +2576,7 @@ QCborStreamReader::StringResult<QString> QCborStreamReader::_readString_helper()
always loop around calling this function, even if isLengthKnown() has
is true. The typical use of this function is as follows:
- \code
- QBytearray decodeBytearray(QCborStreamReader &reader)
- {
- QBytearray result;
- auto r = reader.readBytearray();
- while (r.code == QCborStreamReader::Ok) {
- result += r.data;
- r = reader.readByteArray();
- }
-
- if (r.code == QCborStreamReader::Error) {
- // handle error condition
- result.clear();
- }
- return result;
- }
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 28
This function does not perform any type conversions, including from integers
or from strings. Therefore, it may only be called if isByteArray() is true;
@@ -2856,15 +2646,7 @@ qsizetype QCborStreamReader::_currentStringChunkSize() const
This function is usually used alongside currentStringChunkSize() in a loop.
For example:
- \code
- QCborStreamReader<qsizetype> result;
- do {
- qsizetype size = reader.currentStringChunkSize();
- qsizetype oldsize = buffer.size();
- buffer.resize(oldsize + size);
- result = reader.readStringChunk(buffer.data() + oldsize, size);
- } while (result.status() == QCborStreamReader::Ok);
- \endcode
+ \snippet code/src_corelib_serialization_qcborstream.cpp 29
Unlike readByteArray() and readString(), this function is not limited by
implementation limits of QByteArray and QString.
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp
index 73ac3125e4..288446878c 100644
--- a/src/corelib/serialization/qcborvalue.cpp
+++ b/src/corelib/serialization/qcborvalue.cpp
@@ -102,15 +102,13 @@ QT_BEGIN_NAMESPACE
Qt types compare equal to the tag type of the same contents. In other
words, the following expression is true:
- \code
- QCborValue(uuid) == QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122());
- \endcode
+ \snippet code/src_corelib_serialization_qcborvalue.cpp 0
\section1 Undefined and null values
QCborValue can contain a value of "null", which is not of any specific type.
It resembles the C++ \c {std::nullptr_t} type, whose only possible value is
- \c nullptr. QCborValue has a constructor taking such a type and creates a
+ \nullptr. QCborValue has a constructor taking such a type and creates a
null QCborValue.
Null values are used to indicate that an optional value is not present. In
@@ -130,10 +128,11 @@ QT_BEGIN_NAMESPACE
Such values are completely valid and may appear in CBOR streams, unlike
JSON content and QJsonValue's undefined bit. But like QJsonValue's
- Undefined, it is returned by QCborArray::value() when out of range or
- QCborMap::operator[] when the key is not found in the container. It is not
- possible to tell such a case apart from the value of Undefined, so if that
- is required, check the QCborArray size and use the QCborMap iterator API.
+ Undefined, it is returned by a CBOR container's value() or read-only
+ operator[] for invalid look-ups (index out of range for QCborArray, or key
+ not found for QCborMap). It is not possible to tell such a case apart from
+ the value of Undefined, so if that is required, check the QCborArray size
+ and use the QCborMap iterator API.
\section1 Simple types
@@ -223,7 +222,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \variable qint64 QCborParserError::offset
+ \variable QCborParserError::offset
This field contains the offset from the beginning of the data where the
error was detected. The offset should point to the beginning of the item
@@ -234,7 +233,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \variable QCborError QCborParserError::error
+ \variable QCborParserError::error
This field contains the error code that indicates what decoding problem was
found.
@@ -418,7 +417,7 @@ QT_BEGIN_NAMESPACE
using toSimpleType() as well as isSimpleType(st).
CBOR simple types are types that do not have any associated value, like
- C++'s \c{std::nullptr_t} type, whose only possible value is \c nullptr.
+ C++'s \c{std::nullptr_t} type, whose only possible value is \nullptr.
If \a st is \c{QCborSimpleType::Null}, the resulting QCborValue will be of
the \l{Type}{Null} type and similarly for \c{QCborSimpleType::Undefined}.
@@ -429,9 +428,7 @@ QT_BEGIN_NAMESPACE
This function can be used with simple types not defined in the API. For
example, to create a QCborValue with simple type 12, one could write:
- \code
- QCborValue value(QCborSimpleType(12));
- \endcode
+ \snippet code/src_corelib_serialization_qcborvalue.cpp 1
Simple types should not be used until a specification for them has been
published, since other implementations may not support them properly.
@@ -461,7 +458,7 @@ QT_BEGIN_NAMESPACE
\fn QCborValue::QCborValue(QCborValue &&other)
\overload
- Moves the contents of the \a other CBorValue object into this one and frees
+ Moves the contents of the \a other QCborValue object into this one and frees
the resources of this one.
*/
@@ -469,7 +466,7 @@ QT_BEGIN_NAMESPACE
\fn QCborValue &&QCborValue::operator=(QCborValue &&other)
\overload
- Moves the contents of the \a other CBorValue object into this one and frees
+ Moves the contents of the \a other QCborValue object into this one and frees
the resources of this one. Returns a reference to this object.
*/
@@ -702,9 +699,7 @@ QT_BEGIN_NAMESPACE
any CBOR simple type, even those for which there is no enumeration in the
API. For example, for the simple type of value 12, you could write:
- \code
- value.isSimpleType(QCborSimpleType(12));
- \endcode
+ \snippet code/src_corelib_serialization_qcborvalue.cpp 2
\sa QCborValue::QCborValue(QCborSimpleType), isSimpleType(), isFalse(),
isTrue(), isNull, isUndefined(), toSimpleType()
@@ -1163,9 +1158,7 @@ inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPriv
\l{Type}{Url} and \l{Type}{Url} and its equivalent tagged representation.
So, for example, the following expression is true:
- \code
- QCborValue(QUrl("https://example.com")) == QCborValue(QCborKnownTags::Url, "https://example.com");
- \endcode
+ \snippet code/src_corelib_serialization_qcborvalue.cpp 3
Do note that Qt types like \l QUrl and \l QDateTime will normalize and
otherwise modify their arguments. The expression above is true only because
@@ -1779,6 +1772,7 @@ QCborValue::QCborValue(const QUrl &url)
container->elements[1].type = String;
}
+#if QT_CONFIG(regularexpression)
/*!
Creates a QCborValue object of the regular expression pattern extended type
and containing the value represented by \a rx. The value can later be retrieved
@@ -1797,6 +1791,7 @@ QCborValue::QCborValue(const QRegularExpression &rx)
// change type
t = RegularExpression;
}
+#endif // QT_CONFIG(regularexpression)
/*!
Creates a QCborValue object of the UUID extended type and containing the
@@ -1950,6 +1945,7 @@ QUrl QCborValue::toUrl(const QUrl &defaultValue) const
return QUrl::fromEncoded(byteData->asByteArrayView());
}
+#if QT_CONFIG(regularexpression)
/*!
Returns the regular expression value stored in this QCborValue, if it is of
the regular expression pattern extended type. Otherwise, it returns \a
@@ -1968,6 +1964,7 @@ QRegularExpression QCborValue::toRegularExpression(const QRegularExpression &def
Q_ASSERT(n == -1);
return QRegularExpression(container->stringAt(1));
}
+#endif // QT_CONFIG(regularexpression)
/*!
Returns the UUID value stored in this QCborValue, if it is of the UUID
@@ -2081,9 +2078,7 @@ QCborMap QCborValue::toMap(const QCborMap &defaultValue) const
This function is equivalent to:
- \code
- value.toMap().value(key);
- \endcode
+ \snippet code/src_corelib_serialization_qcborvalue.cpp 4
\sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
QCborMap::find()
@@ -2104,9 +2099,7 @@ const QCborValue QCborValue::operator[](const QString &key) const
This function is equivalent to:
- \code
- value.toMap().value(key);
- \endcode
+ \snippet code/src_corelib_serialization_qcborvalue.cpp 5
\sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
QCborMap::find()
@@ -2119,15 +2112,16 @@ const QCborValue QCborValue::operator[](QLatin1String key) const
}
/*!
+ \overload
+
If this QCborValue is a QCborMap, searches elements for the value whose key
- matches \a key. If this is an array, returns the element whose index is \a
- key. If there's no matching value in the array or map, or if this
+ matches \a key. If this is a QCborArray, returns the element whose index is
+ \a key. If there's no matching value in the array or map, or if this
QCborValue object is not an array or map, returns the undefined value.
\sa operator[], QCborMap::operator[], QCborMap::value(),
QCborMap::find(), QCborArray::operator[], QCborArray::at()
*/
-
const QCborValue QCborValue::operator[](qint64 key) const
{
if (isMap())
@@ -2138,6 +2132,191 @@ const QCborValue QCborValue::operator[](qint64 key) const
}
/*!
+ \internal
+ */
+static Q_DECL_COLD_FUNCTION QCborMap arrayAsMap(const QCborArray &array)
+{
+ if (array.size())
+ qWarning("Using CBOR array as map forced conversion");
+ QCborMap map;
+ for (qsizetype i = array.size(); i-- > 0; ) {
+ QCborValue entry = array.at(i);
+ // Ignore padding entries that may have been added to grow the array
+ // when inserting past its end:
+ if (!entry.isInvalid())
+ map[i] = entry;
+ }
+ return map;
+}
+
+/*!
+ \internal
+ */
+static QCborContainerPrivate *maybeDetach(QCborContainerPrivate *container, qsizetype size)
+{
+ auto replace = QCborContainerPrivate::detach(container, size);
+ Q_ASSERT(replace);
+ if (replace != container) {
+ if (container)
+ container->deref();
+ replace->ref.ref();
+ }
+ return replace;
+}
+
+/*!
+ \internal
+ */
+static QCborContainerPrivate *maybeGrow(QCborContainerPrivate *container, qsizetype index)
+{
+ auto replace = QCborContainerPrivate::grow(container, index);
+ Q_ASSERT(replace);
+ if (replace != container) {
+ if (container)
+ container->deref();
+ replace->ref.ref();
+ }
+ if (replace->elements.size() == index)
+ replace->append(Undefined());
+ else
+ Q_ASSERT(replace->elements.size() > index);
+ return replace;
+}
+
+/*!
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValue is a QCborMap,
+ this function is equivalent to the matching operator[] on that map.
+
+ Before returning the reference: if this QCborValue was an array, it is first
+ converted to a map (so that \c{map[i]} is \c{array[i]} for each index, \c i,
+ with valid \c{array[i]}); otherwise, if it was not a map it will be
+ over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValue::operator[](const QString &key)
+{
+ if (!isMap())
+ *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap());
+
+ const qsizetype size = container ? container->elements.size() : 0;
+ qsizetype index = size + 1;
+ bool found = false;
+ if (container) {
+ QCborMap proxy(*container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ container = maybeDetach(container, size + (found ? 0 : 2));
+ Q_ASSERT(container);
+ if (!found) {
+ container->append(key);
+ container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(container->elements.size() & 1));
+ Q_ASSERT(index < container->elements.size());
+ return { container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValue is a QCborMap,
+ this function is equivalent to the matching operator[] on that map.
+
+ Before returning the reference: if this QCborValue was an array, it is first
+ converted to a map (so that \c{map[i]} is \c{array[i]} for each index, \c i,
+ with valid \c{array[i]}); otherwise, if it was not a map it will be
+ over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValue::operator[](QLatin1String key)
+{
+ if (!isMap())
+ *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap());
+
+ const qsizetype size = container ? container->elements.size() : 0;
+ qsizetype index = size + 1;
+ bool found = false;
+ if (container) {
+ QCborMap proxy(*container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ container = maybeDetach(container, size + (found ? 0 : 2));
+ Q_ASSERT(container);
+ if (!found) {
+ container->append(key);
+ container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(container->elements.size() & 1));
+ Q_ASSERT(index < container->elements.size());
+ return { container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map or array, with the given \a key. When this QCborValue is a
+ QCborMap or, for 0 <= key < 0x10000, a QCborArray, this function is
+ equivalent to the matching operator[] on that map or array.
+
+ Before returning the reference: if this QCborValue was an array but the key
+ is out of range, the array is first converted to a map (so that \c{map[i]}
+ is \c{array[i]} for each index, \c i, with valid \c{array[i]}); otherwise,
+ if it was not a map it will be over-written with an empty map.
+
+ \sa operator[], QCborMap::operator[], QCborMap::value(),
+ QCborMap::find(), QCborArray::operator[], QCborArray::at()
+ */
+QCborValueRef QCborValue::operator[](qint64 key)
+{
+ if (isArray() && key >= 0 && key < 0x10000) {
+ container = maybeGrow(container, key);
+ return { container, qsizetype(key) };
+ }
+ if (!isMap())
+ *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap());
+
+ const qsizetype size = container ? container->elements.size() : 0;
+ Q_ASSERT(!(size & 1));
+ qsizetype index = size + 1;
+ bool found = false;
+ if (container) {
+ QCborMap proxy(*container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ container = maybeDetach(container, size + (found ? 0 : 2));
+ Q_ASSERT(container);
+ if (!found) {
+ container->append(key);
+ container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(container->elements.size() & 1));
+ Q_ASSERT(index < container->elements.size());
+ return { container, index };
+}
+
+/*!
Decodes one item from the CBOR stream found in \a reader and returns the
equivalent representation. This function is recursive: if the item is a map
or array, it will decode all items found in that map or array, until the
@@ -2147,12 +2326,7 @@ const QCborValue QCborValue::operator[](qint64 key) const
QCborStreamReader. For example, the following code illustrates how to skip
the CBOR signature tag from the beginning of a file:
- \code
- if (reader.isTag() && reader.toTag() == QCborKnownTags::Signature)
- reader.next();
-
- QCborValue contents = QCborValue::fromCbor(reader);
- \endcode
+ \snippet code/src_corelib_serialization_qcborvalue.cpp 6
The returned value may be partially complete and indistinguishable from a
valid QCborValue even if the decoding failed. To determine if there was an
@@ -2406,6 +2580,255 @@ QCborValue::Type QCborValueRef::concreteType(QCborValueRef self) noexcept
return self.d->elements.at(self.i).type;
}
+/*!
+ If this QCborValueRef refers to a QCborMap, searches elements for the value
+ whose key matches \a key. If there's no key matching \a key in the map or if
+ this QCborValueRef object is not a map, returns the undefined value.
+
+ This function is equivalent to:
+
+ \code
+ value.toMap().value(key);
+ \endcode
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+const QCborValue QCborValueRef::operator[](const QString &key) const
+{
+ const QCborValue item = d->valueAt(i);
+ return item[key];
+}
+
+/*!
+ \overload
+
+ If this QCborValueRef refers to a QCborMap, searches elements for the value
+ whose key matches \a key. If there's no key matching \a key in the map or if
+ this QCborValueRef object is not a map, returns the undefined value.
+
+ This function is equivalent to:
+
+ \code
+ value.toMap().value(key);
+ \endcode
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+const QCborValue QCborValueRef::operator[](QLatin1String key) const
+{
+ const QCborValue item = d->valueAt(i);
+ return item[key];
+}
+
+/*!
+ \overload
+
+ If this QCborValueRef refers to a QCborMap, searches elements for the value
+ whose key matches \a key. If this is a QCborArray, returns the element whose
+ index is \a key. If there's no matching value in the array or map, or if
+ this QCborValueRef object is not an array or map, returns the undefined
+ value.
+
+ \sa operator[], QCborMap::operator[], QCborMap::value(),
+ QCborMap::find(), QCborArray::operator[], QCborArray::at()
+ */
+const QCborValue QCborValueRef::operator[](qint64 key) const
+{
+ const QCborValue item = d->valueAt(i);
+ return item[key];
+}
+
+/*!
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValueRef refers to a
+ QCborMap, this function is equivalent to the matching operator[] on that
+ map.
+
+ Before returning the reference: if the QCborValue referenced was an array,
+ it is first converted to a map (so that \c{map[i]} is \c{array[i]} for each
+ index, \c i, with valid \c{array[i]}); otherwise, if it was not a map it
+ will be over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValueRef::operator[](const QString &key)
+{
+ auto &e = d->elements[i];
+ qsizetype size = 0;
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.container) {
+ if (e.type == QCborValue::Array) {
+ QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
+ qSwap(e.container, repack.container);
+ } else if (e.type != QCborValue::Map) {
+ e.container->deref();
+ e.container = nullptr;
+ }
+ }
+ e.type = QCborValue::Map;
+ if (e.container)
+ size = e.container->elements.size();
+ } else {
+ // Stomp any prior e.value, replace with a map (that we'll grow)
+ e.container = nullptr;
+ e.type = QCborValue::Map;
+ e.flags = QtCbor::Element::IsContainer;
+ }
+
+ qsizetype index = size + 1;
+ bool found = false;
+ if (e.container) {
+ QCborMap proxy(*e.container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ e.container = maybeDetach(e.container, size + (found ? 0 : 2));
+ Q_ASSERT(e.container);
+ if (!found) {
+ e.container->append(key);
+ e.container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
+ Q_ASSERT(index < e.container->elements.size());
+ return { e.container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValue is a QCborMap,
+ this function is equivalent to the matching operator[] on that map.
+
+ Before returning the reference: if the QCborValue referenced was an array,
+ it is first converted to a map (so that \c{map[i]} is \c{array[i]} for each
+ index, \c i, with valid \c{array[i]}); otherwise, if it was not a map it
+ will be over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValueRef::operator[](QLatin1String key)
+{
+ auto &e = d->elements[i];
+ qsizetype size = 0;
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.container) {
+ if (e.type == QCborValue::Array) {
+ QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
+ qSwap(e.container, repack.container);
+ } else if (e.type != QCborValue::Map) {
+ e.container->deref();
+ e.container = nullptr;
+ }
+ }
+ e.type = QCborValue::Map;
+ if (e.container)
+ size = e.container->elements.size();
+ } else {
+ // Stomp any prior e.value, replace with a map (that we'll grow)
+ e.container = nullptr;
+ e.type = QCborValue::Map;
+ e.flags = QtCbor::Element::IsContainer;
+ }
+
+ qsizetype index = size + 1;
+ bool found = false;
+ if (e.container) {
+ QCborMap proxy(*e.container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ e.container = maybeDetach(e.container, size + (found ? 0 : 2));
+ Q_ASSERT(e.container);
+ if (!found) {
+ e.container->append(key);
+ e.container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
+ Q_ASSERT(index < e.container->elements.size());
+ return { e.container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map or array, with the given \a key. When this QCborValue is a
+ QCborMap or, for 0 <= key < 0x10000, a QCborArray, this function is
+ equivalent to the matching operator[] on that map or array.
+
+ Before returning the reference: if the QCborValue referenced was an array
+ but the key is out of range, the array is first converted to a map (so that
+ \c{map[i]} is \c{array[i]} for each index, \c i, with valid \c{array[i]});
+ otherwise, if it was not a map it will be over-written with an empty map.
+
+ \sa operator[], QCborMap::operator[], QCborMap::value(),
+ QCborMap::find(), QCborArray::operator[], QCborArray::at()
+ */
+QCborValueRef QCborValueRef::operator[](qint64 key)
+{
+ auto &e = d->elements[i];
+ if (e.type == QCborValue::Array && key >= 0 && key < 0x10000) {
+ e.container = maybeGrow(e.container, key);
+ return { e.container, qsizetype(key) };
+ }
+ qsizetype size = 0;
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.container) {
+ if (e.type == QCborValue::Array) {
+ QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
+ qSwap(e.container, repack.container);
+ } else if (e.type != QCborValue::Map) {
+ e.container->deref();
+ e.container = nullptr;
+ }
+ }
+ e.type = QCborValue::Map;
+ if (e.container)
+ size = e.container->elements.size();
+ } else {
+ // Stomp any prior e.value, replace with a map (that we'll grow)
+ e.container = nullptr;
+ e.type = QCborValue::Map;
+ e.flags = QtCbor::Element::IsContainer;
+ }
+ Q_ASSERT(!(size & 1));
+
+ qsizetype index = size + 1;
+ bool found = false;
+ if (e.container) {
+ QCborMap proxy(*e.container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ e.container = maybeDetach(e.container, size + (found ? 0 : 2));
+ Q_ASSERT(e.container);
+ if (!found) {
+ e.container->append(key);
+ e.container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
+ Q_ASSERT(index < e.container->elements.size());
+ return { e.container, index };
+}
+
+
inline QCborArray::QCborArray(QCborContainerPrivate &dd) noexcept
: d(&dd)
{
@@ -2451,12 +2874,16 @@ uint qHash(const QCborValue &value, uint seed)
return qHash(value.toDateTime(), seed);
case QCborValue::Url:
return qHash(value.toUrl(), seed);
+#if QT_CONFIG(regularexpression)
case QCborValue::RegularExpression:
return qHash(value.toRegularExpression(), seed);
+#endif
case QCborValue::Uuid:
return qHash(value.toUuid(), seed);
case QCborValue::Invalid:
return seed;
+ default:
+ break;
}
Q_ASSERT(value.isSimpleType());
@@ -2501,12 +2928,16 @@ static QDebug debugContents(QDebug &dbg, const QCborValue &v)
return dbg << v.toDateTime();
case QCborValue::Url:
return dbg << v.toUrl();
+#if QT_CONFIG(regularexpression)
case QCborValue::RegularExpression:
return dbg << v.toRegularExpression();
+#endif
case QCborValue::Uuid:
return dbg << v.toUuid();
case QCborValue::Invalid:
return dbg << "<invalid>";
+ default:
+ break;
}
if (v.isSimpleType())
return dbg << v.toSimpleType();
diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h
index 5c7f9a3791..f542e44c47 100644
--- a/src/corelib/serialization/qcborvalue.h
+++ b/src/corelib/serialization/qcborvalue.h
@@ -43,7 +43,9 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qcborcommon.h>
-#include <QtCore/qregularexpression.h>
+#if QT_CONFIG(regularexpression)
+# include <QtCore/qregularexpression.h>
+#endif
#include <QtCore/qstring.h>
#include <QtCore/qstringview.h>
#include <QtCore/qurl.h>
@@ -72,11 +74,12 @@ class QDataStream;
struct QCborParserError
{
qint64 offset = 0;
- QCborError error = {};
+ QCborError error = { QCborError::NoError };
QString errorString() const { return error.toString(); }
};
+class QCborValueRef;
class QCborContainerPrivate;
class Q_CORE_EXPORT QCborValue
{
@@ -156,7 +159,9 @@ public:
explicit QCborValue(const QDateTime &dt);
explicit QCborValue(const QUrl &url);
+#if QT_CONFIG(regularexpression)
explicit QCborValue(const QRegularExpression &rx);
+#endif
explicit QCborValue(const QUuid &uuid);
~QCborValue() { if (container) dispose(); }
@@ -234,7 +239,9 @@ public:
QString toString(const QString &defaultValue = {}) const;
QDateTime toDateTime(const QDateTime &defaultValue = {}) const;
QUrl toUrl(const QUrl &defaultValue = {}) const;
+#if QT_CONFIG(regularexpression)
QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const;
+#endif
QUuid toUuid(const QUuid &defaultValue = {}) const;
// only forward-declared, need split functions
@@ -246,6 +253,9 @@ public:
const QCborValue operator[](const QString &key) const;
const QCborValue operator[](QLatin1String key) const;
const QCborValue operator[](qint64 key) const;
+ QCborValueRef operator[](qint64 key);
+ QCborValueRef operator[](QLatin1String key);
+ QCborValueRef operator[](const QString & key);
int compare(const QCborValue &other) const;
#if 0 && QT_HAS_INCLUDE(<compare>)
@@ -376,8 +386,10 @@ public:
{ return concrete().toDateTime(defaultValue); }
QUrl toUrl(const QUrl &defaultValue = {}) const
{ return concrete().toUrl(defaultValue); }
+#if QT_CONFIG(regularexpression)
QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const
{ return concrete().toRegularExpression(defaultValue); }
+#endif
QUuid toUuid(const QUuid &defaultValue = {}) const
{ return concrete().toUuid(defaultValue); }
@@ -387,6 +399,13 @@ public:
QCborMap toMap() const;
QCborMap toMap(const QCborMap &m) const;
+ const QCborValue operator[](const QString &key) const;
+ const QCborValue operator[](QLatin1String key) const;
+ const QCborValue operator[](qint64 key) const;
+ QCborValueRef operator[](qint64 key);
+ QCborValueRef operator[](QLatin1String key);
+ QCborValueRef operator[](const QString & key);
+
int compare(const QCborValue &other) const
{ return concrete().compare(other); }
#if 0 && QT_HAS_INCLUDE(<compare>)
@@ -417,6 +436,7 @@ public:
{ return concrete().toDiagnosticNotation(opt); }
private:
+ friend class QCborValue;
friend class QCborArray;
friend class QCborMap;
friend class QCborContainerPrivate;
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index eccbc357e1..b44d55cb8f 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -98,6 +98,10 @@ QT_BEGIN_NAMESPACE
ensures that you get integers of the size you want and insulates
you from compiler and platform differences.
+ Enumerations can be serialized through QDataStream without the
+ need of manually defining streaming operators. Enum classes are
+ serialized using the declared size.
+
To take one example, a \c{char *} string is written as a 32-bit
integer equal to the length of the string including the '\\0' byte,
followed by all the characters of the string including the
@@ -170,18 +174,12 @@ QT_BEGIN_NAMESPACE
will have appropriate stream operators declared as non-member of
the class:
- \code
- QDataStream &operator<<(QDataStream &, const QXxx &);
- QDataStream &operator>>(QDataStream &, QXxx &);
- \endcode
+ \snippet code/src_corelib_serialization_qdatastream.cpp 0
For example, here are the stream operators declared as non-members
of the QImage class:
- \code
- QDataStream & operator<< (QDataStream& stream, const QImage& image);
- QDataStream & operator>> (QDataStream& stream, QImage& image);
- \endcode
+ \snippet code/src_corelib_serialization_qdatastream.cpp 1
To see if your favorite Qt class has similar stream operators
defined, check the \b {Related Non-Members} section of the
@@ -374,7 +372,7 @@ QDataStream::~QDataStream()
/*!
\fn QIODevice *QDataStream::device() const
- Returns the I/O device currently set, or 0 if no
+ Returns the I/O device currently set, or \nullptr if no
device is currently set.
\sa setDevice()
@@ -383,7 +381,7 @@ QDataStream::~QDataStream()
/*!
void QDataStream::setDevice(QIODevice *d)
- Sets the I/O device to \a d, which can be 0
+ Sets the I/O device to \a d, which can be \nullptr
to unset to current I/O device.
\sa device()
@@ -398,17 +396,18 @@ void QDataStream::setDevice(QIODevice *d)
dev = d;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
Unsets the I/O device.
- Use setDevice(0) instead.
+ Use setDevice(nullptr) instead.
*/
void QDataStream::unsetDevice()
{
- setDevice(0);
+ setDevice(nullptr);
}
-
+#endif
/*!
\fn bool QDataStream::atEnd() const
@@ -565,7 +564,8 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_10 Same as Qt_5_6
\value Qt_5_11 Same as Qt_5_6
\value Qt_5_12 Version 18 (Qt 5.12)
- \value Qt_5_13 Same as Qt_5_12
+ \value Qt_5_13 Version 19 (Qt 5.13)
+ \value Qt_5_14 Same as Qt_5_13
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h
index ad69621bbe..2acf7d8c4b 100644
--- a/src/corelib/serialization/qdatastream.h
+++ b/src/corelib/serialization/qdatastream.h
@@ -99,11 +99,12 @@ public:
Qt_5_10 = Qt_5_9,
Qt_5_11 = Qt_5_10,
Qt_5_12 = 18,
- Qt_5_13 = Qt_5_12,
-#if QT_VERSION >= 0x050e00
+ Qt_5_13 = 19,
+ Qt_5_14 = Qt_5_13,
+#if QT_VERSION >= 0x050f00
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_13
+ Qt_DefaultCompiledVersion = Qt_5_14
};
enum ByteOrder {
@@ -131,7 +132,10 @@ public:
QIODevice *device() const;
void setDevice(QIODevice *);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QDataStream::setDevice(nullptr) instead")
void unsetDevice();
+#endif
bool atEnd() const;
@@ -374,6 +378,16 @@ inline QDataStream &operator>>(QDataStream &s, QFlags<Enum> &e)
{ return s >> e.i; }
template <typename T>
+typename std::enable_if<std::is_enum<T>::value, QDataStream &>::type&
+operator<<(QDataStream &s, const T &t)
+{ return s << static_cast<typename std::underlying_type<T>::type>(t); }
+
+template <typename T>
+typename std::enable_if<std::is_enum<T>::value, QDataStream &>::type&
+operator>>(QDataStream &s, T &t)
+{ return s >> reinterpret_cast<typename std::underlying_type<T>::type &>(t); }
+
+template <typename T>
inline QDataStream &operator>>(QDataStream &s, QList<T> &l)
{
return QtPrivate::readArrayBasedContainer(s, l);
diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp
index b82923fe0c..d74ffb2a20 100644
--- a/src/corelib/serialization/qjson.cpp
+++ b/src/corelib/serialization/qjson.cpp
@@ -70,6 +70,7 @@ void Data::compact()
int size = sizeof(Base) + reserve + base->length*sizeof(offset);
int alloc = sizeof(Header) + size;
Header *h = (Header *) malloc(alloc);
+ Q_CHECK_PTR(h);
h->tag = QJsonDocument::BinaryFormatTag;
h->version = 1;
Base *b = h->root();
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h
index feba1faac6..85fb2a1254 100644
--- a/src/corelib/serialization/qjson_p.h
+++ b/src/corelib/serialization/qjson_p.h
@@ -304,7 +304,7 @@ public:
return *this;
}
- QLatin1String toQLatin1String() const Q_DECL_NOTHROW {
+ QLatin1String toQLatin1String() const noexcept {
return QLatin1String(d->latin1, d->length);
}
@@ -339,23 +339,23 @@ public:
};
#define DEF_OP(op) \
- inline bool operator op(Latin1String lhs, Latin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(Latin1String lhs, Latin1String rhs) noexcept \
{ \
return lhs.toQLatin1String() op rhs.toQLatin1String(); \
} \
- inline bool operator op(QLatin1String lhs, Latin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(QLatin1String lhs, Latin1String rhs) noexcept \
{ \
return lhs op rhs.toQLatin1String(); \
} \
- inline bool operator op(Latin1String lhs, QLatin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(Latin1String lhs, QLatin1String rhs) noexcept \
{ \
return lhs.toQLatin1String() op rhs; \
} \
- inline bool operator op(const QString &lhs, Latin1String rhs) Q_DECL_NOTHROW \
+ inline bool operator op(const QString &lhs, Latin1String rhs) noexcept \
{ \
return lhs op rhs.toQLatin1String(); \
} \
- inline bool operator op(Latin1String lhs, const QString &rhs) Q_DECL_NOTHROW \
+ inline bool operator op(Latin1String lhs, const QString &rhs) noexcept \
{ \
return lhs.toQLatin1String() op rhs; \
} \
@@ -686,7 +686,7 @@ public:
{
}
inline Data(int reserved, QJsonValue::Type valueType)
- : rawData(0), compactionCounter(0), ownsData(true)
+ : rawData(nullptr), compactionCounter(0), ownsData(true)
{
Q_ASSERT(valueType == QJsonValue::Array || valueType == QJsonValue::Object);
@@ -728,7 +728,7 @@ public:
size = qMax(size + reserve, qMin(size *2, (int)Value::MaxSize));
if (size > Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure");
- return 0;
+ return nullptr;
}
}
char *raw = (char *)malloc(size);
@@ -746,7 +746,7 @@ public:
bool valid() const;
private:
- Q_DISABLE_COPY(Data)
+ Q_DISABLE_COPY_MOVE(Data)
};
}
diff --git a/src/corelib/serialization/qjsonarray.cpp b/src/corelib/serialization/qjsonarray.cpp
index 5ba83c41b9..7dfa9b43f0 100644
--- a/src/corelib/serialization/qjsonarray.cpp
+++ b/src/corelib/serialization/qjsonarray.cpp
@@ -675,6 +675,14 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
\sa begin(), constEnd()
*/
+/*! \fn QJsonArray::const_iterator QJsonArray::cbegin() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
+ in the array.
+
+ \sa begin(), cend()
+*/
+
/*! \fn QJsonArray::iterator QJsonArray::end()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
@@ -696,6 +704,14 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
\sa constBegin(), end()
*/
+/*! \fn QJsonArray::const_iterator QJsonArray::cend() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
+ item after the last item in the array.
+
+ \sa cbegin(), end()
+*/
+
/*! \fn void QJsonArray::push_back(const QJsonValue &value)
This function is provided for STL compatibility. It is equivalent
diff --git a/src/corelib/serialization/qjsonarray.h b/src/corelib/serialization/qjsonarray.h
index 0a17951fb7..86b7bf9d76 100644
--- a/src/corelib/serialization/qjsonarray.h
+++ b/src/corelib/serialization/qjsonarray.h
@@ -72,7 +72,7 @@ public:
QJsonArray(const QJsonArray &other);
QJsonArray &operator =(const QJsonArray &other);
- QJsonArray(QJsonArray &&other) Q_DECL_NOTHROW
+ QJsonArray(QJsonArray &&other) noexcept
: d(other.d),
a(other.a)
{
@@ -80,7 +80,7 @@ public:
other.a = nullptr;
}
- QJsonArray &operator =(QJsonArray &&other) Q_DECL_NOTHROW
+ QJsonArray &operator =(QJsonArray &&other) noexcept
{
swap(other);
return *this;
@@ -115,7 +115,7 @@ public:
bool operator==(const QJsonArray &other) const;
bool operator!=(const QJsonArray &other) const;
- void swap(QJsonArray &other) Q_DECL_NOTHROW
+ void swap(QJsonArray &other) noexcept
{
qSwap(d, other.d);
qSwap(a, other.a);
@@ -214,9 +214,11 @@ public:
inline iterator begin() { detach2(); return iterator(this, 0); }
inline const_iterator begin() const { return const_iterator(this, 0); }
inline const_iterator constBegin() const { return const_iterator(this, 0); }
+ inline const_iterator cbegin() const { return const_iterator(this, 0); }
inline iterator end() { detach2(); return iterator(this, size()); }
inline const_iterator end() const { return const_iterator(this, size()); }
inline const_iterator constEnd() const { return const_iterator(this, size()); }
+ inline const_iterator cend() const { return const_iterator(this, size()); }
iterator insert(iterator before, const QJsonValue &value) { insert(before.i, value); return before; }
iterator erase(iterator it) { removeAt(it.i); return it; }
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp
index 158f1950d0..dc5f384108 100644
--- a/src/corelib/serialization/qjsoncbor.cpp
+++ b/src/corelib/serialization/qjsoncbor.cpp
@@ -543,14 +543,19 @@ QVariant QCborValue::toVariant() const
case Url:
return toUrl();
+#if QT_CONFIG(regularexpression)
case RegularExpression:
return toRegularExpression();
+#endif
case Uuid:
return toUuid();
case Invalid:
return QVariant();
+
+ default:
+ break;
}
if (isSimpleType())
@@ -714,8 +719,10 @@ QCborValue QCborValue::fromVariant(const QVariant &variant)
case QVariant::Hash:
return QCborMap::fromVariantHash(variant.toHash());
#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(regularexpression)
case QVariant::RegularExpression:
return QCborValue(variant.toRegularExpression());
+#endif
case QMetaType::QJsonValue:
return fromJsonValue(variant.toJsonValue());
case QMetaType::QJsonObject:
@@ -817,7 +824,7 @@ QCborArray QCborArray::fromJsonArray(const QJsonArray &array)
{
QCborArray a;
a.detach(array.size());
- for (const QJsonValue v : array) {
+ for (const QJsonValue &v : array) {
if (v.isString())
a.d->append(v.toString());
else
diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp
index aaa0f6acaa..179a87c699 100644
--- a/src/corelib/serialization/qjsondocument.cpp
+++ b/src/corelib/serialization/qjsondocument.cpp
@@ -351,22 +351,10 @@ QByteArray QJsonDocument::toJson() const
when converting to a QJsonDocument using toJson().
\value Indented Defines human readable output as follows:
- \code
- {
- "Array": [
- true,
- 999,
- "string"
- ],
- "Key": "Value",
- "null": null
- }
- \endcode
+ \snippet code/src_corelib_serialization_qjsondocument.cpp 0
\value Compact Defines a compact output as follows:
- \code
- {"Array":[true,999,"string"],"Key":"Value","null":null}
- \endcode
+ \snippet code/src_corelib_serialization_qjsondocument.cpp 1
*/
/*!
diff --git a/src/corelib/serialization/qjsondocument.h b/src/corelib/serialization/qjsondocument.h
index a749439b7d..a8006a6cc5 100644
--- a/src/corelib/serialization/qjsondocument.h
+++ b/src/corelib/serialization/qjsondocument.h
@@ -93,19 +93,19 @@ public:
QJsonDocument(const QJsonDocument &other);
QJsonDocument &operator =(const QJsonDocument &other);
- QJsonDocument(QJsonDocument &&other) Q_DECL_NOTHROW
+ QJsonDocument(QJsonDocument &&other) noexcept
: d(other.d)
{
other.d = nullptr;
}
- QJsonDocument &operator =(QJsonDocument &&other) Q_DECL_NOTHROW
+ QJsonDocument &operator =(QJsonDocument &&other) noexcept
{
swap(other);
return *this;
}
- void swap(QJsonDocument &other) Q_DECL_NOTHROW
+ void swap(QJsonDocument &other) noexcept
{
qSwap(d, other.d);
}
diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h
index 80fe6b2f3f..92d45cc838 100644
--- a/src/corelib/serialization/qjsonobject.h
+++ b/src/corelib/serialization/qjsonobject.h
@@ -74,20 +74,20 @@ public:
QJsonObject(const QJsonObject &other);
QJsonObject &operator =(const QJsonObject &other);
- QJsonObject(QJsonObject &&other) Q_DECL_NOTHROW
+ QJsonObject(QJsonObject &&other) noexcept
: d(other.d), o(other.o)
{
other.d = nullptr;
other.o = nullptr;
}
- QJsonObject &operator =(QJsonObject &&other) Q_DECL_NOTHROW
+ QJsonObject &operator =(QJsonObject &&other) noexcept
{
swap(other);
return *this;
}
- void swap(QJsonObject &other) Q_DECL_NOTHROW
+ void swap(QJsonObject &other) noexcept
{
qSwap(d, other.d);
qSwap(o, other.o);
diff --git a/src/corelib/serialization/qjsonparser.cpp b/src/corelib/serialization/qjsonparser.cpp
index 39738b90a8..bfba95520e 100644
--- a/src/corelib/serialization/qjsonparser.cpp
+++ b/src/corelib/serialization/qjsonparser.cpp
@@ -304,6 +304,7 @@ QJsonDocument Parser::parse(QJsonParseError *error)
// allocate some space
dataLength = qMax(end - json, (ptrdiff_t) 256);
data = (char *)malloc(dataLength);
+ Q_CHECK_PTR(data);
// fill in Header data
QJsonPrivate::Header *h = (QJsonPrivate::Header *)data;
diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h
index 16d2c0c14c..37d84f9e60 100644
--- a/src/corelib/serialization/qjsonvalue.h
+++ b/src/corelib/serialization/qjsonvalue.h
@@ -92,7 +92,7 @@ public:
QJsonValue(const QJsonValue &other);
QJsonValue &operator =(const QJsonValue &other);
- QJsonValue(QJsonValue &&other) Q_DECL_NOTHROW
+ QJsonValue(QJsonValue &&other) noexcept
: ui(other.ui),
d(other.d),
t(other.t)
@@ -102,13 +102,13 @@ public:
other.t = Null;
}
- QJsonValue &operator =(QJsonValue &&other) Q_DECL_NOTHROW
+ QJsonValue &operator =(QJsonValue &&other) noexcept
{
swap(other);
return *this;
}
- void swap(QJsonValue &other) Q_DECL_NOTHROW
+ void swap(QJsonValue &other) noexcept
{
qSwap(ui, other.ui);
qSwap(d, other.d);
@@ -219,7 +219,6 @@ private:
uint index : 31;
};
-#ifndef Q_QDOC
// ### Qt 6: Get rid of these fake pointer classes
class QJsonValuePtr
{
@@ -244,7 +243,6 @@ public:
QJsonValueRef& operator*() { return valueRef; }
QJsonValueRef* operator->() { return &valueRef; }
};
-#endif
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonValue)
diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp
index 05a5a55926..0d83bb6cd4 100644
--- a/src/corelib/serialization/qtextstream.cpp
+++ b/src/corelib/serialization/qtextstream.cpp
@@ -135,30 +135,30 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
\table
\header \li Manipulator \li Description
- \row \li \c bin \li Same as setIntegerBase(2).
- \row \li \c oct \li Same as setIntegerBase(8).
- \row \li \c dec \li Same as setIntegerBase(10).
- \row \li \c hex \li Same as setIntegerBase(16).
- \row \li \c showbase \li Same as setNumberFlags(numberFlags() | ShowBase).
- \row \li \c forcesign \li Same as setNumberFlags(numberFlags() | ForceSign).
- \row \li \c forcepoint \li Same as setNumberFlags(numberFlags() | ForcePoint).
- \row \li \c noshowbase \li Same as setNumberFlags(numberFlags() & ~ShowBase).
- \row \li \c noforcesign \li Same as setNumberFlags(numberFlags() & ~ForceSign).
- \row \li \c noforcepoint \li Same as setNumberFlags(numberFlags() & ~ForcePoint).
- \row \li \c uppercasebase \li Same as setNumberFlags(numberFlags() | UppercaseBase).
- \row \li \c uppercasedigits \li Same as setNumberFlags(numberFlags() | UppercaseDigits).
- \row \li \c lowercasebase \li Same as setNumberFlags(numberFlags() & ~UppercaseBase).
- \row \li \c lowercasedigits \li Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
- \row \li \c fixed \li Same as setRealNumberNotation(FixedNotation).
- \row \li \c scientific \li Same as setRealNumberNotation(ScientificNotation).
- \row \li \c left \li Same as setFieldAlignment(AlignLeft).
- \row \li \c right \li Same as setFieldAlignment(AlignRight).
- \row \li \c center \li Same as setFieldAlignment(AlignCenter).
- \row \li \c endl \li Same as operator<<('\\n') and flush().
- \row \li \c flush \li Same as flush().
- \row \li \c reset \li Same as reset().
- \row \li \c ws \li Same as skipWhiteSpace().
- \row \li \c bom \li Same as setGenerateByteOrderMark(true).
+ \row \li \c Qt::bin \li Same as setIntegerBase(2).
+ \row \li \c Qt::oct \li Same as setIntegerBase(8).
+ \row \li \c Qt::dec \li Same as setIntegerBase(10).
+ \row \li \c Qt::hex \li Same as setIntegerBase(16).
+ \row \li \c Qt::showbase \li Same as setNumberFlags(numberFlags() | ShowBase).
+ \row \li \c Qt::forcesign \li Same as setNumberFlags(numberFlags() | ForceSign).
+ \row \li \c Qt::forcepoint \li Same as setNumberFlags(numberFlags() | ForcePoint).
+ \row \li \c Qt::noshowbase \li Same as setNumberFlags(numberFlags() & ~ShowBase).
+ \row \li \c Qt::noforcesign \li Same as setNumberFlags(numberFlags() & ~ForceSign).
+ \row \li \c Qt::noforcepoint \li Same as setNumberFlags(numberFlags() & ~ForcePoint).
+ \row \li \c Qt::uppercasebase \li Same as setNumberFlags(numberFlags() | UppercaseBase).
+ \row \li \c Qt::uppercasedigits \li Same as setNumberFlags(numberFlags() | UppercaseDigits).
+ \row \li \c Qt::lowercasebase \li Same as setNumberFlags(numberFlags() & ~UppercaseBase).
+ \row \li \c Qt::lowercasedigits \li Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
+ \row \li \c Qt::fixed \li Same as setRealNumberNotation(FixedNotation).
+ \row \li \c Qt::scientific \li Same as setRealNumberNotation(ScientificNotation).
+ \row \li \c Qt::left \li Same as setFieldAlignment(AlignLeft).
+ \row \li \c Qt::right \li Same as setFieldAlignment(AlignRight).
+ \row \li \c Qt::center \li Same as setFieldAlignment(AlignCenter).
+ \row \li \c Qt::endl \li Same as operator<<('\\n') and flush().
+ \row \li \c Qt::flush \li Same as flush().
+ \row \li \c Qt::reset \li Same as reset().
+ \row \li \c Qt::ws \li Same as skipWhiteSpace().
+ \row \li \c Qt::bom \li Same as setGenerateByteOrderMark(true).
\endtable
In addition, Qt provides three global manipulators that take a
@@ -326,7 +326,7 @@ QT_BEGIN_NAMESPACE
*/
QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr)
:
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
readConverterSavedState(0),
#endif
readConverterSavedStateOffset(0),
@@ -347,12 +347,12 @@ QTextStreamPrivate::~QTextStreamPrivate()
#endif
delete device;
}
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
delete readConverterSavedState;
#endif
}
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
static void resetCodecConverterStateHelper(QTextCodec::ConverterState *state)
{
state->~ConverterState();
@@ -401,7 +401,7 @@ void QTextStreamPrivate::reset()
readBufferStartDevicePos = 0;
lastTokenSize = 0;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
codec = QTextCodec::codecForLocale();
resetCodecConverterStateHelper(&readConverterState);
resetCodecConverterStateHelper(&writeConverterState);
@@ -461,7 +461,7 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes)
if (bytesRead <= 0)
return false;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
// codec auto detection, explicitly defaults to locale encoding if the
// codec has been set to 0.
if (!codec || autoDetectUnicode) {
@@ -485,7 +485,7 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes)
#endif
int oldReadBufferSize = readBuffer.size();
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
// convert to unicode
readBuffer += Q_LIKELY(codec) ? codec->toUnicode(buf, bytesRead, &readConverterState)
: QString::fromLatin1(buf, bytesRead);
@@ -567,7 +567,7 @@ void QTextStreamPrivate::flushWriteBuffer()
}
#endif
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (!codec)
codec = QTextCodec::codecForLocale();
#if defined (QTEXTSTREAM_DEBUG)
@@ -786,7 +786,7 @@ inline void QTextStreamPrivate::consume(int size)
*/
inline void QTextStreamPrivate::saveConverterState(qint64 newPos)
{
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (readConverterState.d) {
// converter cannot be copied, so don't save anything
// don't update readBufferStartDevicePos either
@@ -807,7 +807,7 @@ inline void QTextStreamPrivate::saveConverterState(qint64 newPos)
*/
inline void QTextStreamPrivate::restoreToSavedConverterState()
{
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (readConverterSavedState) {
// we have a saved state
// that means the converter can be copied
@@ -1202,7 +1202,7 @@ bool QTextStream::seek(qint64 pos)
return false;
d->resetReadBuffer();
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
// Reset the codec converter states.
resetCodecConverterStateHelper(&d->readConverterState);
resetCodecConverterStateHelper(&d->writeConverterState);
@@ -1253,7 +1253,7 @@ qint64 QTextStream::pos() const
QTextStreamPrivate *thatd = const_cast<QTextStreamPrivate *>(d);
thatd->readBuffer.clear();
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
thatd->restoreToSavedConverterState();
if (d->readBufferStartDevicePos == 0)
thatd->autoDetectUnicode = true;
@@ -1332,7 +1332,7 @@ void QTextStream::setDevice(QIODevice *device)
/*!
Returns the current device associated with the QTextStream,
- or 0 if no device has been assigned.
+ or \nullptr if no device has been assigned.
\sa setDevice(), string()
*/
@@ -1369,8 +1369,8 @@ void QTextStream::setString(QString *string, QIODevice::OpenMode openMode)
}
/*!
- Returns the current string assigned to the QTextStream, or 0 if no
- string has been assigned.
+ Returns the current string assigned to the QTextStream, or
+ \nullptr if no string has been assigned.
\sa setString(), device()
*/
@@ -2689,6 +2689,11 @@ QTextStream &QTextStream::operator<<(const void *ptr)
d->params.numberFlags = oldFlags;
return *this;
}
+#if defined(Q_QDOC) || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+namespace Qt {
+#else
+namespace QTextStreamFunctions {
+#endif
/*!
\relates QTextStream
@@ -3015,6 +3020,8 @@ QTextStream &ws(QTextStream &stream)
return stream;
}
+} // namespace QTextStreamFunctions
+
/*!
\fn QTextStreamManipulator qSetFieldWidth(int width)
\relates QTextStream
@@ -3036,7 +3043,13 @@ QTextStream &ws(QTextStream &stream)
Equivalent to QTextStream::setRealNumberPrecision(\a precision).
*/
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
+
+#if defined(Q_QDOC) || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+namespace Qt {
+#else
+namespace QTextStreamFunctions {
+#endif
/*!
\relates QTextStream
@@ -3051,6 +3064,8 @@ QTextStream &bom(QTextStream &stream)
return stream;
}
+} // namespace QTextStreamFunctions
+
/*!
Sets the codec for this stream to \a codec. The codec is used for
decoding any data that is read from the assigned device, and for
@@ -3111,15 +3126,15 @@ QTextCodec *QTextStream::codec() const
}
/*!
- If \a enabled is true, QTextStream will attempt to detect Unicode
- encoding by peeking into the stream data to see if it can find the
- UTF-16 or UTF-32 BOM (Byte Order Mark). If this mark is found, QTextStream
- will replace the current codec with the UTF codec.
+ If \a enabled is true, QTextStream will attempt to detect Unicode encoding
+ by peeking into the stream data to see if it can find the UTF-8, UTF-16, or
+ UTF-32 Byte Order Mark (BOM). If this mark is found, QTextStream will
+ replace the current codec with the UTF codec.
This function can be used together with setCodec(). It is common
to set the codec to UTF-8, and then enable UTF-16 detection.
- \sa autoDetectUnicode(), setCodec()
+ \sa autoDetectUnicode(), setCodec(), QTextCodec::codecForUtfText()
*/
void QTextStream::setAutoDetectUnicode(bool enabled)
{
@@ -3131,7 +3146,7 @@ void QTextStream::setAutoDetectUnicode(bool enabled)
Returns \c true if automatic Unicode detection is enabled, otherwise
returns \c false. Automatic Unicode detection is enabled by default.
- \sa setAutoDetectUnicode(), setCodec()
+ \sa setAutoDetectUnicode(), setCodec(), QTextCodec::codecForUtfText()
*/
bool QTextStream::autoDetectUnicode() const
{
@@ -3200,6 +3215,43 @@ QLocale QTextStream::locale() const
return d->locale;
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_QDOC)
+// Binary compatible definitions for Qt<5.14
+Q_CORE_EXPORT QTextStream &bin(QTextStream &s) { return Qt::bin(s); }
+Q_CORE_EXPORT QTextStream &oct(QTextStream &s) { return Qt::oct(s); }
+Q_CORE_EXPORT QTextStream &dec(QTextStream &s) { return Qt::dec(s); }
+Q_CORE_EXPORT QTextStream &hex(QTextStream &s) { return Qt::hex(s); }
+
+Q_CORE_EXPORT QTextStream &showbase(QTextStream &s) { return Qt::showbase(s); }
+Q_CORE_EXPORT QTextStream &forcesign(QTextStream &s) { return Qt::forcesign(s); }
+Q_CORE_EXPORT QTextStream &forcepoint(QTextStream &s) { return Qt::forcepoint(s); }
+Q_CORE_EXPORT QTextStream &noshowbase(QTextStream &s) { return Qt::noshowbase(s); }
+Q_CORE_EXPORT QTextStream &noforcesign(QTextStream &s) { return Qt::noforcesign(s); }
+Q_CORE_EXPORT QTextStream &noforcepoint(QTextStream &s) { return Qt::noforcepoint(s); }
+
+Q_CORE_EXPORT QTextStream &uppercasebase(QTextStream &s) { return Qt::uppercasebase(s); }
+Q_CORE_EXPORT QTextStream &uppercasedigits(QTextStream &s) { return Qt::uppercasedigits(s); }
+Q_CORE_EXPORT QTextStream &lowercasebase(QTextStream &s) { return Qt::lowercasebase(s); }
+Q_CORE_EXPORT QTextStream &lowercasedigits(QTextStream &s) { return Qt::lowercasedigits(s); }
+
+Q_CORE_EXPORT QTextStream &fixed(QTextStream &s) { return Qt::fixed(s); }
+Q_CORE_EXPORT QTextStream &scientific(QTextStream &s) { return Qt::scientific(s); }
+
+Q_CORE_EXPORT QTextStream &left(QTextStream &s) { return Qt::left(s); }
+Q_CORE_EXPORT QTextStream &right(QTextStream &s) { return Qt::right(s); }
+Q_CORE_EXPORT QTextStream &center(QTextStream &s) { return Qt::center(s); }
+
+Q_CORE_EXPORT QTextStream &endl(QTextStream &s) { return Qt::endl(s); }
+Q_CORE_EXPORT QTextStream &flush(QTextStream &s) { return Qt::flush(s); }
+Q_CORE_EXPORT QTextStream &reset(QTextStream &s) { return Qt::reset(s); }
+
+Q_CORE_EXPORT QTextStream &ws(QTextStream &s) { return Qt::ws(s); }
+
+#if QT_CONFIG(textcodec)
+Q_CORE_EXPORT QTextStream &bom(QTextStream &s) { return Qt::bom(s); }
+#endif
+#endif
+
QT_END_NAMESPACE
#ifndef QT_NO_QOBJECT
diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h
index ee90d01779..4efa84f1f1 100644
--- a/src/corelib/serialization/qtextstream.h
+++ b/src/corelib/serialization/qtextstream.h
@@ -98,7 +98,7 @@ public:
explicit QTextStream(const QByteArray &array, QIODevice::OpenMode openMode = QIODevice::ReadOnly);
virtual ~QTextStream();
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
void setCodec(QTextCodec *codec);
void setCodec(const char *codecName);
QTextCodec *codec() const;
@@ -213,8 +213,8 @@ typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument
class Q_CORE_EXPORT QTextStreamManipulator
{
public:
- Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFI m, int a) Q_DECL_NOTHROW : mf(m), mc(nullptr), arg(a), ch() {}
- Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFC m, QChar c) Q_DECL_NOTHROW : mf(nullptr), mc(m), arg(-1), ch(c) {}
+ Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFI m, int a) noexcept : mf(m), mc(nullptr), arg(a), ch() {}
+ Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFC m, QChar c) noexcept : mf(nullptr), mc(m), arg(-1), ch(c) {}
void exec(QTextStream &s) { if (mf) { (s.*mf)(arg); } else { (s.*mc)(ch); } }
private:
@@ -233,6 +233,13 @@ inline QTextStream &operator<<(QTextStream &s, QTextStreamFunction f)
inline QTextStream &operator<<(QTextStream &s, QTextStreamManipulator m)
{ m.exec(s); return s; }
+#if defined(Q_QDOC) || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+namespace Qt {
+#else
+// This namespace only exists for 'using namespace' declarations.
+namespace QTextStreamFunctions {
+#endif
+
Q_CORE_EXPORT QTextStream &bin(QTextStream &s);
Q_CORE_EXPORT QTextStream &oct(QTextStream &s);
Q_CORE_EXPORT QTextStream &dec(QTextStream &s);
@@ -265,6 +272,18 @@ Q_CORE_EXPORT QTextStream &bom(QTextStream &s);
Q_CORE_EXPORT QTextStream &ws(QTextStream &s);
+} // namespace QTextStreamFunctions
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_QDOC)
+namespace Qt {
+using namespace QTextStreamFunctions;
+}
+
+// We use 'using namespace' as that doesn't cause
+// conflicting definitions compiler errors.
+using namespace QTextStreamFunctions;
+#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_QDOC)
+
inline QTextStreamManipulator qSetFieldWidth(int width)
{
QTSMFI func = &QTextStream::setFieldWidth;
diff --git a/src/corelib/serialization/qtextstream_p.h b/src/corelib/serialization/qtextstream_p.h
index a642beddc4..172824d27d 100644
--- a/src/corelib/serialization/qtextstream_p.h
+++ b/src/corelib/serialization/qtextstream_p.h
@@ -54,7 +54,7 @@
#include <QtCore/private/qglobal_p.h>
#include "qtextstream.h"
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
#include "qtextcodec.h"
#endif
@@ -118,7 +118,7 @@ public:
int stringOffset;
QIODevice::OpenMode stringOpenMode;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
// codec
QTextCodec *codec;
QTextCodec::ConverterState readConverterState;
@@ -141,7 +141,7 @@ public:
int lastTokenSize;
bool deleteDevice;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
bool autoDetectUnicode;
#endif
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index 5002848d83..0170be7602 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -45,7 +45,9 @@
#include <qdebug.h>
#include <qfile.h>
#include <stdio.h>
+#if QT_CONFIG(textcodec)
#include <qtextcodec.h>
+#endif
#include <qstack.h>
#include <qbuffer.h>
#ifndef QT_BOOTSTRAPPED
@@ -221,7 +223,7 @@ QString QXmlStreamReaderPrivate::resolveUndeclaredEntity(const QString &name)
The stream reader does \e not take ownership of the resolver. It's
the callers responsibility to ensure that the resolver is valid
during the entire life-time of the stream reader object, or until
- another resolver or 0 is set.
+ another resolver or \nullptr is set.
\sa entityResolver()
*/
@@ -234,7 +236,7 @@ void QXmlStreamReader::setEntityResolver(QXmlStreamEntityResolver *resolver)
/*!
\since 4.4
- Returns the entity resolver, or 0 if there is no entity resolver.
+ Returns the entity resolver, or \nullptr if there is no entity resolver.
\sa setEntityResolver()
*/
@@ -420,7 +422,7 @@ QXmlStreamReader::QXmlStreamReader(const QString &data)
: d_ptr(new QXmlStreamReaderPrivate(this))
{
Q_D(QXmlStreamReader);
-#ifdef QT_NO_TEXTCODEC
+#if !QT_CONFIG(textcodec)
d->dataBuffer = data.toLatin1();
#else
d->dataBuffer = d->codec->fromUnicode(data);
@@ -478,7 +480,7 @@ void QXmlStreamReader::setDevice(QIODevice *device)
/*!
Returns the current device associated with the QXmlStreamReader,
- or 0 if no device has been assigned.
+ or \nullptr if no device has been assigned.
\sa setDevice()
*/
@@ -515,7 +517,7 @@ void QXmlStreamReader::addData(const QString &data)
{
Q_D(QXmlStreamReader);
d->lockEncoding = true;
-#ifdef QT_NO_TEXTCODEC
+#if !QT_CONFIG(textcodec)
addData(data.toLatin1());
#else
addData(d->codec->fromUnicode(data));
@@ -792,7 +794,7 @@ QXmlStreamReaderPrivate::QXmlStreamReaderPrivate(QXmlStreamReader *q)
{
device = 0;
deleteDevice = false;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
decoder = 0;
#endif
stack_size = 64;
@@ -838,7 +840,7 @@ void QXmlStreamReaderPrivate::init()
lineNumber = lastLineStart = characterOffset = 0;
readBufferPos = 0;
nbytesread = 0;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
codec = QTextCodec::codecForMib(106); // utf8
delete decoder;
decoder = 0;
@@ -903,7 +905,7 @@ inline void QXmlStreamReaderPrivate::reallocateStack()
QXmlStreamReaderPrivate::~QXmlStreamReaderPrivate()
{
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
delete decoder;
#endif
free(sym_stack);
@@ -1482,7 +1484,7 @@ uint QXmlStreamReaderPrivate::getChar_helper()
characterOffset += readBufferPos;
readBufferPos = 0;
readBuffer.resize(0);
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (decoder)
#endif
nbytesread = 0;
@@ -1503,7 +1505,7 @@ uint QXmlStreamReaderPrivate::getChar_helper()
return StreamEOF;
}
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (!decoder) {
if (nbytesread < 4) { // the 4 is to cover 0xef 0xbb 0xbf plus
// one extra for the utf8 codec
@@ -1545,7 +1547,7 @@ uint QXmlStreamReaderPrivate::getChar_helper()
}
#else
readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread);
-#endif // QT_NO_TEXTCODEC
+#endif // textcodec
readBuffer.reserve(1); // keep capacity when calling resize() next time
@@ -1816,7 +1818,7 @@ void QXmlStreamReaderPrivate::startDocument()
if (!QXmlUtils::isEncName(value))
err = QXmlStream::tr("%1 is an invalid encoding name.").arg(value);
else {
-#ifdef QT_NO_TEXTCODEC
+#if !QT_CONFIG(textcodec)
readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread);
#else
QTextCodec *const newCodec = QTextCodec::codecForName(value.toLatin1());
@@ -1828,7 +1830,7 @@ void QXmlStreamReaderPrivate::startDocument()
decoder = codec->makeDecoder();
decoder->toUnicode(&readBuffer, rawReadBuffer.data(), nbytesread);
}
-#endif // QT_NO_TEXTCODEC
+#endif // textcodec
}
} else if (prefix.isEmpty() && key == QLatin1String("standalone")) {
hasStandalone = true;
@@ -2966,7 +2968,7 @@ public:
~QXmlStreamWriterPrivate() {
if (deleteDevice)
delete device;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
delete encoder;
#endif
}
@@ -2993,7 +2995,7 @@ public:
NamespaceDeclaration emptyNamespace;
int lastNamespaceDeclaration;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
QTextCodec *codec;
QTextEncoder *encoder;
#endif
@@ -3015,7 +3017,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q)
device = 0;
stringDevice = 0;
deleteDevice = false;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
codec = QTextCodec::codecForMib(106); // utf8
encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8
#endif
@@ -3032,7 +3034,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q)
void QXmlStreamWriterPrivate::checkIfASCIICompatibleCodec()
{
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
Q_ASSERT(encoder);
// test ASCII-compatibility using the letter 'a'
QChar letterA = QLatin1Char('a');
@@ -3052,7 +3054,7 @@ void QXmlStreamWriterPrivate::write(const QStringRef &s)
if (device) {
if (hasIoError)
return;
-#ifdef QT_NO_TEXTCODEC
+#if !QT_CONFIG(textcodec)
QByteArray bytes = s.toLatin1();
#else
QByteArray bytes = encoder->fromUnicode(s.constData(), s.size());
@@ -3075,7 +3077,7 @@ void QXmlStreamWriterPrivate::write(const QString &s)
if (device) {
if (hasIoError)
return;
-#ifdef QT_NO_TEXTCODEC
+#if !QT_CONFIG(textcodec)
QByteArray bytes = s.toLatin1();
#else
QByteArray bytes = encoder->fromUnicode(s);
@@ -3313,7 +3315,7 @@ void QXmlStreamWriter::setDevice(QIODevice *device)
/*!
Returns the current device associated with the QXmlStreamWriter,
- or 0 if no device has been assigned.
+ or \nullptr if no device has been assigned.
\sa setDevice()
*/
@@ -3324,7 +3326,7 @@ QIODevice *QXmlStreamWriter::device() const
}
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
/*!
Sets the codec for this stream to \a codec. The codec is used for
encoding any data that is written. By default, QXmlStreamWriter
@@ -3382,7 +3384,7 @@ QTextCodec *QXmlStreamWriter::codec() const
Q_D(const QXmlStreamWriter);
return d->codec;
}
-#endif // QT_NO_TEXTCODEC
+#endif // textcodec
/*!
\property QXmlStreamWriter::autoFormatting
@@ -3847,7 +3849,7 @@ void QXmlStreamWriter::writeStartDocument(const QString &version)
d->write(version);
if (d->device) { // stringDevice does not get any encoding
d->write("\" encoding=\"");
-#ifdef QT_NO_TEXTCODEC
+#if !QT_CONFIG(textcodec)
d->write("iso-8859-1");
#else
const QByteArray name = d->codec->name();
@@ -3871,7 +3873,7 @@ void QXmlStreamWriter::writeStartDocument(const QString &version, bool standalon
d->write(version);
if (d->device) { // stringDevice does not get any encoding
d->write("\" encoding=\"");
-#ifdef QT_NO_TEXTCODEC
+#if !QT_CONFIG(textcodec)
d->write("iso-8859-1");
#else
const QByteArray name = d->codec->name();
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
index fd69a6e4af..e6328a11ac 100644
--- a/src/corelib/serialization/qxmlstream.g
+++ b/src/corelib/serialization/qxmlstream.g
@@ -41,6 +41,8 @@
%merged_output qxmlstream_p.h
+%expect 4
+
%token NOTOKEN
%token SPACE " "
%token LANGLE "<"
@@ -144,7 +146,12 @@
%start document
+
+
/.
+
+#include <QtCore/private/qglobal_p.h>
+
template <typename T> class QXmlStreamSimpleStack {
T *data;
int tos, cap;
@@ -155,7 +162,8 @@ public:
inline void reserve(int extraCapacity) {
if (tos + extraCapacity + 1 > cap) {
cap = qMax(tos + extraCapacity + 1, cap << 1 );
- data = reinterpret_cast<T *>(realloc(data, cap * sizeof(T)));
+ void *ptr = realloc(static_cast<void *>(data), cap * sizeof(T));
+ data = reinterpret_cast<T *>(ptr);
Q_CHECK_PTR(data);
}
}
@@ -291,7 +299,7 @@ public:
QIODevice *device;
bool deleteDevice;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
QTextCodec *codec;
QTextDecoder *decoder;
#endif
@@ -584,7 +592,7 @@ bool QXmlStreamReaderPrivate::parse()
lockEncoding = true;
documentVersion.clear();
documentEncoding.clear();
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (decoder && decoder->hasFailure()) {
raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
readBuffer.clear();
@@ -753,7 +761,7 @@ bool QXmlStreamReaderPrivate::parse()
state_stack[tos] = 0;
return true;
} else if (act > 0) {
- if (++tos == stack_size-1)
+ if (++tos >= stack_size-1)
reallocateStack();
Value &val = sym_stack[tos];
@@ -890,7 +898,7 @@ doctype_decl ::= langle_bang DOCTYPE qname markup space_opt RANGLE;
/.
case $rule_number:
dtdName = symString(3);
- // fall through
+ Q_FALLTHROUGH();
./
doctype_decl ::= doctype_decl_start external_id space_opt markup space_opt RANGLE;
/.
diff --git a/src/corelib/serialization/qxmlstream.h b/src/corelib/serialization/qxmlstream.h
index 2350d12dd6..55dcc4e4e8 100644
--- a/src/corelib/serialization/qxmlstream.h
+++ b/src/corelib/serialization/qxmlstream.h
@@ -59,19 +59,15 @@ public:
inline QXmlStreamStringRef(const QStringRef &aString)
:m_string(aString.string()?*aString.string():QString()), m_position(aString.position()), m_size(aString.size()){}
QXmlStreamStringRef(const QString &aString) : m_string(aString), m_position(0), m_size(m_string.size()) {}
-#ifdef Q_COMPILER_RVALUE_REFS
- QXmlStreamStringRef(QString &&aString) Q_DECL_NOTHROW : m_string(std::move(aString)), m_position(0), m_size(m_string.size()) {}
-#endif
+ QXmlStreamStringRef(QString &&aString) noexcept : m_string(std::move(aString)), m_position(0), m_size(m_string.size()) {}
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
QXmlStreamStringRef(const QXmlStreamStringRef &other) // = default
: m_string(other.m_string), m_position(other.m_position), m_size(other.m_size) {}
-#ifdef Q_COMPILER_RVALUE_REFS
- QXmlStreamStringRef(QXmlStreamStringRef &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamStringRef(QXmlStreamStringRef &&other) noexcept // = default
: m_string(std::move(other.m_string)), m_position(other.m_position), m_size(other.m_size) {}
- QXmlStreamStringRef &operator=(QXmlStreamStringRef &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamStringRef &operator=(QXmlStreamStringRef &&other) noexcept // = default
{ swap(other); return *this; }
-#endif
QXmlStreamStringRef &operator=(const QXmlStreamStringRef &other) // = default
{ m_string = other.m_string; m_position = other.m_position; m_size = other.m_size; return *this; }
inline ~QXmlStreamStringRef() {} // ### this prevents (or deprecates) all the move/copy special member functions,
@@ -79,7 +75,7 @@ public:
// ### Qt 5, since that would change the way its passed to functions. In Qt 6, remove all.
#endif // Qt < 6.0
- void swap(QXmlStreamStringRef &other) Q_DECL_NOTHROW
+ void swap(QXmlStreamStringRef &other) noexcept
{
qSwap(m_string, other.m_string);
qSwap(m_position, other.m_position);
@@ -111,8 +107,7 @@ public:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value);
QXmlStreamAttribute(const QXmlStreamAttribute &);
-#ifdef Q_COMPILER_RVALUE_REFS
- QXmlStreamAttribute(QXmlStreamAttribute &&other) Q_DECL_NOTHROW // = default;
+ QXmlStreamAttribute(QXmlStreamAttribute &&other) noexcept // = default;
: m_name(std::move(other.m_name)),
m_namespaceUri(std::move(other.m_namespaceUri)),
m_qualifiedName(std::move(other.m_qualifiedName)),
@@ -122,7 +117,7 @@ public:
{
other.reserved = nullptr;
}
- QXmlStreamAttribute &operator=(QXmlStreamAttribute &&other) Q_DECL_NOTHROW // = default;
+ QXmlStreamAttribute &operator=(QXmlStreamAttribute &&other) noexcept // = default;
{
m_name = std::move(other.m_name);
m_namespaceUri = std::move(other.m_namespaceUri);
@@ -132,7 +127,6 @@ public:
m_isDefault = other.m_isDefault;
return *this;
}
-#endif
QXmlStreamAttribute& operator=(const QXmlStreamAttribute &);
~QXmlStreamAttribute();
#endif // < Qt 6
@@ -199,14 +193,14 @@ public:
QXmlStreamNamespaceDeclaration();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QXmlStreamNamespaceDeclaration(const QXmlStreamNamespaceDeclaration &);
- QXmlStreamNamespaceDeclaration(QXmlStreamNamespaceDeclaration &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamNamespaceDeclaration(QXmlStreamNamespaceDeclaration &&other) noexcept // = default
: m_prefix(std::move(other.m_prefix)),
m_namespaceUri(std::move(other.m_namespaceUri)),
reserved(other.reserved)
{
other.reserved = nullptr;
}
- QXmlStreamNamespaceDeclaration &operator=(QXmlStreamNamespaceDeclaration &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamNamespaceDeclaration &operator=(QXmlStreamNamespaceDeclaration &&other) noexcept // = default
{
m_prefix = std::move(other.m_prefix);
m_namespaceUri = std::move(other.m_namespaceUri);
@@ -242,7 +236,7 @@ public:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
~QXmlStreamNotationDeclaration();
QXmlStreamNotationDeclaration(const QXmlStreamNotationDeclaration &);
- QXmlStreamNotationDeclaration(QXmlStreamNotationDeclaration &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamNotationDeclaration(QXmlStreamNotationDeclaration &&other) noexcept // = default
: m_name(std::move(other.m_name)),
m_systemId(std::move(other.m_systemId)),
m_publicId(std::move(other.m_publicId)),
@@ -251,7 +245,7 @@ public:
other.reserved = nullptr;
}
QXmlStreamNotationDeclaration& operator=(const QXmlStreamNotationDeclaration &);
- QXmlStreamNotationDeclaration &operator=(QXmlStreamNotationDeclaration &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamNotationDeclaration &operator=(QXmlStreamNotationDeclaration &&other) noexcept // = default
{
m_name = std::move(other.m_name);
m_systemId = std::move(other.m_systemId);
@@ -287,7 +281,7 @@ public:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
~QXmlStreamEntityDeclaration();
QXmlStreamEntityDeclaration(const QXmlStreamEntityDeclaration &);
- QXmlStreamEntityDeclaration(QXmlStreamEntityDeclaration &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamEntityDeclaration(QXmlStreamEntityDeclaration &&other) noexcept // = default
: m_name(std::move(other.m_name)),
m_notationName(std::move(other.m_notationName)),
m_systemId(std::move(other.m_systemId)),
@@ -298,7 +292,7 @@ public:
other.reserved = nullptr;
}
QXmlStreamEntityDeclaration& operator=(const QXmlStreamEntityDeclaration &);
- QXmlStreamEntityDeclaration &operator=(QXmlStreamEntityDeclaration &&other) Q_DECL_NOTHROW // = default
+ QXmlStreamEntityDeclaration &operator=(QXmlStreamEntityDeclaration &&other) noexcept // = default
{
m_name = std::move(other.m_name);
m_notationName = std::move(other.m_notationName);
@@ -478,7 +472,7 @@ public:
void setDevice(QIODevice *device);
QIODevice *device() const;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
void setCodec(QTextCodec *codec);
void setCodec(const char *codecName);
QTextCodec *codec() const;
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index f8b1ede943..cde66a48a3 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -162,12 +162,12 @@ public:
const char *const QXmlStreamReader_Table::spell [] = {
- "end of file", 0, " ", "<", ">", "&", "#", "\'", "\"", "[",
+ "end of file", nullptr, " ", "<", ">", "&", "#", "\'", "\"", "[",
"]", "(", ")", "|", "=", "%", "/", ":", ";", ",",
"-", "+", "*", ".", "?", "!", "[a-zA-Z]", "[0-9]", "[CDATA[", "DOCTYPE",
"ELEMENT", "ATTLIST", "ENTITY", "NOTATION", "SYSTEM", "PUBLIC", "NDATA", "REQUIRED", "IMPLIED", "FIXED",
- "EMPTY", "ANY", "PCDATA", 0, 0, 0, 0, "CDATA", "ID", "IDREF",
- "IDREFS", "ENTITIES", "NMTOKEN", "NMTOKENS", "<?xml", "version", 0};
+ "EMPTY", "ANY", "PCDATA", nullptr, nullptr, nullptr, nullptr, "CDATA", "ID", "IDREF",
+ "IDREFS", "ENTITIES", "NMTOKEN", "NMTOKENS", "<?xml", "version", nullptr};
const short QXmlStreamReader_Table::lhs [] = {
57, 57, 59, 59, 59, 59, 59, 59, 59, 59,
@@ -645,7 +645,7 @@ template <typename T> class QXmlStreamSimpleStack {
T *data;
int tos, cap;
public:
- inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
+ inline QXmlStreamSimpleStack():data(nullptr), tos(-1), cap(0){}
inline ~QXmlStreamSimpleStack(){ if (data) free(data); }
inline void reserve(int extraCapacity) {
@@ -788,7 +788,7 @@ public:
QIODevice *device;
bool deleteDevice;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
QTextCodec *codec;
QTextDecoder *decoder;
#endif
@@ -995,7 +995,7 @@ public:
int fastScanLiteralContent();
int fastScanSpace();
int fastScanContentCharList();
- int fastScanName(int *prefix = 0);
+ int fastScanName(int *prefix = nullptr);
inline int fastScanNMTOKEN();
@@ -1081,7 +1081,7 @@ bool QXmlStreamReaderPrivate::parse()
lockEncoding = true;
documentVersion.clear();
documentEncoding.clear();
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (decoder && decoder->hasFailure()) {
raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
readBuffer.clear();