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 QtXml 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 QXML_P_H |
41 | #define QXML_P_H |
42 | |
43 | #include <qstack.h> |
44 | #include <qmap.h> |
45 | #include <qxml.h> |
46 | |
47 | #include <stack> |
48 | |
49 | #if QT_DEPRECATED_SINCE(5, 15) |
50 | |
51 | QT_BEGIN_NAMESPACE |
52 | |
53 | // |
54 | // W A R N I N G |
55 | // ------------- |
56 | // |
57 | // This file is not part of the Qt API. It exists for the convenience of |
58 | // qxml.cpp and qdom.cpp. This header file may change from version to version without |
59 | // notice, or even be removed. |
60 | // |
61 | // We mean it. |
62 | // |
63 | |
64 | QT_WARNING_PUSH |
65 | QT_WARNING_DISABLE_DEPRECATED |
66 | |
67 | class QXmlSimpleReaderPrivate |
68 | { |
69 | public: |
70 | ~QXmlSimpleReaderPrivate(); |
71 | private: |
72 | // functions |
73 | QXmlSimpleReaderPrivate(QXmlSimpleReader *reader); |
74 | void initIncrementalParsing(); |
75 | |
76 | // used to determine if elements are correctly nested |
77 | std::stack<QString, QStringList> tags; |
78 | |
79 | // used by parseReference() and parsePEReference() |
80 | enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD }; |
81 | |
82 | // used for entity declarations |
83 | struct ExternParameterEntity |
84 | { |
85 | ExternParameterEntity() {} |
86 | ExternParameterEntity(const QString &p, const QString &s) |
87 | : publicId(p), systemId(s) {} |
88 | QString publicId; |
89 | QString systemId; |
90 | |
91 | Q_DUMMY_COMPARISON_OPERATOR(ExternParameterEntity) |
92 | }; |
93 | friend class QTypeInfo<ExternParameterEntity>; |
94 | |
95 | struct ExternEntity |
96 | { |
97 | ExternEntity() {} |
98 | ExternEntity(const QString &p, const QString &s, const QString &n) |
99 | : publicId(p), systemId(s), notation(n) {} |
100 | QString publicId; |
101 | QString systemId; |
102 | QString notation; |
103 | Q_DUMMY_COMPARISON_OPERATOR(ExternEntity) |
104 | }; |
105 | friend class QTypeInfo<ExternEntity>; |
106 | |
107 | QMap<QString,ExternParameterEntity> externParameterEntities; |
108 | QMap<QString,QString> parameterEntities; |
109 | QMap<QString,ExternEntity> externEntities; |
110 | QMap<QString,QString> entities; |
111 | |
112 | // used for parsing of entity references |
113 | struct XmlRef { |
114 | XmlRef() |
115 | : index(0) {} |
116 | XmlRef(const QString &_name, const QString &_value) |
117 | : name(_name), value(_value), index(0) {} |
118 | bool isEmpty() const { return index == value.length(); } |
119 | QChar next() { return value.at(i: index++); } |
120 | QString name; |
121 | QString value; |
122 | int index; |
123 | }; |
124 | friend class QTypeInfo<XmlRef>; |
125 | QStack<XmlRef> xmlRefStack; |
126 | |
127 | // used for standalone declaration |
128 | enum Standalone { Yes, No, Unknown }; |
129 | |
130 | QString doctype; // only used for the doctype |
131 | QString xmlVersion; // only used to store the version information |
132 | QString encoding; // only used to store the encoding |
133 | Standalone standalone; // used to store the value of the standalone declaration |
134 | |
135 | QString publicId; // used by parseExternalID() to store the public ID |
136 | QString systemId; // used by parseExternalID() to store the system ID |
137 | |
138 | // Since publicId/systemId is used as temporary variables by parseExternalID(), it |
139 | // might overwrite the PUBLIC/SYSTEM for the document we're parsing. In effect, we would |
140 | // possibly send off an QXmlParseException that has the PUBLIC/SYSTEM of a entity declaration |
141 | // instead of those of the current document. |
142 | // Hence we have these two variables for storing the document's data. |
143 | QString thisPublicId; |
144 | QString thisSystemId; |
145 | |
146 | QString attDeclEName; // use by parseAttlistDecl() |
147 | QString attDeclAName; // use by parseAttlistDecl() |
148 | |
149 | // flags for some features support |
150 | bool useNamespaces; |
151 | bool useNamespacePrefixes; |
152 | bool reportWhitespaceCharData; |
153 | bool reportEntities; |
154 | |
155 | // used to build the attribute list |
156 | QXmlAttributes attList; |
157 | |
158 | // used in QXmlSimpleReader::parseContent() to decide whether character |
159 | // data was read |
160 | bool contentCharDataRead; |
161 | // Hack for letting QDom know where the skipped entity occurred |
162 | bool skipped_entity_in_content; |
163 | |
164 | // helper classes |
165 | QScopedPointer<QXmlLocator> locator; |
166 | QXmlNamespaceSupport namespaceSupport; |
167 | |
168 | // error string |
169 | QString error; |
170 | |
171 | // arguments for parse functions (this is needed to allow incremental |
172 | // parsing) |
173 | bool parsePI_xmldecl; |
174 | bool parseName_useRef; |
175 | bool parseReference_charDataRead; |
176 | EntityRecognitionContext parseReference_context; |
177 | bool parseExternalID_allowPublicID; |
178 | EntityRecognitionContext parsePEReference_context; |
179 | QString parseString_s; |
180 | |
181 | // for incremental parsing |
182 | struct ParseState { |
183 | typedef bool (QXmlSimpleReaderPrivate::*ParseFunction)(); |
184 | ParseFunction function; |
185 | int state; |
186 | }; |
187 | friend class QTypeInfo<ParseState>; |
188 | QStack<ParseState> *parseStack; |
189 | |
190 | // used in parseProlog() |
191 | bool xmldecl_possible; |
192 | bool doctype_read; |
193 | |
194 | // used in parseDoctype() |
195 | bool startDTDwasReported; |
196 | |
197 | // used in parseString() |
198 | signed char Done; |
199 | |
200 | |
201 | // variables |
202 | QXmlContentHandler *contentHnd; |
203 | QXmlErrorHandler *errorHnd; |
204 | QXmlDTDHandler *dtdHnd; |
205 | QXmlEntityResolver *entityRes; |
206 | QXmlLexicalHandler *lexicalHnd; |
207 | QXmlDeclHandler *declHnd; |
208 | |
209 | QXmlInputSource *inputSource; |
210 | |
211 | QChar c; // the character at reading position |
212 | int lineNr; // number of line |
213 | int columnNr; // position in line |
214 | |
215 | QChar nameArray[256]; // only used for names |
216 | QString nameValue; // only used for names |
217 | int nameArrayPos; |
218 | int nameValueLen; |
219 | QChar refArray[256]; // only used for references |
220 | QString refValue; // only used for references |
221 | int refArrayPos; |
222 | int refValueLen; |
223 | QChar stringArray[256]; // used for any other strings that are parsed |
224 | QString stringValue; // used for any other strings that are parsed |
225 | int stringArrayPos; |
226 | int stringValueLen; |
227 | QString emptyStr; |
228 | |
229 | QHash<QString, int> literalEntitySizes; |
230 | // The entity at (QMap<QString,) referenced the entities at (QMap<QString,) (int>) times. |
231 | QHash<QString, QHash<QString, int> > referencesToOtherEntities; |
232 | QHash<QString, int> expandedSizes; |
233 | // The limit to the amount of times the DTD parsing functions can be called |
234 | // for the DTD currently being parsed. |
235 | static const int dtdRecursionLimit = 2; |
236 | // The maximum amount of characters an entity value may contain, after expansion. |
237 | static const int entityCharacterLimit = 4096; |
238 | |
239 | const QString &string(); |
240 | void stringClear(); |
241 | void stringAddC(QChar); |
242 | inline void stringAddC() { stringAddC(c); } |
243 | const QString &name(); |
244 | void nameClear(); |
245 | void nameAddC(QChar); |
246 | inline void nameAddC() { nameAddC(c); } |
247 | const QString &ref(); |
248 | void refClear(); |
249 | void refAddC(QChar); |
250 | inline void refAddC() { refAddC(c); } |
251 | |
252 | // private functions |
253 | bool eat_ws(); |
254 | bool next_eat_ws(); |
255 | |
256 | void QT_FASTCALL next(); |
257 | bool atEnd(); |
258 | |
259 | void init(const QXmlInputSource* i); |
260 | void initData(); |
261 | |
262 | bool entityExist(const QString&) const; |
263 | |
264 | bool parseBeginOrContinue(int state, bool incremental); |
265 | |
266 | bool parseProlog(); |
267 | bool parseElement(); |
268 | bool processElementEmptyTag(); |
269 | bool processElementETagBegin2(); |
270 | bool processElementAttribute(); |
271 | bool parseMisc(); |
272 | bool parseContent(); |
273 | |
274 | bool parsePI(); |
275 | bool parseDoctype(); |
276 | bool (); |
277 | |
278 | bool parseName(); |
279 | bool parseNmtoken(); |
280 | bool parseAttribute(); |
281 | bool parseReference(); |
282 | bool processReference(); |
283 | |
284 | bool parseExternalID(); |
285 | bool parsePEReference(); |
286 | bool parseMarkupdecl(); |
287 | bool parseAttlistDecl(); |
288 | bool parseAttType(); |
289 | bool parseAttValue(); |
290 | bool parseElementDecl(); |
291 | bool parseNotationDecl(); |
292 | bool parseChoiceSeq(); |
293 | bool parseEntityDecl(); |
294 | bool parseEntityValue(); |
295 | |
296 | bool parseString(); |
297 | |
298 | bool insertXmlRef(const QString&, const QString&, bool); |
299 | |
300 | bool reportEndEntities(); |
301 | void reportParseError(const QString& error); |
302 | |
303 | typedef bool (QXmlSimpleReaderPrivate::*ParseFunction) (); |
304 | void unexpectedEof(ParseFunction where, int state); |
305 | void parseFailed(ParseFunction where, int state); |
306 | void pushParseState(ParseFunction function, int state); |
307 | |
308 | bool isExpandedEntityValueTooLarge(QString *errorMessage); |
309 | |
310 | Q_DECLARE_PUBLIC(QXmlSimpleReader) |
311 | QXmlSimpleReader *q_ptr; |
312 | |
313 | friend class QXmlSimpleReaderLocator; |
314 | friend class QDomHandler; |
315 | }; |
316 | Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ParseState, Q_PRIMITIVE_TYPE); |
317 | Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::XmlRef, Q_MOVABLE_TYPE); |
318 | Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternParameterEntity, Q_MOVABLE_TYPE); |
319 | Q_DECLARE_TYPEINFO(QXmlSimpleReaderPrivate::ExternEntity, Q_MOVABLE_TYPE); |
320 | |
321 | QT_WARNING_POP |
322 | |
323 | QT_END_NAMESPACE |
324 | |
325 | #endif // QT_DEPRECATED_SINCE(5, 15) |
326 | |
327 | #endif // QXML_P_H |
328 | |