diff --git a/pydablooms/pydablooms.c b/pydablooms/pydablooms.c index c101fc2..76b65d4 100644 --- a/pydablooms/pydablooms.c +++ b/pydablooms/pydablooms.c @@ -4,6 +4,8 @@ int Py_ModuleVersion = 1; +static PyObject *DabloomsError; + typedef struct { PyObject_HEAD scaling_bloom_t *filter; /* Type-specific fields go here. */ @@ -11,7 +13,8 @@ typedef struct { static void Dablooms_dealloc(Dablooms *self) { - free_scaling_bloom(self->filter); + if(self->filter) + free_scaling_bloom(self->filter); self->ob_type->tp_free((PyObject *)self); } @@ -24,21 +27,33 @@ static PyObject *Dablooms_new(PyTypeObject *type, PyObject *args, PyObject *kwds } self->filter = NULL; - return (PyObject *) self; } static int Dablooms_init(Dablooms *self, PyObject *args, PyObject *kwds) { - double error_rate; - const char *filepath; - unsigned int capacity; + double error_rate = 0.1; + const char *filepath = "/tmp/bloom.bin"; + int capacity = 1; // dropped the unsigned modifier to avoid implicit conversion from negative static char *kwlist[] = {"capacity", "error_rate", "filepath", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kwds, "|ids", kwlist, &capacity, &error_rate, &filepath)) { return -1; } + + if (capacity < 1){ + PyErr_SetString(DabloomsError, "Bloom creation failed: capacity must be greater than zero"); + return -1; + } + if (error_rate > 1 || error_rate < 0){ + PyErr_SetString(DabloomsError, "Bloom creation failed: error_rate must be between 0 and 1"); + return -1; + } + if(!(filepath && strlen(filepath))){ + PyErr_SetString(DabloomsError, "Bloom creation failed: filepath required"); + return -1; + } self->filter = new_scaling_bloom(capacity, error_rate, filepath); @@ -181,18 +196,36 @@ static PyTypeObject DabloomsType = { static PyObject *load_dabloom(PyTypeObject *type, PyObject *args, PyObject *kwds) { Dablooms *self = (Dablooms *)PyObject_New(Dablooms, &DabloomsType); - double error_rate; - const char *filepath; - unsigned int capacity; + double error_rate = 0.1; + const char *filepath = "/tmp/bloom.bin"; + int capacity = 1; // dropped the unsigned modifier to avoid implicit conversion from negative + int result = 0; static char *kwlist[] = {"capacity", "error_rate", "filepath", NULL}; - + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|ids", kwlist, &capacity, &error_rate, &filepath)) { return NULL; } - - self->filter = new_scaling_bloom_from_file(capacity, error_rate, filepath); - return (PyObject *) self; + + if (capacity < 1){ + PyErr_SetString(DabloomsError, "Bloom creation failed: capacity must be greater than zero"); + result = -1; + } + else if (error_rate > 1 || error_rate < 0){ + PyErr_SetString(DabloomsError, "Bloom creation failed: error_rate must be between 0 and 1"); + result = -1; + } + else if(!(filepath && strlen(filepath))){ + PyErr_SetString(DabloomsError, "Bloom creation failed: filepath required"); + result = -1; + } + + if (!result){ + self->filter = new_scaling_bloom_from_file(capacity, error_rate, filepath); + return (PyObject *) self; + } + Dablooms_dealloc(self); + return NULL; } static PyMethodDef pydablooms_methods[] = { @@ -222,4 +255,8 @@ PyMODINIT_FUNC initpydablooms(void) Py_INCREF(&DabloomsType); PyModule_AddObject(m, "Dablooms", (PyObject *)&DabloomsType); + + DabloomsError = PyErr_NewException("Dablooms.Error", NULL, NULL); + Py_INCREF(DabloomsError); + PyModule_AddObject(m, "error", DabloomsError); }