summaryrefslogtreecommitdiffstats
path: root/src/corelib/xml
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/xml')
-rw-r--r--src/corelib/xml/qxmlstream.cpp70
-rw-r--r--src/corelib/xml/qxmlstream.g105
-rw-r--r--src/corelib/xml/qxmlstream_p.h73
-rw-r--r--src/corelib/xml/qxmlutils.cpp37
-rw-r--r--src/corelib/xml/qxmlutils_p.h7
5 files changed, 150 insertions, 142 deletions
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index af35193b13..f6ae3571ab 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -775,8 +775,8 @@ QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack()
tagStackStringStorage.reserve(32);
tagStackStringStorageSize = 0;
NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
- namespaceDeclaration.prefix = addToStringStorage(QLatin1String("xml"));
- namespaceDeclaration.namespaceUri = addToStringStorage(QLatin1String("http://www.w3.org/XML/1998/namespace"));
+ namespaceDeclaration.prefix = addToStringStorage(QStringViewLiteral("xml"));
+ namespaceDeclaration.namespaceUri = addToStringStorage(QStringViewLiteral("http://www.w3.org/XML/1998/namespace"));
initialTagStackStringStorageSize = tagStackStringStorageSize;
}
@@ -796,11 +796,17 @@ QXmlStreamReaderPrivate::QXmlStreamReaderPrivate(QXmlStreamReader *q)
reallocateStack();
entityResolver = 0;
init();
- entityHash.insert(QLatin1String("lt"), Entity::createLiteral(QLatin1String("<")));
- entityHash.insert(QLatin1String("gt"), Entity::createLiteral(QLatin1String(">")));
- entityHash.insert(QLatin1String("amp"), Entity::createLiteral(QLatin1String("&")));
- entityHash.insert(QLatin1String("apos"), Entity::createLiteral(QLatin1String("'")));
- entityHash.insert(QLatin1String("quot"), Entity::createLiteral(QLatin1String("\"")));
+#define ADD_PREDEFINED(n, v) \
+ do { \
+ Entity e = Entity::createLiteral(QLatin1String(n), QLatin1String(v)); \
+ entityHash.insert(qToStringViewIgnoringNull(e.name), std::move(e)); \
+ } while (false)
+ ADD_PREDEFINED("lt", "<");
+ ADD_PREDEFINED("gt", ">");
+ ADD_PREDEFINED("amp", "&");
+ ADD_PREDEFINED("apos", "'");
+ ADD_PREDEFINED("quot", "\"");
+#undef ADD_PREDEFINED
}
void QXmlStreamReaderPrivate::init()
@@ -1558,7 +1564,7 @@ QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(const QStringRef &prefix)
#if 1
if (namespaceProcessing && !prefix.isEmpty())
- raiseWellFormedError(QXmlStream::tr("Namespace prefix '%1' not declared").arg(prefix.toString()));
+ raiseWellFormedError(QXmlStream::tr("Namespace prefix '%1' not declared").arg(prefix));
#endif
return QStringRef();
@@ -1636,7 +1642,7 @@ void QXmlStreamReaderPrivate::resolveTag()
if (attributes[j].name() == attribute.name()
&& attributes[j].namespaceUri() == attribute.namespaceUri()
&& (namespaceProcessing || attributes[j].qualifiedName() == attribute.qualifiedName()))
- raiseWellFormedError(QXmlStream::tr("Attribute '%1' redefined.").arg(attribute.qualifiedName().toString()));
+ raiseWellFormedError(QXmlStream::tr("Attribute '%1' redefined.").arg(attribute.qualifiedName()));
}
}
@@ -1798,20 +1804,19 @@ void QXmlStreamReaderPrivate::startDocument()
QStringRef value(symString(attrib.value));
if (prefix.isEmpty() && key == QLatin1String("encoding")) {
- const QString name(value.toString());
documentEncoding = value;
if(hasStandalone)
err = QXmlStream::tr("The standalone pseudo attribute must appear after the encoding.");
- if(!QXmlUtils::isEncName(name))
- err = QXmlStream::tr("%1 is an invalid encoding name.").arg(name);
+ if (!QXmlUtils::isEncName(value))
+ err = QXmlStream::tr("%1 is an invalid encoding name.").arg(value);
else {
#ifdef QT_NO_TEXTCODEC
readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread);
#else
- QTextCodec *const newCodec = QTextCodec::codecForName(name.toLatin1());
+ QTextCodec *const newCodec = QTextCodec::codecForName(value.toLatin1());
if (!newCodec)
- err = QXmlStream::tr("Encoding %1 is unsupported").arg(name);
+ err = QXmlStream::tr("Encoding %1 is unsupported").arg(value);
else if (newCodec != codec && !lockEncoding) {
codec = newCodec;
delete decoder;
@@ -1881,32 +1886,25 @@ void QXmlStreamReaderPrivate::parseError()
}
}
- error_message.clear ();
if (nexpected && nexpected < nmax) {
- bool first = true;
-
- for (int s = 0; s < nexpected; ++s) {
- if (first)
- error_message += QXmlStream::tr ("Expected ");
- else if (s == nexpected - 1)
- error_message += QLatin1String (nexpected > 2 ? ", or " : " or ");
- else
- error_message += QLatin1String (", ");
-
- first = false;
- error_message += QLatin1String("\'");
- error_message += QLatin1String (spell [expected[s]]);
- error_message += QLatin1String("\'");
+ //: '<first option>'
+ QString exp_str = QXmlStream::tr("'%1'", "expected").arg(QLatin1String(spell[expected[0]]));
+ if (nexpected == 2) {
+ //: <first option>, '<second option>'
+ exp_str = QXmlStream::tr("%1 or '%2'", "expected").arg(exp_str, QLatin1String(spell[expected[1]]));
+ } else if (nexpected > 2) {
+ int s = 1;
+ for (; s < nexpected - 1; ++s) {
+ //: <options so far>, '<next option>'
+ exp_str = QXmlStream::tr("%1, '%2'", "expected").arg(exp_str, QLatin1String(spell[expected[s]]));
+ }
+ //: <options so far>, or '<final option>'
+ exp_str = QXmlStream::tr("%1, or '%2'", "expected").arg(exp_str, QLatin1String(spell[expected[s]]));
}
- error_message += QXmlStream::tr(", but got \'");
- error_message += QLatin1String(spell [token]);
- error_message += QLatin1String("\'");
+ error_message = QXmlStream::tr("Expected %1, but got '%2'.").arg(exp_str, QLatin1String(spell[token]));
} else {
- error_message += QXmlStream::tr("Unexpected \'");
- error_message += QLatin1String(spell [token]);
- error_message += QLatin1String("\'");
+ error_message = QXmlStream::tr("Unexpected '%1'.").arg(QLatin1String(spell[token]));
}
- error_message += QLatin1Char('.');
raiseWellFormedError(error_message);
}
diff --git a/src/corelib/xml/qxmlstream.g b/src/corelib/xml/qxmlstream.g
index 567d36d4b9..fd69a6e4af 100644
--- a/src/corelib/xml/qxmlstream.g
+++ b/src/corelib/xml/qxmlstream.g
@@ -201,23 +201,22 @@ public:
QXmlStreamSimpleStack<NamespaceDeclaration> namespaceDeclarations;
QString tagStackStringStorage;
int tagStackStringStorageSize;
+ int initialTagStackStringStorageSize;
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);
}
@@ -259,20 +258,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) {
@@ -425,6 +428,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);
@@ -455,7 +463,7 @@ public:
short token;
- ushort token_char;
+ uint token_char;
uint filterCarriageReturn();
inline uint getChar();
@@ -466,7 +474,7 @@ public:
void putStringLiteral(const QString &s);
void putReplacement(const QString &s);
void putReplacementInAttributeValue(const QString &s);
- ushort getChar_helper();
+ uint getChar_helper();
bool scanUntil(const char *str, short tokenToInject = -1);
bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
@@ -525,10 +533,8 @@ bool QXmlStreamReaderPrivate::parse()
prefix.clear();
qualifiedName.clear();
namespaceUri.clear();
- if (publicNamespaceDeclarations.size())
- publicNamespaceDeclarations.clear();
- if (attributes.size())
- attributes.resize(0);
+ publicNamespaceDeclarations.clear();
+ attributes.clear();
if (isEmptyElement) {
setType(QXmlStreamReader::EndElement);
Tag &tag = tagStack_pop();
@@ -553,7 +559,7 @@ bool QXmlStreamReaderPrivate::parse()
dtdName.clear();
dtdPublicId.clear();
dtdSystemId.clear();
- // fall through
+ Q_FALLTHROUGH();
case QXmlStreamReader::Comment:
case QXmlStreamReader::Characters:
isCDATA = false;
@@ -579,13 +585,13 @@ bool QXmlStreamReaderPrivate::parse()
documentVersion.clear();
documentEncoding.clear();
#ifndef QT_NO_TEXTCODEC
- if (decoder->hasFailure()) {
+ if (decoder && decoder->hasFailure()) {
raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
readBuffer.clear();
return false;
}
#endif
- // fall through
+ Q_FALLTHROUGH();
default:
clearTextBuffer();
;
@@ -610,8 +616,8 @@ bool QXmlStreamReaderPrivate::parse()
if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
uint cu = getChar();
token = NOTOKEN;
- token_char = cu;
- if (cu & 0xff0000) {
+ token_char = cu == ~0U ? cu : ushort(cu);
+ if ((cu != ~0U) && (cu & 0xff0000)) {
token = cu >> 16;
} else switch (token_char) {
case 0xfffe:
@@ -629,8 +635,8 @@ bool QXmlStreamReaderPrivate::parse()
} else {
break;
}
- // fall through
- case '\0': {
+ Q_FALLTHROUGH();
+ case ~0U: {
token = EOF_SYMBOL;
if (!tagsDone && !inParseEntity) {
int a = t_action(act, token);
@@ -644,6 +650,7 @@ bool QXmlStreamReaderPrivate::parse()
case '\n':
++lineNumber;
lastLineStart = characterOffset + readBufferPos;
+ Q_FALLTHROUGH();
case ' ':
case '\t':
token = SPACE;
@@ -1127,7 +1134,7 @@ entity_decl ::= entity_decl_external NDATA name space_opt RANGLE;
if (entityDeclaration.parameter)
raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
}
- //fall through
+ Q_FALLTHROUGH();
./
entity_decl ::= entity_decl_external space_opt RANGLE;
@@ -1144,13 +1151,13 @@ entity_decl ::= entity_decl_start entity_value space_opt RANGLE;
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;
./
@@ -1164,12 +1171,12 @@ processing_instruction ::= LANGLE QUESTIONMARK name space;
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($rule_number);
return false;
@@ -1182,7 +1189,7 @@ processing_instruction ::= LANGLE QUESTIONMARK name QUESTIONMARK RANGLE;
case $rule_number:
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;
./
@@ -1281,7 +1288,7 @@ scan_content_char ::= content_char;
/.
case $rule_number:
isWhitespace = false;
- // fall through
+ Q_FALLTHROUGH();
./
scan_content_char ::= SPACE;
@@ -1379,8 +1386,8 @@ literal_content ::= literal_content_start;
public_literal ::= literal;
/.
case $rule_number: {
- 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($rule_number);
return false;
}
@@ -1567,7 +1574,7 @@ empty_element_tag ::= stag_start attribute_list_opt SLASH RANGLE;
/.
case $rule_number:
isEmptyElement = true;
- // fall through
+ Q_FALLTHROUGH();
./
@@ -1614,7 +1621,7 @@ entity_ref ::= AMPERSAND name SEMICOLON;
/.
case $rule_number: {
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) {
@@ -1635,7 +1642,7 @@ entity_ref ::= AMPERSAND name SEMICOLON;
}
if (entityResolver) {
- QString replacementText = resolveUndeclaredEntity(reference);
+ QString replacementText = resolveUndeclaredEntity(reference.toString());
if (!replacementText.isNull()) {
putReplacement(replacementText);
textBuffer.chop(2 + sym(2).len);
@@ -1656,7 +1663,7 @@ pereference ::= PERCENT name SEMICOLON;
/.
case $rule_number: {
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];
@@ -1669,7 +1676,7 @@ pereference ::= PERCENT name SEMICOLON;
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;
./
@@ -1687,7 +1694,7 @@ entity_ref_in_attribute_value ::= AMPERSAND name SEMICOLON;
/.
case $rule_number: {
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()) {
@@ -1708,7 +1715,7 @@ entity_ref_in_attribute_value ::= AMPERSAND name SEMICOLON;
}
if (entityResolver) {
- QString replacementText = resolveUndeclaredEntity(reference);
+ QString replacementText = resolveUndeclaredEntity(reference.toString());
if (!replacementText.isNull()) {
putReplacement(replacementText);
textBuffer.chop(2 + sym(2).len);
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);
diff --git a/src/corelib/xml/qxmlutils.cpp b/src/corelib/xml/qxmlutils.cpp
index 23caae2935..01c84251fd 100644
--- a/src/corelib/xml/qxmlutils.cpp
+++ b/src/corelib/xml/qxmlutils.cpp
@@ -227,19 +227,22 @@ bool QXmlUtils::isBaseChar(const QChar c)
\sa {http://www.w3.org/TR/REC-xml/#NT-EncName},
{Extensible Markup Language (XML) 1.0 (Fourth Edition), [81] EncName}
*/
-bool QXmlUtils::isEncName(const QString &encName)
+bool QXmlUtils::isEncName(QStringView encName)
{
// Valid encoding names are given by "[A-Za-z][A-Za-z0-9._\\-]*"
- const ushort *c = encName.utf16();
- int l = encName.length();
- if (l < 1 || !((c[0] >= 'a' && c[0] <= 'z') || (c[0] >= 'A' && c[0] <= 'Z')))
+ if (encName.isEmpty())
return false;
- for (int i = 1; i < l; ++i) {
- if ((c[i] >= 'a' && c[i] <= 'z')
- || (c[i] >= 'A' && c[i] <= 'Z')
- || (c[i] >= '0' && c[i] <= '9')
- || c[i] == '.' || c[i] == '_' || c[i] == '-')
+ const auto first = encName.front().unicode();
+ if (!((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z')))
+ return false;
+ for (QChar ch : encName.mid(1)) {
+ const auto cp = ch.unicode();
+ if ((cp >= 'a' && cp <= 'z')
+ || (cp >= 'A' && cp <= 'Z')
+ || (cp >= '0' && cp <= '9')
+ || cp == '.' || cp == '_' || cp == '-') {
continue;
+ }
return false;
}
return true;
@@ -310,13 +313,10 @@ bool QXmlUtils::isNameChar(const QChar c)
\sa {http://www.w3.org/TR/REC-xml/#NT-PubidLiteral},
{Extensible Markup Language (XML) 1.0 (Fourth Edition), [12] PubidLiteral}
*/
-bool QXmlUtils::isPublicID(const QString &candidate)
+bool QXmlUtils::isPublicID(QStringView candidate)
{
- const int len = candidate.length();
-
- for(int i = 0; i < len; ++i)
- {
- const ushort cp = candidate.at(i).unicode();
+ for (QChar ch : candidate) {
+ const ushort cp = ch.unicode();
if ((cp >= 'a' && cp <= 'z')
|| (cp >= 'A' && cp <= 'Z')
@@ -369,7 +369,7 @@ bool QXmlUtils::isPublicID(const QString &candidate)
\sa {http://www.w3.org/TR/REC-xml-names/#NT-NCName},
{W3CNamespaces in XML 1.0 (Second Edition), [4] NCName}
*/
-bool QXmlUtils::isNCName(const QStringRef &ncName)
+bool QXmlUtils::isNCName(QStringView ncName)
{
if(ncName.isEmpty())
return false;
@@ -379,10 +379,7 @@ bool QXmlUtils::isNCName(const QStringRef &ncName)
if(!QXmlUtils::isLetter(first) && first.unicode() != '_' && first.unicode() != ':')
return false;
- const int len = ncName.size();
- for(int i = 0; i < len; ++i)
- {
- const QChar at = ncName.at(i);
+ for (QChar at : ncName) {
if(!QXmlUtils::isNameChar(at) || at == QLatin1Char(':'))
return false;
}
diff --git a/src/corelib/xml/qxmlutils_p.h b/src/corelib/xml/qxmlutils_p.h
index 6db347b3ee..db6bddd5be 100644
--- a/src/corelib/xml/qxmlutils_p.h
+++ b/src/corelib/xml/qxmlutils_p.h
@@ -68,13 +68,12 @@ class QXmlCharRange;
class Q_CORE_EXPORT QXmlUtils
{
public:
- static bool isEncName(const QString &encName);
+ static bool isEncName(QStringView encName);
static bool isChar(const QChar c);
static bool isNameChar(const QChar c);
static bool isLetter(const QChar c);
- static bool isNCName(const QStringRef &ncName);
- static inline bool isNCName(const QString &ncName) { return isNCName(QStringRef(&ncName)); }
- static bool isPublicID(const QString &candidate);
+ static bool isNCName(QStringView ncName);
+ static bool isPublicID(QStringView candidate);
private:
typedef const QXmlCharRange *RangeIter;