summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2018-06-26 22:46:49 -0700
committerThiago Macieira <thiago.macieira@intel.com>2018-09-01 15:19:39 +0000
commitd9766ddc3d525cf08acec4c3483e61d86c9899a8 (patch)
tree755b9c9181a24cbc1663714e888e2e3f4cd4db45 /src
parent7391662f80470549b9f9c182da43cf433efabdf7 (diff)
Plugins: store the metadata in CBOR instead of binary JSON
In preparation for Qt 6 deprecating the binary JSON format. Also reduces the size of the metadata a little: for the xcb platform plugin, it went down from 264 bytes to 138; for the jpeg image plugin, it went from 320 to 135. I've had to change the signature so older versions of Qt won't try to parse the CBOR data as Binary JSON. Unfortunately, before QJsonDocument could get a chance to reject it, qJsonFromRawLibraryMetaData() needed to allocate memory and that causes crashes with Qt < 5.11.2. Change-Id: Ieb48f7c0dd0e4e0fb35efffd153bee34e16ce347 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/plugin/plugin.pri1
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp75
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h3
-rw-r--r--src/corelib/plugin/qlibrary.cpp44
-rw-r--r--src/corelib/plugin/qplugin_p.h77
-rw-r--r--src/corelib/plugin/qpluginloader.cpp11
-rw-r--r--src/tools/moc/cbordevice.h94
-rw-r--r--src/tools/moc/generator.cpp158
-rw-r--r--src/tools/moc/moc.pri6
9 files changed, 390 insertions, 79 deletions
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index a0e0d76044..13153e8d0a 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -4,6 +4,7 @@ HEADERS += \
plugin/qfactoryinterface.h \
plugin/qpluginloader.h \
plugin/qplugin.h \
+ plugin/qplugin_p.h \
plugin/quuid.h \
plugin/qfactoryloader_p.h
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 0b35f41ca3..9f877ccda8 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -47,9 +47,12 @@
#include <qdebug.h>
#include "qmutex.h"
#include "qplugin.h"
+#include "qplugin_p.h"
#include "qpluginloader.h"
#include "private/qobject_p.h"
#include "private/qcoreapplication_p.h"
+#include "qcbormap.h"
+#include "qcborvalue.h"
#include "qjsondocument.h"
#include "qjsonvalue.h"
#include "qjsonobject.h"
@@ -64,22 +67,70 @@ static inline int metaDataSignatureLength()
return sizeof("QTMETADATA ") - 1;
}
-QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype sectionSize)
+static QJsonDocument jsonFromCborMetaData(const char *raw, qsizetype size, QString *errMsg)
+{
+ if (Q_UNLIKELY(raw[-1] != '!')) {
+ *errMsg = QStringLiteral("Invalid metadata signature");
+ return QJsonDocument();
+ }
+
+ QByteArray ba = QByteArray::fromRawData(raw, int(size));
+ QCborParserError err;
+ QCborValue metadata = QCborValue::fromCbor(ba, &err);
+
+ if (err.error != QCborError::NoError) {
+ *errMsg = QLatin1String("Metadata parsing error: ") + err.error.toString();
+ return QJsonDocument();
+ }
+
+ if (!metadata.isMap()) {
+ *errMsg = QStringLiteral("Unexpected metadata contents");
+ return QJsonDocument();
+ }
+
+ // convert the top-level map integer keys
+ QJsonObject o;
+ for (auto it : metadata.toMap()) {
+ QString key;
+ if (it.first.isInteger()) {
+ switch (it.first.toInteger()) {
+#define CONVERT_TO_STRING(IntKey, StringKey, Description) \
+ case int(IntKey): key = QStringLiteral(StringKey); break;
+ QT_PLUGIN_FOREACH_METADATA(CONVERT_TO_STRING)
+#undef CONVERT_TO_STRING
+ }
+ } else {
+ key = it.first.toString();
+ }
+
+ if (!key.isEmpty())
+ o.insert(key, it.second.toJsonValue());
+ }
+ return QJsonDocument(o);
+}
+
+QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype sectionSize, QString *errMsg)
{
raw += metaDataSignatureLength();
sectionSize -= metaDataSignatureLength();
- // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h)
- uint size = qFromLittleEndian<uint>(raw + 8);
- // but the maximum size of binary JSON is 128 MB
- size = qMin(size, 128U * 1024 * 1024);
- // and it doesn't include the size of the header (8 bytes)
- size += 8;
- // finally, it can't be bigger than the file or section size
- size = qMin(sectionSize, qsizetype(size));
-
- QByteArray json(raw, size);
- return QJsonDocument::fromBinaryData(json);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ if (Q_UNLIKELY(raw[-1] == ' ')) {
+ // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h)
+ uint size = qFromLittleEndian<uint>(raw + 8);
+ // but the maximum size of binary JSON is 128 MB
+ size = qMin(size, 128U * 1024 * 1024);
+ // and it doesn't include the size of the header (8 bytes)
+ size += 8;
+ // finally, it can't be bigger than the file or section size
+ size = qMin(sectionSize, qsizetype(size));
+
+ QByteArray json(raw, size);
+ return QJsonDocument::fromBinaryData(json);
+ }
+#endif
+
+ return jsonFromCborMetaData(raw, sectionSize, errMsg);
}
class QFactoryLoaderPrivate : public QObjectPrivate
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index fe722999ae..7815ea0b5d 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -56,6 +56,7 @@
#include "QtCore/qobject.h"
#include "QtCore/qstringlist.h"
+#include "QtCore/qcborvalue.h"
#include "QtCore/qjsonobject.h"
#include "QtCore/qjsondocument.h"
#include "QtCore/qmap.h"
@@ -66,7 +67,7 @@
QT_BEGIN_NAMESPACE
-QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype size);
+QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype size, QString *errMsg);
class QFactoryLoaderPrivate;
class Q_CORE_EXPORT QFactoryLoader : public QObject
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 869ef6181f..aa63ed1a6b 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -268,7 +268,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
*/
bool hasMetaData = false;
qsizetype pos = 0;
- char pattern[] = "qTMETADATA ";
+ char pattern[] = "qTMETADATA ";
pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it.
const ulong plen = qstrlen(pattern);
#if defined (Q_OF_ELF) && defined(Q_CC_GNU)
@@ -314,10 +314,14 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
bool ret = false;
- if (pos >= 0) {
- if (hasMetaData) {
- const char *data = filedata + pos;
- QJsonDocument doc = qJsonFromRawLibraryMetaData(data, qsizetype(fdlen));
+ if (pos >= 0 && hasMetaData) {
+ const char *data = filedata + pos;
+ QString errMsg;
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(data, fdlen, &errMsg);
+ if (doc.isNull()) {
+ qWarning("Found invalid metadata in lib %s: %s",
+ qPrintable(library), qPrintable(errMsg));
+ } else {
lib->metaData = doc.object();
if (qt_debug_component())
qWarning("Found metadata in lib %s, metadata=\n%s\n",
@@ -679,20 +683,26 @@ bool QLibrary::isLibrary(const QString &fileName)
#endif
}
-typedef const char * (*QtPluginQueryVerificationDataFunction)();
-
-static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv)
+static bool qt_get_metadata(QLibraryPrivate *priv, QString *errMsg)
{
- const char *szData = 0;
- if (!pfn)
- return false;
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ auto getMetaData = [](QFunctionPointer fptr) {
+ auto f = reinterpret_cast<const char * (*)()>(fptr);
+ return qMakePair<const char *, size_t>(f(), INT_MAX);
+ };
+#else
+ auto getMetaData = [](QFunctionPointer fptr) {
+ auto f = reinterpret_cast<QPair<const char *, size_t> (*)()>(fptr);
+ return f();
+ };
+#endif
- szData = pfn();
- if (!szData)
+ QFunctionPointer pfn = priv->resolve("qt_plugin_query_metadata");
+ if (!pfn)
return false;
- // the data is already loaded, so the size doesn't matter
- QJsonDocument doc = qJsonFromRawLibraryMetaData(szData, INT_MAX);
+ auto metaData = getMetaData(pfn);
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(metaData.first, metaData.second, errMsg);
if (doc.isNull())
return false;
priv->metaData = doc.object();
@@ -735,9 +745,7 @@ void QLibraryPrivate::updatePluginState()
} else {
// library is already loaded (probably via QLibrary)
// simply get the target function and call it.
- QtPluginQueryVerificationDataFunction getMetaData = NULL;
- getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
- success = qt_get_metadata(getMetaData, this);
+ success = qt_get_metadata(this, &errorString);
}
if (!success) {
diff --git a/src/corelib/plugin/qplugin_p.h b/src/corelib/plugin/qplugin_p.h
new file mode 100644
index 0000000000..99ee16a3e8
--- /dev/null
+++ b/src/corelib/plugin/qplugin_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLUGIN_P_H
+#define QPLUGIN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+enum class QtPluginMetaDataKeys {
+ QtVersion,
+ Debug,
+ IID,
+ ClassName,
+ MetaData
+};
+
+// F(IntKey, StringKey, Description)
+// Keep this list sorted in the order moc should output.
+#define QT_PLUGIN_FOREACH_METADATA(F) \
+ F(QtPluginMetaDataKeys::QtVersion, "version", "Qt version built against") \
+ F(QtPluginMetaDataKeys::Debug, "debug", "Whether it is a debug build") \
+ F(QtPluginMetaDataKeys::IID, "IID", "Plugin's Interface ID") \
+ F(QtPluginMetaDataKeys::ClassName, "className", "Plugin class name") \
+ F(QtPluginMetaDataKeys::MetaData, "MetaData", "Other meta data")
+
+QT_END_NAMESPACE
+
+#endif // QPLUGIN_P_H
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 83cbcd2b44..0f94bb6adf 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -475,10 +475,19 @@ QVector<QStaticPlugin> QPluginLoader::staticPlugins()
*/
QJsonObject QStaticPlugin::metaData() const
{
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// the data is already loaded, so this doesn't matter
qsizetype rawMetaDataSize = INT_MAX;
+ const char *ptr = rawMetaData();
+#else
+ auto ptr = static_cast<const char *>(rawMetaData);
+#endif
- return qJsonFromRawLibraryMetaData(rawMetaData(), rawMetaDataSize).object();
+ QString errMsg;
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(ptr, rawMetaDataSize, &errMsg);
+ Q_ASSERT(doc.isObject());
+ Q_ASSERT(errMsg.isEmpty());
+ return doc.object();
}
QT_END_NAMESPACE
diff --git a/src/tools/moc/cbordevice.h b/src/tools/moc/cbordevice.h
new file mode 100644
index 0000000000..25b75b79eb
--- /dev/null
+++ b/src/tools/moc/cbordevice.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CBORDEVICE_H
+#define CBORDEVICE_H
+
+#include <memory>
+#include <stdio.h>
+
+#define CBOR_API inline
+#define CBOR_PRIVATE_API inline
+#define CBOR_NO_PARSER_API 1
+#include <cbor.h>
+
+class CborDevice
+{
+public:
+ CborDevice(FILE *out) : out(out) {}
+
+ void nextItem(const char *comment = nullptr)
+ {
+ i = 0;
+ if (comment)
+ fprintf(out, "\n // %s", comment);
+ }
+
+ static CborError callback(void *self, const void *ptr, size_t len, CborEncoderAppendType t)
+ {
+ auto that = static_cast<CborDevice *>(self);
+ auto data = static_cast<const char *>(ptr);
+ if (t == CborEncoderAppendCborData) {
+ while (len--)
+ that->putByte(*data++);
+ } else {
+ while (len--)
+ that->putChar(*data++);
+ }
+ return CborNoError;
+ }
+
+private:
+ FILE *out;
+ int i = 0;
+
+ void putNewline()
+ {
+ if ((i++ % 8) == 0)
+ fputs("\n ", out);
+ }
+
+ void putByte(uint8_t c)
+ {
+ putNewline();
+ fprintf(out, " 0x%02x, ", c);
+ }
+
+ void putChar(char c)
+ {
+ putNewline();
+ if (c < 0x20 || c >= 0x7f)
+ fprintf(out, " '\\x%x',", uint8_t(c));
+ else if (c == '\'' || c == '\\')
+ fprintf(out, " '\\%c',", c);
+ else
+ fprintf(out, " '%c', ", c);
+ }
+};
+
+#endif // CBORDEVICE_H
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index a3ef1147d6..e5154b779b 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -2,6 +2,7 @@
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -28,6 +29,7 @@
****************************************************************************/
#include "generator.h"
+#include "cbordevice.h"
#include "outputrevision.h"
#include "utils.h"
#include <QtCore/qmetatype.h>
@@ -36,9 +38,13 @@
#include <QtCore/qjsonvalue.h>
#include <QtCore/qjsonarray.h>
#include <QtCore/qplugin.h>
+#include <QtCore/qstringview.h>
+
+#include <math.h>
#include <stdio.h>
#include <private/qmetaobject_p.h> //for the flags.
+#include <private/qplugin_p.h> //for the flags.
QT_BEGIN_NAMESPACE
@@ -1560,31 +1566,56 @@ void Generator::generateSignal(FunctionDef *def,int index)
fprintf(out, "}\n");
}
-static void writePluginMetaData(FILE *out, const QJsonObject &data)
+static CborError jsonValueToCbor(CborEncoder *parent, const QJsonValue &v);
+static CborError jsonObjectToCbor(CborEncoder *parent, const QJsonObject &o)
{
- const QJsonDocument doc(data);
+ auto it = o.constBegin();
+ auto end = o.constEnd();
+ CborEncoder map;
+ cbor_encoder_create_map(parent, &map, o.size());
+
+ for ( ; it != end; ++it) {
+ QByteArray key = it.key().toUtf8();
+ cbor_encode_text_string(&map, key.constData(), key.size());
+ jsonValueToCbor(&map, it.value());
+ }
+ return cbor_encoder_close_container(parent, &map);
+}
- fputs("\nQT_PLUGIN_METADATA_SECTION\n"
- "static const unsigned char qt_pluginMetaData[] = {\n"
- " 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', ' ',\n ", out);
-#if 0
- fprintf(out, "\"%s\";\n", doc.toJson().constData());
-#else
- const QByteArray binary = doc.toBinaryData();
- const int last = binary.size() - 1;
- for (int i = 0; i < last; ++i) {
- uchar c = (uchar)binary.at(i);
- if (c < 0x20 || c >= 0x7f)
- fprintf(out, " 0x%02x,", c);
- else if (c == '\'' || c == '\\')
- fprintf(out, " '\\%c',", c);
- else
- fprintf(out, " '%c', ", c);
- if (!((i + 1) % 8))
- fputs("\n ", out);
+static CborError jsonArrayToCbor(CborEncoder *parent, const QJsonArray &a)
+{
+ CborEncoder array;
+ cbor_encoder_create_array(parent, &array, a.size());
+ for (const QJsonValue &v : a)
+ jsonValueToCbor(&array, v);
+ return cbor_encoder_close_container(parent, &array);
+}
+
+static CborError jsonValueToCbor(CborEncoder *parent, const QJsonValue &v)
+{
+ switch (v.type()) {
+ case QJsonValue::Null:
+ case QJsonValue::Undefined:
+ return cbor_encode_null(parent);
+ case QJsonValue::Bool:
+ return cbor_encode_boolean(parent, v.toBool());
+ case QJsonValue::Array:
+ return jsonArrayToCbor(parent, v.toArray());
+ case QJsonValue::Object:
+ return jsonObjectToCbor(parent, v.toObject());
+ case QJsonValue::String: {
+ QByteArray s = v.toString().toUtf8();
+ return cbor_encode_text_string(parent, s.constData(), s.size());
}
- fprintf(out, " 0x%02x\n};\n", (uchar)binary.at(last));
-#endif
+ case QJsonValue::Double: {
+ double d = v.toDouble();
+ if (d == floor(d) && fabs(d) <= (Q_INT64_C(1) << std::numeric_limits<double>::digits))
+ return cbor_encode_int(parent, qint64(d));
+ return cbor_encode_double(parent, d);
+ }
+ }
+ Q_UNREACHABLE();
+ return CborUnknownError;
}
void Generator::generatePluginMetaData()
@@ -1592,32 +1623,59 @@ void Generator::generatePluginMetaData()
if (cdef->pluginData.iid.isEmpty())
return;
- // Write plugin meta data #ifdefed QT_NO_DEBUG with debug=false,
- // true, respectively.
-
- QJsonObject data;
- const QString debugKey = QStringLiteral("debug");
- data.insert(QStringLiteral("IID"), QLatin1String(cdef->pluginData.iid.constData()));
- data.insert(QStringLiteral("className"), QLatin1String(cdef->classname.constData()));
- data.insert(QStringLiteral("version"), (int)QT_VERSION);
- data.insert(debugKey, QJsonValue(false));
- data.insert(QStringLiteral("MetaData"), cdef->pluginData.metaData.object());
+ fputs("\nQT_PLUGIN_METADATA_SECTION\n"
+ "static const unsigned char qt_pluginMetaData[] = {\n"
+ " 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',", out);
+
+ CborDevice dev(out);
+ CborEncoder enc;
+ cbor_encoder_init_writer(&enc, CborDevice::callback, &dev);
+
+ CborEncoder map;
+ cbor_encoder_create_map(&enc, &map, CborIndefiniteLength);
+
+ dev.nextItem("\"version\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::QtVersion));
+ cbor_encode_int(&map, QT_VERSION);
+
+ fputs("\n#ifdef QT_NO_DEBUG", out);
+ dev.nextItem("\"debug\" = false");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::Debug));
+ cbor_encode_boolean(&map, false);
+ fputs("\n#else", out);
+ dev.nextItem("\"debug\" = true");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::Debug));
+ cbor_encode_boolean(&map, true);
+ fputs("\n#endif", out);
+
+ dev.nextItem("\"IID\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::IID));
+ cbor_encode_text_string(&map, cdef->pluginData.iid.constData(), cdef->pluginData.iid.size());
+
+ dev.nextItem("\"className\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::ClassName));
+ cbor_encode_text_string(&map, cdef->classname.constData(), cdef->classname.size());
+
+ QJsonObject o = cdef->pluginData.metaData.object();
+ if (!o.isEmpty()) {
+ dev.nextItem("\"MetaData\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::MetaData));
+ jsonObjectToCbor(&map, o);
+ }
// Add -M args from the command line:
- for (auto it = cdef->pluginData.metaArgs.cbegin(), end = cdef->pluginData.metaArgs.cend(); it != end; ++it)
- data.insert(it.key(), it.value());
-
- fputs("\nQT_PLUGIN_METADATA_SECTION const uint qt_section_alignment_dummy = 42;\n\n"
- "#ifdef QT_NO_DEBUG\n", out);
- writePluginMetaData(out, data);
-
- fputs("\n#else // QT_NO_DEBUG\n", out);
-
- data.remove(debugKey);
- data.insert(debugKey, QJsonValue(true));
- writePluginMetaData(out, data);
+ for (auto it = cdef->pluginData.metaArgs.cbegin(), end = cdef->pluginData.metaArgs.cend(); it != end; ++it) {
+ const QJsonArray &a = it.value();
+ QByteArray key = it.key().toUtf8();
+ dev.nextItem(QByteArray("command-line \"" + key + "\"").constData());
+ cbor_encode_text_string(&map, key.constData(), key.size());
+ jsonArrayToCbor(&map, a);
+ }
- fputs("#endif // QT_NO_DEBUG\n\n", out);
+ // Close the CBOR map manually
+ dev.nextItem();
+ cbor_encoder_close_container(&enc, &map);
+ fputs("\n};\n", out);
// 'Use' all namespaces.
int pos = cdef->qualified.indexOf("::");
@@ -1627,4 +1685,14 @@ void Generator::generatePluginMetaData()
cdef->qualified.constData(), cdef->classname.constData());
}
+QT_WARNING_DISABLE_GCC("-Wunused-function")
+QT_WARNING_DISABLE_CLANG("-Wunused-function")
+QT_WARNING_DISABLE_CLANG("-Wundefined-internal")
+QT_WARNING_DISABLE_MSVC(4334) // '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
+
+#define CBOR_ENCODER_WRITER_CONTROL 1
+#define CBOR_ENCODER_WRITE_FUNCTION CborDevice::callback
+
QT_END_NAMESPACE
+
+#include "cborencoder.c"
diff --git a/src/tools/moc/moc.pri b/src/tools/moc/moc.pri
index b689a35478..90839a445b 100644
--- a/src/tools/moc/moc.pri
+++ b/src/tools/moc/moc.pri
@@ -1,5 +1,6 @@
-INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD \
+ $$PWD/../../3rdparty/tinycbor/src
HEADERS = $$PWD/moc.h \
$$PWD/preprocessor.h \
@@ -8,7 +9,8 @@ HEADERS = $$PWD/moc.h \
$$PWD/token.h \
$$PWD/utils.h \
$$PWD/generator.h \
- $$PWD/outputrevision.h
+ $$PWD/outputrevision.h \
+ $$PWD/cbordevice.h
SOURCES = $$PWD/moc.cpp \
$$PWD/preprocessor.cpp \
$$PWD/generator.cpp \