4#include "QtCore/qxmlstream.h"
6#if QT_CONFIG(xmlstream)
18#include <private/qoffsetstringarray_p.h>
19#include <private/qtools_p.h>
24#include <private/qstringconverter_p.h>
32enum { StreamEOF = ~0U };
35template <
typename Range>
36auto reversed(Range &
r)
40 auto begin() {
return std::make_reverse_iterator(std::end(*
r)); }
41 auto end() {
return std::make_reverse_iterator(std::begin(*
r)); }
47template <
typename Range>
48void reversed(
const Range &&) =
delete;
54 return R{haystack,
uchar(needle)};
60 return R{haystack,
uchar(needle)};
66 return R{haystack, needle};
72 return R{haystack, needle};
78 return R{haystack, needle};
87#define WRAP(method, Needle) \
88 auto method (QAnyStringView s, Needle needle) noexcept \
90 return s.visit([needle](auto s) { \
91 auto r = transform(s, needle); \
92 return r.haystack. method (r.needle); \
235#if QT_CONFIG(xmlstreamreader)
260 Q_D(QXmlStreamReader);
261 d->entityResolver = resolver;
273 Q_D(
const QXmlStreamReader);
274 return d->entityResolver;
429QXmlStreamReader::QXmlStreamReader()
465 Q_D(QXmlStreamReader);
468 d->dataBuffer =
data.toUtf8();
470 d->lockEncoding =
true;
476 d->lockEncoding =
true;
489QXmlStreamReader::QXmlStreamReader(
const QByteArray &
data, PrivateConstructorTag)
492 Q_D(QXmlStreamReader);
493 d->dataBuffer =
data;
499QXmlStreamReader::~QXmlStreamReader()
501 Q_D(QXmlStreamReader);
520 Q_D(QXmlStreamReader);
521 if (
d->deleteDevice) {
523 d->deleteDevice =
false;
536QIODevice *QXmlStreamReader::device()
const
538 Q_D(
const QXmlStreamReader);
564 Q_D(QXmlStreamReader);
567 d->lockEncoding =
true;
568 if (!
d->decoder.isValid())
570 addDataImpl(
data.toUtf8());
574 if (!
d->decoder.isValid())
591 Q_D(QXmlStreamReader);
593 qWarning(
"QXmlStreamReader: addData() with device()");
596 d->dataBuffer +=
data;
605void QXmlStreamReader::clear()
607 Q_D(QXmlStreamReader);
631bool QXmlStreamReader::atEnd()
const
633 Q_D(
const QXmlStreamReader);
635 && ((
d->type == QXmlStreamReader::Invalid &&
d->error == PrematureEndOfDocumentError)
636 || (
d->type == QXmlStreamReader::EndDocument))) {
638 return d->device->atEnd();
640 return !
d->dataBuffer.size();
642 return (
d->atEnd ||
d->type == QXmlStreamReader::Invalid);
664QXmlStreamReader::TokenType QXmlStreamReader::readNext()
666 Q_D(QXmlStreamReader);
668 if (!
d->hasCheckedStartDocument)
669 if (!
d->checkStartDocument())
672 if (
d->atEnd &&
d->type != EndDocument &&
d->type !=
Invalid)
673 d->raiseError(PrematureEndOfDocumentError);
674 else if (!
d->atEnd &&
d->type == EndDocument)
675 d->raiseWellFormedError(QXmlStream::tr(
"Extra content at end of document."));
676 }
else if (
d->error == PrematureEndOfDocumentError) {
698QXmlStreamReader::TokenType QXmlStreamReader::tokenType()
const
700 Q_D(
const QXmlStreamReader);
721bool QXmlStreamReader::readNextStartElement()
723 while (readNext() !=
Invalid) {
726 else if (isStartElement())
743void QXmlStreamReader::skipCurrentElement()
749 else if (isStartElement())
765 "ProcessingInstruction"
785void QXmlStreamReader::setNamespaceProcessing(
bool enable)
787 Q_D(QXmlStreamReader);
788 d->namespaceProcessing =
enable;
791bool QXmlStreamReader::namespaceProcessing()
const
793 Q_D(
const QXmlStreamReader);
794 return d->namespaceProcessing;
801QString QXmlStreamReader::tokenString()
const
803 Q_D(
const QXmlStreamReader);
813 return QLatin1StringView(QXmlStreamReader_XmlContextString.at(
static_cast<int>(ctxt)));
825 namespaceDeclaration.namespaceUri =
addToStringStorage(u
"http://www.w3.org/XML/1998/namespace");
830#if QT_CONFIG(xmlstreamreader)
836 deleteDevice =
false;
839 state_stack =
nullptr;
841 entityResolver =
nullptr;
843#define ADD_PREDEFINED(n, v) \
845 Entity e = Entity::createLiteral(n##_L1, v##_L1); \
846 entityHash.insert(qToStringViewIgnoringNull(e.name), std::move(e)); \
848 ADD_PREDEFINED(
"lt",
"<");
849 ADD_PREDEFINED(
"gt",
">");
850 ADD_PREDEFINED(
"amp",
"&");
851 ADD_PREDEFINED(
"apos",
"'");
852 ADD_PREDEFINED(
"quot",
"\"");
901 type = QXmlStreamReader::NoToken;
902 error = QXmlStreamReader::NoError;
913 Q_Q(QXmlStreamReader);
960 if (peekc == StreamEOF) {
1019 while ((
c =
getChar()) != StreamEOF) {
1046 if (tokenToInject >= 0)
1086 if (tokenToInject >= 0)
1194 while ((
c =
getChar()) != StreamEOF) {
1223 if (!(
c & 0xff0000)) {
1244 while ((
c =
getChar()) != StreamEOF) {
1277 while ((
c =
getChar()) != StreamEOF) {
1319 if (!(
c & 0xff0000)) {
1342 while ((
c =
getChar()) != StreamEOF) {
1347 return std::nullopt;
1376 if (
val &&
val->prefix ==
n + 1) {
1384 if (
val->prefix == 0) {
1409enum NameChar { NameBeginning, NameNotBeginning, NotName };
1411static const char Begi =
static_cast<char>(NameBeginning);
1412static const char NtBg =
static_cast<char>(NameNotBeginning);
1413static const char NotN =
static_cast<char>(NotName);
1415static const char nameCharTable[128] =
1418 NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
1419 NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
1421 NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
1422 NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
1424 NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
1425 NotN, NotN, NotN, NotN, NotN, NtBg, NtBg, NotN,
1427 NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg,
1428 NtBg, NtBg, Begi, NotN, NotN, NotN, NotN, NotN,
1430 NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
1431 Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
1433 Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
1434 Begi, Begi, Begi, NotN, NotN, NotN, NotN, Begi,
1436 NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
1437 Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
1439 Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
1440 Begi, Begi, Begi, NotN, NotN, NotN, NotN, NotN
1443static inline NameChar fastDetermineNameChar(
QChar ch)
1447 return static_cast<NameChar
>(nameCharTable[uc]);
1453 return NameBeginning;
1456 return NameNotBeginning;
1464 while ((
c =
getChar()) != StreamEOF) {
1465 if (fastDetermineNameChar(
QChar(
c)) == NotName) {
1503 char16_t c =
it->unicode();
1504 if (
c ==
'\n' ||
c ==
'\r')
1514 char16_t c =
it->unicode();
1515 if (
c ==
'&' ||
c ==
';')
1517 else if (
c ==
'\n' ||
c ==
'\r')
1585 if (namespaceDeclaration.prefix ==
prefix) {
1586 return namespaceDeclaration.namespaceUri;
1608 if (!dtdAttribute.isNamespaceAttribute
1609 || dtdAttribute.defaultValue.isNull()
1611 || dtdAttribute.attributeQualifiedName.isNull())
1618 if (dtdAttribute.attributePrefix.isEmpty() && dtdAttribute.attributeName ==
"xmlns"_L1) {
1620 namespaceDeclaration.prefix.clear();
1623 if (
ns ==
"http://www.w3.org/2000/xmlns/"_L1 ||
1624 ns ==
"http://www.w3.org/XML/1998/namespace"_L1)
1627 namespaceDeclaration.namespaceUri =
ns;
1628 }
else if (dtdAttribute.attributePrefix ==
"xmlns"_L1) {
1630 XmlStringRef namespacePrefix = dtdAttribute.attributeName;
1632 if (((namespacePrefix ==
"xml"_L1)
1633 ^ (
namespaceUri ==
"http://www.w3.org/XML/1998/namespace"_L1))
1636 || namespacePrefix ==
"xmlns"_L1)
1639 namespaceDeclaration.prefix = namespacePrefix;
1678 if (dtdAttribute.isNamespaceAttribute
1679 || dtdAttribute.defaultValue.isNull()
1681 || dtdAttribute.attributeQualifiedName.isNull())
1692 attribute.m_name = dtdAttribute.attributeName;
1693 attribute.m_qualifiedName = dtdAttribute.attributeQualifiedName;
1694 attribute.m_value = dtdAttribute.defaultValue;
1696 if (!dtdAttribute.attributePrefix.isEmpty()) {
1713 publicNamespaceDeclaration.m_prefix = namespaceDeclaration.prefix;
1714 publicNamespaceDeclaration.m_namespaceUri = namespaceDeclaration.namespaceUri;
1724 publicNotationDeclaration.m_name = notationDeclaration.
name;
1725 publicNotationDeclaration.m_systemId = notationDeclaration.
systemId;
1726 publicNotationDeclaration.m_publicId = notationDeclaration.
publicId;
1734 publicEntityDeclaration.m_name = entityDeclaration.
name;
1735 publicEntityDeclaration.m_notationName = entityDeclaration.
notationName;
1736 publicEntityDeclaration.m_systemId = entityDeclaration.
systemId;
1737 publicEntityDeclaration.m_publicId = entityDeclaration.
publicId;
1738 publicEntityDeclaration.m_value = entityDeclaration.
value;
1749 if (
sym(symbolIndex).
c ==
'x')
1754 ok &= (
s == 0x9 ||
s == 0xa ||
s == 0xd || (
s >= 0x20 &&
s <= 0xd7ff)
1765 const char16_t *
data = publicId.
utf16();
1768 for (
i = publicId.
size() - 1;
i >= 0; --
i) {
1771 case ' ':
case '\n':
case '\r':
case '-':
case '(':
case ')':
1772 case '+':
case ',':
case '.':
case '/':
case ':':
case '=':
1773 case '?':
case ';':
case '!':
case '*':
case '#':
case '@':
1774 case '$':
case '_':
case '%':
case '\'':
case '\"':
1798 type = QXmlStreamReader::StartDocument;
1801 raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
1811 err = QXmlStream::tr(
"Invalid XML version string.");
1813 err = QXmlStream::tr(
"Unsupported XML version.");
1828 if (
prefix.isEmpty() &&
key ==
"encoding"_L1) {
1832 err = QXmlStream::tr(
"The standalone pseudo attribute must appear after the encoding.");
1834 err = QXmlStream::tr(
"%1 is an invalid encoding name.").
arg(
value);
1840 err = QXmlStream::tr(
"Encoding %1 is unsupported").
arg(
value);
1846 }
else if (
prefix.isEmpty() &&
key ==
"standalone"_L1) {
1848 if (
value ==
"yes"_L1)
1850 else if (
value ==
"no"_L1)
1853 err = QXmlStream::tr(
"Standalone accepts only yes or no.");
1855 err = QXmlStream::tr(
"Invalid attribute in XML declaration: %1 = %2").
arg(
key).
arg(
value);
1867 this->error =
error;
1870 if (
error == QXmlStreamReader::PrematureEndOfDocumentError)
1871 errorString = QXmlStream::tr(
"Premature end of document.");
1872 else if (
error == QXmlStreamReader::CustomError)
1873 errorString = QXmlStream::tr(
"Invalid document.");
1876 type = QXmlStreamReader::Invalid;
1887 raiseError(QXmlStreamReader::NotWellFormedError,
1888 QXmlStream::tr(
"Length of XML attribute name exceeds implementation limits (4KiB "
1896 raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
1910 if (nexpected < nmax)
1915 if (nexpected && nexpected < nmax) {
1917 QString exp_str = QXmlStream::tr(
"'%1'",
"expected")
1919 if (nexpected == 2) {
1921 exp_str = QXmlStream::tr(
"%1 or '%2'",
"expected")
1923 }
else if (nexpected > 2) {
1925 for (;
s < nexpected - 1; ++
s) {
1927 exp_str = QXmlStream::tr(
"%1, '%2'",
"expected")
1931 exp_str = QXmlStream::tr(
"%1, or '%2'",
"expected")
1934 error_message = QXmlStream::tr(
"Expected %1, but got '%2'.")
1945 if (
error == QXmlStreamReader::NoError)
1946 raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
1953qint64 QXmlStreamReader::lineNumber()
const
1955 Q_D(
const QXmlStreamReader);
1956 return d->lineNumber + 1;
1963qint64 QXmlStreamReader::columnNumber()
const
1965 Q_D(
const QXmlStreamReader);
1966 return d->characterOffset -
d->lastLineStart +
d->readBufferPos;
1973qint64 QXmlStreamReader::characterOffset()
const
1975 Q_D(
const QXmlStreamReader);
1976 return d->characterOffset +
d->readBufferPos;
1985 Q_D(
const QXmlStreamReader);
1998 Q_D(
const QXmlStreamReader);
1999 if (
d->notationDeclarations.size())
2001 return d->publicNotationDeclarations;
2013 Q_D(
const QXmlStreamReader);
2014 if (
d->entityDeclarations.size())
2016 return d->publicEntityDeclarations;
2028 Q_D(
const QXmlStreamReader);
2029 if (
d->type == QXmlStreamReader::DTD)
2043 Q_D(
const QXmlStreamReader);
2044 if (
d->type == QXmlStreamReader::DTD)
2045 return d->dtdPublicId;
2058 Q_D(
const QXmlStreamReader);
2059 if (
d->type == QXmlStreamReader::DTD)
2060 return d->dtdSystemId;
2073int QXmlStreamReader::entityExpansionLimit()
const
2075 Q_D(
const QXmlStreamReader);
2076 return d->entityExpansionLimit;
2094void QXmlStreamReader::setEntityExpansionLimit(
int limit)
2096 Q_D(QXmlStreamReader);
2097 d->entityExpansionLimit =
limit;
2111 Q_D(
const QXmlStreamReader);
2112 if (
d->publicNamespaceDeclarations.isEmpty() &&
d->type == StartElement)
2114 return d->publicNamespaceDeclarations;
2130 Q_D(QXmlStreamReader);
2132 namespaceDeclaration.
prefix =
d->addToStringStorage(extraNamespaceDeclaration.
prefix());
2145 for (
const auto &extraNamespaceDeclaration : extraNamespaceDeclarations)
2146 addExtraNamespaceDeclaration(extraNamespaceDeclaration);
2167QString QXmlStreamReader::readElementText(ReadElementTextBehaviour behaviour)
2169 Q_D(QXmlStreamReader);
2170 if (isStartElement()) {
2173 switch (readNext()) {
2175 case EntityReference:
2180 case ProcessingInstruction:
2184 if (behaviour == SkipChildElements) {
2185 skipCurrentElement();
2187 }
else if (behaviour == IncludeChildElements) {
2188 result += readElementText(behaviour);
2193 if (
d->error || behaviour == ErrorOnUnexpectedElement) {
2195 d->raiseError(UnexpectedElementError, QXmlStream::tr(
"Expected character data."));
2210 Q_D(QXmlStreamReader);
2211 d->raiseError(CustomError,
message);
2219QString QXmlStreamReader::errorString()
const
2221 Q_D(
const QXmlStreamReader);
2222 if (
d->type == QXmlStreamReader::Invalid)
2223 return d->errorString;
2231QXmlStreamReader::Error QXmlStreamReader::error()
const
2233 Q_D(
const QXmlStreamReader);
2234 if (
d->type == QXmlStreamReader::Invalid)
2242QStringView QXmlStreamReader::processingInstructionTarget()
const
2244 Q_D(
const QXmlStreamReader);
2245 return d->processingInstructionTarget;
2251QStringView QXmlStreamReader::processingInstructionData()
const
2253 Q_D(
const QXmlStreamReader);
2254 return d->processingInstructionData;
2266 Q_D(
const QXmlStreamReader);
2277 Q_D(
const QXmlStreamReader);
2278 return d->namespaceUri;
2293QStringView QXmlStreamReader::qualifiedName()
const
2295 Q_D(
const QXmlStreamReader);
2296 return d->qualifiedName;
2310 Q_D(
const QXmlStreamReader);
2319 Q_D(
const QXmlStreamReader);
2320 return d->attributes;
2345 m_isDefault =
false;
2354 m_name = m_qualifiedName =
name;
2658 if (
attribute.qualifiedName() == qualifiedName)
2682#if QT_CONFIG(xmlstreamreader)
2719bool QXmlStreamReader::isWhitespace()
const
2721 Q_D(
const QXmlStreamReader);
2722 return d->type == QXmlStreamReader::Characters &&
d->isWhitespace;
2730bool QXmlStreamReader::isCDATA()
const
2732 Q_D(
const QXmlStreamReader);
2733 return d->type == QXmlStreamReader::Characters &&
d->isCDATA;
2746bool QXmlStreamReader::isStandaloneDocument()
const
2748 Q_D(
const QXmlStreamReader);
2749 return d->standalone;
2762bool QXmlStreamReader::hasStandaloneDeclaration()
const
2764 Q_D(
const QXmlStreamReader);
2765 return d->hasStandalone;
2775QStringView QXmlStreamReader::documentVersion()
const
2777 Q_D(
const QXmlStreamReader);
2778 if (
d->type == QXmlStreamReader::StartDocument)
2779 return d->documentVersion;
2790QStringView QXmlStreamReader::documentEncoding()
const
2792 Q_D(
const QXmlStreamReader);
2793 if (
d->type == QXmlStreamReader::StartDocument)
2794 return d->documentEncoding;
2875#if QT_CONFIG(xmlstreamwriter)
2879 QXmlStreamWriter *q_ptr;
2880 Q_DECLARE_PUBLIC(QXmlStreamWriter)
2882 QXmlStreamWriterPrivate(QXmlStreamWriter *
q);
2883 ~QXmlStreamWriterPrivate() {
2889 void writeEscaped(
QAnyStringView,
bool escapeWhitespace =
false);
2890 bool finishStartElement(
bool contents =
true);
2894 uint deleteDevice :1;
2895 uint inStartElement :1;
2896 uint inEmptyElement :1;
2897 uint lastWasStartElement :1;
2898 uint wroteSomething :1;
2900 uint hasEncodingError :1;
2901 uint autoFormatting :1;
2902 std::string autoFormattingIndent;
2903 NamespaceDeclaration emptyNamespace;
2906 NamespaceDeclaration &findNamespace(
QAnyStringView namespaceUri,
bool writeDeclaration =
false,
bool noDefault =
false);
2907 void writeNamespaceDeclaration(
const NamespaceDeclaration &namespaceDeclaration);
2909 int namespacePrefixCount;
2911 void indent(
int level);
2919QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *
q)
2920 : autoFormattingIndent(4,
' ')
2924 stringDevice =
nullptr;
2925 deleteDevice =
false;
2926 inStartElement = inEmptyElement =
false;
2927 wroteSomething =
false;
2929 hasEncodingError =
false;
2930 lastWasStartElement =
false;
2931 lastNamespaceDeclaration = 1;
2932 autoFormatting =
false;
2933 namespacePrefixCount = 0;
2942 s.visit([&] (
auto s) { doWriteToDevice(
s); });
2943 }
else if (stringDevice) {
2944 s.visit([&] (
auto s) { stringDevice->append(
s); });
2946 qWarning(
"QXmlStreamWriter: No device");
2950void QXmlStreamWriterPrivate::writeEscaped(
QAnyStringView s,
bool escapeWhitespace)
2954 s.visit([&] (
auto s) {
2955 using View =
decltype(
s);
2958 const auto end =
s.end();
2966 replacement =
"<"_L1;
2968 }
else if (*
it == u
'>') {
2969 replacement =
">"_L1;
2971 }
else if (*
it == u
'&') {
2972 replacement =
"&"_L1;
2974 }
else if (*
it == u
'\"') {
2975 replacement =
"""_L1;
2977 }
else if (*
it == u
'\t') {
2978 if (escapeWhitespace) {
2979 replacement =
"	"_L1;
2982 }
else if (*
it == u
'\n') {
2983 if (escapeWhitespace) {
2984 replacement =
" "_L1;
2987 }
else if (*
it == u
'\v' || *
it == u
'\f') {
2988 hasEncodingError =
true;
2990 }
else if (*
it == u
'\r') {
2991 if (escapeWhitespace) {
2992 replacement =
" "_L1;
2995 }
else if (*
it <= u
'\x1F' || *
it >= u
'\uFFFE') {
2996 hasEncodingError =
true;
3003 escaped.
append(replacement);
3012void QXmlStreamWriterPrivate::writeNamespaceDeclaration(
const NamespaceDeclaration &namespaceDeclaration) {
3013 if (namespaceDeclaration.prefix.isEmpty()) {
3015 write(namespaceDeclaration.namespaceUri);
3019 write(namespaceDeclaration.prefix);
3021 write(namespaceDeclaration.namespaceUri);
3026bool QXmlStreamWriterPrivate::finishStartElement(
bool contents)
3028 bool hadSomethingWritten = wroteSomething;
3030 if (!inStartElement)
3031 return hadSomethingWritten;
3033 if (inEmptyElement) {
3035 QXmlStreamWriterPrivate::Tag
tag = tagStack_pop();
3036 lastNamespaceDeclaration =
tag.namespaceDeclarationsSize;
3037 lastWasStartElement =
false;
3041 inStartElement = inEmptyElement =
false;
3042 lastNamespaceDeclaration = namespaceDeclarations.size();
3043 return hadSomethingWritten;
3048 for (NamespaceDeclaration &namespaceDeclaration : reversed(namespaceDeclarations)) {
3049 if (namespaceDeclaration.namespaceUri == namespaceUri) {
3050 if (!noDefault || !namespaceDeclaration.prefix.isEmpty())
3051 return namespaceDeclaration;
3055 return emptyNamespace;
3056 NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
3058 namespaceDeclaration.
prefix.clear();
3061 int n = ++namespacePrefixCount;
3064 qsizetype j = namespaceDeclarations.size() - 2;
3065 while (
j >= 0 && namespaceDeclarations.at(
j).prefix !=
s)
3070 namespaceDeclaration.prefix = addToStringStorage(
s);
3072 namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
3073 if (writeDeclaration)
3074 writeNamespaceDeclaration(namespaceDeclaration);
3075 return namespaceDeclaration;
3080void QXmlStreamWriterPrivate::indent(
int level)
3084 write(autoFormattingIndent);
3087void QXmlStreamWriterPrivate::doWriteToDevice(
QStringView s)
3090 char buffer [3 * MaxChunkSize];
3092 while (!
s.isEmpty()) {
3093 const qsizetype chunkSize = std::min(
s.size(), MaxChunkSize);
3096 s =
s.sliced(chunkSize);
3098 if (
state.remainingChars > 0)
3099 hasEncodingError =
true;
3112 char buffer [2 * MaxChunkSize];
3113 while (!
s.isEmpty()) {
3114 const qsizetype chunkSize = std::min(
s.size(), MaxChunkSize);
3117 s =
s.sliced(chunkSize);
3126QXmlStreamWriter::QXmlStreamWriter()
3127 : d_ptr(new QXmlStreamWriterPrivate(
this))
3135 : d_ptr(new QXmlStreamWriterPrivate(
this))
3137 Q_D(QXmlStreamWriter);
3146 : d_ptr(new QXmlStreamWriterPrivate(
this))
3148 Q_D(QXmlStreamWriter);
3151 d->deleteDevice =
true;
3158QXmlStreamWriter::QXmlStreamWriter(
QString *
string)
3159 : d_ptr(new QXmlStreamWriterPrivate(
this))
3161 Q_D(QXmlStreamWriter);
3168QXmlStreamWriter::~QXmlStreamWriter()
3181 Q_D(QXmlStreamWriter);
3184 d->stringDevice =
nullptr;
3185 if (
d->deleteDevice) {
3187 d->deleteDevice =
false;
3198QIODevice *QXmlStreamWriter::device()
const
3200 Q_D(
const QXmlStreamWriter);
3228void QXmlStreamWriter::setAutoFormatting(
bool enable)
3230 Q_D(QXmlStreamWriter);
3239bool QXmlStreamWriter::autoFormatting()
const
3241 Q_D(
const QXmlStreamWriter);
3242 return d->autoFormatting;
3259void QXmlStreamWriter::setAutoFormattingIndent(
int spacesOrTabs)
3261 Q_D(QXmlStreamWriter);
3262 d->autoFormattingIndent.assign(
size_t(
qAbs(spacesOrTabs)), spacesOrTabs >= 0 ?
' ' :
'\t');
3265int QXmlStreamWriter::autoFormattingIndent()
const
3267 Q_D(
const QXmlStreamWriter);
3269 return indent.count(u
' ') - indent.count(u
'\t');
3281bool QXmlStreamWriter::hasError()
const
3283 Q_D(
const QXmlStreamWriter);
3284 return d->hasIoError ||
d->hasEncodingError;
3300 Q_D(QXmlStreamWriter);
3304 d->write(qualifiedName);
3306 d->writeEscaped(
value,
true);
3323 Q_D(QXmlStreamWriter);
3326 QXmlStreamWriterPrivate::NamespaceDeclaration &namespaceDeclaration =
d->findNamespace(namespaceUri,
true,
true);
3328 if (!namespaceDeclaration.prefix.isEmpty()) {
3329 d->write(namespaceDeclaration.prefix);
3334 d->writeEscaped(
value,
true);
3366 Q_D(QXmlStreamWriter);
3369 for (
const auto &attr : attributes)
3387 Q_D(QXmlStreamWriter);
3388 d->finishStartElement();
3389 d->write(
"<![CDATA[");
3416 Q_D(QXmlStreamWriter);
3417 d->finishStartElement();
3418 d->writeEscaped(
text);
3431 Q_D(QXmlStreamWriter);
3433 if (!
d->finishStartElement(
false) &&
d->autoFormatting)
3434 d->indent(
d->tagStack.size());
3438 d->inStartElement =
d->lastWasStartElement =
false;
3450 Q_D(QXmlStreamWriter);
3451 d->finishStartElement();
3452 if (
d->autoFormatting)
3455 if (
d->autoFormatting)
3468void QXmlStreamWriter::writeEmptyElement(
QAnyStringView qualifiedName)
3470 Q_D(QXmlStreamWriter);
3472 d->writeStartElement({}, qualifiedName);
3473 d->inEmptyElement =
true;
3489 Q_D(QXmlStreamWriter);
3491 d->writeStartElement(namespaceUri,
name);
3492 d->inEmptyElement =
true;
3538void QXmlStreamWriter::writeEndDocument()
3540 Q_D(QXmlStreamWriter);
3541 while (
d->tagStack.size())
3551void QXmlStreamWriter::writeEndElement()
3553 Q_D(QXmlStreamWriter);
3554 if (
d->tagStack.isEmpty())
3558 if (
d->inStartElement && !
d->inEmptyElement) {
3560 d->lastWasStartElement =
d->inStartElement =
false;
3561 QXmlStreamWriterPrivate::Tag
tag =
d->tagStack_pop();
3562 d->lastNamespaceDeclaration =
tag.namespaceDeclarationsSize;
3566 if (!
d->finishStartElement(
false) && !
d->lastWasStartElement &&
d->autoFormatting)
3567 d->indent(
d->tagStack.size()-1);
3568 if (
d->tagStack.isEmpty())
3570 d->lastWasStartElement =
false;
3571 QXmlStreamWriterPrivate::Tag
tag =
d->tagStack_pop();
3572 d->lastNamespaceDeclaration =
tag.namespaceDeclarationsSize;
3574 if (!
tag.namespaceDeclaration.prefix.isEmpty()) {
3575 d->write(
tag.namespaceDeclaration.prefix);
3592 Q_D(QXmlStreamWriter);
3593 d->finishStartElement();
3619 Q_D(QXmlStreamWriter);
3622 d->findNamespace(namespaceUri,
d->inStartElement);
3624 Q_ASSERT(!((prefix ==
"xml"_L1) ^ (namespaceUri ==
"http://www.w3.org/XML/1998/namespace"_L1)));
3625 Q_ASSERT(namespaceUri !=
"http://www.w3.org/2000/xmlns/"_L1);
3626 QXmlStreamWriterPrivate::NamespaceDeclaration &namespaceDeclaration =
d->namespaceDeclarations.push();
3627 namespaceDeclaration.prefix =
d->addToStringStorage(prefix);
3628 namespaceDeclaration.namespaceUri =
d->addToStringStorage(namespaceUri);
3629 if (
d->inStartElement)
3630 d->writeNamespaceDeclaration(namespaceDeclaration);
3648void QXmlStreamWriter::writeDefaultNamespace(
QAnyStringView namespaceUri)
3650 Q_D(QXmlStreamWriter);
3651 Q_ASSERT(namespaceUri !=
"http://www.w3.org/XML/1998/namespace"_L1);
3652 Q_ASSERT(namespaceUri !=
"http://www.w3.org/2000/xmlns/"_L1);
3653 QXmlStreamWriterPrivate::NamespaceDeclaration &namespaceDeclaration =
d->namespaceDeclarations.push();
3654 namespaceDeclaration.prefix.clear();
3655 namespaceDeclaration.namespaceUri =
d->addToStringStorage(namespaceUri);
3656 if (
d->inStartElement)
3657 d->writeNamespaceDeclaration(namespaceDeclaration);
3670 Q_D(QXmlStreamWriter);
3672 if (!
d->finishStartElement(
false) &&
d->autoFormatting)
3673 d->indent(
d->tagStack.size());
3676 if (!
data.isNull()) {
3692void QXmlStreamWriter::writeStartDocument()
3694 writeStartDocument(
"1.0"_L1);
3708 Q_D(QXmlStreamWriter);
3709 d->finishStartElement(
false);
3710 d->write(
"<?xml version=\"");
3713 d->write(
"\" encoding=\"UTF-8");
3726void QXmlStreamWriter::writeStartDocument(
QAnyStringView version,
bool standalone)
3728 Q_D(QXmlStreamWriter);
3729 d->finishStartElement(
false);
3730 d->write(
"<?xml version=\"");
3733 d->write(
"\" encoding=\"UTF-8");
3735 d->write(
"\" standalone=\"yes\"?>");
3737 d->write(
"\" standalone=\"no\"?>");
3751void QXmlStreamWriter::writeStartElement(
QAnyStringView qualifiedName)
3753 Q_D(QXmlStreamWriter);
3755 d->writeStartElement({}, qualifiedName);
3772 Q_D(QXmlStreamWriter);
3774 d->writeStartElement(namespaceUri,
name);
3779 if (!finishStartElement(
false) && autoFormatting)
3780 indent(tagStack.size());
3782 Tag &
tag = tagStack_push();
3783 tag.name = addToStringStorage(
name);
3784 tag.namespaceDeclaration = findNamespace(namespaceUri);
3786 if (!
tag.namespaceDeclaration.prefix.isEmpty()) {
3787 write(
tag.namespaceDeclaration.prefix);
3791 inStartElement = lastWasStartElement =
true;
3793 for (
qsizetype i = lastNamespaceDeclaration;
i < namespaceDeclarations.size(); ++
i)
3794 writeNamespaceDeclaration(namespaceDeclarations[
i]);
3795 tag.namespaceDeclarationsSize = lastNamespaceDeclaration;
3798#if QT_CONFIG(xmlstreamreader)
3806void QXmlStreamWriter::writeCurrentToken(
const QXmlStreamReader &reader)
3808 switch (
reader.tokenType()) {
3809 case QXmlStreamReader::NoToken:
3811 case QXmlStreamReader::StartDocument:
3812 writeStartDocument();
3814 case QXmlStreamReader::EndDocument:
3817 case QXmlStreamReader::StartElement: {
3820 for (
const auto &namespaceDeclaration : decls) {
3821 writeNamespace(namespaceDeclaration.namespaceUri(),
3822 namespaceDeclaration.prefix());
3824 writeAttributes(
reader.attributes());
3826 case QXmlStreamReader::EndElement:
3829 case QXmlStreamReader::Characters:
3835 case QXmlStreamReader::Comment:
3838 case QXmlStreamReader::DTD:
3841 case QXmlStreamReader::EntityReference:
3842 writeEntityReference(
reader.name());
3844 case QXmlStreamReader::ProcessingInstruction:
3845 writeProcessingInstruction(
reader.processingInstructionTarget(),
3846 reader.processingInstructionData());
3850 qWarning(
"QXmlStreamWriter: writeCurrentToken() with invalid state.");
3855static constexpr bool isTokenAllowedInContext(QXmlStreamReader::TokenType
type,
3859 case QXmlStreamReader::StartDocument:
3860 case QXmlStreamReader::DTD:
3863 case QXmlStreamReader::StartElement:
3864 case QXmlStreamReader::EndElement:
3865 case QXmlStreamReader::Characters:
3866 case QXmlStreamReader::EntityReference:
3867 case QXmlStreamReader::EndDocument:
3870 case QXmlStreamReader::Comment:
3871 case QXmlStreamReader::ProcessingInstruction:
3874 case QXmlStreamReader::NoToken:
3875 case QXmlStreamReader::Invalid:
3880#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
3881 Q_UNREACHABLE_RETURN(
false);
3897 if (
type == QXmlStreamReader::Invalid ||
type == QXmlStreamReader::NoToken)
3917 Q_Q(QXmlStreamReader);
3924 if (
error != QXmlStreamReader::Error::NoError)
3928 raiseError(QXmlStreamReader::UnexpectedElementError,
3929 QObject::tr(
"Unexpected token type %1 in %2.")
3934 if (
type != QXmlStreamReader::DTD)
3939 raiseError(QXmlStreamReader::UnexpectedElementError,
3940 QObject::tr(
"Found second DTD token in %1.").
arg(contextString(
context)));
IOBluetoothDevice * device
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
\inmodule QtCore \reentrant
constexpr qsizetype size() const noexcept
constexpr const_pointer data() const noexcept
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
void clear()
Clears the contents of the byte array and makes it null.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
Category
This enum maps the Unicode character categories.
\inmodule QtCore \reentrant
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
QString text(const QString &key) const
void reserve(qsizetype size)
void resize(qsizetype size)
bool hasError() const noexcept
Returns true if a conversion could not correctly convert a character.
bool isValid() const noexcept
Returns true if this is a valid string converter that can be used for encoding or decoding text.
static Q_CORE_EXPORT std::optional< Encoding > encodingForData(QByteArrayView data, char16_t expectedFirstCharacter=0) noexcept
Returns the encoding for the content of data if it can be determined.
constexpr const storage_type * utf16() const noexcept
constexpr qsizetype size() const noexcept
Returns the size of this string view, in UTF-16 code units (that is, surrogate pairs count as two for...
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void clear()
Clears the contents of the string and makes it null.
bool isNull() const
Returns true if this string is null; otherwise returns false.
qsizetype size() const
Returns the number of characters in this string.
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
QString first(qsizetype n) const
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString sliced(qsizetype pos) const
QString & append(QChar c)
QByteArray toUtf8() const &
void resize(qsizetype size)
Sets the size of the string to size characters.
QStringView value() const
QStringView qualifiedName() const
QStringView namespaceUri() const
Q_CORE_EXPORT void append(const QString &namespaceUri, const QString &name, const QString &value)
Q_CORE_EXPORT QStringView value(QAnyStringView namespaceUri, QAnyStringView name) const noexcept
QXmlStreamEntityDeclaration()
virtual QString resolveEntity(const QString &publicId, const QString &systemId)
virtual QString resolveUndeclaredEntity(const QString &name)
virtual ~QXmlStreamEntityResolver()
static int t_action(int state, int token)
static const char *const spell[]
QStringView namespaceUri() const
QXmlStreamNamespaceDeclaration()
QStringView prefix() const
QXmlStreamNotationDeclaration()
QXmlStreamReaderPrivate(QXmlStreamReader *q)
bool scanAfterLangleBang()
uint referenceToUnparsedEntityDetected
void parseEntity(const QString &value)
void raiseError(QXmlStreamReader::Error error, const QString &message=QString())
~QXmlStreamReaderPrivate()
XmlStringRef documentVersion
XmlStringRef qualifiedName
bool scanUntil(const char *str, short tokenToInject=-1)
XmlStringRef symPrefix(int index)
void checkPublicLiteral(QStringView publicId)
XmlContext currentContext
bool isValidToken(QXmlStreamReader::TokenType type)
bool lastAttributeIsCData
uint referenceToParameterEntityDetected
XmlStringRef namespaceUri
qsizetype fastScanLiteralContent()
QXmlStreamEntityDeclarations publicEntityDeclarations
QString resolveUndeclaredEntity(const QString &name)
std::optional< qsizetype > fastScanName(Value *val=nullptr)
QXmlStreamAttributes attributes
void putString(QStringView s, qsizetype from=0)
Value & sym(int index) const
uint resolveCharRef(int symbolIndex)
QXmlStreamSimpleStack< EntityDeclaration > entityDeclarations
qsizetype fastScanNMTOKEN()
void putStringLiteral(QStringView s)
void putReplacement(QStringView s)
bool scanAfterDefaultDecl()
std::unique_ptr< QXmlStreamReaderPrivate > entityParser
XmlStringRef symName(int index)
uint filterCarriageReturn()
void putReplacementInAttributeValue(QStringView s)
QXmlStreamSimpleStack< Attribute > attributeStack
XmlStringRef namespaceForPrefix(QStringView prefix)
qsizetype fastScanSpace()
void raiseNamePrefixTooLongError()
void resolvePublicNamespaces()
QXmlStreamSimpleStack< uint > putStack
QHash< QStringView, Entity > parameterEntityHash
void raiseWellFormedError(const QString &message)
QXmlStreamNotationDeclarations publicNotationDeclarations
XmlStringRef documentEncoding
QXmlStreamNamespaceDeclarations publicNamespaceDeclarations
QXmlStreamEntityResolver * entityResolver
QXmlStreamSimpleStack< DtdAttribute > dtdAttributes
uint hasExternalDtdSubset
qsizetype fastScanContentCharList()
void injectToken(ushort tokenToInject)
bool checkStartDocument()
XmlStringRef symString(int index)
QXmlStreamReader::Error error
QXmlStreamSimpleStack< NotationDeclaration > notationDeclarations
bool scanString(const char *str, short tokenToInject, bool requireSpace=true)
uint hasCheckedStartDocument
bool scanPublicOrSystem()
void reserve(qsizetype extraCapacity)
static bool isEncName(QStringView encName)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
int toUtf8(char16_t u, OutputPtr &dst, InputPtr &src, InputPtr end)
constexpr bool isAsciiLetterOrNumber(char32_t c) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
QImageReader reader("image.png")
[1]
static void writeAttribute(QXmlStreamWriter *stream, const QVariant &attribute)
AudioChannelLayoutTag tag
DBusConnection const char * rule
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
EGLOutputLayerEXT EGLint attribute
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
constexpr auto qOffsetStringArray(const char(&...strings)[Nx]) noexcept
static bool contains(const QJsonArray &haystack, unsigned needle)
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLuint GLint level
GLenum GLenum GLsizei count
GLuint GLsizei const GLchar * message
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLenum GLenum transform
GLdouble GLdouble GLdouble GLdouble q
GLsizei const GLchar *const * string
[0]
GLbitfield GLuint readBuffer
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
Q_CHECK_PTR(a=new int[80])
gzip write("uncompressed data")
writeStartElement(qualifiedName)
[0]
\inmodule QtCore \reentrant
static Q_CORE_EXPORT QByteArray convertFromUnicode(QStringView in)
static Q_CORE_EXPORT char * convertFromLatin1(char *out, QLatin1StringView in)
XmlStringRef notationName