- Values *self = (Values *) s;
- int interval = 0, ret;
- double time = 0;
- PyObject *values = 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};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sOssssdi", kwlist,
- &type, &values, &plugin_instance, &type_instance,
- &plugin, &host, &time, &interval))
- return -1;
-
- tmp = Py_BuildValue("sssssd", type, plugin_instance, type_instance, plugin, host, time);
- if (tmp == NULL)
- return -1;
- ret = PluginDataType.tp_init(s, tmp, NULL);
- Py_DECREF(tmp);
- if (ret != 0)
- return -1;
-
- if (values == NULL) {
- values = PyList_New(0);
- PyErr_Clear();
- } else {
- Py_INCREF(values);
- }
-
- tmp = self->values;
- self->values = values;
- Py_XDECREF(tmp);
-
- self->interval = interval;
- return 0;
+ Values *self = (Values *)s;
+ double interval = 0, time = 0;
+ PyObject *values = NULL, *meta = NULL, *tmp;
+ char *type = NULL, *plugin_instance = NULL, *type_instance = NULL,
+ *plugin = NULL, *host = NULL;
+ static char *kwlist[] = {
+ "type", "values", "plugin_instance", "type_instance", "plugin",
+ "host", "time", "interval", "meta", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist, NULL,
+ &type, &values, NULL, &plugin_instance, NULL,
+ &type_instance, NULL, &plugin, NULL, &host,
+ &time, &interval, &meta))
+ return -1;
+
+ if (type && plugin_get_ds(type) == NULL) {
+ PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
+ FreeAll();
+ return -1;
+ }
+
+ sstrncpy(self->data.host, host ? host : "", sizeof(self->data.host));
+ sstrncpy(self->data.plugin, plugin ? plugin : "", sizeof(self->data.plugin));
+ sstrncpy(self->data.plugin_instance, plugin_instance ? plugin_instance : "",
+ sizeof(self->data.plugin_instance));
+ sstrncpy(self->data.type, type ? type : "", sizeof(self->data.type));
+ sstrncpy(self->data.type_instance, type_instance ? type_instance : "",
+ sizeof(self->data.type_instance));
+ self->data.time = time;
+
+ FreeAll();
+
+ if (values == NULL) {
+ values = PyList_New(0);
+ PyErr_Clear();
+ } else {
+ Py_INCREF(values);
+ }
+
+ if (meta == NULL) {
+ meta = PyDict_New();
+ PyErr_Clear();
+ } else {
+ Py_INCREF(meta);
+ }
+
+ tmp = self->values;
+ self->values = values;
+ Py_XDECREF(tmp);
+
+ tmp = self->meta;
+ self->meta = meta;
+ Py_XDECREF(tmp);
+
+ self->interval = interval;
+ return 0;
+}
+
+static int cpy_build_meta_generic(PyObject *meta,
+ cpy_build_meta_handler_t *meta_func,
+ void *m) {
+ int s;
+ PyObject *l;
+
+ if ((meta == NULL) || (meta == Py_None))
+ return -1;
+
+ l = PyDict_Items(meta); /* New reference. */
+ if (!l) {
+ cpy_log_exception("building meta data");
+ return -1;
+ }
+ s = PyList_Size(l);
+ if (s <= 0) {
+ Py_XDECREF(l);
+ return -1;
+ }
+
+ for (int i = 0; i < s; ++i) {
+ const char *string, *keystring;
+ PyObject *key, *value, *item, *tmp;
+
+ item = PyList_GET_ITEM(l, i);
+ key = PyTuple_GET_ITEM(item, 0);
+ Py_INCREF(key);
+ keystring = cpy_unicode_or_bytes_to_string(&key);
+ if (!keystring) {
+ PyErr_Clear();
+ Py_XDECREF(key);
+ continue;
+ }
+ value = PyTuple_GET_ITEM(item, 1);
+ Py_INCREF(value);
+ if (value == Py_True) {
+ meta_func->add_boolean(m, keystring, 1);
+ } else if (value == Py_False) {
+ meta_func->add_boolean(m, keystring, 0);
+ } else if (PyFloat_Check(value)) {
+ meta_func->add_double(m, keystring, PyFloat_AsDouble(value));
+ } else if (PyObject_TypeCheck(value, &SignedType)) {
+ long long int lli;
+ lli = PyLong_AsLongLong(value);
+ if (!PyErr_Occurred() && (lli == (int64_t)lli))
+ meta_func->add_signed_int(m, keystring, lli);
+ } else if (PyObject_TypeCheck(value, &UnsignedType)) {
+ long long unsigned llu;
+ llu = PyLong_AsUnsignedLongLong(value);
+ if (!PyErr_Occurred() && (llu == (uint64_t)llu))
+ meta_func->add_unsigned_int(m, keystring, llu);
+ } else if (PyNumber_Check(value)) {
+ long long int lli;
+ long long unsigned llu;
+ tmp = PyNumber_Long(value);
+ lli = PyLong_AsLongLong(tmp);
+ if (!PyErr_Occurred() && (lli == (int64_t)lli)) {
+ meta_func->add_signed_int(m, keystring, lli);
+ } else {
+ PyErr_Clear();
+ llu = PyLong_AsUnsignedLongLong(tmp);
+ if (!PyErr_Occurred() && (llu == (uint64_t)llu))
+ meta_func->add_unsigned_int(m, keystring, llu);
+ }
+ Py_XDECREF(tmp);
+ } else {
+ string = cpy_unicode_or_bytes_to_string(&value);
+ if (string) {
+ meta_func->add_string(m, keystring, string);
+ } else {
+ PyErr_Clear();
+ tmp = PyObject_Str(value);
+ string = cpy_unicode_or_bytes_to_string(&tmp);
+ if (string)
+ meta_func->add_string(m, keystring, string);
+ Py_XDECREF(tmp);
+ }
+ }
+ if (PyErr_Occurred())
+ cpy_log_exception("building meta data");
+ Py_XDECREF(value);
+ Py_DECREF(key);
+ }
+ Py_XDECREF(l);
+ return 0;
+}
+
+#define CPY_BUILD_META_FUNC(meta_type, func, val_type) \
+ static int cpy_##func(void *meta, const char *key, val_type val) { \
+ return func((meta_type *)meta, key, val); \
+ }
+
+#define CPY_BUILD_META_HANDLER(func_prefix, meta_type) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_string, const char *) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_signed_int, int64_t) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_unsigned_int, uint64_t) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_double, double) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_boolean, _Bool) \
+ \
+ static cpy_build_meta_handler_t cpy_##func_prefix = { \
+ .add_string = cpy_##func_prefix##_add_string, \
+ .add_signed_int = cpy_##func_prefix##_add_signed_int, \
+ .add_unsigned_int = cpy_##func_prefix##_add_unsigned_int, \
+ .add_double = cpy_##func_prefix##_add_double, \
+ .add_boolean = cpy_##func_prefix##_add_boolean}
+
+CPY_BUILD_META_HANDLER(meta_data, meta_data_t);
+CPY_BUILD_META_HANDLER(plugin_notification_meta, notification_t);
+
+static meta_data_t *cpy_build_meta(PyObject *meta) {
+ meta_data_t *m = meta_data_create();
+ if (cpy_build_meta_generic(meta, &cpy_meta_data, (void *)m) < 0) {
+ meta_data_destroy(m);
+ return NULL;
+ }
+ return m;
+}
+
+static void cpy_build_notification_meta(notification_t *n, PyObject *meta) {
+ cpy_build_meta_generic(meta, &cpy_plugin_notification_meta, (void *)n);