Port QXmlStreamReader from QStringRef to QStringView

Use the new QtPrivate::XmlString class as the container holding
the string data internally. It basically a "QStringRef lite",
purely used in the implemntation. This replaces all usages of
QStringRef in the parser.

Fixes: QTBUG-84318
Change-Id: I557bbc6831301866602586d11d53283affd034a8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Karsten Heimrich 2020-07-21 15:27:53 +02:00
parent 8dc7761e6d
commit ecfb5d2d15
6 changed files with 162 additions and 134 deletions

View File

@ -1535,7 +1535,7 @@ uint QXmlStreamReaderPrivate::getChar_helper()
return StreamEOF;
}
QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(QStringView prefix)
XmlStringRef QXmlStreamReaderPrivate::namespaceForPrefix(QStringView prefix)
{
for (const NamespaceDeclaration &namespaceDeclaration : reversed(namespaceDeclarations)) {
if (namespaceDeclaration.prefix == prefix) {
@ -1548,7 +1548,7 @@ QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(QStringView prefix)
raiseWellFormedError(QXmlStream::tr("Namespace prefix '%1' not declared").arg(prefix));
#endif
return QStringRef();
return XmlStringRef();
}
/*
@ -1575,7 +1575,7 @@ void QXmlStreamReaderPrivate::resolveTag()
NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
namespaceDeclaration.prefix.clear();
const QStringRef ns(dtdAttribute.defaultValue);
const XmlStringRef ns(dtdAttribute.defaultValue);
if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
@ -1583,8 +1583,8 @@ void QXmlStreamReaderPrivate::resolveTag()
namespaceDeclaration.namespaceUri = ns;
} else if (dtdAttribute.attributePrefix == QLatin1String("xmlns")) {
NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
QStringRef namespacePrefix = dtdAttribute.attributeName;
QStringRef namespaceUri = dtdAttribute.defaultValue;
XmlStringRef namespacePrefix = dtdAttribute.attributeName;
XmlStringRef namespaceUri = dtdAttribute.defaultValue;
if (((namespacePrefix == QLatin1String("xml"))
^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
|| namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
@ -1605,18 +1605,18 @@ void QXmlStreamReaderPrivate::resolveTag()
for (qsizetype i = 0; i < n; ++i) {
QXmlStreamAttribute &attribute = attributes[i];
Attribute &attrib = attributeStack[i];
QStringRef prefix(symPrefix(attrib.key));
QStringRef name(symString(attrib.key));
QStringRef qualifiedName(symName(attrib.key));
QStringRef value(symString(attrib.value));
XmlStringRef prefix(symPrefix(attrib.key));
XmlStringRef name(symString(attrib.key));
XmlStringRef qualifiedName(symName(attrib.key));
XmlStringRef value(symString(attrib.value));
attribute.m_name = name;
attribute.m_qualifiedName = qualifiedName;
attribute.m_value = value;
if (!prefix.isEmpty()) {
QStringRef attributeNamespaceUri = namespaceForPrefix(prefix);
attribute.m_namespaceUri = attributeNamespaceUri;
XmlStringRef attributeNamespaceUri = namespaceForPrefix(prefix);
attribute.m_namespaceUri = XmlStringRef(attributeNamespaceUri);
}
for (qsizetype j = 0; j < i; ++j) {
@ -1650,8 +1650,8 @@ void QXmlStreamReaderPrivate::resolveTag()
attribute.m_value = dtdAttribute.defaultValue;
if (!dtdAttribute.attributePrefix.isEmpty()) {
QStringRef attributeNamespaceUri = namespaceForPrefix(dtdAttribute.attributePrefix);
attribute.m_namespaceUri = attributeNamespaceUri;
XmlStringRef attributeNamespaceUri = namespaceForPrefix(dtdAttribute.attributePrefix);
attribute.m_namespaceUri = XmlStringRef(attributeNamespaceUri);
}
attribute.m_isDefault = true;
attributes.append(std::move(attribute));
@ -1701,11 +1701,11 @@ uint QXmlStreamReaderPrivate::resolveCharRef(int symbolIndex)
{
bool ok = true;
uint s;
// ### add toXShort to QStringRef?
// ### add toXShort to XmlString?
if (sym(symbolIndex).c == 'x')
s = symString(symbolIndex, 1).toUInt(&ok, 16);
s = symString(symbolIndex, 1).view().toUInt(&ok, 16);
else
s = symString(symbolIndex).toUInt(&ok, 10);
s = symString(symbolIndex).view().toUInt(&ok, 10);
ok &= (s == 0x9 || s == 0xa || s == 0xd || (s >= 0x20 && s <= 0xd7ff)
|| (s >= 0xe000 && s <= 0xfffd) || (s >= 0x10000 && s <= QChar::LastValidCodePoint));
@ -1765,7 +1765,7 @@ void QXmlStreamReaderPrivate::startDocument()
{
QString err;
if (documentVersion != QLatin1String("1.0")) {
if (documentVersion.contains(QLatin1Char(' ')))
if (documentVersion.view().contains(QLatin1Char(' ')))
err = QXmlStream::tr("Invalid XML version string.");
else
err = QXmlStream::tr("Unsupported XML version.");
@ -1780,9 +1780,9 @@ void QXmlStreamReaderPrivate::startDocument()
for (qsizetype i = 0; err.isNull() && i < n; ++i) {
Attribute &attrib = attributeStack[i];
QStringRef prefix(symPrefix(attrib.key));
QStringRef key(symString(attrib.key));
QStringRef value(symString(attrib.value));
XmlStringRef prefix(symPrefix(attrib.key));
XmlStringRef key(symString(attrib.key));
XmlStringRef value(symString(attrib.value));
if (prefix.isEmpty() && key == QLatin1String("encoding")) {
documentEncoding = value;
@ -2119,7 +2119,7 @@ QString QXmlStreamReader::readElementText(ReadElementTextBehaviour behaviour)
switch (readNext()) {
case Characters:
case EntityReference:
result.insert(result.size(), d->text.unicode(), d->text.size());
result.insert(result.size(), d->text);
break;
case EndElement:
return result;
@ -2296,10 +2296,10 @@ QXmlStreamAttribute::QXmlStreamAttribute()
*/
QXmlStreamAttribute::QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value)
{
m_namespaceUri = QStringRef(&namespaceUri);
m_name = m_qualifiedName = QStringRef(&name);
m_value = QStringRef(&value);
m_namespaceUri = QStringRef(&namespaceUri);
m_namespaceUri = namespaceUri;
m_name = m_qualifiedName = name;
m_value = value;
m_namespaceUri = namespaceUri;
}
/*!
@ -2308,9 +2308,9 @@ QXmlStreamAttribute::QXmlStreamAttribute(const QString &namespaceUri, const QStr
QXmlStreamAttribute::QXmlStreamAttribute(const QString &qualifiedName, const QString &value)
{
int colon = qualifiedName.indexOf(QLatin1Char(':'));
m_name = QStringRef(&qualifiedName, colon + 1, qualifiedName.size() - (colon + 1));
m_qualifiedName = QStringRef(&qualifiedName);
m_value = QStringRef(&value);
m_name = qualifiedName.mid(colon + 1);
m_qualifiedName = qualifiedName;
m_value = value;
}
/*! \fn QStringView QXmlStreamAttribute::namespaceUri() const
@ -2861,7 +2861,7 @@ public:
delete device;
}
void write(const QStringRef &);
void write(const XmlStringRef &);
void write(const QString &);
void writeEscaped(const QString &, bool escapeWhitespace = false);
void write(const char *s, int len);
@ -2910,7 +2910,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q)
namespacePrefixCount = 0;
}
void QXmlStreamWriterPrivate::write(const QStringRef &s)
void QXmlStreamWriterPrivate::write(const XmlStringRef &s)
{
if (device) {
if (hasIoError)
@ -2924,7 +2924,7 @@ void QXmlStreamWriterPrivate::write(const QStringRef &s)
hasIoError = true;
}
else if (stringDevice)
s.appendTo(stringDevice);
stringDevice->append(s);
else
qWarning("QXmlStreamWriter: No device");
}

View File

@ -235,7 +235,7 @@ bool QXmlStreamReaderPrivate::parse()
attributes.clear();
if (isEmptyElement) {
setType(QXmlStreamReader::EndElement);
Tag &tag = tagStack_pop();
Tag tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
name = tag.name;
qualifiedName = tag.qualifiedName;
@ -753,7 +753,7 @@ attlist_decl ::= langle_bang ATTLIST qname attdef_list space_opt RANGLE;
if (referenceToUnparsedEntityDetected && !standalone)
break;
int n = dtdAttributes.size();
QStringRef tagName = addToStringStorage(symName(3));
XmlStringRef tagName = addToStringStorage(symName(3));
while (n--) {
DtdAttribute &dtdAttribute = dtdAttributes[n];
if (!dtdAttribute.tagName.isNull())
@ -850,7 +850,7 @@ entity_decl ::= entity_decl_start entity_value space_opt RANGLE;
if (!entityDeclaration.external)
entityDeclaration.value = symString(2);
auto &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
if (!hash.contains(qToStringViewIgnoringNull(entityDeclaration.name))) {
if (!hash.contains(entityDeclaration.name)) {
Entity entity(entityDeclaration.name.toString(),
entityDeclaration.value.toString());
entity.unparsed = (!entityDeclaration.notationName.isNull());
@ -868,8 +868,8 @@ processing_instruction ::= LANGLE QUESTIONMARK name space;
int pos = sym(4).pos + sym(4).len;
processingInstructionTarget = symString(3);
if (scanUntil("?>")) {
processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
processingInstructionData = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
if (!processingInstructionTarget.view().compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
}
else if (!QXmlUtils::isNCName(processingInstructionTarget))
@ -887,7 +887,7 @@ processing_instruction ::= LANGLE QUESTIONMARK name QUESTIONMARK RANGLE;
case $rule_number:
setType(QXmlStreamReader::ProcessingInstruction);
processingInstructionTarget = symString(3);
if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive))
if (!processingInstructionTarget.view().compare(QLatin1String("xml"), Qt::CaseInsensitive))
raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
break;
./
@ -918,7 +918,7 @@ comment ::= comment_start RANGLE;
case $rule_number: {
setType(QXmlStreamReader::Comment);
int pos = sym(1).pos + 4;
text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
} break;
./
@ -931,7 +931,7 @@ cdata ::= langle_bang CDATA_START;
isWhitespace = false;
int pos = sym(2).pos;
if (scanUntil("]]>", -1)) {
text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
} else {
resume($rule_number);
return false;
@ -1179,14 +1179,14 @@ attribute_value_content ::= literal_content | char_ref | entity_ref_in_attribute
attribute ::= qname space_opt EQ space_opt attribute_value;
/.
case $rule_number: {
QStringRef prefix = symPrefix(1);
XmlStringRef prefix = symPrefix(1);
if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
namespaceDeclaration.prefix.clear();
const QStringRef ns(symString(5));
if (ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
const XmlStringRef ns(symString(5));
if (ns.view() == QLatin1String("http://www.w3.org/2000/xmlns/") ||
ns.view() == QLatin1String("http://www.w3.org/XML/1998/namespace"))
raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
else
namespaceDeclaration.namespaceUri = addToStringStorage(ns);
@ -1195,7 +1195,7 @@ attribute ::= qname space_opt EQ space_opt attribute_value;
attribute.key = sym(1);
attribute.value = sym(5);
QStringRef attributeQualifiedName = symName(1);
XmlStringRef attributeQualifiedName = symName(1);
bool normalize = false;
for (int a = 0; a < dtdAttributes.size(); ++a) {
DtdAttribute &dtdAttribute = dtdAttributes[a];
@ -1232,8 +1232,8 @@ attribute ::= qname space_opt EQ space_opt attribute_value;
}
if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
QStringRef namespacePrefix = symString(attribute.key);
QStringRef namespaceUri = symString(attribute.value);
XmlStringRef namespacePrefix = symString(attribute.key);
XmlStringRef namespaceUri = symString(attribute.value);
attributeStack.pop();
if (((namespacePrefix == QLatin1String("xml"))
^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
@ -1292,7 +1292,7 @@ etag ::= LANGLE SLASH qname space_opt RANGLE;
/.
case $rule_number: {
setType(QXmlStreamReader::EndElement);
Tag &tag = tagStack_pop();
Tag tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
name = tag.name;

View File

@ -51,34 +51,25 @@
QT_BEGIN_NAMESPACE
namespace QtPrivate {
class QXmlString {
QStringPrivate m_string;
public:
inline constexpr QXmlString() {}
inline QXmlString(const QStringRef &aString)
{
if (!aString.string())
return;
m_string = aString.string()->data_ptr();
m_string = { m_string.d_ptr(), m_string.data() + aString.position(), size_t(aString.size()) };
// need to manually call ref(), as the constructor above does not do it
m_string.ref();
}
QXmlString(const QString &aString) : m_string(aString.data_ptr()) {}
QXmlString(QString &&aString) noexcept
{ qSwap(m_string, aString.data_ptr()); }
QXmlString &operator=(const QStringRef &s)
{ *this = QXmlString(s); return *this; }
class QXmlString {
QStringPrivate m_string;
public:
QXmlString(QStringPrivate &&d) : m_string(std::move(d)) {}
QXmlString(const QString &s) : m_string(s.data_ptr()) {}
QXmlString & operator=(const QString &s) { m_string = s.data_ptr(); return *this; }
QXmlString & operator=(QString &&s) { qSwap(m_string, s.data_ptr()); return *this; }
inline constexpr QXmlString() {}
void swap(QXmlString &other) noexcept
{
qSwap(m_string, other.m_string);
}
void swap(QXmlString &other) noexcept
{
qSwap(m_string, other.m_string);
}
inline operator QStringView() const { return QStringView(m_string.data(), m_string.size); }
inline int size() const { return m_string.size; }
};
inline operator QStringView() const { return QStringView(m_string.data(), m_string.size); }
inline int size() const { return m_string.size; }
};
}
Q_DECLARE_SHARED(QtPrivate::QXmlString)

View File

@ -53,11 +53,53 @@
#include <qxmlstream.h>
#include "qxmlstreamgrammar_p.h"
#include <memory>
#ifndef QXMLSTREAM_P_H
#define QXMLSTREAM_P_H
QT_BEGIN_NAMESPACE
namespace QtPrivate {
class XmlStringRef
{
public:
const QString *m_string = nullptr;
qsizetype m_pos = 0;
qsizetype m_size = 0;
constexpr XmlStringRef() = default;
constexpr inline XmlStringRef(const QString *string, int pos, int length)
: m_string(string), m_pos(pos), m_size(length)
{
}
XmlStringRef(const QString *string)
: XmlStringRef(string, 0, string->length())
{
}
operator QXmlString() const {
if (!m_string)
return QXmlString();
QStringPrivate d = m_string->data_ptr();
d.setBegin(d.data() + m_pos);
d.size = m_size;
return QXmlString(std::move(d));
}
operator QStringView() const { return view(); }
void clear() { m_string = nullptr; m_pos = 0; m_size= 0; }
QStringView view() const { return m_string ? QStringView(m_string->data() + m_pos, m_size) : QStringView(); }
bool isEmpty() const { return m_size == 0; }
bool isNull() const { return !m_string; }
QString toString() const { return view().toString(); }
};
}
using namespace QtPrivate;
template <typename T> class QXmlStreamSimpleStack
{
T *data;
@ -116,14 +158,14 @@ class QXmlStreamPrivateTagStack {
public:
struct NamespaceDeclaration
{
QStringRef prefix;
QStringRef namespaceUri;
XmlStringRef prefix;
XmlStringRef namespaceUri;
};
struct Tag
{
QStringRef name;
QStringRef qualifiedName;
XmlStringRef name;
XmlStringRef qualifiedName;
NamespaceDeclaration namespaceDeclaration;
int tagStackStringStorageSize;
qsizetype namespaceDeclarationsSize;
@ -137,13 +179,7 @@ public:
int initialTagStackStringStorageSize;
bool tagsDone;
inline QStringRef addToStringStorage(const QStringRef &s) {
return addToStringStorage(qToStringViewIgnoringNull(s));
}
inline QStringRef addToStringStorage(const QString &s) {
return addToStringStorage(qToStringViewIgnoringNull(s));
}
QStringRef addToStringStorage(QStringView s)
XmlStringRef addToStringStorage(QStringView s)
{
int pos = tagStackStringStorageSize;
int sz = s.size();
@ -151,7 +187,7 @@ public:
tagStackStringStorage.resize(pos);
tagStackStringStorage.append(s.data(), sz);
tagStackStringStorageSize += sz;
return QStringRef(&tagStackStringStorage, pos, sz);
return XmlStringRef(&tagStackStringStorage, pos, sz);
}
QXmlStreamSimpleStack<Tag> tagStack;
@ -253,7 +289,7 @@ public:
QXmlStreamAttributes attributes;
QStringRef namespaceForPrefix(QStringView prefix);
XmlStringRef namespaceForPrefix(QStringView prefix);
void resolveTag();
void resolvePublicNamespaces();
void resolveDtd();
@ -264,33 +300,33 @@ public:
void checkPublicLiteral(QStringView publicId);
bool scanDtd;
QStringRef lastAttributeValue;
XmlStringRef lastAttributeValue;
bool lastAttributeIsCData;
struct DtdAttribute {
QStringRef tagName;
QStringRef attributeQualifiedName;
QStringRef attributePrefix;
QStringRef attributeName;
QStringRef defaultValue;
XmlStringRef tagName;
XmlStringRef attributeQualifiedName;
XmlStringRef attributePrefix;
XmlStringRef attributeName;
XmlStringRef defaultValue;
bool isCDATA;
bool isNamespaceAttribute;
};
QXmlStreamSimpleStack<DtdAttribute> dtdAttributes;
struct NotationDeclaration {
QStringRef name;
QStringRef publicId;
QStringRef systemId;
XmlStringRef name;
XmlStringRef publicId;
XmlStringRef systemId;
};
QXmlStreamSimpleStack<NotationDeclaration> notationDeclarations;
QXmlStreamNotationDeclarations publicNotationDeclarations;
QXmlStreamNamespaceDeclarations publicNamespaceDeclarations;
struct EntityDeclaration {
QStringRef name;
QStringRef notationName;
QStringRef publicId;
QStringRef systemId;
QStringRef value;
XmlStringRef name;
XmlStringRef notationName;
XmlStringRef publicId;
XmlStringRef systemId;
XmlStringRef value;
bool parameter;
bool external;
inline void clear() {
@ -305,12 +341,12 @@ public:
QXmlStreamSimpleStack<EntityDeclaration> entityDeclarations;
QXmlStreamEntityDeclarations publicEntityDeclarations;
QStringRef text;
XmlStringRef text;
QStringRef prefix, namespaceUri, qualifiedName, name;
QStringRef processingInstructionTarget, processingInstructionData;
QStringRef dtdName, dtdPublicId, dtdSystemId;
QStringRef documentVersion, documentEncoding;
XmlStringRef prefix, namespaceUri, qualifiedName, name;
XmlStringRef processingInstructionTarget, processingInstructionData;
XmlStringRef dtdName, dtdPublicId, dtdSystemId;
XmlStringRef documentVersion, documentEncoding;
uint isEmptyElement : 1;
uint isWhitespace : 1;
uint isCDATA : 1;
@ -364,39 +400,39 @@ public:
};
QXmlStreamSimpleStack<Attribute> attributeStack;
inline QStringRef symString(int index) {
inline XmlStringRef symString(int index) {
const Value &symbol = sym(index);
return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
return XmlStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
}
QStringView symView(int index) const
{
const Value &symbol = sym(index);
return QStringView(textBuffer.data() + symbol.pos, symbol.len).mid(symbol.prefix);
}
inline QStringRef symName(int index) {
inline XmlStringRef symName(int index) {
const Value &symbol = sym(index);
return QStringRef(&textBuffer, symbol.pos, symbol.len);
return XmlStringRef(&textBuffer, symbol.pos, symbol.len);
}
inline QStringRef symString(int index, int offset) {
inline XmlStringRef symString(int index, int offset) {
const Value &symbol = sym(index);
return QStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix - offset);
return XmlStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix - offset);
}
inline QStringRef symPrefix(int index) {
inline XmlStringRef symPrefix(int index) {
const Value &symbol = sym(index);
if (symbol.prefix)
return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
return QStringRef();
return XmlStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
return XmlStringRef();
}
inline QStringRef symString(const Value &symbol) {
return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
inline XmlStringRef symString(const Value &symbol) {
return XmlStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
}
inline QStringRef symName(const Value &symbol) {
return QStringRef(&textBuffer, symbol.pos, symbol.len);
inline XmlStringRef symName(const Value &symbol) {
return XmlStringRef(&textBuffer, symbol.pos, symbol.len);
}
inline QStringRef symPrefix(const Value &symbol) {
inline XmlStringRef symPrefix(const Value &symbol) {
if (symbol.prefix)
return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
return QStringRef();
return XmlStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
return XmlStringRef();
}
inline void clearSym() { Value &val = sym(1); val.pos = textBuffer.size(); val.len = 0; }

View File

@ -481,7 +481,7 @@ bool QXmlStreamReaderPrivate::parse()
if (referenceToUnparsedEntityDetected && !standalone)
break;
int n = dtdAttributes.size();
QStringRef tagName = addToStringStorage(symName(3));
XmlStringRef tagName = addToStringStorage(symName(3));
while (n--) {
DtdAttribute &dtdAttribute = dtdAttributes[n];
if (!dtdAttribute.tagName.isNull())
@ -557,7 +557,7 @@ bool QXmlStreamReaderPrivate::parse()
if (!entityDeclaration.external)
entityDeclaration.value = symString(2);
auto &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
if (!hash.contains(qToStringViewIgnoringNull(entityDeclaration.name))) {
if (!hash.contains(entityDeclaration.name)) {
Entity entity(entityDeclaration.name.toString(),
entityDeclaration.value.toString());
entity.unparsed = (!entityDeclaration.notationName.isNull());
@ -571,8 +571,8 @@ bool QXmlStreamReaderPrivate::parse()
int pos = sym(4).pos + sym(4).len;
processingInstructionTarget = symString(3);
if (scanUntil("?>")) {
processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
processingInstructionData = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
if (!processingInstructionTarget.view().compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
}
else if (!QXmlUtils::isNCName(processingInstructionTarget))
@ -587,7 +587,7 @@ bool QXmlStreamReaderPrivate::parse()
case 97:
setType(QXmlStreamReader::ProcessingInstruction);
processingInstructionTarget = symString(3);
if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive))
if (!processingInstructionTarget.view().compare(QLatin1String("xml"), Qt::CaseInsensitive))
raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
break;
@ -608,7 +608,7 @@ bool QXmlStreamReaderPrivate::parse()
case 100: {
setType(QXmlStreamReader::Comment);
int pos = sym(1).pos + 4;
text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
} break;
case 101: {
@ -617,7 +617,7 @@ bool QXmlStreamReaderPrivate::parse()
isWhitespace = false;
int pos = sym(2).pos;
if (scanUntil("]]>", -1)) {
text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
} else {
resume(101);
return false;
@ -744,14 +744,14 @@ bool QXmlStreamReaderPrivate::parse()
break;
case 229: {
QStringRef prefix = symPrefix(1);
XmlStringRef prefix = symPrefix(1);
if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
namespaceDeclaration.prefix.clear();
const QStringRef ns(symString(5));
if (ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
const XmlStringRef ns(symString(5));
if (ns.view() == QLatin1String("http://www.w3.org/2000/xmlns/") ||
ns.view() == QLatin1String("http://www.w3.org/XML/1998/namespace"))
raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
else
namespaceDeclaration.namespaceUri = addToStringStorage(ns);
@ -760,7 +760,7 @@ bool QXmlStreamReaderPrivate::parse()
attribute.key = sym(1);
attribute.value = sym(5);
QStringRef attributeQualifiedName = symName(1);
XmlStringRef attributeQualifiedName = symName(1);
bool normalize = false;
for (int a = 0; a < dtdAttributes.size(); ++a) {
DtdAttribute &dtdAttribute = dtdAttributes[a];
@ -797,8 +797,8 @@ bool QXmlStreamReaderPrivate::parse()
}
if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
QStringRef namespacePrefix = symString(attribute.key);
QStringRef namespaceUri = symString(attribute.value);
XmlStringRef namespacePrefix = symString(attribute.key);
XmlStringRef namespaceUri = symString(attribute.value);
attributeStack.pop();
if (((namespacePrefix == QLatin1String("xml"))
^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))

View File

@ -193,6 +193,7 @@ public:
typename Data::ArrayOptions detachFlags() const noexcept { return d ? d->detachFlags() : Data::DefaultAllocationFlags; }
Data *d_ptr() noexcept { return d; }
void setBegin(T *begin) noexcept { ptr = begin; }
qsizetype freeSpaceAtBegin() const noexcept
{