File indexing completed on 2024-05-19 03:51:49
0001 /* 0002 SPDX-FileCopyrightText: 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef MARBLE_GEOTAGHANDLER_H 0008 #define MARBLE_GEOTAGHANDLER_H 0009 0010 #include <QHash> 0011 #include "marble_export.h" 0012 #include "GeoParser.h" 0013 0014 namespace Marble 0015 { 0016 0017 class GeoNode; 0018 0019 /** 0020 * @brief A base class for XML tag handlers 0021 * This is a base class that is used in the GeoParser architecture. To implement 0022 * a new GeoData format you will need to subclass GeoTagHandler and reimplement 0023 * the @see parse(GeoParser&) method. You also need to register the newly 0024 * implemented GeoTagHandler by declaring an instance of the helper structure 0025 * @see GeoTagHandlerRegistrar with a corresponding @see QualifiedName. 0026 */ 0027 class MARBLE_EXPORT GeoTagHandler 0028 { 0029 public: 0030 // API to be implemented by child handlers. 0031 virtual GeoNode* parse(GeoParser&) const = 0; 0032 0033 protected: // This base class is not directly constructable nor is it copyable. 0034 GeoTagHandler(); 0035 virtual ~GeoTagHandler(); 0036 0037 private: 0038 GeoTagHandler(const GeoTagHandler&) = delete; 0039 GeoTagHandler& operator=(const GeoTagHandler&) = delete; 0040 0041 private: // Only our registrar is allowed to register tag handlers. 0042 friend struct GeoTagHandlerRegistrar; 0043 static void registerHandler(const GeoParser::QualifiedName&, const GeoTagHandler*); 0044 static void unregisterHandler(const GeoParser::QualifiedName&); 0045 0046 private: // Only our parser is allowed to access tag handlers. 0047 friend class GeoParser; 0048 static const GeoTagHandler* recognizes(const GeoParser::QualifiedName&); 0049 0050 private: 0051 typedef QHash<GeoParser::QualifiedName, const GeoTagHandler*> TagHash; 0052 0053 static TagHash* tagHandlerHash(); 0054 static TagHash* s_tagHandlerHash; 0055 }; 0056 0057 // Helper structure 0058 struct GeoTagHandlerRegistrar 0059 { 0060 public: 0061 GeoTagHandlerRegistrar(const GeoParser::QualifiedName& name, const GeoTagHandler* handler) 0062 :m_name( name ) 0063 { 0064 GeoTagHandler::registerHandler(name, handler); 0065 } 0066 0067 ~GeoTagHandlerRegistrar() 0068 { 0069 GeoTagHandler::unregisterHandler(m_name); 0070 } 0071 0072 private: 0073 GeoParser::QualifiedName m_name; 0074 }; 0075 0076 // Macros to ease registering new handlers 0077 #define GEODATA_DEFINE_TAG_HANDLER(Module, UpperCaseModule, Name, NameSpace) \ 0078 static GeoTagHandlerRegistrar s_handler##Name##NameSpace(GeoParser::QualifiedName(QLatin1String(Module##Tag_##Name), QLatin1String(NameSpace)), \ 0079 new UpperCaseModule##Name##TagHandler()); 0080 0081 } 0082 0083 #endif