4848
4949#include < memory>
5050
51- #include < QtXml>
51+ #include < QFile>
52+ #include < QTextStream>
53+ #include < QXmlStreamReader>
5254#include < qcompilerdetection.h> // Q_FALLTHROUGH
5355
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-
7056QString strings_Object = QLatin1String(" Object" );
7157QString strings_String = QLatin1String(" String" );
7258QString strings_Thread = QLatin1String(" Thread" );
@@ -150,9 +136,48 @@ class StackElement
150136 } value;
151137};
152138
153- class Handler : public QXmlDefaultHandler
139+ class Handler
154140{
155141public:
142+ class Attributes
143+ {
144+ public:
145+ Attributes () = default ;
146+ explicit Attributes (const QXmlStreamAttributes &attributes)
147+ : m_attributes(attributes) {}
148+
149+ int length () const { return m_attributes.size (); }
150+
151+ QString localName (int index) const
152+ {
153+ return m_attributes.at (index).name ().toString ();
154+ }
155+
156+ QString value (int index) const
157+ {
158+ return m_attributes.at (index).value ().toString ();
159+ }
160+
161+ QString value (const QString &qualifiedName) const
162+ {
163+ return m_attributes.hasAttribute (qualifiedName)
164+ ? m_attributes.value (qualifiedName).toString ()
165+ : QString ();
166+ }
167+
168+ int index (const QString &qualifiedName) const
169+ {
170+ for (int i = 0 ; i < m_attributes.size (); ++i) {
171+ if (m_attributes.at (i).name ().toString () == qualifiedName)
172+ return i;
173+ }
174+ return -1 ;
175+ }
176+
177+ private:
178+ QXmlStreamAttributes m_attributes;
179+ };
180+
156181 Handler (TypeDatabase *database, unsigned int qtVersion, bool generate)
157182 : m_database(database)
158183 , m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
@@ -197,25 +222,23 @@ class Handler : public QXmlDefaultHandler
197222 tagNames[" reference-count" ] = StackElement::ReferenceCount;
198223 }
199224
225+ bool parse (QXmlStreamReader &reader);
200226 bool startDocument () { m_nestingLevel = 0 ; m_disabledLevel = -1 ; return true ; }
201227 bool startElement (const QString &namespaceURI, const QString &localName,
202- const QString &qName, const QXmlAttributes &atts);
228+ const QString &qName, const Attributes &atts);
203229 bool endElement (const QString &namespaceURI, const QString &localName, const QString &qName);
204230
205231 QString errorString () const { return m_error; }
206- bool error (const QXmlParseException &exception);
207- bool fatalError (const QXmlParseException &exception);
208- bool warning (const QXmlParseException &exception);
209232
210233 bool characters (const QString &ch);
211234
212235private:
213- void fetchAttributeValues (const QString &name, const QXmlAttributes &atts,
236+ void fetchAttributeValues (const QString &name, const Attributes &atts,
214237 QHash<QString, QString> *acceptedAttributes);
215238
216- bool importFileElement (const QXmlAttributes &atts);
239+ bool importFileElement (const Attributes &atts);
217240 bool convertBoolean (const QString &, const QString &, bool );
218- bool qtVersionMatches (const QXmlAttributes & atts, bool & ok);
241+ bool qtVersionMatches (const Attributes & atts, bool & ok);
219242
220243 TypeDatabase *m_database;
221244 StackElement* current;
@@ -237,31 +260,55 @@ class Handler : public QXmlDefaultHandler
237260 int m_disabledLevel{}; // if this is != 0, elements should be ignored
238261};
239262
240- bool Handler::error ( const QXmlParseException &e )
263+ bool Handler::parse (QXmlStreamReader &reader )
241264{
242- qWarning () << " Error: line=" << e.lineNumber ()
243- << " , column=" << e.columnNumber ()
244- << " , message=" << e.message () << " \n " ;
245- return false ;
246- }
265+ if (!startDocument ())
266+ return false ;
247267
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- }
268+ while (!reader.atEnd ()) {
269+ const auto token = reader.readNext ();
270+ switch (token) {
271+ case QXmlStreamReader::StartElement: {
272+ Attributes attributes (reader.attributes ());
273+ if (!startElement (reader.namespaceUri ().toString (),
274+ reader.name ().toString (),
275+ reader.qualifiedName ().toString (),
276+ attributes)) {
277+ return false ;
278+ }
279+ break ;
280+ }
281+ case QXmlStreamReader::EndElement:
282+ if (!endElement (reader.namespaceUri ().toString (),
283+ reader.name ().toString (),
284+ reader.qualifiedName ().toString ())) {
285+ return false ;
286+ }
287+ break ;
288+ case QXmlStreamReader::Characters:
289+ case QXmlStreamReader::EntityReference:
290+ if (!characters (reader.text ().toString ())) {
291+ return false ;
292+ }
293+ break ;
294+ default :
295+ break ;
296+ }
297+ }
255298
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 ;
299+ if (reader.hasError ()) {
300+ m_error = QStringLiteral (" Parse error at line %1, column %2: %3" )
301+ .arg (reader.lineNumber ())
302+ .arg (reader.columnNumber ())
303+ .arg (reader.errorString ());
304+ qWarning () << m_error;
305+ return false ;
306+ }
307+
308+ return true ;
262309}
263310
264- void Handler::fetchAttributeValues (const QString &name, const QXmlAttributes &atts,
311+ void Handler::fetchAttributeValues (const QString &name, const Attributes &atts,
265312 QHash<QString, QString> *acceptedAttributes)
266313{
267314 Q_ASSERT (acceptedAttributes != 0 );
@@ -398,7 +445,7 @@ bool Handler::characters(const QString &ch)
398445 return true ;
399446}
400447
401- bool Handler::importFileElement (const QXmlAttributes &atts)
448+ bool Handler::importFileElement (const Attributes &atts)
402449{
403450 QString fileName = atts.value (" name" );
404451 if (fileName.isEmpty ()){
@@ -470,7 +517,7 @@ bool Handler::convertBoolean(const QString &_value, const QString &attributeName
470517 }
471518}
472519
473- bool Handler::qtVersionMatches (const QXmlAttributes & atts, bool & ok)
520+ bool Handler::qtVersionMatches (const Attributes & atts, bool & ok)
474521{
475522 ok = true ;
476523 int beforeIndex = atts.index (" before-version" );
@@ -501,7 +548,7 @@ bool Handler::qtVersionMatches(const QXmlAttributes& atts, bool& ok)
501548}
502549
503550bool Handler::startElement (const QString &, const QString &n,
504- const QString &, const QXmlAttributes &atts)
551+ const QString &, const Attributes &atts)
505552{
506553 QString tagName = n.toLower ();
507554 m_nestingLevel++;
@@ -1605,22 +1652,19 @@ bool TypeDatabase::parseFile(const QString &filename, unsigned int qtVersion, bo
16051652 // If opening fails, attempt to load from Qt resources
16061653 file.setFileName (" :/trolltech/generator/" + filename);
16071654 if (!file.open (QIODevice::ReadOnly | QIODevice::Text)) {
1608- qWarning () << " Could not open file:" << filename;
1655+ ReportHandler::warning ( QString::fromLatin1 ( " Could not open typesystem file: '%1' " ). arg ( filename)) ;
16091656 return false ;
16101657 }
16111658 }
16121659
1613- QXmlInputSource source (&file);
1614-
16151660 int count = m_entries.size ();
16161661
1617- QXmlSimpleReader reader;
16181662 Handler handler (this , qtVersion, generate);
1663+ QXmlStreamReader reader (&file);
16191664
1620- reader.setContentHandler (&handler);
1621- reader.setErrorHandler (&handler);
1622-
1623- bool ok = reader.parse (&source, false );
1665+ bool ok = handler.parse (reader);
1666+ if (!ok && !handler.errorString ().isEmpty ())
1667+ ReportHandler::warning (handler.errorString ());
16241668
16251669 int newCount = m_entries.size ();
16261670
0 commit comments