diff options
Diffstat (limited to 'src/corelib/xml/qxmlstream_p.h')
-rw-r--r-- | src/corelib/xml/qxmlstream_p.h | 73 |
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); |