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 }