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 );
@@ -358,6 +405,9 @@ bool Handler::endElement(const QString &, const QString &localName, const QStrin
358405
359406bool  Handler::characters (const  QString &ch)
360407{
408+     if  (!current)
409+         return  true ;
410+ 
361411    if (current->type  == StackElement::Template){
362412        current->value .templateEntry ->addCode (ch);
363413        return  true ;
@@ -398,7 +448,7 @@ bool Handler::characters(const QString &ch)
398448    return  true ;
399449}
400450
401- bool  Handler::importFileElement (const  QXmlAttributes  &atts)
451+ bool  Handler::importFileElement (const  Attributes  &atts)
402452{
403453    QString fileName = atts.value (" name"  );
404454    if (fileName.isEmpty ()){
@@ -470,7 +520,7 @@ bool Handler::convertBoolean(const QString &_value, const QString &attributeName
470520    }
471521}
472522
473- bool  Handler::qtVersionMatches (const  QXmlAttributes & atts, bool & ok)
523+ bool  Handler::qtVersionMatches (const  Attributes & atts, bool & ok)
474524{
475525  ok = true ;
476526  int  beforeIndex = atts.index (" before-version"  );
@@ -501,7 +551,7 @@ bool Handler::qtVersionMatches(const QXmlAttributes& atts, bool& ok)
501551}
502552
503553bool  Handler::startElement (const  QString &, const  QString &n,
504-                            const  QString &, const  QXmlAttributes  &atts)
554+                            const  QString &, const  Attributes  &atts)
505555{
506556    QString tagName = n.toLower ();
507557    m_nestingLevel++;
@@ -1601,17 +1651,19 @@ bool TypeDatabase::parseFile(const QString &filename, unsigned int qtVersion, bo
16011651    QFile file (filename);
16021652
16031653    Q_ASSERT (file.exists ());
1604-     QXmlInputSource source (&file);
1654+     if  (!file.open (QIODevice::ReadOnly | QIODevice::Text)) {
1655+         ReportHandler::warning (QString::fromLatin1 (" Could not open typesystem file: '%1'"  ).arg (filename));
1656+         return  false ;
1657+     }
16051658
16061659    int  count = m_entries.size ();
16071660
1608-     QXmlSimpleReader reader;
16091661    Handler handler (this , qtVersion, generate);
1662+     QXmlStreamReader reader (&file);
16101663
1611-     reader.setContentHandler (&handler);
1612-     reader.setErrorHandler (&handler);
1613- 
1614-     bool  ok = reader.parse (&source, false );
1664+     bool  ok = handler.parse (reader);
1665+     if  (!ok && !handler.errorString ().isEmpty ())
1666+         ReportHandler::warning (handler.errorString ());
16151667
16161668    int  newCount = m_entries.size ();
16171669
0 commit comments