File indexing completed on 2025-01-05 03:59:10
0001 /* 0002 SPDX-FileCopyrightText: 2008 Nikolas Zimmermann <zimmermann@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #ifndef MARBLE_GEOPARSER_H 0007 #define MARBLE_GEOPARSER_H 0008 0009 #include <QString> 0010 #include <QPair> 0011 #include <QStack> 0012 #include <QXmlStreamReader> 0013 0014 #include "digikam_export.h" 0015 0016 namespace Marble 0017 { 0018 0019 using GeoDataGenericSourceType = int; 0020 0021 class GeoDocument; 0022 class GeoNode; 0023 class GeoStackItem; 0024 0025 class DIGIKAM_EXPORT GeoParser : public QXmlStreamReader 0026 { 0027 public: 0028 typedef QPair<QString, QString> QualifiedName; // Tag Name & Namespace pair 0029 0030 explicit GeoParser( GeoDataGenericSourceType sourceType ); 0031 virtual ~GeoParser(); 0032 0033 /** 0034 * @brief Main API for reading the XML document. 0035 * This is the only method that is necessary to call to start the GeoParser. 0036 * To retrieve the resulting data see @see releaseDocument() and 0037 * @see releaseModel() 0038 */ 0039 bool read( QIODevice* ); 0040 0041 /** 0042 * @brief retrieve the parsed document and reset the parser 0043 * If parsing was successful, retrieve the resulting document 0044 * and set the contained m_document pointer to 0. 0045 */ 0046 GeoDocument* releaseDocument(); 0047 GeoDocument* activeDocument() { return m_document; } 0048 0049 // Used by tag handlers, to be overridden by GeoDataParser/GeoSceneParser 0050 virtual bool isValidElement( const QString& tagName ) const; 0051 0052 // Used by tag handlers, to access a parent element's associated GeoStackItem 0053 GeoStackItem parentElement( unsigned int depth = 0 ) const; 0054 0055 // Used by tag handlers, to Q_EMIT a warning while parsing 0056 void raiseWarning( const QString& ); 0057 0058 // Used by tag handlers, to retrieve the value for an attribute of the currently parsed element 0059 QString attribute( const char* attributeName ) const; 0060 0061 protected: 0062 /** 0063 * This method is intended to check if the current element being served by 0064 * the GeoParser is a valid Document Root element. This method is to be 0065 * implemented by GeoDataParser/GeoSceneParser and must check based on the 0066 * current XML Document type, e.g. KML, GPX etc. 0067 * @return @c true if the element is a valid document root. 0068 */ 0069 virtual bool isValidRootElement() = 0; 0070 0071 virtual GeoDocument* createDocument() const = 0; 0072 0073 protected: 0074 GeoDocument* m_document; 0075 GeoDataGenericSourceType m_source; 0076 0077 private: 0078 void parseDocument(); 0079 QStack<GeoStackItem> m_nodeStack; 0080 }; 0081 0082 class GeoStackItem 0083 { 0084 public: 0085 GeoStackItem() 0086 : m_qualifiedName(), 0087 m_node( nullptr ) 0088 { 0089 } 0090 0091 GeoStackItem( const GeoParser::QualifiedName& qualifiedName, GeoNode* node ) 0092 : m_qualifiedName( qualifiedName ), 0093 m_node( node ) 0094 { 0095 } 0096 0097 // Fast path for tag handlers 0098 bool represents( const char* tagName ) const 0099 { 0100 return m_node && (QString::fromUtf8(tagName) == m_qualifiedName.first); 0101 } 0102 0103 // Helper for tag handlers. Does NOT guard against miscasting. Use with care. 0104 template<class T> 0105 T* nodeAs() 0106 { 0107 Q_ASSERT( dynamic_cast<T*>( m_node ) != nullptr ); 0108 return static_cast<T*>(m_node); 0109 } 0110 0111 template<class T> 0112 bool is() const 0113 { 0114 return nullptr != dynamic_cast<T*>(m_node); 0115 } 0116 0117 GeoParser::QualifiedName qualifiedName() const { return m_qualifiedName; } 0118 GeoNode* associatedNode() const { return m_node; } 0119 0120 private: 0121 friend class GeoParser; 0122 void assignNode( GeoNode* node ) { m_node = node; } 0123 GeoParser::QualifiedName m_qualifiedName; 0124 GeoNode* m_node; 0125 }; 0126 0127 } 0128 0129 #endif