summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/serialization')
-rw-r--r--src/corelib/serialization/qbinaryjson.cpp81
-rw-r--r--src/corelib/serialization/qbinaryjson_p.h102
-rw-r--r--src/corelib/serialization/qbinaryjsonarray.cpp12
-rw-r--r--src/corelib/serialization/qbinaryjsonobject.cpp14
-rw-r--r--src/corelib/serialization/qbinaryjsonvalue.cpp2
-rw-r--r--src/corelib/serialization/qxmlstream.cpp2
-rw-r--r--src/corelib/serialization/qxmlstream.g2
-rw-r--r--src/corelib/serialization/qxmlstream_p.h2
8 files changed, 126 insertions, 91 deletions
diff --git a/src/corelib/serialization/qbinaryjson.cpp b/src/corelib/serialization/qbinaryjson.cpp
index 3d359f0998..8c16178c59 100644
--- a/src/corelib/serialization/qbinaryjson.cpp
+++ b/src/corelib/serialization/qbinaryjson.cpp
@@ -64,17 +64,17 @@ void MutableData::compact()
Base *base = header->root();
int reserve = 0;
- if (base->is_object) {
+ if (base->isObject()) {
auto *o = static_cast<Object *>(base);
- for (uint i = 0; i < o->length; ++i)
+ for (uint i = 0; i < o->length(); ++i)
reserve += o->entryAt(i)->usedStorage(o);
} else {
auto *a = static_cast<Array *>(base);
- for (uint i = 0; i < a->length; ++i)
+ for (uint i = 0; i < a->length(); ++i)
reserve += a->at(i)->usedStorage(a);
}
- uint size = sizeof(Base) + reserve + base->length * sizeof(offset);
+ uint size = sizeof(Base) + reserve + base->length() * sizeof(offset);
uint alloc = sizeof(Header) + size;
auto *h = reinterpret_cast<Header *>(malloc(alloc));
Q_CHECK_PTR(h);
@@ -82,16 +82,19 @@ void MutableData::compact()
h->version = 1;
Base *b = h->root();
b->size = size;
- b->is_object = header->root()->is_object;
- b->length = base->length;
+ if (header->root()->isObject())
+ b->setIsObject();
+ else
+ b->setIsArray();
+ b->setLength(base->length());
b->tableOffset = reserve + sizeof(Array);
uint offset = sizeof(Base);
- if (b->is_object) {
+ if (b->isObject()) {
const auto *o = static_cast<const Object *>(base);
auto *no = static_cast<Object *>(b);
- for (uint i = 0; i < o->length; ++i) {
+ for (uint i = 0; i < o->length(); ++i) {
no->table()[i] = offset;
const Entry *e = o->entryAt(i);
@@ -102,7 +105,7 @@ void MutableData::compact()
uint dataSize = e->value.usedStorage(o);
if (dataSize) {
memcpy(reinterpret_cast<char *>(no) + offset, e->value.data(o), dataSize);
- ne->value.value = offset;
+ ne->value.setValue(offset);
offset += dataSize;
}
}
@@ -110,14 +113,14 @@ void MutableData::compact()
const auto *a = static_cast<const Array *>(base);
auto *na = static_cast<Array *>(b);
- for (uint i = 0; i < a->length; ++i) {
+ for (uint i = 0; i < a->length(); ++i) {
const Value *v = a->at(i);
Value *nv = na->at(i);
*nv = *v;
uint dataSize = v->usedStorage(a);
if (dataSize) {
memcpy(reinterpret_cast<char *>(na) + offset, v->data(a), dataSize);
- nv->value = offset;
+ nv->setValue(offset);
offset += dataSize;
}
}
@@ -137,7 +140,7 @@ bool ConstData::isValid() const
const Base *root = header->root();
const uint maxSize = alloc - sizeof(Header);
- return root->is_object
+ return root->isObject()
? static_cast<const Object *>(root)->isValid(maxSize)
: static_cast<const Array *>(root)->isValid(maxSize);
}
@@ -145,14 +148,14 @@ bool ConstData::isValid() const
QJsonDocument ConstData::toJsonDocument() const
{
const Base *root = header->root();
- return root->is_object
+ return root->isObject()
? QJsonDocument(static_cast<const Object *>(root)->toJsonObject())
: QJsonDocument(static_cast<const Array *>(root)->toJsonArray());
}
uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool replace)
{
- Q_ASSERT(posInTable <= length);
+ Q_ASSERT(posInTable <= length());
if (size + dataSize >= Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure %d %d %d",
uint(size), dataSize, Value::MaxSize);
@@ -162,10 +165,10 @@ uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool repl
offset off = tableOffset;
// move table to new position
if (replace) {
- memmove(reinterpret_cast<char *>(table()) + dataSize, table(), length * sizeof(offset));
+ memmove(reinterpret_cast<char *>(table()) + dataSize, table(), length() * sizeof(offset));
} else {
memmove(reinterpret_cast<char *>(table() + posInTable + numItems) + dataSize,
- table() + posInTable, (length - posInTable) * sizeof(offset));
+ table() + posInTable, (length() - posInTable) * sizeof(offset));
memmove(reinterpret_cast<char *>(table()) + dataSize, table(), posInTable * sizeof(offset));
}
tableOffset += dataSize;
@@ -173,7 +176,7 @@ uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool repl
table()[posInTable + i] = off;
size += dataSize;
if (!replace) {
- length += numItems;
+ setLength(length() + numItems);
size += numItems * sizeof(offset);
}
return off;
@@ -182,7 +185,7 @@ uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool repl
uint Object::indexOf(QStringView key, bool *exists) const
{
uint min = 0;
- uint n = length;
+ uint n = length();
while (n > 0) {
uint half = n >> 1;
uint middle = min + half;
@@ -193,7 +196,7 @@ uint Object::indexOf(QStringView key, bool *exists) const
n -= half + 1;
}
}
- if (min < length && *entryAt(min) == key) {
+ if (min < length() && *entryAt(min) == key) {
*exists = true;
return min;
}
@@ -204,7 +207,7 @@ uint Object::indexOf(QStringView key, bool *exists) const
QJsonObject Object::toJsonObject() const
{
QJsonObject object;
- for (uint i = 0; i < length; ++i) {
+ for (uint i = 0; i < length(); ++i) {
const Entry *e = entryAt(i);
object.insert(e->key(), e->value.toJsonValue(this));
}
@@ -213,11 +216,11 @@ QJsonObject Object::toJsonObject() const
bool Object::isValid(uint maxSize) const
{
- if (size > maxSize || tableOffset + length * sizeof(offset) > size)
+ if (size > maxSize || tableOffset + length() * sizeof(offset) > size)
return false;
QString lastKey;
- for (uint i = 0; i < length; ++i) {
+ for (uint i = 0; i < length(); ++i) {
if (table()[i] + sizeof(Entry) >= tableOffset)
return false;
const Entry *e = entryAt(i);
@@ -237,18 +240,18 @@ QJsonArray Array::toJsonArray() const
{
QJsonArray array;
const offset *values = table();
- for (uint i = 0; i < length; ++i)
+ for (uint i = 0; i < length(); ++i)
array.append(reinterpret_cast<const Value *>(values + i)->toJsonValue(this));
return array;
}
bool Array::isValid(uint maxSize) const
{
- if (size > maxSize || tableOffset + length * sizeof(offset) > size)
+ if (size > maxSize || tableOffset + length() * sizeof(offset) > size)
return false;
const offset *values = table();
- for (uint i = 0; i < length; ++i) {
+ for (uint i = 0; i < length(); ++i) {
if (!reinterpret_cast<const Value *>(values + i)->isValid(this))
return false;
}
@@ -258,14 +261,14 @@ bool Array::isValid(uint maxSize) const
uint Value::usedStorage(const Base *b) const
{
uint s = 0;
- switch (type) {
+ switch (type()) {
case QJsonValue::Double:
- if (!latinOrIntValue)
+ if (!isLatinOrIntValue())
s = sizeof(double);
break;
case QJsonValue::String: {
const char *d = data(b);
- s = latinOrIntValue
+ s = isLatinOrIntValue()
? (sizeof(ushort)
+ qFromLittleEndian(*reinterpret_cast<const ushort *>(d)))
: (sizeof(int)
@@ -286,7 +289,7 @@ uint Value::usedStorage(const Base *b) const
QJsonValue Value::toJsonValue(const Base *b) const
{
- switch (type) {
+ switch (type()) {
case QJsonValue::Null:
return QJsonValue(QJsonValue::Null);
case QJsonValue::Bool:
@@ -314,24 +317,24 @@ inline bool isValidValueOffset(uint offset, uint tableOffset)
bool Value::isValid(const Base *b) const
{
- switch (type) {
+ switch (type()) {
case QJsonValue::Null:
case QJsonValue::Bool:
return true;
case QJsonValue::Double:
- return latinOrIntValue || isValidValueOffset(value, b->tableOffset);
+ return isLatinOrIntValue() || isValidValueOffset(value(), b->tableOffset);
case QJsonValue::String:
- if (!isValidValueOffset(value, b->tableOffset))
+ if (!isValidValueOffset(value(), b->tableOffset))
return false;
- if (latinOrIntValue)
- return asLatin1String(b).isValid(b->tableOffset - value);
- return asString(b).isValid(b->tableOffset - value);
+ if (isLatinOrIntValue())
+ return asLatin1String(b).isValid(b->tableOffset - value());
+ return asString(b).isValid(b->tableOffset - value());
case QJsonValue::Array:
- return isValidValueOffset(value, b->tableOffset)
- && static_cast<const Array *>(base(b))->isValid(b->tableOffset - value);
+ return isValidValueOffset(value(), b->tableOffset)
+ && static_cast<const Array *>(base(b))->isValid(b->tableOffset - value());
case QJsonValue::Object:
- return isValidValueOffset(value, b->tableOffset)
- && static_cast<const Object *>(base(b))->isValid(b->tableOffset - value);
+ return isValidValueOffset(value(), b->tableOffset)
+ && static_cast<const Object *>(base(b))->isValid(b->tableOffset - value());
default:
return false;
}
diff --git a/src/corelib/serialization/qbinaryjson_p.h b/src/corelib/serialization/qbinaryjson_p.h
index 132c36f227..6502f1fbd2 100644
--- a/src/corelib/serialization/qbinaryjson_p.h
+++ b/src/corelib/serialization/qbinaryjson_p.h
@@ -136,11 +136,15 @@ using qle_ushort = q_littleendian<unsigned short>;
using qle_int = q_littleendian<int>;
using qle_uint = q_littleendian<unsigned int>;
-template<int pos, int width>
-using qle_bitfield = QLEIntegerBitfield<uint, pos, width>;
+template<typename... Accessors>
+using qle_bitfield = QLEIntegerBitfieldUnion<uint, Accessors...>;
template<int pos, int width>
-using qle_signedbitfield = QLEIntegerBitfield<int, pos, width>;
+using qle_bitfield_accessor
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width>;
+template<int pos, int width>
+using qle_signedbitfield_accessor
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width, int>;
using offset = qle_uint;
@@ -316,19 +320,24 @@ static inline void copyString(char *dest, QStringView str, bool compress)
*/
class Base
{
+private:
+ using IsObjectAccessor = qle_bitfield_accessor<0, 1>;
+ using LengthAccessor = qle_bitfield_accessor<1, 31>;
public:
qle_uint size;
- union {
- uint _dummy;
- qle_bitfield<0, 1> is_object;
- qle_bitfield<1, 31> length;
- };
+ qle_bitfield<IsObjectAccessor, LengthAccessor> isObjectAndLength;
offset tableOffset;
// content follows here
- bool isObject() const { return !!is_object; }
+ void setIsObject() { isObjectAndLength.set<IsObjectAccessor>(1); }
+ bool isObject() const { return !!isObjectAndLength.get<IsObjectAccessor>(); }
+
+ void setIsArray() { isObjectAndLength.set<IsObjectAccessor>(0); }
bool isArray() const { return !isObject(); }
+ void setLength(uint length) { isObjectAndLength.set<LengthAccessor>(length); }
+ uint length() const { return isObjectAndLength.get<LengthAccessor>(); }
+
offset *table()
{
return reinterpret_cast<offset *>(reinterpret_cast<char *>(this) + tableOffset);
@@ -372,39 +381,46 @@ public:
class Value
{
+private:
+ using TypeAccessor = qle_bitfield_accessor<0, 3>;
+ using LatinOrIntValueAccessor = qle_bitfield_accessor<3, 1>;
+ using LatinKeyAccessor = qle_bitfield_accessor<4, 1>;
+ using ValueAccessor = qle_bitfield_accessor<5, 27>;
+ using IntValueAccessor = qle_signedbitfield_accessor<5, 27>;
+ qle_bitfield<
+ TypeAccessor,
+ LatinOrIntValueAccessor,
+ LatinKeyAccessor,
+ ValueAccessor,
+ IntValueAccessor
+ > m_data;
+ int intValue() const { return m_data.get<IntValueAccessor>(); }
+
public:
enum {
MaxSize = (1 << 27) - 1
};
- union {
- uint _dummy;
- qle_bitfield<0, 3> type;
- qle_bitfield<3, 1> latinOrIntValue;
- qle_bitfield<4, 1> latinKey;
- qle_bitfield<5, 27> value;
- qle_signedbitfield<5, 27> int_value;
- };
inline const char *data(const Base *b) const
{
- return reinterpret_cast<const char *>(b) + value;
+ return reinterpret_cast<const char *>(b) + value();
}
uint usedStorage(const Base *b) const;
bool toBoolean() const
{
- Q_ASSERT(type == QJsonValue::Bool);
- return value != 0;
+ Q_ASSERT(type() == QJsonValue::Bool);
+ return value() != 0;
}
double toDouble(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::Double);
- if (latinOrIntValue)
- return int_value;
+ Q_ASSERT(type() == QJsonValue::Double);
+ if (isLatinOrIntValue())
+ return intValue();
- auto i = qFromLittleEndian<quint64>(reinterpret_cast<const uchar *>(b) + value);
+ auto i = qFromLittleEndian<quint64>(reinterpret_cast<const uchar *>(b) + value());
double d;
memcpy(&d, &i, sizeof(double));
return d;
@@ -412,26 +428,26 @@ public:
QString toString(const Base *b) const
{
- return latinOrIntValue
+ return isLatinOrIntValue()
? asLatin1String(b).toString()
: asString(b).toString();
}
String asString(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::String && !latinOrIntValue);
+ Q_ASSERT(type() == QJsonValue::String && !isLatinOrIntValue());
return String(data(b));
}
Latin1String asLatin1String(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::String && latinOrIntValue);
+ Q_ASSERT(type() == QJsonValue::String && isLatinOrIntValue());
return Latin1String(data(b));
}
const Base *base(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::Array || type == QJsonValue::Object);
+ Q_ASSERT(type() == QJsonValue::Array || type() == QJsonValue::Object);
return reinterpret_cast<const Base *>(data(b));
}
@@ -441,6 +457,15 @@ public:
static uint requiredStorage(const QBinaryJsonValue &v, bool *compressed);
static uint valueToStore(const QBinaryJsonValue &v, uint offset);
static void copyData(const QBinaryJsonValue &v, char *dest, bool compressed);
+
+ void setIsLatinKey(bool isLatinKey) { m_data.set<LatinKeyAccessor>(isLatinKey); }
+ bool isLatinKey() const { return m_data.get<LatinKeyAccessor>(); }
+ void setIsLatinOrIntValue(bool v) { m_data.set<LatinOrIntValueAccessor>(v); }
+ bool isLatinOrIntValue() const { return m_data.get<LatinOrIntValueAccessor>(); }
+ void setType(uint type) { m_data.set<TypeAccessor>(type); }
+ uint type() const { return m_data.get<TypeAccessor>(); }
+ void setValue(uint value) { m_data.set<ValueAccessor>(value); }
+ uint value() const { return m_data.get<ValueAccessor>(); }
};
class Entry {
@@ -452,7 +477,7 @@ public:
uint size() const
{
uint s = sizeof(Entry);
- if (value.latinKey)
+ if (value.isLatinKey())
s += shallowLatin1Key().byteSize();
else
s += shallowKey().byteSize();
@@ -466,19 +491,19 @@ public:
String shallowKey() const
{
- Q_ASSERT(!value.latinKey);
+ Q_ASSERT(!value.isLatinKey());
return String(reinterpret_cast<const char *>(this) + sizeof(Entry));
}
Latin1String shallowLatin1Key() const
{
- Q_ASSERT(value.latinKey);
+ Q_ASSERT(value.isLatinKey());
return Latin1String(reinterpret_cast<const char *>(this) + sizeof(Entry));
}
QString key() const
{
- return value.latinKey
+ return value.isLatinKey()
? shallowLatin1Key().toString()
: shallowKey().toString();
}
@@ -488,21 +513,21 @@ public:
if (maxSize < sizeof(Entry))
return false;
maxSize -= sizeof(Entry);
- return value.latinKey
+ return value.isLatinKey()
? shallowLatin1Key().isValid(maxSize)
: shallowKey().isValid(maxSize);
}
bool operator ==(QStringView key) const
{
- return value.latinKey
+ return value.isLatinKey()
? (shallowLatin1Key().toQLatin1String() == key)
: (shallowKey() == key);
}
bool operator >=(QStringView key) const
{
- return value.latinKey
+ return value.isLatinKey()
? (shallowLatin1Key().toQLatin1String() >= key)
: (shallowKey().toString() >= key);
}
@@ -560,9 +585,12 @@ public:
header->version = 1;
Base *b = header->root();
b->size = sizeof(Base);
- b->is_object = (valueType == QJsonValue::Object);
+ if (valueType == QJsonValue::Object)
+ b->setIsObject();
+ else
+ b->setIsArray();
b->tableOffset = sizeof(Base);
- b->length = 0;
+ b->setLength(0);
}
~MutableData()
diff --git a/src/corelib/serialization/qbinaryjsonarray.cpp b/src/corelib/serialization/qbinaryjsonarray.cpp
index 68937fe17d..dfbe94db84 100644
--- a/src/corelib/serialization/qbinaryjsonarray.cpp
+++ b/src/corelib/serialization/qbinaryjsonarray.cpp
@@ -63,7 +63,7 @@ QBinaryJsonArray QBinaryJsonArray::fromJsonArray(const QJsonArray &array)
void QBinaryJsonArray::append(const QBinaryJsonValue &value)
{
- const uint i = a ? a->length : 0;
+ const uint i = a ? a->length() : 0;
bool compressed;
uint valueSize = QBinaryJsonPrivate::Value::requiredStorage(value, &compressed);
@@ -71,7 +71,7 @@ void QBinaryJsonArray::append(const QBinaryJsonValue &value)
if (!detach(valueSize + sizeof(QBinaryJsonPrivate::Value)))
return;
- if (!a->length)
+ if (!a->length())
a->tableOffset = sizeof(QBinaryJsonPrivate::Array);
uint valueOffset = a->reserveSpace(valueSize, i, 1, false);
@@ -79,10 +79,10 @@ void QBinaryJsonArray::append(const QBinaryJsonValue &value)
return;
QBinaryJsonPrivate::Value *v = a->at(i);
- v->type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
- v->latinOrIntValue = compressed;
- v->latinKey = false;
- v->value = QBinaryJsonPrivate::Value::valueToStore(value, valueOffset);
+ v->setType(value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
+ v->setIsLatinOrIntValue(compressed);
+ v->setIsLatinKey(false);
+ v->setValue(QBinaryJsonPrivate::Value::valueToStore(value, valueOffset));
if (valueSize) {
QBinaryJsonPrivate::Value::copyData(value, reinterpret_cast<char *>(a) + valueOffset,
compressed);
diff --git a/src/corelib/serialization/qbinaryjsonobject.cpp b/src/corelib/serialization/qbinaryjsonobject.cpp
index 3186ab6087..a9e830228e 100644
--- a/src/corelib/serialization/qbinaryjsonobject.cpp
+++ b/src/corelib/serialization/qbinaryjsonobject.cpp
@@ -74,7 +74,7 @@ void QBinaryJsonObject::insert(const QString &key, const QBinaryJsonValue &value
if (!detach(requiredSize + sizeof(QBinaryJsonPrivate::offset))) // offset for the new index entry
return;
- if (!o->length)
+ if (!o->length())
o->tableOffset = sizeof(QBinaryJsonPrivate::Object);
bool keyExists = false;
@@ -87,18 +87,18 @@ void QBinaryJsonObject::insert(const QString &key, const QBinaryJsonValue &value
return;
QBinaryJsonPrivate::Entry *e = o->entryAt(pos);
- e->value.type = value.t;
- e->value.latinKey = latinKey;
- e->value.latinOrIntValue = latinOrIntValue;
- e->value.value = QBinaryJsonPrivate::Value::valueToStore(
- value, reinterpret_cast<char *>(e) - reinterpret_cast<char *>(o) + valueOffset);
+ e->value.setType(value.t);
+ e->value.setIsLatinKey(latinKey);
+ e->value.setIsLatinOrIntValue(latinOrIntValue);
+ e->value.setValue(QBinaryJsonPrivate::Value::valueToStore(
+ value, reinterpret_cast<char *>(e) - reinterpret_cast<char *>(o) + valueOffset));
QBinaryJsonPrivate::copyString(reinterpret_cast<char *>(e + 1), key, latinKey);
if (valueSize) {
QBinaryJsonPrivate::Value::copyData(value, reinterpret_cast<char *>(e) + valueOffset,
latinOrIntValue);
}
- if (d->compactionCounter > 32U && d->compactionCounter >= unsigned(o->length) / 2U)
+ if (d->compactionCounter > 32U && d->compactionCounter >= unsigned(o->length()) / 2U)
compact();
}
diff --git a/src/corelib/serialization/qbinaryjsonvalue.cpp b/src/corelib/serialization/qbinaryjsonvalue.cpp
index 5e3a01ad38..b1636b331e 100644
--- a/src/corelib/serialization/qbinaryjsonvalue.cpp
+++ b/src/corelib/serialization/qbinaryjsonvalue.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
QBinaryJsonValue::QBinaryJsonValue(QBinaryJsonPrivate::MutableData *data,
QBinaryJsonPrivate::Base *parent,
const QBinaryJsonPrivate::Value &v)
- : t(QJsonValue::Type(uint(v.type)))
+ : t(QJsonValue::Type(uint(v.type())))
{
switch (t) {
case QJsonValue::Undefined:
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index b2f846544d..7cd457ba3a 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
{
int pos = textBuffer.size();
- int oldLineNumber = lineNumber;
+ const auto oldLineNumber = lineNumber;
uint c;
while ((c = getChar()) != StreamEOF) {
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
index b623de9505..4321fed68a 100644
--- a/src/corelib/serialization/qxmlstream.g
+++ b/src/corelib/serialization/qxmlstream.g
@@ -557,6 +557,7 @@ bool QXmlStreamReaderPrivate::parse()
setType(QXmlStreamReader::EndElement);
Tag &tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ prefix = tag.namespaceDeclaration.prefix;
name = tag.name;
qualifiedName = tag.qualifiedName;
isEmptyElement = false;
@@ -1617,6 +1618,7 @@ etag ::= LANGLE SLASH qname space_opt RANGLE;
Tag &tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ prefix = tag.namespaceDeclaration.prefix;
name = tag.name;
qualifiedName = tag.qualifiedName;
if (qualifiedName != symName(3))
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index 103b123b10..e5bde7b98e 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -1046,6 +1046,7 @@ bool QXmlStreamReaderPrivate::parse()
setType(QXmlStreamReader::EndElement);
Tag &tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ prefix = tag.namespaceDeclaration.prefix;
name = tag.name;
qualifiedName = tag.qualifiedName;
isEmptyElement = false;
@@ -1798,6 +1799,7 @@ bool QXmlStreamReaderPrivate::parse()
namespaceUri = tag.namespaceDeclaration.namespaceUri;
name = tag.name;
qualifiedName = tag.qualifiedName;
+ prefix = tag.namespaceDeclaration.prefix;
if (qualifiedName != symName(3))
raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
} break;