summaryrefslogtreecommitdiffstats
path: root/src/corelib/xml/qxmlstream_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/xml/qxmlstream_p.h')
-rw-r--r--src/corelib/xml/qxmlstream_p.h73
1 files changed, 40 insertions, 33 deletions
diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h
index 9ef95c1fbe..5645d812eb 100644
--- a/src/corelib/xml/qxmlstream_p.h
+++ b/src/corelib/xml/qxmlstream_p.h
@@ -701,20 +701,18 @@ public:
bool tagsDone;
inline QStringRef addToStringStorage(const QStringRef &s) {
- int pos = tagStackStringStorageSize;
- int sz = s.size();
- if (pos != tagStackStringStorage.size())
- tagStackStringStorage.resize(pos);
- tagStackStringStorage.insert(pos, s.unicode(), sz);
- tagStackStringStorageSize += sz;
- return QStringRef(&tagStackStringStorage, pos, sz);
+ return addToStringStorage(qToStringViewIgnoringNull(s));
}
inline QStringRef addToStringStorage(const QString &s) {
+ return addToStringStorage(qToStringViewIgnoringNull(s));
+ }
+ QStringRef addToStringStorage(QStringView s)
+ {
int pos = tagStackStringStorageSize;
int sz = s.size();
if (pos != tagStackStringStorage.size())
tagStackStringStorage.resize(pos);
- tagStackStringStorage.insert(pos, s.unicode(), sz);
+ tagStackStringStorage.append(s.data(), sz);
tagStackStringStorageSize += sz;
return QStringRef(&tagStackStringStorage, pos, sz);
}
@@ -756,20 +754,24 @@ public:
int readBufferPos;
QXmlStreamSimpleStack<uint> putStack;
struct Entity {
- Entity(const QString& str = QString())
- :value(str), external(false), unparsed(false), literal(false),
+ Entity() = default;
+ Entity(const QString &name, const QString &value)
+ : name(name), value(value), external(false), unparsed(false), literal(false),
hasBeenParsed(false), isCurrentlyReferenced(false){}
- static inline Entity createLiteral(const QString &entity)
- { Entity result(entity); result.literal = result.hasBeenParsed = true; return result; }
- QString value;
+ static inline Entity createLiteral(QLatin1String name, QLatin1String value)
+ { Entity result(name, value); result.literal = result.hasBeenParsed = true; return result; }
+ QString name, value;
uint external : 1;
uint unparsed : 1;
uint literal : 1;
uint hasBeenParsed : 1;
uint isCurrentlyReferenced : 1;
};
- QHash<QString, Entity> entityHash;
- QHash<QString, Entity> parameterEntityHash;
+ // these hash tables use a QStringView as a key to avoid creating QStrings
+ // just for lookup. The keys are usually views into Entity::name and thus
+ // are guaranteed to have the same lifetime as the referenced data:
+ QHash<QStringView, Entity> entityHash;
+ QHash<QStringView, Entity> parameterEntityHash;
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
inline bool referenceEntity(Entity &entity) {
if (entity.isCurrentlyReferenced) {
@@ -922,6 +924,11 @@ public:
const Value &symbol = sym(index);
return QStringRef(&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) {
const Value &symbol = sym(index);
return QStringRef(&textBuffer, symbol.pos, symbol.len);
@@ -1492,13 +1499,13 @@ bool QXmlStreamReaderPrivate::parse()
EntityDeclaration &entityDeclaration = entityDeclarations.top();
if (!entityDeclaration.external)
entityDeclaration.value = symString(2);
- QString entityName = entityDeclaration.name.toString();
- QHash<QString, Entity> &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
- if (!hash.contains(entityName)) {
- Entity entity(entityDeclaration.value.toString());
+ auto &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
+ if (!hash.contains(qToStringViewIgnoringNull(entityDeclaration.name))) {
+ Entity entity(entityDeclaration.name.toString(),
+ entityDeclaration.value.toString());
entity.unparsed = (!entityDeclaration.notationName.isNull());
entity.external = entityDeclaration.external;
- hash.insert(entityName, entity);
+ hash.insert(qToStringViewIgnoringNull(entity.name), entity);
}
} break;
@@ -1508,12 +1515,12 @@ bool QXmlStreamReaderPrivate::parse()
processingInstructionTarget = symString(3);
if (scanUntil("?>")) {
processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
- const QString piTarget(processingInstructionTarget.toString());
- if (!piTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
+ if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
}
- else if(!QXmlUtils::isNCName(piTarget))
- raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget));
+ else if (!QXmlUtils::isNCName(processingInstructionTarget))
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.")
+ .arg(processingInstructionTarget));
} else if (type != QXmlStreamReader::Invalid){
resume(96);
return false;
@@ -1523,7 +1530,7 @@ bool QXmlStreamReaderPrivate::parse()
case 97:
setType(QXmlStreamReader::ProcessingInstruction);
processingInstructionTarget = symString(3);
- if (!processingInstructionTarget.toString().compare(QLatin1String("xml"), Qt::CaseInsensitive))
+ if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive))
raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
break;
@@ -1637,8 +1644,8 @@ bool QXmlStreamReaderPrivate::parse()
break;
case 175: {
- if (!QXmlUtils::isPublicID(symString(1).toString())) {
- raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString()));
+ if (!QXmlUtils::isPublicID(symString(1))) {
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1)));
resume(175);
return false;
}
@@ -1793,7 +1800,7 @@ bool QXmlStreamReaderPrivate::parse()
case 240: {
sym(1).len += sym(2).len + 1;
- QString reference = symString(2).toString();
+ QStringView reference = symView(2);
if (entityHash.contains(reference)) {
Entity &entity = entityHash[reference];
if (entity.unparsed) {
@@ -1814,7 +1821,7 @@ bool QXmlStreamReaderPrivate::parse()
}
if (entityResolver) {
- QString replacementText = resolveUndeclaredEntity(reference);
+ QString replacementText = resolveUndeclaredEntity(reference.toString());
if (!replacementText.isNull()) {
putReplacement(replacementText);
textBuffer.chop(2 + sym(2).len);
@@ -1832,7 +1839,7 @@ bool QXmlStreamReaderPrivate::parse()
case 241: {
sym(1).len += sym(2).len + 1;
- QString reference = symString(2).toString();
+ QStringView reference = symView(2);
if (parameterEntityHash.contains(reference)) {
referenceToParameterEntityDetected = true;
Entity &entity = parameterEntityHash[reference];
@@ -1845,7 +1852,7 @@ bool QXmlStreamReaderPrivate::parse()
clearSym();
}
} else if (entitiesMustBeDeclared()) {
- raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2).toString()));
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2)));
}
} break;
@@ -1855,7 +1862,7 @@ bool QXmlStreamReaderPrivate::parse()
case 243: {
sym(1).len += sym(2).len + 1;
- QString reference = symString(2).toString();
+ QStringView reference = symView(2);
if (entityHash.contains(reference)) {
Entity &entity = entityHash[reference];
if (entity.unparsed || entity.value.isNull()) {
@@ -1876,7 +1883,7 @@ bool QXmlStreamReaderPrivate::parse()
}
if (entityResolver) {
- QString replacementText = resolveUndeclaredEntity(reference);
+ QString replacementText = resolveUndeclaredEntity(reference.toString());
if (!replacementText.isNull()) {
putReplacement(replacementText);
textBuffer.chop(2 + sym(2).len);