4848
4949#include < memory>
5050
51- #include < QtXml>
51+ #include < QDebug>
52+ #include < QFile>
53+ #include < QTextStream>
54+ #include < QXmlStreamReader>
5255#include < qcompilerdetection.h> // Q_FALLTHROUGH
5356
54- /* This file needs to be rewritten as documented here:
55- *
56- * See: https://doc.qt.io/qt-6/xml-changes-qt6.html
57- *
58- * The rewrite may be backward compatible to Qt4.3 APIs because the base
59- * facilites (QXmlStreamReader) used to relace the 'SAX' parser were apparently
60- * available then. Use of Xml5Compat is a work round until such a rewrite has
61- * been done.
62- */
63- #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
64- # if defined(__GNUC__)
65- # pragma GCC warning "Qt6: implement Qt6 compatible XML reading"
66- # endif
67- # include < QtCore5Compat/QXmlDefaultHandler>
68- #endif
69-
7057QString strings_Object = QLatin1String(" Object" );
7158QString strings_String = QLatin1String(" String" );
7259QString strings_Thread = QLatin1String(" Thread" );
@@ -150,9 +137,48 @@ class StackElement
150137 } value;
151138};
152139
153- class Handler : public QXmlDefaultHandler
140+ class Handler
154141{
155142public:
143+ class Attributes
144+ {
145+ public:
146+ Attributes () = default ;
147+ explicit Attributes (const QXmlStreamAttributes &attributes)
148+ : m_attributes(attributes) {}
149+
150+ int length () const { return m_attributes.size (); }
151+
152+ QString localName (int index) const
153+ {
154+ return m_attributes.at (index).name ().toString ();
155+ }
156+
157+ QString value (int index) const
158+ {
159+ return m_attributes.at (index).value ().toString ();
160+ }
161+
162+ QString value (const QString &qualifiedName) const
163+ {
164+ return m_attributes.hasAttribute (qualifiedName)
165+ ? m_attributes.value (qualifiedName).toString ()
166+ : QString ();
167+ }
168+
169+ int index (const QString &qualifiedName) const
170+ {
171+ for (int i = 0 ; i < m_attributes.size (); ++i) {
172+ if (m_attributes.at (i).name ().toString () == qualifiedName)
173+ return i;
174+ }
175+ return -1 ;
176+ }
177+
178+ private:
179+ QXmlStreamAttributes m_attributes;
180+ };
181+
156182 Handler (TypeDatabase *database, unsigned int qtVersion, bool generate)
157183 : m_database(database)
158184 , m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
@@ -197,25 +223,23 @@ class Handler : public QXmlDefaultHandler
197223 tagNames[" reference-count" ] = StackElement::ReferenceCount;
198224 }
199225
226+ bool parse (QXmlStreamReader &reader);
200227 bool startDocument () { m_nestingLevel = 0 ; m_disabledLevel = -1 ; return true ; }
201228 bool startElement (const QString &namespaceURI, const QString &localName,
202- const QString &qName, const QXmlAttributes &atts);
229+ const QString &qName, const Attributes &atts);
203230 bool endElement (const QString &namespaceURI, const QString &localName, const QString &qName);
204231
205232 QString errorString () const { return m_error; }
206- bool error (const QXmlParseException &exception);
207- bool fatalError (const QXmlParseException &exception);
208- bool warning (const QXmlParseException &exception);
209233
210234 bool characters (const QString &ch);
211235
212236private:
213- void fetchAttributeValues (const QString &name, const QXmlAttributes &atts,
237+ void fetchAttributeValues (const QString &name, const Attributes &atts,
214238 QHash<QString, QString> *acceptedAttributes);
215239
216- bool importFileElement (const QXmlAttributes &atts);
240+ bool importFileElement (const Attributes &atts);
217241 bool convertBoolean (const QString &, const QString &, bool );
218- bool qtVersionMatches (const QXmlAttributes & atts, bool & ok);
242+ bool qtVersionMatches (const Attributes & atts, bool & ok);
219243
220244 TypeDatabase *m_database;
221245 StackElement* current;
@@ -237,31 +261,55 @@ class Handler : public QXmlDefaultHandler
237261 int m_disabledLevel{}; // if this is != 0, elements should be ignored
238262};
239263
240- bool Handler::error ( const QXmlParseException &e )
264+ bool Handler::parse (QXmlStreamReader &reader )
241265{
242- qWarning () << " Error: line=" << e.lineNumber ()
243- << " , column=" << e.columnNumber ()
244- << " , message=" << e.message () << " \n " ;
245- return false ;
246- }
266+ if (!startDocument ())
267+ return false ;
247268
248- bool Handler::fatalError (const QXmlParseException &e)
249- {
250- qWarning () << " Fatal error: line=" << e.lineNumber ()
251- << " , column=" << e.columnNumber ()
252- << " , message=" << e.message () << " \n " ;
253- return false ;
254- }
269+ while (!reader.atEnd ()) {
270+ const auto token = reader.readNext ();
271+ switch (token) {
272+ case QXmlStreamReader::StartElement: {
273+ Attributes attributes (reader.attributes ());
274+ if (!startElement (reader.namespaceUri ().toString (),
275+ reader.name ().toString (),
276+ reader.qualifiedName ().toString (),
277+ attributes)) {
278+ return false ;
279+ }
280+ break ;
281+ }
282+ case QXmlStreamReader::EndElement:
283+ if (!endElement (reader.namespaceUri ().toString (),
284+ reader.name ().toString (),
285+ reader.qualifiedName ().toString ())) {
286+ return false ;
287+ }
288+ break ;
289+ case QXmlStreamReader::Characters:
290+ case QXmlStreamReader::EntityReference:
291+ if (!characters (reader.text ().toString ())) {
292+ return false ;
293+ }
294+ break ;
295+ default :
296+ break ;
297+ }
298+ }
255299
256- bool Handler::warning (const QXmlParseException &e)
257- {
258- qWarning () << " Warning: line=" << e.lineNumber ()
259- << " , column=" << e.columnNumber ()
260- << " , message=" << e.message () << " \n " ;
261- return false ;
300+ if (reader.hasError ()) {
301+ m_error = QStringLiteral (" Parse error at line %1, column %2: %3" )
302+ .arg (reader.lineNumber ())
303+ .arg (reader.columnNumber ())
304+ .arg (reader.errorString ());
305+ qWarning () << m_error;
306+ return false ;
307+ }
308+
309+ return true ;
262310}
263311
264- void Handler::fetchAttributeValues (const QString &name, const QXmlAttributes &atts,
312+ void Handler::fetchAttributeValues (const QString &name, const Attributes &atts,
265313 QHash<QString, QString> *acceptedAttributes)
266314{
267315 Q_ASSERT (acceptedAttributes != 0 );
@@ -358,6 +406,9 @@ bool Handler::endElement(const QString &, const QString &localName, const QStrin
358406
359407bool Handler::characters (const QString &ch)
360408{
409+ if (!current)
410+ return true ;
411+
361412 if (current->type == StackElement::Template){
362413 current->value .templateEntry ->addCode (ch);
363414 return true ;
@@ -398,7 +449,7 @@ bool Handler::characters(const QString &ch)
398449 return true ;
399450}
400451
401- bool Handler::importFileElement (const QXmlAttributes &atts)
452+ bool Handler::importFileElement (const Attributes &atts)
402453{
403454 QString fileName = atts.value (" name" );
404455 if (fileName.isEmpty ()){
@@ -470,7 +521,7 @@ bool Handler::convertBoolean(const QString &_value, const QString &attributeName
470521 }
471522}
472523
473- bool Handler::qtVersionMatches (const QXmlAttributes & atts, bool & ok)
524+ bool Handler::qtVersionMatches (const Attributes & atts, bool & ok)
474525{
475526 ok = true ;
476527 int beforeIndex = atts.index (" before-version" );
@@ -501,7 +552,7 @@ bool Handler::qtVersionMatches(const QXmlAttributes& atts, bool& ok)
501552}
502553
503554bool Handler::startElement (const QString &, const QString &n,
504- const QString &, const QXmlAttributes &atts)
555+ const QString &, const Attributes &atts)
505556{
506557 QString tagName = n.toLower ();
507558 m_nestingLevel++;
@@ -1601,17 +1652,19 @@ bool TypeDatabase::parseFile(const QString &filename, unsigned int qtVersion, bo
16011652 QFile file (filename);
16021653
16031654 Q_ASSERT (file.exists ());
1604- QXmlInputSource source (&file);
1655+ if (!file.open (QIODevice::ReadOnly | QIODevice::Text)) {
1656+ ReportHandler::warning (QString::fromLatin1 (" Could not open typesystem file: '%1'" ).arg (filename));
1657+ return false ;
1658+ }
16051659
16061660 int count = m_entries.size ();
16071661
1608- QXmlSimpleReader reader;
16091662 Handler handler (this , qtVersion, generate);
1663+ QXmlStreamReader reader (&file);
16101664
1611- reader.setContentHandler (&handler);
1612- reader.setErrorHandler (&handler);
1613-
1614- bool ok = reader.parse (&source, false );
1665+ bool ok = handler.parse (reader);
1666+ if (!ok && !handler.errorString ().isEmpty ())
1667+ ReportHandler::warning (handler.errorString ());
16151668
16161669 int newCount = m_entries.size ();
16171670
0 commit comments