1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QXMLSTREAM_H |
5 | #define QXMLSTREAM_H |
6 | |
7 | #include <QtCore/qiodevice.h> |
8 | |
9 | #if QT_CONFIG(xmlstream) |
10 | |
11 | #include <QtCore/qlist.h> |
12 | #include <QtCore/qscopedpointer.h> |
13 | #include <QtCore/qstring.h> |
14 | |
15 | QT_BEGIN_NAMESPACE |
16 | |
17 | namespace QtPrivate { |
18 | |
19 | class QXmlString { |
20 | QStringPrivate m_string; |
21 | public: |
22 | QXmlString(QStringPrivate &&d) : m_string(std::move(d)) {} |
23 | QXmlString(const QString &s) : m_string(s.data_ptr()) {} |
24 | QXmlString & operator=(const QString &s) { m_string = s.data_ptr(); return *this; } |
25 | QXmlString & operator=(QString &&s) { m_string.swap(other&: s.data_ptr()); return *this; } |
26 | inline constexpr QXmlString() {} |
27 | |
28 | void swap(QXmlString &other) noexcept |
29 | { |
30 | m_string.swap(other&: other.m_string); |
31 | } |
32 | |
33 | inline operator QStringView() const { return QStringView(m_string.data(), m_string.size); } |
34 | inline qsizetype size() const { return m_string.size; } |
35 | }; |
36 | |
37 | } |
38 | Q_DECLARE_SHARED(QtPrivate::QXmlString) |
39 | |
40 | |
41 | class QXmlStreamReaderPrivate; |
42 | class QXmlStreamAttributes; |
43 | class Q_CORE_EXPORT QXmlStreamAttribute { |
44 | QtPrivate::QXmlString m_name, m_namespaceUri, m_qualifiedName, m_value; |
45 | uint m_isDefault : 1; |
46 | friend class QXmlStreamReaderPrivate; |
47 | friend class QXmlStreamAttributes; |
48 | public: |
49 | QXmlStreamAttribute(); |
50 | QXmlStreamAttribute(const QString &qualifiedName, const QString &value); |
51 | QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value); |
52 | |
53 | inline QStringView namespaceUri() const { return m_namespaceUri; } |
54 | inline QStringView name() const { return m_name; } |
55 | inline QStringView qualifiedName() const { return m_qualifiedName; } |
56 | inline QStringView prefix() const { |
57 | return QStringView(m_qualifiedName).left(n: qMax(a: 0, b: m_qualifiedName.size() - m_name.size() - 1)); |
58 | } |
59 | inline QStringView value() const { return m_value; } |
60 | inline bool isDefault() const { return m_isDefault; } |
61 | inline bool operator==(const QXmlStreamAttribute &other) const { |
62 | return (value() == other.value() |
63 | && (namespaceUri().isNull() ? (qualifiedName() == other.qualifiedName()) |
64 | : (namespaceUri() == other.namespaceUri() && name() == other.name()))); |
65 | } |
66 | inline bool operator!=(const QXmlStreamAttribute &other) const |
67 | { return !operator==(other); } |
68 | }; |
69 | |
70 | Q_DECLARE_TYPEINFO(QXmlStreamAttribute, Q_RELOCATABLE_TYPE); |
71 | |
72 | // We export each out-of-line method individually to prevent MSVC from |
73 | // exporting the whole QList class. |
74 | class QXmlStreamAttributes : public QList<QXmlStreamAttribute> |
75 | { |
76 | public: |
77 | inline QXmlStreamAttributes() {} |
78 | #if QT_CORE_REMOVED_SINCE(6, 6) |
79 | Q_CORE_EXPORT QStringView value(const QString &namespaceUri, const QString &name) const; |
80 | Q_CORE_EXPORT QStringView value(const QString &namespaceUri, QLatin1StringView name) const; |
81 | Q_CORE_EXPORT QStringView value(QLatin1StringView namespaceUri, QLatin1StringView name) const; |
82 | Q_CORE_EXPORT QStringView value(const QString &qualifiedName) const; |
83 | Q_CORE_EXPORT QStringView value(QLatin1StringView qualifiedName) const; |
84 | #endif |
85 | Q_CORE_EXPORT QStringView value(QAnyStringView namespaceUri, QAnyStringView name) const noexcept; |
86 | Q_CORE_EXPORT QStringView value(QAnyStringView qualifiedName) const noexcept; |
87 | |
88 | Q_CORE_EXPORT void append(const QString &namespaceUri, const QString &name, const QString &value); |
89 | Q_CORE_EXPORT void append(const QString &qualifiedName, const QString &value); |
90 | |
91 | bool hasAttribute(QAnyStringView qualifiedName) const |
92 | { |
93 | return !value(qualifiedName).isNull(); |
94 | } |
95 | |
96 | bool hasAttribute(QAnyStringView namespaceUri, QAnyStringView name) const |
97 | { |
98 | return !value(namespaceUri, name).isNull(); |
99 | } |
100 | |
101 | using QList<QXmlStreamAttribute>::append; |
102 | }; |
103 | |
104 | class Q_CORE_EXPORT QXmlStreamNamespaceDeclaration { |
105 | QtPrivate::QXmlString m_prefix, m_namespaceUri; |
106 | |
107 | friend class QXmlStreamReaderPrivate; |
108 | public: |
109 | QXmlStreamNamespaceDeclaration(); |
110 | QXmlStreamNamespaceDeclaration(const QString &prefix, const QString &namespaceUri); |
111 | |
112 | inline QStringView prefix() const { return m_prefix; } |
113 | inline QStringView namespaceUri() const { return m_namespaceUri; } |
114 | inline bool operator==(const QXmlStreamNamespaceDeclaration &other) const { |
115 | return (prefix() == other.prefix() && namespaceUri() == other.namespaceUri()); |
116 | } |
117 | inline bool operator!=(const QXmlStreamNamespaceDeclaration &other) const |
118 | { return !operator==(other); } |
119 | }; |
120 | |
121 | Q_DECLARE_TYPEINFO(QXmlStreamNamespaceDeclaration, Q_RELOCATABLE_TYPE); |
122 | typedef QList<QXmlStreamNamespaceDeclaration> QXmlStreamNamespaceDeclarations; |
123 | |
124 | class Q_CORE_EXPORT QXmlStreamNotationDeclaration { |
125 | QtPrivate::QXmlString m_name, m_systemId, m_publicId; |
126 | |
127 | friend class QXmlStreamReaderPrivate; |
128 | public: |
129 | QXmlStreamNotationDeclaration(); |
130 | |
131 | inline QStringView name() const { return m_name; } |
132 | inline QStringView systemId() const { return m_systemId; } |
133 | inline QStringView publicId() const { return m_publicId; } |
134 | inline bool operator==(const QXmlStreamNotationDeclaration &other) const { |
135 | return (name() == other.name() && systemId() == other.systemId() |
136 | && publicId() == other.publicId()); |
137 | } |
138 | inline bool operator!=(const QXmlStreamNotationDeclaration &other) const |
139 | { return !operator==(other); } |
140 | }; |
141 | |
142 | Q_DECLARE_TYPEINFO(QXmlStreamNotationDeclaration, Q_RELOCATABLE_TYPE); |
143 | typedef QList<QXmlStreamNotationDeclaration> QXmlStreamNotationDeclarations; |
144 | |
145 | class Q_CORE_EXPORT QXmlStreamEntityDeclaration { |
146 | QtPrivate::QXmlString m_name, m_notationName, m_systemId, m_publicId, m_value; |
147 | |
148 | friend class QXmlStreamReaderPrivate; |
149 | public: |
150 | QXmlStreamEntityDeclaration(); |
151 | |
152 | inline QStringView name() const { return m_name; } |
153 | inline QStringView notationName() const { return m_notationName; } |
154 | inline QStringView systemId() const { return m_systemId; } |
155 | inline QStringView publicId() const { return m_publicId; } |
156 | inline QStringView value() const { return m_value; } |
157 | inline bool operator==(const QXmlStreamEntityDeclaration &other) const { |
158 | return (name() == other.name() |
159 | && notationName() == other.notationName() |
160 | && systemId() == other.systemId() |
161 | && publicId() == other.publicId() |
162 | && value() == other.value()); |
163 | } |
164 | inline bool operator!=(const QXmlStreamEntityDeclaration &other) const |
165 | { return !operator==(other); } |
166 | }; |
167 | |
168 | Q_DECLARE_TYPEINFO(QXmlStreamEntityDeclaration, Q_RELOCATABLE_TYPE); |
169 | typedef QList<QXmlStreamEntityDeclaration> QXmlStreamEntityDeclarations; |
170 | |
171 | class Q_CORE_EXPORT QXmlStreamEntityResolver |
172 | { |
173 | public: |
174 | virtual ~QXmlStreamEntityResolver(); |
175 | virtual QString resolveEntity(const QString& publicId, const QString& systemId); |
176 | virtual QString resolveUndeclaredEntity(const QString &name); |
177 | }; |
178 | |
179 | #if QT_CONFIG(xmlstreamreader) |
180 | class Q_CORE_EXPORT QXmlStreamReader |
181 | { |
182 | QDOC_PROPERTY(bool namespaceProcessing READ namespaceProcessing WRITE setNamespaceProcessing) |
183 | public: |
184 | enum TokenType { |
185 | NoToken = 0, |
186 | Invalid, |
187 | StartDocument, |
188 | EndDocument, |
189 | StartElement, |
190 | EndElement, |
191 | Characters, |
192 | , |
193 | DTD, |
194 | EntityReference, |
195 | ProcessingInstruction |
196 | }; |
197 | |
198 | |
199 | QXmlStreamReader(); |
200 | explicit QXmlStreamReader(QIODevice *device); |
201 | #if QT_CORE_REMOVED_SINCE(6, 5) |
202 | explicit QXmlStreamReader(const QByteArray &data); |
203 | explicit QXmlStreamReader(const QString &data); |
204 | explicit QXmlStreamReader(const char * data); |
205 | #endif // QT_CORE_REMOVED_SINCE(6, 5) |
206 | Q_WEAK_OVERLOAD |
207 | explicit QXmlStreamReader(const QByteArray &data) |
208 | : QXmlStreamReader(data, PrivateConstructorTag{}) { } |
209 | explicit QXmlStreamReader(QAnyStringView data); |
210 | ~QXmlStreamReader(); |
211 | |
212 | void setDevice(QIODevice *device); |
213 | QIODevice *device() const; |
214 | #if QT_CORE_REMOVED_SINCE(6, 5) |
215 | void addData(const QByteArray &data); |
216 | void addData(const QString &data); |
217 | void addData(const char *data); |
218 | #endif // QT_CORE_REMOVED_SINCE(6, 5) |
219 | Q_WEAK_OVERLOAD |
220 | void addData(const QByteArray &data) { addDataImpl(data); } |
221 | void addData(QAnyStringView data); |
222 | void clear(); |
223 | |
224 | |
225 | bool atEnd() const; |
226 | TokenType readNext(); |
227 | |
228 | bool readNextStartElement(); |
229 | void skipCurrentElement(); |
230 | |
231 | TokenType tokenType() const; |
232 | QString tokenString() const; |
233 | |
234 | void setNamespaceProcessing(bool); |
235 | bool namespaceProcessing() const; |
236 | |
237 | inline bool isStartDocument() const { return tokenType() == StartDocument; } |
238 | inline bool isEndDocument() const { return tokenType() == EndDocument; } |
239 | inline bool isStartElement() const { return tokenType() == StartElement; } |
240 | inline bool isEndElement() const { return tokenType() == EndElement; } |
241 | inline bool isCharacters() const { return tokenType() == Characters; } |
242 | bool isWhitespace() const; |
243 | bool isCDATA() const; |
244 | inline bool () const { return tokenType() == Comment; } |
245 | inline bool isDTD() const { return tokenType() == DTD; } |
246 | inline bool isEntityReference() const { return tokenType() == EntityReference; } |
247 | inline bool isProcessingInstruction() const { return tokenType() == ProcessingInstruction; } |
248 | |
249 | bool isStandaloneDocument() const; |
250 | bool hasStandaloneDeclaration() const; |
251 | QStringView documentVersion() const; |
252 | QStringView documentEncoding() const; |
253 | |
254 | qint64 lineNumber() const; |
255 | qint64 columnNumber() const; |
256 | qint64 characterOffset() const; |
257 | |
258 | QXmlStreamAttributes attributes() const; |
259 | |
260 | enum ReadElementTextBehaviour { |
261 | ErrorOnUnexpectedElement, |
262 | IncludeChildElements, |
263 | SkipChildElements |
264 | }; |
265 | QString readElementText(ReadElementTextBehaviour behaviour = ErrorOnUnexpectedElement); |
266 | |
267 | QStringView name() const; |
268 | QStringView namespaceUri() const; |
269 | QStringView qualifiedName() const; |
270 | QStringView prefix() const; |
271 | |
272 | QStringView processingInstructionTarget() const; |
273 | QStringView processingInstructionData() const; |
274 | |
275 | QStringView text() const; |
276 | |
277 | QXmlStreamNamespaceDeclarations namespaceDeclarations() const; |
278 | void (const QXmlStreamNamespaceDeclaration &); |
279 | void (const QXmlStreamNamespaceDeclarations &); |
280 | QXmlStreamNotationDeclarations notationDeclarations() const; |
281 | QXmlStreamEntityDeclarations entityDeclarations() const; |
282 | QStringView dtdName() const; |
283 | QStringView dtdPublicId() const; |
284 | QStringView dtdSystemId() const; |
285 | |
286 | int entityExpansionLimit() const; |
287 | void setEntityExpansionLimit(int limit); |
288 | |
289 | enum Error { |
290 | NoError, |
291 | UnexpectedElementError, |
292 | CustomError, |
293 | NotWellFormedError, |
294 | PrematureEndOfDocumentError |
295 | }; |
296 | void raiseError(const QString& message = QString()); |
297 | QString errorString() const; |
298 | Error error() const; |
299 | |
300 | inline bool hasError() const |
301 | { |
302 | return error() != NoError; |
303 | } |
304 | |
305 | void setEntityResolver(QXmlStreamEntityResolver *resolver); |
306 | QXmlStreamEntityResolver *entityResolver() const; |
307 | |
308 | private: |
309 | struct PrivateConstructorTag { }; |
310 | QXmlStreamReader(const QByteArray &data, PrivateConstructorTag); |
311 | void addDataImpl(const QByteArray &data); |
312 | |
313 | Q_DISABLE_COPY(QXmlStreamReader) |
314 | Q_DECLARE_PRIVATE(QXmlStreamReader) |
315 | QScopedPointer<QXmlStreamReaderPrivate> d_ptr; |
316 | |
317 | }; |
318 | #endif // feature xmlstreamreader |
319 | |
320 | #if QT_CONFIG(xmlstreamwriter) |
321 | |
322 | class QXmlStreamWriterPrivate; |
323 | |
324 | class Q_CORE_EXPORT QXmlStreamWriter |
325 | { |
326 | QDOC_PROPERTY(bool autoFormatting READ autoFormatting WRITE setAutoFormatting) |
327 | QDOC_PROPERTY(int autoFormattingIndent READ autoFormattingIndent WRITE setAutoFormattingIndent) |
328 | public: |
329 | QXmlStreamWriter(); |
330 | explicit QXmlStreamWriter(QIODevice *device); |
331 | explicit QXmlStreamWriter(QByteArray *array); |
332 | explicit QXmlStreamWriter(QString *string); |
333 | ~QXmlStreamWriter(); |
334 | |
335 | void setDevice(QIODevice *device); |
336 | QIODevice *device() const; |
337 | |
338 | void setAutoFormatting(bool); |
339 | bool autoFormatting() const; |
340 | |
341 | void setAutoFormattingIndent(int spacesOrTabs); |
342 | int autoFormattingIndent() const; |
343 | |
344 | #if QT_CORE_REMOVED_SINCE(6,5) |
345 | void writeAttribute(const QString &qualifiedName, const QString &value); |
346 | void writeAttribute(const QString &namespaceUri, const QString &name, const QString &value); |
347 | #endif |
348 | void writeAttribute(QAnyStringView qualifiedName, QAnyStringView value); |
349 | void writeAttribute(QAnyStringView namespaceUri, QAnyStringView name, QAnyStringView value); |
350 | |
351 | void writeAttribute(const QXmlStreamAttribute& attribute); |
352 | void writeAttributes(const QXmlStreamAttributes& attributes); |
353 | |
354 | #if QT_CORE_REMOVED_SINCE(6,5) |
355 | void writeCDATA(const QString &text); |
356 | void writeCharacters(const QString &text); |
357 | void writeComment(const QString &text); |
358 | |
359 | void writeDTD(const QString &dtd); |
360 | |
361 | void writeEmptyElement(const QString &qualifiedName); |
362 | void writeEmptyElement(const QString &namespaceUri, const QString &name); |
363 | |
364 | void writeTextElement(const QString &qualifiedName, const QString &text); |
365 | void writeTextElement(const QString &namespaceUri, const QString &name, const QString &text); |
366 | #endif |
367 | void writeCDATA(QAnyStringView text); |
368 | void writeCharacters(QAnyStringView text); |
369 | void (QAnyStringView text); |
370 | |
371 | void writeDTD(QAnyStringView dtd); |
372 | |
373 | void writeEmptyElement(QAnyStringView qualifiedName); |
374 | void writeEmptyElement(QAnyStringView namespaceUri, QAnyStringView name); |
375 | |
376 | void writeTextElement(QAnyStringView qualifiedName, QAnyStringView text); |
377 | void writeTextElement(QAnyStringView namespaceUri, QAnyStringView name, QAnyStringView text); |
378 | |
379 | |
380 | void writeEndDocument(); |
381 | void writeEndElement(); |
382 | |
383 | #if QT_CORE_REMOVED_SINCE(6,5) |
384 | void writeEntityReference(const QString &name); |
385 | void writeNamespace(const QString &namespaceUri, const QString &prefix); |
386 | void writeDefaultNamespace(const QString &namespaceUri); |
387 | void writeProcessingInstruction(const QString &target, const QString &data); |
388 | #endif |
389 | void writeEntityReference(QAnyStringView name); |
390 | void writeNamespace(QAnyStringView namespaceUri, QAnyStringView prefix = {}); |
391 | void writeDefaultNamespace(QAnyStringView namespaceUri); |
392 | void writeProcessingInstruction(QAnyStringView target, QAnyStringView data = {}); |
393 | |
394 | void writeStartDocument(); |
395 | #if QT_CORE_REMOVED_SINCE(6,5) |
396 | void writeStartDocument(const QString &version); |
397 | void writeStartDocument(const QString &version, bool standalone); |
398 | void writeStartElement(const QString &qualifiedName); |
399 | void writeStartElement(const QString &namespaceUri, const QString &name); |
400 | #endif |
401 | void writeStartDocument(QAnyStringView version); |
402 | void writeStartDocument(QAnyStringView version, bool standalone); |
403 | void writeStartElement(QAnyStringView qualifiedName); |
404 | void writeStartElement(QAnyStringView namespaceUri, QAnyStringView name); |
405 | |
406 | #if QT_CONFIG(xmlstreamreader) |
407 | void writeCurrentToken(const QXmlStreamReader &reader); |
408 | #endif |
409 | |
410 | bool hasError() const; |
411 | |
412 | private: |
413 | Q_DISABLE_COPY(QXmlStreamWriter) |
414 | Q_DECLARE_PRIVATE(QXmlStreamWriter) |
415 | QScopedPointer<QXmlStreamWriterPrivate> d_ptr; |
416 | }; |
417 | #endif // feature xmlstreamwriter |
418 | |
419 | QT_END_NAMESPACE |
420 | |
421 | #endif // feature xmlstream |
422 | |
423 | #endif // QXMLSTREAM_H |
424 | |