31 #include <unordered_map>
41 #if PY_MAJOR_VERSION >= 3
42 #if PY_VERSION_HEX < 0x03030000
43 #error "Python 3.0 - 3.2 are not supported."
45 #define PyString_AsStringAndSize(ob, charpp, sizep) \
46 (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \
47 PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
50 : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
57 namespace message_factory {
61 PyType_GenericAlloc(
type, 0));
62 if (factory ==
NULL) {
79 PyObject*
New(PyTypeObject*
type, PyObject*
args, PyObject* kwargs) {
80 static char* kwlist[] = {
"pool", 0};
82 if (!PyArg_ParseTupleAndKeywords(
args, kwargs,
"|O", kwlist, &
pool)) {
87 owned_pool.
reset(PyObject_CallFunction(
89 if (owned_pool ==
NULL) {
95 PyErr_Format(PyExc_TypeError,
"Expected a DescriptorPool, got %s",
96 pool->ob_type->tp_name);
101 return reinterpret_cast<PyObject*
>(
108 typedef PyMessageFactory::ClassesByMessageMap::iterator iterator;
109 for (iterator
it =
self->classes_by_descriptor->begin();
110 it !=
self->classes_by_descriptor->end(); ++
it) {
111 Py_CLEAR(
it->second);
113 delete self->classes_by_descriptor;
114 delete self->message_factory;
115 Py_CLEAR(
self->pool);
121 Py_VISIT(
self->pool);
122 for (
const auto& desc_and_class : *
self->classes_by_descriptor) {
123 Py_VISIT(desc_and_class.second);
132 for (
auto& desc_and_class : *
self->classes_by_descriptor) {
133 Py_CLEAR(desc_and_class.second);
144 typedef PyMessageFactory::ClassesByMessageMap::iterator iterator;
145 std::pair<iterator, bool> ret =
self->classes_by_descriptor->insert(
149 Py_DECREF(ret.first->second);
160 std::unordered_map<const Descriptor*, CMessageClass*>::iterator
it =
161 self->classes_by_descriptor->find(
descriptor);
162 if (
it !=
self->classes_by_descriptor->end()) {
163 Py_INCREF(
it->second);
168 if (py_descriptor ==
NULL) {
174 "DESCRIPTOR", py_descriptor.
get(),
175 "__module__", Py_None,
176 "message_factory",
self));
187 for (
int field_idx = 0; field_idx <
descriptor->field_count(); field_idx++) {
191 if (sub_descriptor !=
NULL) {
193 if (result ==
NULL) {
201 for (
int ext_idx = 0 ; ext_idx <
descriptor->extension_count() ; ext_idx++) {
206 if (py_extended_class ==
NULL) {
210 if (py_extension ==
NULL) {
214 py_extended_class.
get(), py_extension.
get()));
215 if (result ==
NULL) {
225 typedef PyMessageFactory::ClassesByMessageMap::iterator iterator;
226 iterator ret =
self->classes_by_descriptor->find(message_descriptor);
227 if (ret ==
self->classes_by_descriptor->end()) {
228 PyErr_Format(PyExc_TypeError,
"No message class registered for '%s'",
229 message_descriptor->
full_name().c_str());
240 Py_INCREF(
self->pool);
241 return reinterpret_cast<PyObject*
>(
self->pool);
271 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
272 "A static Message Factory",