File indexing completed on 2024-05-12 04:42:41

0001 /*
0002     SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "scopedxmlstreamreader.h"
0008 
0009 #include <QDebug>
0010 
0011 using namespace KPublicTransport;
0012 
0013 ScopedXmlStreamReader::ScopedXmlStreamReader(QXmlStreamReader &reader)
0014     : m_reader(reader)
0015 {
0016 }
0017 
0018 ScopedXmlStreamReader::ScopedXmlStreamReader(QXmlStreamReader &reader, ScopedXmlStreamReader *parent)
0019     : m_reader(reader)
0020     , m_parent(parent)
0021 {
0022     Q_ASSERT_X(!m_parent->m_subReaderLock, "ScopedXmlStreamReader", "Only one sub-reader can be active at the same time!");
0023     m_parent->m_subReaderLock = true;
0024 }
0025 
0026 
0027 ScopedXmlStreamReader::ScopedXmlStreamReader(ScopedXmlStreamReader&&) noexcept = default;
0028 
0029 ScopedXmlStreamReader::~ScopedXmlStreamReader()
0030 {
0031     while (!m_reader.atEnd() && !m_reader.hasError() && m_depth > 1) {
0032         if (m_reader.isStartElement()) {
0033             ++m_depth;
0034         }
0035         if (m_reader.isEndElement()) {
0036             m_depth--;
0037             if (m_depth == 1) {
0038                 break;
0039             }
0040         }
0041         m_reader.readNext();
0042     }
0043 
0044     if (m_parent) {
0045         m_parent->m_subReaderLock = false;
0046     }
0047 }
0048 
0049 bool ScopedXmlStreamReader::readNextElement()
0050 {
0051     Q_ASSERT_X(!m_subReaderLock, "ScopedXmlStreamReader", "Operations while a sub-reader is active are forbidden!");
0052 
0053     // previous element was  consumed, so adapt the depth counter before we continue reading
0054     if (m_reader.isEndElement()) {
0055         --m_depth;
0056     }
0057 
0058     while (!m_reader.atEnd() && !m_reader.hasError() && m_depth > 0) {
0059         m_reader.readNext();
0060         if (m_reader.isStartElement()) {
0061             ++m_depth;
0062             return true;
0063         }
0064         if (m_reader.isEndElement()) {
0065             m_depth--;
0066         }
0067     }
0068 
0069     return false;
0070 }
0071 
0072 bool ScopedXmlStreamReader::readNextSibling()
0073 {
0074     // if we are at the root node still, next sibling makes no sense, jump to the first child element first
0075     if (m_depth == 1 && m_reader.isStartElement()) {
0076         return readNextElement();
0077     }
0078     // if there is no progress compared to last round, skip that element first
0079     if (m_depth > 1 && m_reader.isStartElement()) {
0080         m_reader.skipCurrentElement();
0081         --m_depth;
0082     } else if (m_reader.isEndElement()) { // content was consumed
0083         --m_depth;
0084     }
0085 
0086     const auto currentDepth = m_depth;
0087     while (!m_reader.atEnd() && !m_reader.hasError() && m_depth >= currentDepth) {
0088         m_reader.readNext();
0089         if (m_reader.isStartElement()) {
0090             ++m_depth;
0091             if (m_depth == (currentDepth + 1)) {
0092                 return true;
0093             }
0094         } else if (m_reader.isEndElement()) {
0095             --m_depth;
0096         }
0097     }
0098 
0099     return false;
0100 }
0101 
0102 ScopedXmlStreamReader ScopedXmlStreamReader::subReader()
0103 {
0104     return ScopedXmlStreamReader(m_reader, this);
0105 }
0106 
0107 QXmlStreamAttributes ScopedXmlStreamReader::attributes() const
0108 {
0109     Q_ASSERT_X(!m_subReaderLock, "ScopedXmlStreamReader", "Operations while a sub-reader is active are forbidden!");
0110     return m_reader.attributes();
0111 }
0112 
0113 QStringView ScopedXmlStreamReader::name() const
0114 {
0115     Q_ASSERT_X(!m_subReaderLock, "ScopedXmlStreamReader", "Operations while a sub-reader is active are forbidden!");
0116     return m_reader.name();
0117 }
0118 
0119 QString ScopedXmlStreamReader::readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour)
0120 {
0121     Q_ASSERT_X(!m_subReaderLock, "ScopedXmlStreamReader", "Operations while a sub-reader is active are forbidden!");
0122     return m_reader.readElementText(behaviour);
0123 }
0124 
0125 bool ScopedXmlStreamReader::isElement(const char* name) const
0126 {
0127     Q_ASSERT_X(!m_subReaderLock, "ScopedXmlStreamReader", "Operations while a sub-reader is active are forbidden!");
0128     return m_reader.name() == QLatin1String(name);
0129 }