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 #ifndef KPUBLICTRANSPORT_SCOPEDXMLSTREAMREADER_H
0008 #define KPUBLICTRANSPORT_SCOPEDXMLSTREAMREADER_H
0009 
0010 #include <QXmlStreamReader>
0011 
0012 namespace KPublicTransport {
0013 
0014 /** Safety wrapper around QXmlStreamReader to consume a element sub-tree. */
0015 class ScopedXmlStreamReader
0016 {
0017 public:
0018     /** Construct a new ScopedXmlStreamReader from a QXmlStreamReader.
0019      *  Do not use @p reader API directly while this instance is alive.
0020      */
0021     explicit ScopedXmlStreamReader(QXmlStreamReader &reader);
0022 
0023     ScopedXmlStreamReader(const ScopedXmlStreamReader&) = delete;
0024     ScopedXmlStreamReader& operator=(const ScopedXmlStreamReader) = delete;
0025     ScopedXmlStreamReader(ScopedXmlStreamReader&&) noexcept;
0026 
0027     /** Destroying a ScopedXmlStreamReader will make it consume whatever remains of the
0028      *  current element sub-tree. The underlying QXmlStreamReader will be left pointing
0029      *  to the EndElement of the current sub-tree.
0030      */
0031     ~ScopedXmlStreamReader();
0032 
0033     /** Forward the reader to the start of the next element.
0034      *  @returns @c true if this succeeded, @c false if the input end has been reached or
0035      *  the element sub-tree this instance was created on has been entirely consumed.
0036      */
0037     bool readNextElement();
0038 
0039     /** Forward the reader to the start of the next sibling element, skipping over the sub trees.
0040      *  @returns @c true if this succeeded, @c false if the input end has been reached or
0041      *  the element sub-tree this instance was created on has been entirely consumed.
0042      */
0043     bool readNextSibling();
0044 
0045     /** Creates a ScopedXmlStreamReader for consuming the current sub-tree.
0046      *  Use this to recursively process element trees.
0047      *  Only one sub-reader can be active at a time, using this (or a parent) while
0048      *  a sub-reader is active is not allowed.
0049      */
0050     ScopedXmlStreamReader subReader();
0051 
0052     /** Same as QXmlStreamReader::attributes. */
0053     QXmlStreamAttributes attributes() const;
0054     /** Same as QXmlStreamReader::name. */
0055     QStringView name() const;
0056     /** Same as QXmlStreamReader::readElementText. */
0057     QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour = QXmlStreamReader::ErrorOnUnexpectedElement);
0058 
0059     /** Checks if the current element has the specified name. */
0060     bool isElement(const char *name) const;
0061 
0062 private:
0063     explicit ScopedXmlStreamReader(QXmlStreamReader &reader, ScopedXmlStreamReader *parent);
0064 
0065     QXmlStreamReader &m_reader;
0066     ScopedXmlStreamReader *m_parent = nullptr;
0067     int m_depth = 1;
0068     bool m_subReaderLock = false;
0069 };
0070 
0071 }
0072 
0073 #endif // KPUBLICTRANSPORT_SCOPEDXMLSTREAMREADER_H