File indexing completed on 2024-05-12 15:55:24

0001 // SPDX-FileCopyrightText: 2013 Jesper K. Pedersen <jesper.pedersen@kdab.com>
0002 // SPDX-FileCopyrightText: 2013-2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 // SPDX-FileCopyrightText: 2020 Robert Krawitz <rlk@alum.mit.edu>
0004 // SPDX-FileCopyrightText: 2022 Tobias Leupold <tl@stonemx.de>
0005 //
0006 // SPDX-License-Identifier: GPL-2.0-or-later
0007 
0008 #include "XmlReader.h"
0009 
0010 #include <kpabase/Logging.h>
0011 #include <kpabase/UIDelegate.h>
0012 
0013 #include <KLocalizedString>
0014 
0015 namespace DB
0016 {
0017 
0018 XmlReader::XmlReader(DB::UIDelegate &ui, const QString &friendlyStreamName)
0019     : m_ui(ui)
0020     , m_streamName(friendlyStreamName)
0021 {
0022 }
0023 
0024 QString XmlReader::attribute(const QString &name, const QString &defaultValue)
0025 {
0026     QStringRef ref = attributes().value(name);
0027     if (ref.isNull())
0028         return defaultValue;
0029     else
0030         return ref.toString();
0031 }
0032 
0033 ElementInfo XmlReader::readNextStartOrStopElement(const QString &expectedStart)
0034 {
0035     if (m_peek.isValid) {
0036         m_peek.isValid = false;
0037         return m_peek;
0038     }
0039 
0040     TokenType type = readNextInternal();
0041 
0042     if (hasError())
0043         reportError(i18n("Error reading next element"));
0044 
0045     if (type != StartElement && type != EndElement)
0046         reportError(i18n("Expected to read a start or stop element, but read %1", tokenString()));
0047 
0048     const QString elementName = name().toString();
0049     if (type == StartElement) {
0050         if (!expectedStart.isNull() && elementName != expectedStart)
0051             reportError(i18n("Expected to read %1, but read %2", expectedStart, elementName));
0052     }
0053 
0054     return ElementInfo(type == StartElement, elementName);
0055 }
0056 
0057 void XmlReader::readEndElement(bool readNextElement)
0058 {
0059     if (readNextElement)
0060         readNextInternal();
0061     if (tokenType() != EndElement)
0062         reportError(i18n("Expected to read an end element but read %1", tokenString()));
0063 }
0064 
0065 bool XmlReader::hasAttribute(const QString &name)
0066 {
0067     return attributes().hasAttribute(name);
0068 }
0069 
0070 ElementInfo XmlReader::peekNext()
0071 {
0072     if (m_peek.isValid)
0073         return m_peek;
0074     m_peek = readNextStartOrStopElement(QString());
0075     return m_peek;
0076 }
0077 
0078 void XmlReader::complainStartElementExpected(const QString &name)
0079 {
0080     reportError(i18n("Expected to read start element '%1'", name));
0081 }
0082 
0083 void XmlReader::reportError(const QString &text)
0084 {
0085     QString message = i18n(
0086         "<p>An error was encountered on line %1, column %2:<nl/>"
0087         "<message>%3</message></p>",
0088         lineNumber(), columnNumber(), text);
0089     if (hasError())
0090         message += i18n("<p>Additional error information:<nl/><message>%1</message></p>", errorString());
0091     message += xi18n("<p>Database path: <filename>%1</filename></p>", m_streamName);
0092 
0093     m_ui.error(DB::LogMessage { DBLog(), QStringLiteral("XmlReader: error in line %1, column %2 (%3)").arg(lineNumber()).arg(columnNumber()).arg(errorString()) },
0094                message, i18n("Error while reading database file"));
0095     exit(-1);
0096 }
0097 
0098 QXmlStreamReader::TokenType XmlReader::readNextInternal()
0099 {
0100     for (;;) {
0101         TokenType type = readNext();
0102         if (type == Comment || type == StartDocument)
0103             continue;
0104         else if (type == Characters) {
0105             if (isWhitespace())
0106                 continue;
0107         } else
0108             return type;
0109     }
0110 }
0111 
0112 }
0113 
0114 // vi:expandtab:tabstop=4 shiftwidth=4: