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