From dda55268556fe9fc5ed8c66d336b1f8e5a53f378 Mon Sep 17 00:00:00 2001 From: Sven Trenkel Date: Wed, 27 Jan 2010 11:27:54 +0100 Subject: [PATCH] Added support for receiving meta data in write callbacks. Probably, it's not like there is a test case. --- src/cpython.h | 1 + src/python.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/pyvalues.c | 36 +++++++++++++++++++++++++++++------- 3 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/cpython.h b/src/cpython.h index 3e80cb0c..df7fc6a4 100644 --- a/src/cpython.h +++ b/src/cpython.h @@ -182,6 +182,7 @@ PyTypeObject PluginDataType; typedef struct { PluginData data; PyObject *values; /* Sequence */ + PyObject *meta; /* dict */ int interval; } Values; diff --git a/src/python.c b/src/python.c index 5664b0c6..a1e6a7e2 100644 --- a/src/python.c +++ b/src/python.c @@ -335,7 +335,7 @@ static int cpy_read_callback(user_data_t *data) { static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) { int i; cpy_callback_t *c = data->data; - PyObject *ret, *list; + PyObject *ret, *list, *temp, *dict = NULL; Values *v; CPY_LOCK_THREADS @@ -374,6 +374,60 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li CPY_RETURN_FROM_THREADS 0; } } + dict = PyDict_New(); + if (value_list->meta) { + int i, num; + char **table; + meta_data_t *meta = value_list->meta; + + num = meta_data_toc(meta, &table); + for (i = 0; i < num; ++i) { + int type; + char *string; + int64_t si; + uint64_t ui; + double d; + _Bool b; + + type = meta_data_type(meta, table[i]); + if (type == MD_TYPE_STRING) { + if (meta_data_get_string(meta, table[i], &string)) + continue; + temp = cpy_string_to_unicode_or_bytes(string); + free(string); + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_SIGNED_INT) { + if (meta_data_get_signed_int(meta, table[i], &si)) + continue; + temp = PyLong_FromLongLong(si); + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_UNSIGNED_INT) { + if (meta_data_get_unsigned_int(meta, table[i], &ui)) + continue; + temp = PyLong_FromUnsignedLongLong(ui); + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_DOUBLE) { + if (meta_data_get_double(meta, table[i], &d)) + continue; + temp = PyFloat_FromDouble(d); + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_BOOLEAN) { + if (meta_data_get_boolean(meta, table[i], &b)) + continue; + if (b) + temp = Py_True; + else + temp = Py_False; + PyDict_SetItemString(dict, table[i], temp); + } + free(table[i]); + } + free(table); + } v = PyObject_New(Values, (void *) &ValuesType); sstrncpy(v->data.host, value_list->host, sizeof(v->data.host)); sstrncpy(v->data.type, value_list->type, sizeof(v->data.type)); @@ -383,6 +437,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li v->data.time = value_list->time; v->interval = value_list->interval; v->values = list; + v->meta = dict; ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, (void *) 0); /* New reference. */ if (ret == NULL) { cpy_log_exception("write callback"); diff --git a/src/pyvalues.c b/src/pyvalues.c index a632dc16..ed0270f5 100644 --- a/src/pyvalues.c +++ b/src/pyvalues.c @@ -308,6 +308,10 @@ static char values_doc[] = "These are the actual values that get dispatched to c "exception will be raised. If the content of the sequence is not a number,\n" "a TypeError exception will be raised."; +static char meta_doc[] = "These are the meta data for this Value object.\n" + "It has to be a dictionary of numbers, strings or bools.\n" + "If the dict contains anything else a TypeError exception will be raised."; + static char dispatch_doc[] = "dispatch([type][, values][, plugin_instance][, type_instance]" "[, plugin][, host][, time][, interval]) -> None. Dispatch a value list.\n" "\n" @@ -344,14 +348,14 @@ static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) { Values *self = (Values *) s; int interval = 0; double time = 0; - PyObject *values = NULL, *tmp; + PyObject *values = NULL, *meta = NULL, *tmp; const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = ""; static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance", - "plugin", "host", "time", "interval", NULL}; + "plugin", "host", "time", "interval", "meta", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdi", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist, NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance, - NULL, &plugin, NULL, &host, &time, &interval)) + NULL, &plugin, NULL, &host, &time, &interval, &meta)) return -1; if (type[0] != 0 && plugin_get_ds(type) == NULL) { @@ -373,8 +377,16 @@ static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) { Py_INCREF(values); } + if (meta == NULL) { + meta = PyDict_New(); + PyErr_Clear(); + } else { + Py_INCREF(meta); + } + tmp = self->values; self->values = values; + self->meta = meta; Py_XDECREF(tmp); self->interval = interval; @@ -582,17 +594,19 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) { static PyObject *Values_repr(PyObject *s) { PyObject *ret, *tmp; - static PyObject *l_interval = NULL, *l_values = NULL, *l_closing = NULL; + static PyObject *l_interval = NULL, *l_values = NULL, *l_meta = NULL, *l_closing = NULL; Values *self = (Values *) s; if (l_interval == NULL) l_interval = cpy_string_to_unicode_or_bytes(",interval="); if (l_values == NULL) l_values = cpy_string_to_unicode_or_bytes(",values="); + if (l_meta == NULL) + l_meta = cpy_string_to_unicode_or_bytes(",meta="); if (l_closing == NULL) l_closing = cpy_string_to_unicode_or_bytes(")"); - if (l_interval == NULL || l_values == NULL || l_closing == NULL) + if (l_interval == NULL || l_values == NULL || l_meta == NULL || l_closing == NULL) return NULL; ret = cpy_common_repr(s); @@ -602,11 +616,16 @@ static PyObject *Values_repr(PyObject *s) { CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); CPY_STRCAT_AND_DEL(&ret, tmp); } - if (self->values != NULL && PySequence_Length(self->values) > 0) { + if (self->values && (!PyList_Check(self->values) || PySequence_Length(self->values) > 0)) { CPY_STRCAT(&ret, l_values); tmp = PyObject_Repr(self->values); CPY_STRCAT_AND_DEL(&ret, tmp); } + if (self->meta && (!PyDict_Check(self->meta) || PyDict_Size(self->meta) > 0)) { + CPY_STRCAT(&ret, l_meta); + tmp = PyObject_Repr(self->meta); + CPY_STRCAT_AND_DEL(&ret, tmp); + } CPY_STRCAT(&ret, l_closing); return ret; } @@ -614,12 +633,14 @@ static PyObject *Values_repr(PyObject *s) { static int Values_traverse(PyObject *self, visitproc visit, void *arg) { Values *v = (Values *) self; Py_VISIT(v->values); + Py_VISIT(v->meta); return 0; } static int Values_clear(PyObject *self) { Values *v = (Values *) self; Py_CLEAR(v->values); + Py_CLEAR(v->meta); return 0; } @@ -631,6 +652,7 @@ static void Values_dealloc(PyObject *self) { static PyMemberDef Values_members[] = { {"interval", T_INT, offsetof(Values, interval), 0, interval_doc}, {"values", T_OBJECT_EX, offsetof(Values, values), 0, values_doc}, + {"meta", T_OBJECT_EX, offsetof(Values, meta), 0, meta_doc}, {NULL} }; -- 2.11.0