return NULL; \
}
+/*
+ * A note about PyLdbObject back-references and struct member ordering.
+ *
+ * PyLdbDnObject, PyLdbMessageObject, and PyLdbResultObject all
+ * contain pointers to the PyLdbObject that was used to create them.
+ * This is used to check that the ldb pointer in the underlying ldb
+ * struct is still valid -- that is, it points to the same ldb as the
+ * PyLdbObject.
+ *
+ * We keep these pointers in third place in the structs, like this
+ * {
+ * PyObject_HEAD
+ * TALLOC_CTX *mem_ctx;
+ * PyLdbObject *pyldb;
+ * ...
+ * }
+ *
+ * so that, if we feel like it in future, we can do type-punning in
+ * the way Python does. For example:
+ *
+ * typedef struct {
+ * PyObject_HEAD
+ * TALLOC_CTX *mem_ctx;
+ * PyLdbObject *pyldb;
+ * } PyLdbChildObject;
+ *
+ * #define pyldb_child_get_pyldb(pyobj) ((PyLdbChildObject *)pyobj)->pyldb
+ *
+ * #define PY_LDB_OWNS_THIS_CHILD(pyldb, child) \
+ * (((PyLdbObject *)ldb) == ((PyLdbChildObject *)child)->ldb)
+ *
+ * At present we don't do this, because there are not a whole lot of
+ * cases where we want to do the same things with dNs, messages, and
+ * results.
+ */
+
typedef struct {
PyObject_HEAD
TALLOC_CTX *mem_ctx;
- struct ldb_dn *dn;
/*
* We use this to keep a reference to the ldb context within
* the struct ldb_dn and to know if it is still valid
*/
PyLdbObject *pyldb;
+ struct ldb_dn *dn;
} PyLdbDnObject;
PyObject *pyldb_Dn_FromDn(struct ldb_dn *dn, PyLdbObject *pyldb);
typedef struct {
PyObject_HEAD
TALLOC_CTX *mem_ctx;
- struct ldb_message *msg;
/*
* We use this to keep a reference to the ldb context within
* the struct ldb_dn (under struct ldb_message) and to know if
* it is still valid
*/
PyLdbObject *pyldb;
+ struct ldb_message *msg;
} PyLdbMessageObject;
+
#define pyldb_Message_AsMessage(pyobj) ((PyLdbMessageObject *)pyobj)->msg
/*
typedef struct {
PyObject_HEAD
TALLOC_CTX *mem_ctx;
+ PyLdbObject *pyldb;
PyObject *msgs;
PyObject *referals;
PyObject *controls;
- PyLdbObject *pyldb;
} PyLdbResultObject;
typedef struct {