New submission from Gregory P. Smith:
This is my svn diff of a py3k Modules/_bsddb.c converted to use the
buffer API. I'm submitting it here as so it doesn't get misplaced as it
currently won't work until bytes objects support PyBUF_LOCKDATA (a
separate bug)
----------
assignee: gregory.p.smith
components: Extension Modules
files: py3k-_bsddb-bufferAPI-001.patch
keywords: patch, py3k
messages: 55334
nosy: gregory.p.smith
severity: normal
status: open
title: py3k _bsddb.c patch to use the new buffer API
versions: Python 3.0
__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1036>
__________________________________
Index: Modules/_bsddb.c
===================================================================
--- Modules/_bsddb.c (revision 57549)
+++ Modules/_bsddb.c (working copy)
@@ -348,10 +348,7 @@
#define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
-#define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
- dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
-
static int makeDBError(int err);
@@ -372,22 +369,78 @@
}
+/* Handy function to free a DBT and any self-allocated data within.
+ To be used on self created DBTs. The make_dbt and make_key_dbt
+ functions have their own free routines that do more that this. */
+static void free_dbt(DBT *dbt)
+{
+ if ((dbt->flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && dbt->data != NULL) {
+ free(dbt->data);
+ dbt->data = NULL;
+ }
+}
+
+
+/* Cleanup a Python buffer API view created by make_dbt() */
+static void free_buf_view(PyObject *obj, PyBuffer *view)
+{
+ if (view) {
+ PyObject_ReleaseBuffer(obj, view);
+ PyMem_Free(view);
+ }
+}
+
+
+/* Cleanup a DBT and an associated Python buffer API view
+ created by make_key_dbt() */
+#define FREE_DBT_VIEW(dbt, obj, view) \
+ do { \
+ free_dbt(&(dbt)); \
+ free_buf_view((obj), (view)); \
+ } while(0);
+
+
/* Create a DBT structure (containing key and data values) from Python
- strings. Returns 1 on success, 0 on an error. */
-static int make_dbt(PyObject* obj, DBT* dbt)
+ strings. Returns >= 1 on success, 0 on an error. The returned_view_p
+ may be filled with a newly allocated PyBuffer view on success.
+ The caller MUST call free_buf_view() on any returned PyBuffer. */
+static int make_dbt(PyObject* obj, DBT* dbt, PyBuffer** returned_view_p)
{
+ PyBuffer *view;
+
+ /* simple way to ensure the caller can detect if we've returned a
+ new buffer view or not: require their pointer to start out NULL. */
+ assert(*returned_view_p == NULL);
+
CLEAR_DBT(*dbt);
if (obj == Py_None) {
/* no need to do anything, the structure has already been zeroed */
return 1;
}
- if (!PyBytes_Check(obj)) {
+ if (!PyObject_CheckBuffer(obj)) {
PyErr_SetString(PyExc_TypeError,
- "Data values must be of type bytes or None.");
+ "Data values must support the buffer API or be None.");
return 0;
}
- dbt->data = PyBytes_AS_STRING(obj);
- dbt->size = PyBytes_GET_SIZE(obj);
+ if (!(view = PyMem_Malloc(sizeof(PyBuffer)))) {
+ PyErr_SetString(PyExc_MemoryError,
+ "PyBuffer malloc failed");
+ return 0;
+ }
+ if (PyObject_GetBuffer(obj, view, PyBUF_LOCKDATA) == -1) {
+ PyMem_Free(view);
+ return 0;
+ }
+ if (view->ndim > 1) {
+ PyErr_SetString(PyExc_BufferError,
+ "buffers must be single dimension");
+ PyObject_ReleaseBuffer(obj, view);
+ PyMem_Free(view);
+ return 0;
+ }
+ dbt->data = view->buf;
+ dbt->size = Py_SAFE_DOWNCAST(view->len, Py_ssize_t, u_int32_t);
+ *returned_view_p = view;
return 1;
}
@@ -395,13 +448,20 @@
/* Recno and Queue DBs can have integer keys. This function figures out
what's been given, verifies that it's allowed, and then makes the DBT.
- Caller MUST call FREE_DBT(key) when done. */
+ Caller MUST call FREE_DBT_VIEW(keydbt, keyobj, key_view) with all
+ returned DBT and PyBuffer values when done. */
static int
-make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
+make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags,
+ PyBuffer** returned_view_p)
{
db_recno_t recno;
int type;
+ PyBuffer *view;
+ /* simple way to ensure the caller can detect if we've returned a
+ new buffer view or not: require their pointer to start out NULL. */
+ assert(*returned_view_p == NULL);
+
CLEAR_DBT(*key);
if (keyobj == Py_None) {
type = _DB_get_type(self);
@@ -416,22 +476,6 @@
/* no need to do anything, the structure has already been zeroed */
}
- else if (PyBytes_Check(keyobj)) {
- /* verify access method type */
- type = _DB_get_type(self);
- if (type == -1)
- return 0;
- if (type == DB_RECNO || type == DB_QUEUE) {
- PyErr_SetString(
- PyExc_TypeError,
- "String keys not allowed for Recno and Queue DB's");
- return 0;
- }
-
- key->data = PyBytes_AS_STRING(keyobj);
- key->size = PyBytes_GET_SIZE(keyobj);
- }
-
else if (PyInt_Check(keyobj)) {
/* verify access method type */
type = _DB_get_type(self);
@@ -461,9 +505,44 @@
memcpy(key->data, &recno, sizeof(db_recno_t));
key->flags = DB_DBT_REALLOC;
}
+
+ else if (PyObject_CheckBuffer(keyobj)) {
+ /* verify access method type */
+ type = _DB_get_type(self);
+ if (type == -1)
+ return 0;
+ if (type == DB_RECNO || type == DB_QUEUE) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "Non-integer keys not allowed for Recno and Queue DB's");
+ return 0;
+ }
+
+ if (!(view = PyMem_Malloc(sizeof(PyBuffer)))) {
+ PyErr_SetString(PyExc_MemoryError,
+ "PyBuffer malloc failed");
+ return 0;
+ }
+ if (PyObject_GetBuffer(keyobj, view, PyBUF_LOCKDATA) == -1) {
+ PyMem_Free(view);
+ return 0;
+ }
+ if (view->ndim > 1) {
+ PyErr_SetString(PyExc_BufferError,
+ "buffers must be single dimension");
+ PyObject_ReleaseBuffer(keyobj, view);
+ PyMem_Free(view);
+ return 0;
+ }
+
+ key->data = view->buf;
+ key->size = Py_SAFE_DOWNCAST(view->len, Py_ssize_t, u_int32_t);
+ *returned_view_p = view;
+ }
+
else {
PyErr_Format(PyExc_TypeError,
- "Bytes or Integer object expected for key, %s found",
+ "buffer or int object expected for key, %s found",
Py_Type(keyobj)->tp_name);
return 0;
}
@@ -736,8 +815,8 @@
}
}
if (!err) {
- FREE_DBT(key);
- FREE_DBT(data);
+ free_dbt(&key);
+ free_dbt(&data);
}
return retval;
}
@@ -1141,6 +1220,7 @@
{
PyObject* txnobj = NULL;
PyObject* dataobj;
+ PyBuffer* data_buf_view = NULL;
db_recno_t recno;
DBT key, data;
DB_TXN *txn = NULL;
@@ -1158,12 +1238,15 @@
key.ulen = key.size;
key.flags = DB_DBT_USERMEM;
- if (!make_dbt(dataobj, &data)) return NULL;
if (!checkTxnObj(txnobj, &txn)) return NULL;
+ if (!make_dbt(dataobj, &data, &data_buf_view)) return NULL;
- if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
+ if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND)) {
+ free_buf_view(dataobj, data_buf_view);
return NULL;
+ }
+ free_buf_view(dataobj, data_buf_view);
return PyInt_FromLong(recno);
}
@@ -1396,8 +1479,8 @@
else if (!err) {
retval = Py_BuildValue("y#y#", key.data, key.size, data.data,
data.size);
- FREE_DBT(key);
- FREE_DBT(data);
+ free_dbt(&key);
+ free_dbt(&data);
}
RETURN_IF_ERR();
@@ -1450,6 +1533,7 @@
PyObject* txnobj = NULL;
int flags = 0;
PyObject* keyobj;
+ PyBuffer* key_buf_view = NULL;
DBT key;
DB_TXN *txn = NULL;
static char* kwnames[] = { "key", "txn", "flags", NULL };
@@ -1458,19 +1542,19 @@
&keyobj, &txnobj, &flags))
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, NULL))
+ if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
return NULL;
if (!checkTxnObj(txnobj, &txn)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
if (-1 == _DB_delete(self, txn, &key, 0)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
RETURN_NONE();
}
@@ -1500,6 +1584,7 @@
PyObject* keyobj;
PyObject* dfltobj = NULL;
PyObject* retval = NULL;
+ PyBuffer* key_buf_view = NULL;
int dlen = -1;
int doff = -1;
DBT key, data;
@@ -1513,10 +1598,10 @@
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, &flags))
+ if (!make_key_dbt(self, keyobj, &key, &flags, &key_buf_view))
return NULL;
if (!checkTxnObj(txnobj, &txn)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -1526,7 +1611,7 @@
data.flags = DB_DBT_MALLOC;
}
if (!add_partial_dbt(&data, dlen, doff)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -1551,9 +1636,9 @@
data.size);
else /* return just the data */
retval = PyBytes_FromStringAndSize((char*)data.data, data.size);
- FREE_DBT(data);
+ free_dbt(&data);
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
RETURN_IF_ERR();
return retval;
@@ -1568,6 +1653,7 @@
PyObject* keyobj;
PyObject* dfltobj = NULL;
PyObject* retval = NULL;
+ PyBuffer* key_buf_view = NULL;
int dlen = -1;
int doff = -1;
DBT key, pkey, data;
@@ -1581,10 +1667,10 @@
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, &flags))
+ if (!make_key_dbt(self, keyobj, &key, &flags, &key_buf_view))
return NULL;
if (!checkTxnObj(txnobj, &txn)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -1594,7 +1680,7 @@
data.flags = DB_DBT_MALLOC;
}
if (!add_partial_dbt(&data, dlen, doff)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -1652,10 +1738,10 @@
}
Py_DECREF(dataObj);
Py_DECREF(pkeyObj);
- FREE_DBT(pkey);
- FREE_DBT(data);
+ free_dbt(&pkey);
+ free_dbt(&data);
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
RETURN_IF_ERR();
return retval;
@@ -1671,6 +1757,7 @@
PyObject* txnobj = NULL;
PyObject* keyobj;
PyObject* retval = NULL;
+ PyBuffer* key_buf_view = NULL;
DBT key, data;
DB_TXN *txn = NULL;
static char* kwnames[] = { "key", "txn", NULL };
@@ -1679,10 +1766,10 @@
&keyobj, &txnobj))
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, &flags))
+ if (!make_key_dbt(self, keyobj, &key, &flags, &key_buf_view))
return NULL;
if (!checkTxnObj(txnobj, &txn)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
CLEAR_DBT(data);
@@ -1699,8 +1786,8 @@
err = 0;
}
- FREE_DBT(key);
- FREE_DBT(data);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_dbt(&data);
RETURN_IF_ERR();
return retval;
}
@@ -1714,6 +1801,8 @@
PyObject* keyobj;
PyObject* dataobj;
PyObject* retval = NULL;
+ PyBuffer* data_buf_view = NULL;
+ PyBuffer* key_buf_view = NULL;
DBT key, data;
void *orig_data;
DB_TXN *txn = NULL;
@@ -1725,12 +1814,12 @@
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, NULL))
+ if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
return NULL;
- if ( !make_dbt(dataobj, &data) ||
- !checkTxnObj(txnobj, &txn) )
+ if ( !checkTxnObj(txnobj, &txn) ||
+ !make_dbt(dataobj, &data, &data_buf_view) )
{
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -1747,6 +1836,8 @@
err = self->db->get(self->db, txn, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
+ free_buf_view(dataobj, data_buf_view);
+
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
&& self->moduleFlags.getReturnsNone) {
err = 0;
@@ -1755,15 +1846,16 @@
}
else if (!err) {
/* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
+ /* XXX(gps) I think not: buffer API input vs. bytes object output. */
retval = PyBytes_FromStringAndSize((char*)data.data, data.size);
/* Even though the flags require DB_DBT_MALLOC, data is not always
allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
if (data.data != orig_data)
- FREE_DBT(data);
+ free_dbt(&data);
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
RETURN_IF_ERR();
return retval;
}
@@ -1876,6 +1968,7 @@
int err, flags=0;
PyObject* txnobj = NULL;
PyObject* keyobj;
+ PyBuffer* key_buf_view = NULL;
DBT key;
DB_TXN *txn = NULL;
DB_KEY_RANGE range;
@@ -1885,16 +1978,18 @@
&keyobj, &txnobj, &flags))
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_dbt(keyobj, &key))
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+ if (!make_dbt(keyobj, &key, &key_buf_view))
/* BTree only, don't need to allow for an int key */
return NULL;
- if (!checkTxnObj(txnobj, &txn))
- return NULL;
MYDB_BEGIN_ALLOW_THREADS;
err = self->db->key_range(self->db, txn, &key, &range, flags);
MYDB_END_ALLOW_THREADS;
+ free_buf_view(keyobj, key_buf_view);
+
RETURN_IF_ERR();
return Py_BuildValue("ddd", range.less, range.equal, range.greater);
}
@@ -2003,7 +2098,9 @@
PyObject* txnobj = NULL;
int dlen = -1;
int doff = -1;
- PyObject* keyobj, *dataobj, *retval;
+ PyObject *keyobj, *dataobj, *retval;
+ PyBuffer *data_buf_view = NULL;
+ PyBuffer *key_buf_view = NULL;
DBT key, data;
DB_TXN *txn = NULL;
static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
@@ -2014,18 +2111,20 @@
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, NULL))
+ if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
return NULL;
- if ( !make_dbt(dataobj, &data) ||
+ if ( !make_dbt(dataobj, &data, &data_buf_view) ||
!add_partial_dbt(&data, dlen, doff) ||
!checkTxnObj(txnobj, &txn) )
{
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return NULL;
}
if (-1 == _DB_put(self, txn, &key, &data, flags)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return NULL;
}
@@ -2035,7 +2134,8 @@
retval = Py_None;
Py_INCREF(retval);
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return retval;
}
@@ -2780,11 +2880,12 @@
{
int err;
PyObject* retval;
+ PyBuffer* key_buf_view = NULL;
DBT key;
DBT data;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, NULL))
+ if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
return NULL;
CLEAR_DBT(data);
@@ -2804,10 +2905,10 @@
}
else {
retval = PyBytes_FromStringAndSize((char*)data.data, data.size);
- FREE_DBT(data);
+ free_dbt(&data);
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return retval;
}
@@ -2818,6 +2919,8 @@
DBT key, data;
int retval;
int flags = 0;
+ PyBuffer *data_buf_view = NULL;
+ PyBuffer *key_buf_view = NULL;
if (self->db == NULL) {
PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
@@ -2826,11 +2929,11 @@
return -1;
}
- if (!make_key_dbt(self, keyobj, &key, NULL))
+ if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
return -1;
if (dataobj != NULL) {
- if (!make_dbt(dataobj, &data))
+ if (!make_dbt(dataobj, &data, &data_buf_view))
retval = -1;
else {
if (self->setflags & (DB_DUP|DB_DUPSORT))
@@ -2851,7 +2954,8 @@
/* dataobj == NULL, so delete the key */
retval = _DB_delete(self, NULL, &key, 0);
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return retval;
}
@@ -2861,6 +2965,7 @@
{
int err;
PyObject* keyobj;
+ PyBuffer* key_buf_view = NULL;
DBT key, data;
PyObject* txnobj = NULL;
DB_TXN *txn = NULL;
@@ -2868,10 +2973,10 @@
if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj))
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_key_dbt(self, keyobj, &key, NULL))
+ if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
return NULL;
if (!checkTxnObj(txnobj, &txn)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -2885,7 +2990,7 @@
MYDB_BEGIN_ALLOW_THREADS;
err = self->db->get(self->db, txn, &key, &data, 0);
MYDB_END_ALLOW_THREADS;
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
if (err == DB_BUFFER_SMALL || err == 0) {
return PyInt_FromLong(1);
@@ -3003,8 +3108,8 @@
}
done:
- FREE_DBT(key);
- FREE_DBT(data);
+ free_dbt(&key);
+ free_dbt(&data);
MYDB_BEGIN_ALLOW_THREADS;
cursor->c_close(cursor);
MYDB_END_ALLOW_THREADS;
@@ -3157,6 +3262,8 @@
PyObject* keyobj = NULL;
PyObject* dataobj = NULL;
PyObject* retval = NULL;
+ PyBuffer* data_buf_view = NULL;
+ PyBuffer* key_buf_view = NULL;
int dlen = -1;
int doff = -1;
DBT key, data;
@@ -3185,12 +3292,13 @@
CHECK_CURSOR_NOT_CLOSED(self);
- if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
+ if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
return NULL;
- if ( (dataobj && !make_dbt(dataobj, &data)) ||
+ if ( (dataobj && !make_dbt(dataobj, &data, &data_buf_view)) ||
(!add_partial_dbt(&data, dlen, doff)) )
{
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return NULL;
}
@@ -3230,9 +3338,10 @@
data.data, data.size);
break;
}
- FREE_DBT(data);
+ free_dbt(&data);
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return retval;
}
@@ -3244,6 +3353,8 @@
PyObject* keyobj = NULL;
PyObject* dataobj = NULL;
PyObject* retval = NULL;
+ PyBuffer* data_buf_view = NULL;
+ PyBuffer* key_buf_view = NULL;
int dlen = -1;
int doff = -1;
DBT key, pkey, data;
@@ -3272,11 +3383,12 @@
CHECK_CURSOR_NOT_CLOSED(self);
- if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
+ if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
return NULL;
- if ( (dataobj && !make_dbt(dataobj, &data)) ||
+ if ( (dataobj && !make_dbt(dataobj, &data, &data_buf_view)) ||
(!add_partial_dbt(&data, dlen, doff)) ) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return NULL;
}
@@ -3327,7 +3439,7 @@
retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
#endif
Py_DECREF(keyObj);
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
}
else /* return just the pkey and data */
{
@@ -3339,14 +3451,11 @@
}
Py_DECREF(dataObj);
Py_DECREF(pkeyObj);
- FREE_DBT(pkey);
- FREE_DBT(data);
+ free_dbt(&pkey);
+ free_dbt(&data);
}
- /* the only time REALLOC should be set is if we used an integer
- * key that make_key_dbt malloc'd for us. always free these. */
- if (key.flags & DB_DBT_REALLOC) {
- FREE_DBT(key);
- }
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return retval;
}
#endif
@@ -3379,8 +3488,8 @@
RETURN_IF_ERR();
recno = *((db_recno_t*)data.data);
- FREE_DBT(key);
- FREE_DBT(data);
+ free_dbt(&key);
+ free_dbt(&data);
return PyInt_FromLong(recno);
}
@@ -3410,7 +3519,9 @@
DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
{
int err, flags = 0;
- PyObject* keyobj, *dataobj;
+ PyObject *keyobj, *dataobj;
+ PyBuffer *data_buf_view = NULL;
+ PyBuffer *key_buf_view = NULL;
DBT key, data;
static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
NULL };
@@ -3423,19 +3534,21 @@
CHECK_CURSOR_NOT_CLOSED(self);
- if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
return NULL;
- if (!make_dbt(dataobj, &data) ||
+ if (!make_dbt(dataobj, &data, &data_buf_view) ||
!add_partial_dbt(&data, dlen, doff) )
{
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;
err = self->dbc->c_put(self->dbc, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
RETURN_IF_ERR();
self->mydb->haveStat = 0;
RETURN_NONE();
@@ -3447,7 +3560,8 @@
{
int err, flags = 0;
DBT key, data;
- PyObject* retval, *keyobj;
+ PyObject *retval, *keyobj;
+ PyBuffer *key_buf_view = NULL;
static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
int dlen = -1;
int doff = -1;
@@ -3458,7 +3572,7 @@
CHECK_CURSOR_NOT_CLOSED(self);
- if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
return NULL;
CLEAR_DBT(data);
@@ -3467,7 +3581,7 @@
data.flags = DB_DBT_MALLOC;
}
if (!add_partial_dbt(&data, dlen, doff)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -3499,14 +3613,9 @@
data.data, data.size);
break;
}
- FREE_DBT(data);
- FREE_DBT(key);
+ free_dbt(&data);
}
- /* the only time REALLOC should be set is if we used an integer
- * key that make_key_dbt malloc'd for us. always free these. */
- if (key.flags & DB_DBT_REALLOC) {
- FREE_DBT(key);
- }
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return retval;
}
@@ -3517,7 +3626,8 @@
{
int err, flags = 0;
DBT key, data;
- PyObject* retval, *keyobj;
+ PyObject *retval, *keyobj;
+ PyBuffer *key_buf_view = NULL;
static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
int dlen = -1;
int doff = -1;
@@ -3528,12 +3638,12 @@
CHECK_CURSOR_NOT_CLOSED(self);
- if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
return NULL;
CLEAR_DBT(data);
if (!add_partial_dbt(&data, dlen, doff)) {
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
@@ -3572,14 +3682,9 @@
data.data, data.size);
break;
}
- FREE_DBT(key);
- FREE_DBT(data);
+ free_dbt(&data);
}
- /* the only time REALLOC should be set is if we used an integer
- * key that make_key_dbt malloc'd for us. always free these. */
- if (key.flags & DB_DBT_REALLOC) {
- FREE_DBT(key);
- }
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return retval;
}
@@ -3590,13 +3695,15 @@
{
int err;
DBT key, data;
- PyObject* retval;
+ PyObject *retval;
+ PyBuffer *data_buf_view = NULL;
+ PyBuffer *key_buf_view = NULL;
/* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
- if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
return NULL;
- if (!make_dbt(dataobj, &data)) {
- FREE_DBT(key);
+ if (!make_dbt(dataobj, &data, &data_buf_view)) {
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
return NULL;
}
@@ -3629,7 +3736,8 @@
}
}
- FREE_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
+ free_buf_view(dataobj, data_buf_view);
return retval;
}
@@ -3676,8 +3784,8 @@
err = 0;
}
- FREE_DBT(key);
- FREE_DBT(data);
+ free_dbt(&key);
+ free_dbt(&data);
RETURN_IF_ERR();
return retval;
}
@@ -3736,7 +3844,7 @@
data.flags = DB_DBT_MALLOC;
}
if (!add_partial_dbt(&data, dlen, doff)) {
- FREE_DBT(key);
+ free_dbt(&key);
return NULL;
}
@@ -3754,9 +3862,9 @@
else { /* Can only be used for BTrees, so no need to return int key */
retval = Py_BuildValue("y#y#", key.data, key.size,
data.data, data.size);
- FREE_DBT(data);
+ free_dbt(&data);
}
- FREE_DBT(key);
+ free_dbt(&key);
return retval;
}
@@ -3822,7 +3930,7 @@
}
else {
retval = Py_BuildValue("y#", key.data, key.size);
- FREE_DBT(key);
+ free_dbt(&key);
}
return retval;
@@ -4362,16 +4470,18 @@
int flags=0;
int locker, lock_mode;
DBT obj;
- PyObject* objobj;
+ PyObject *objobj, *retval;
+ PyBuffer *obj_buf_view = NULL;
if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
return NULL;
-
- if (!make_dbt(objobj, &obj))
+ if (!make_dbt(objobj, &obj, &obj_buf_view))
return NULL;
- return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
+ retval = (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
+ free_buf_view(objobj, obj_buf_view);
+ return retval;
}
@@ -4937,7 +5047,8 @@
DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
{
int err, flags = 0;
- PyObject* keyobj;
+ PyObject *keyobj;
+ PyBuffer *key_buf_view = NULL;
PyObject *txnobj = NULL;
DB_TXN *txn = NULL;
DBT key;
@@ -4949,14 +5060,14 @@
if (!checkTxnObj(txnobj, &txn))
return NULL;
- if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
return NULL;
MYDB_BEGIN_ALLOW_THREADS
err = self->sequence->open(self->sequence, txn, &key, flags);
MYDB_END_ALLOW_THREADS
- CLEAR_DBT(key);
+ FREE_DBT_VIEW(key, keyobj, key_buf_view);
RETURN_IF_ERR();
RETURN_NONE();
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com