123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- #include "qprotobufserializerregistry_p.h"
- #include "qprotobufserializer.h"
- #include "qprotobufjsonserializer.h"
- #include "qprotobufserializationplugininterface.h"
- #include <QDir>
- #include <QString>
- #include <QHash>
- #include <QPluginLoader>
- #include <QJsonObject>
- #include <QJsonArray>
- namespace {
- const QLatin1String Serializationplugin("serializationplugin");
- const QLatin1String TypeNames("types");
- const QLatin1String MetaData("MetaData");
- const QLatin1String Version("version");
- const QLatin1String Rating("rating");
- const QLatin1String ProtoVersion("protobufVersion");
- const QLatin1String PluginName("name");
- const QLatin1String ProtobufSerializer("protobuf");
- const QLatin1String JsonSerializer("json");
- #ifdef _WIN32
- const QLatin1String libExtension(".dll");
- const QLatin1String libPrefix("");
- #else
- const QLatin1String libExtension(".so");
- const QLatin1String libPrefix("lib");
- #endif
- }
- #define STRINGIFY2(s) #s
- #define STRINGIFY(s) STRINGIFY2(s)
- static const char *QtProtobufPluginPath = STRINGIFY(QT_PROTOBUF_PLUGIN_PATH)"/";
- namespace QtProtobuf {
- class QProtobufSerializerRegistryPrivateRecord final
- {
- public:
- QProtobufSerializerRegistryPrivateRecord() : loader(nullptr) {}
- void createDefaultImpl()
- {
- if (serializers.find(ProtobufSerializer) == serializers.end()) {
- serializers[ProtobufSerializer] = std::shared_ptr<QAbstractProtobufSerializer>(new QProtobufSerializer);
- }
- if (serializers.find(JsonSerializer) == serializers.end()) {
- serializers[JsonSerializer] = std::shared_ptr<QAbstractProtobufSerializer>(new QProtobufJsonSerializer);
- }
- }
- void loadPluginMetadata(const QString &path, const QString &pluginName)
- {
-
- if (path.isEmpty() || pluginName.isEmpty()){
- libPath = QtProtobufPluginPath + libPrefix + Serializationplugin + libExtension;
- }
-
- else {
- libPath = path + libPrefix + pluginName + libExtension;
- }
- loader = new QPluginLoader(libPath);
- pluginData = loader->metaData();
- QVariantMap fullJson = pluginData.toVariantMap();
- if (!fullJson.isEmpty()) {
- metaData = fullJson.value(MetaData).toMap();
- pluginLoadedName = metaData.value(PluginName).toString();
- typeArray = metaData.value(TypeNames).toList();
- }
- }
- void loadPlugin()
- {
- QProtobufSerializationPluginInterface *loadedPlugin = qobject_cast<QProtobufSerializationPluginInterface*>(loadPluginImpl());
- if (!pluginData.isEmpty() && loadedPlugin) {
- for (int i = 0; i < typeArray.count(); i++) {
- QString typeName = typeArray.at(i).toString();
- serializers[typeName] = std::shared_ptr<QAbstractProtobufSerializer>(loadedPlugin->serializer(typeName));
- }
- }
- }
- QObject* loadPluginImpl()
- {
- if (loader == nullptr || !loader->load())
- {
- qProtoWarning() << "Can't load plugin from" << libPath << loader->errorString();
- return nullptr;
- }
- return loader->instance();
- }
- std::unordered_map<QString, std::shared_ptr<QAbstractProtobufSerializer>> serializers;
- QJsonObject pluginData;
- QVariantMap metaData;
- QString pluginLoadedName;
- QPluginLoader *loader;
- QString libPath;
- QVariantList typeArray;
- };
- class QProtobufSerializerRegistryPrivate
- {
- public:
- QProtobufSerializerRegistryPrivate()
- {
-
- std::shared_ptr<QProtobufSerializerRegistryPrivateRecord> plugin = std::shared_ptr<QProtobufSerializerRegistryPrivateRecord>(new QProtobufSerializerRegistryPrivateRecord());
- plugin->createDefaultImpl();
- m_plugins[DefaultImpl] = plugin;
- }
- static const QString &loadPlugin(const QString &path, const QString &name)
- {
- std::shared_ptr<QProtobufSerializerRegistryPrivateRecord> plugin = std::shared_ptr<QProtobufSerializerRegistryPrivateRecord>(new QProtobufSerializerRegistryPrivateRecord());
- plugin->loadPluginMetadata(path, name);
- const QString &pluginName = plugin->pluginLoadedName;
- if (m_plugins.find(pluginName) == m_plugins.end()) {
- plugin->loadPlugin();
- m_plugins[pluginName] = plugin;
- }
- return pluginName;
- }
- static std::unordered_map<QString/*pluginName*/, std::shared_ptr<QProtobufSerializerRegistryPrivateRecord>> m_plugins;
- };
- std::unordered_map<QString/*pluginName*/, std::shared_ptr<QProtobufSerializerRegistryPrivateRecord>> QProtobufSerializerRegistryPrivate::m_plugins;
- }
- using namespace QtProtobuf;
- QProtobufSerializerRegistry::QProtobufSerializerRegistry() :
- dPtr(new QProtobufSerializerRegistryPrivate())
- {
- }
- QProtobufSerializerRegistry::~QProtobufSerializerRegistry() = default;
- const QString &QProtobufSerializerRegistry::loadPlugin(const QString &path, const QString &name)
- {
- return dPtr->loadPlugin(path, name);
- }
- std::shared_ptr<QAbstractProtobufSerializer> QProtobufSerializerRegistry::getSerializer(const QString &id, const QString &plugin)
- {
- return dPtr->m_plugins[plugin]->serializers.at(id);
- }
- std::unique_ptr<QAbstractProtobufSerializer> QProtobufSerializerRegistry::acquireSerializer(const QString &, const QString &)
- {
- Q_ASSERT_X(false, "QProtobufSerializerRegistry", "acquireSerializer is unimplemented");
- return std::unique_ptr<QAbstractProtobufSerializer>();
- }
- float QProtobufSerializerRegistry::pluginVersion(const QString &plugin)
- {
- if (dPtr->m_plugins.find(plugin) == dPtr->m_plugins.end())
- return 0.0;
- std::shared_ptr<QProtobufSerializerRegistryPrivateRecord> implementation = dPtr->m_plugins[plugin];
- if (implementation->metaData.isEmpty())
- return 0.0;
- return implementation->metaData.value(Version).toFloat();
- }
- QStringList QProtobufSerializerRegistry::pluginSerializers(const QString &plugin)
- {
- QStringList strList;
- if (dPtr->m_plugins.find(plugin) == dPtr->m_plugins.end())
- return strList;
- std::shared_ptr<QProtobufSerializerRegistryPrivateRecord> implementation = dPtr->m_plugins[plugin];
- QVariantList typeArray = implementation->metaData.value(TypeNames).toList();
- foreach(QVariant value, typeArray) {
- if (!value.toString().isEmpty()) {
- strList.append(value.toString());
- }
- }
- return strList;
- }
- float QProtobufSerializerRegistry::pluginProtobufVersion(const QString &plugin)
- {
- if (dPtr->m_plugins.find(plugin) == dPtr->m_plugins.end())
- return 0.0;
- std::shared_ptr<QProtobufSerializerRegistryPrivateRecord> implementation = dPtr->m_plugins[plugin];
- if (implementation.get() && implementation->metaData.isEmpty())
- return 0.0;
- return implementation->metaData.value(ProtoVersion).toFloat();
- }
- int QProtobufSerializerRegistry::pluginRating(const QString &plugin)
- {
- if (dPtr->m_plugins.find(plugin) == dPtr->m_plugins.end())
- return 0;
- std::shared_ptr<QProtobufSerializerRegistryPrivateRecord> implementation = dPtr->m_plugins[plugin];
- if (implementation->metaData.isEmpty())
- return 0;
- return implementation->metaData.value(Rating).toInt();
- }
|