1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "pyfield.h"
#include "extensioncontext.h"
#include "pytype.h"
#include "pycdbextmodule.h"
struct PyFieldPrivate
{
PyFieldPrivate(std::string name, const PyType &parentType)
: name(name), parentType(parentType)
{}
std::string name;
unsigned long offset = 0;
PyType parentType;
PyType type;
};
PyField::PyField(std::string name, const PyType &parentType)
: d(new PyFieldPrivate(name, parentType))
{
auto extcmd = ExtensionCommandContext::instance();
unsigned long typeID = 0;
if (SUCCEEDED(extcmd->symbols()->GetFieldTypeAndOffset(
d->parentType.moduleId(), d->parentType.getTypeId(), d->name.c_str(),
&typeID, &d->offset))) {
d->type = PyType(d->parentType.moduleId(), typeID);
}
}
std::string PyField::name() const
{ return d->name; }
const PyType &PyField::type() const
{ return d->type; }
const PyType &PyField::parentType() const
{ return d->parentType; }
ULONG64 PyField::bitsize() const
{ return d->type.bitsize(); }
ULONG64 PyField::bitpos() const
{ return d->offset; }
bool PyField::isValid() const
{
return d != nullptr;
}
// Python interface implementation
namespace PyFieldInterface {
#define PY_OBJ_NAME FieldPythonObject
PY_NEW_FUNC(PY_OBJ_NAME)
PY_DEALLOC_FUNC(PY_OBJ_NAME)
PY_FUNC_RET_STD_STRING(name, PY_OBJ_NAME)
PY_FUNC_RET_NONE(isBaseClass, PY_OBJ_NAME)
PY_FUNC_RET_OBJECT(type, PY_OBJ_NAME)
PY_FUNC_RET_OBJECT(parentType, PY_OBJ_NAME)
PY_FUNC(bitsize, PY_OBJ_NAME, "K")
PY_FUNC(bitpos, PY_OBJ_NAME, "K")
static PyMethodDef fieldMethods[] = {
{"name", PyCFunction(name), METH_NOARGS,
"Return the name of this field or None for anonymous fields"},
{"isBaseClass", PyCFunction(isBaseClass), METH_NOARGS,
"Whether this is a base class or normal member"},
{"type", PyCFunction(type), METH_NOARGS,
"Type of this member"},
{"parentType", PyCFunction(parentType), METH_NOARGS,
"Type of class this member belongs to"},
{"bitsize", PyCFunction(bitsize), METH_NOARGS,
"Size of member in bits"},
{"bitpos", PyCFunction(bitpos), METH_NOARGS,
"Offset of member in parent type in bits"},
{NULL} /* Sentinel */
};
} // PyFieldInterface
PyTypeObject *field_pytype()
{
static PyTypeObject cdbext_FieldType = {
PyVarObject_HEAD_INIT(NULL, 0)
"cdbext.Field", /* tp_name */
sizeof(FieldPythonObject), /* tp_basicsize */
0,
(destructor)PyFieldInterface::dealloc, /* tp_dealloc */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Py_TPFLAGS_DEFAULT, /* tp_flags */
"Field objects", /* tp_doc */
0, 0, 0, 0, 0, 0,
PyFieldInterface::fieldMethods, /* tp_methods */
0, 0, 0, 0, 0, 0, 0, 0, 0,
PyFieldInterface::newObject, /* tp_new */
};
return &cdbext_FieldType;
}
PyObject *createPythonObject(PyField implClass)
{
if (!implClass.isValid())
Py_RETURN_NONE;
FieldPythonObject *newPyField = PyObject_New(FieldPythonObject, field_pytype());
newPyField->impl = new PyField(implClass);
return reinterpret_cast<PyObject *>(newPyField);
}
|