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