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