1 // This is the implementation of the QVariantMap convertors.
2 //
3 // Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
4 //
5 // This file is part of PyQt5.
6 //
7 // This file may be used under the terms of the GNU General Public License
8 // version 3.0 as published by the Free Software Foundation and appearing in
9 // the file LICENSE included in the packaging of this file.  Please review the
10 // following information to ensure the GNU General Public License version 3.0
11 // requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 //
13 // If you do not wish to use this file under the terms of the GPL version 3.0
14 // then you may purchase a commercial license.  For more information contact
15 // info@riverbankcomputing.com.
16 //
17 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 
20 
21 #include <Python.h>
22 
23 #include <QString>
24 #include <QVariant>
25 
26 #include "qpycore_api.h"
27 #include "qpycore_chimera.h"
28 
29 #include "sipAPIQtCore.h"
30 
31 
32 // Convert a Python object to a QVariantMap and return false if there was an
33 // error.
qpycore_toQVariantMap(PyObject * py,QVariantMap & cpp)34 bool qpycore_toQVariantMap(PyObject *py, QVariantMap &cpp)
35 {
36     Q_ASSERT(PyDict_Check(py));
37 
38     PyObject *key_obj, *val_obj;
39     Py_ssize_t i;
40 
41     i = 0;
42     while (PyDict_Next(py, &i, &key_obj, &val_obj))
43     {
44         int key_state, val_state, iserr = 0;
45 
46         QString *key = reinterpret_cast<QString *>(sipForceConvertToType(
47                 key_obj, sipType_QString, NULL, SIP_NOT_NONE, &key_state,
48                 &iserr));
49 
50         QVariant *val = reinterpret_cast<QVariant *>(sipForceConvertToType(
51                 val_obj, sipType_QVariant, NULL, SIP_NOT_NONE, &val_state,
52                 &iserr));
53 
54         if (iserr)
55             return false;
56 
57         cpp.insert(*key, *val);
58 
59         sipReleaseType(key, sipType_QString, key_state);
60         sipReleaseType(val, sipType_QVariant, val_state);
61     }
62 
63     return true;
64 }
65 
66 
67 // Convert a QVariantMap to a Python object and return 0 if there was an error.
qpycore_fromQVariantMap(const QVariantMap & qm)68 PyObject *qpycore_fromQVariantMap(const QVariantMap &qm)
69 {
70     PyObject *py = PyDict_New();
71 
72     if (!py)
73         return 0;
74 
75     for (QVariantMap::const_iterator it = qm.constBegin(); it != qm.constEnd(); ++it)
76         if (!Chimera::addVariantToDict(py, it.key(), it.value()))
77         {
78             Py_DECREF(py);
79             return 0;
80         }
81 
82     return py;
83 }
84