mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
refactoring: json.c => config_helper.c & sample_io_json.c
This commit is contained in:
parent
6369373149
commit
51d80b73ce
19 changed files with 329 additions and 156 deletions
37
include/villas/config_helper.h
Normal file
37
include/villas/config_helper.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/** Helpers for configuration parsers.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASnode
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jansson.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "sample.h"
|
||||
|
||||
/* Convert a libconfig object to a jansson object */
|
||||
json_t * config_to_json(config_setting_t *cfg);
|
||||
|
||||
/* Convert a jansson object into a libconfig object. */
|
||||
int json_to_config(json_t *json, config_setting_t *parent);
|
||||
|
||||
/* Create a libconfig object from command line parameters. */
|
||||
int config_parse_cli(config_t *cfg, int argc, char *argv[]);
|
|
@ -34,42 +34,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "log_config.h"
|
||||
#include "queue.h"
|
||||
#include "list.h"
|
||||
#include "super_node.h"
|
||||
#include "hook_type.h"
|
||||
#include "common.h"
|
||||
|
||||
/* Forward declarations */
|
||||
struct path;
|
||||
struct hook;
|
||||
struct sample;
|
||||
struct super_node;
|
||||
|
||||
struct hook_type {
|
||||
int priority; /**< Default priority of this hook type. */
|
||||
bool builtin; /**< Should we add this hook by default to every path?. */
|
||||
|
||||
size_t size; /**< Size of allocation for struct hook::_vd */
|
||||
|
||||
int (*parse)(struct hook *h, config_setting_t *cfg);
|
||||
|
||||
int (*init)(struct hook *h); /**< Called before path is started to parseHOOK_DESTROYs. */
|
||||
int (*destroy)(struct hook *h); /**< Called after path has been stopped to release memory allocated by HOOK_INIT */
|
||||
|
||||
int (*start)(struct hook *h); /**< Called whenever a path is started; before threads are created. */
|
||||
int (*stop)(struct hook *h); /**< Called whenever a path is stopped; after threads are destoyed. */
|
||||
|
||||
int (*periodic)(struct hook *h);/**< Called periodically. Period is set by global 'stats' option in the configuration file. */
|
||||
int (*restart)(struct hook *h); /**< Called whenever a new simulation case is started. This is detected by a sequence no equal to zero. */
|
||||
|
||||
int (*read)(struct hook *h, struct sample *smps[], size_t *cnt); /**< Called for every single received samples. */
|
||||
int (*write)(struct hook *h, struct sample *smps[], size_t *cnt); /**< Called for every single sample which will be sent. */
|
||||
};
|
||||
struct list;
|
||||
|
||||
/** Descriptor for user defined hooks. See hooks[]. */
|
||||
struct hook {
|
||||
|
@ -96,6 +67,8 @@ int hook_init(struct hook *h, struct hook_type *vt, struct path *p);
|
|||
*/
|
||||
int hook_parse(struct hook *h, config_setting_t *cfg);
|
||||
|
||||
int hook_parse_cli(struct hook *h, int argc, char *argv[]);
|
||||
|
||||
int hook_destroy(struct hook *h);
|
||||
|
||||
int hook_start(struct hook *h);
|
||||
|
|
66
include/villas/hook_type.h
Normal file
66
include/villas/hook_type.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/** Hook funktions
|
||||
*
|
||||
* Every path can register a hook function which is called for every received
|
||||
* message. This can be used to debug the data flow, get statistics
|
||||
* or alter the message.
|
||||
*
|
||||
* This file includes some examples.
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASnode
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @addtogroup hooks User-defined hook functions
|
||||
* @ingroup path
|
||||
* @{
|
||||
*********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <libconfig.h>
|
||||
|
||||
/* Forward declarations */
|
||||
struct hook;
|
||||
struct sample;
|
||||
|
||||
struct hook_type {
|
||||
int priority; /**< Default priority of this hook type. */
|
||||
bool builtin; /**< Should we add this hook by default to every path?. */
|
||||
|
||||
size_t size; /**< Size of allocation for struct hook::_vd */
|
||||
|
||||
int (*parse)(struct hook *h, config_setting_t *cfg);
|
||||
int (*parse_cli)(struct hook *h, int argc, char *argv[]);
|
||||
|
||||
int (*init)(struct hook *h); /**< Called before path is started to parseHOOK_DESTROYs. */
|
||||
int (*destroy)(struct hook *h); /**< Called after path has been stopped to release memory allocated by HOOK_INIT */
|
||||
|
||||
int (*start)(struct hook *h); /**< Called whenever a path is started; before threads are created. */
|
||||
int (*stop)(struct hook *h); /**< Called whenever a path is stopped; after threads are destoyed. */
|
||||
|
||||
int (*periodic)(struct hook *h);/**< Called periodically. Period is set by global 'stats' option in the configuration file. */
|
||||
int (*restart)(struct hook *h); /**< Called whenever a new simulation case is started. This is detected by a sequence no equal to zero. */
|
||||
|
||||
int (*read)(struct hook *h, struct sample *smps[], size_t *cnt); /**< Called for every single received samples. */
|
||||
int (*write)(struct hook *h, struct sample *smps[], size_t *cnt); /**< Called for every single sample which will be sent. */
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
/** JSON serializtion of various objects.
|
||||
/** JSON serializtion sample data.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
|
@ -23,15 +23,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <jansson.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "sample.h"
|
||||
|
||||
/* Convert a libconfig object to a libjansson object */
|
||||
json_t * config_to_json(config_setting_t *cfg);
|
||||
|
||||
int json_to_config(json_t *json, config_setting_t *parent);
|
||||
|
||||
int sample_io_json_pack(json_t **j, struct sample *s, int flags);
|
||||
|
||||
int sample_io_json_unpack(json_t *j, struct sample *s, int *flags);
|
|
@ -10,12 +10,12 @@
|
|||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# any later version.
|
||||
#
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
###################################################################################
|
||||
|
@ -31,7 +31,8 @@ LIB_SRCS += $(addprefix lib/nodes/, file.c cbuilder.c shmem.c signal.c) \
|
|||
log.c log_config.c utils.c super_node.c hist.c timing.c pool.c \
|
||||
list.c queue.c queue_signalled.c memory.c advio.c web.c api.c \
|
||||
plugin.c node_type.c stats.c mapping.c sample_io.c shmem.c \
|
||||
json.c crypt.c compat.c log_table.c log_helper.c \
|
||||
config_helper.c sample_io_json.c crypt.c compat.c log_table.c \
|
||||
log_helper.c \
|
||||
)
|
||||
|
||||
LIB_LDFLAGS = -shared
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
#include "api.h"
|
||||
#include "utils.h"
|
||||
#include "plugin.h"
|
||||
#include "json.h"
|
||||
#include "config_helper.h"
|
||||
#include "super_node.h"
|
||||
|
||||
static int api_config(struct api_action *h, json_t *args, json_t **resp, struct api_session *s)
|
||||
{
|
||||
|
@ -43,4 +44,4 @@ static struct plugin p = {
|
|||
.api.cb = api_config
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN(&p)
|
||||
REGISTER_PLUGIN(&p)
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
#include "plugin.h"
|
||||
#include "node.h"
|
||||
#include "super_node.h"
|
||||
#include "utils.h"
|
||||
#include "json.h"
|
||||
#include "config_helper.h"
|
||||
|
||||
#include "api.h"
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
#include "plugin.h"
|
||||
#include "path.h"
|
||||
#include "utils.h"
|
||||
#include "json.h"
|
||||
#include "config_helper.h"
|
||||
#include "stats.h"
|
||||
#include "super_node.h"
|
||||
|
||||
#include "api.h"
|
||||
|
||||
|
@ -40,7 +41,7 @@ static int api_paths(struct api_action *r, json_t *args, json_t **resp, struct a
|
|||
json_t *json_path = json_pack("{ s: i }",
|
||||
"state", p->state
|
||||
);
|
||||
|
||||
|
||||
if (p->stats)
|
||||
json_object_set(json_path, "stats", stats_json(p->stats));
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/** JSON serializtion of various objects.
|
||||
/** Helpers for configuration parsers.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
|
@ -20,7 +20,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include "json.h"
|
||||
#include "config_helper.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int json_to_config_type(int type)
|
||||
{
|
||||
|
@ -138,102 +139,22 @@ int json_to_config(json_t *json, config_setting_t *parent)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sample_io_json_pack(json_t **j, struct sample *s, int flags)
|
||||
{
|
||||
json_error_t err;
|
||||
json_t *json_data = json_array();
|
||||
|
||||
for (int i = 0; i < s->length; i++) {
|
||||
json_t *json_value = sample_get_data_format(s, i)
|
||||
? json_integer(s->data[i].i)
|
||||
: json_real(s->data[i].f);
|
||||
|
||||
json_array_append(json_data, json_value);
|
||||
}
|
||||
|
||||
*j = json_pack_ex(&err, 0, "{ s: { s: [ I, I ], s: [ I, I ], s: [ I, I ] }, s: I, s: o }",
|
||||
"ts",
|
||||
"origin", s->ts.origin.tv_sec, s->ts.origin.tv_nsec,
|
||||
"received", s->ts.received.tv_sec, s->ts.received.tv_nsec,
|
||||
"sent", s->ts.sent.tv_sec, s->ts.sent.tv_nsec,
|
||||
"sequence", s->sequence,
|
||||
"data", json_data);
|
||||
|
||||
if (!*j)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sample_io_json_unpack(json_t *j, struct sample *s, int *flags)
|
||||
{
|
||||
int ret, i;
|
||||
json_t *json_data, *json_value;
|
||||
|
||||
ret = json_unpack(j, "{ s: { s: [ I, I ], s: [ I, I ], s: [ I, I ] }, s: I, s: o }",
|
||||
"ts",
|
||||
"origin", &s->ts.origin.tv_sec, &s->ts.origin.tv_nsec,
|
||||
"received", &s->ts.received.tv_sec, &s->ts.received.tv_nsec,
|
||||
"sent", &s->ts.sent.tv_sec, &s->ts.sent.tv_nsec,
|
||||
"sequence", &s->sequence,
|
||||
"data", &json_data);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
s->length = 0;
|
||||
|
||||
json_array_foreach(json_data, i, json_value) {
|
||||
switch (json_typeof(json_value)) {
|
||||
case JSON_REAL:
|
||||
s->data[i].f = json_real_value(json_value);
|
||||
sample_set_data_format(s, i, SAMPLE_DATA_FORMAT_FLOAT);
|
||||
break;
|
||||
|
||||
case JSON_INTEGER:
|
||||
s->data[i].f = json_integer_value(json_value);
|
||||
sample_set_data_format(s, i, SAMPLE_DATA_FORMAT_INT);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->length++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sample_io_json_fprint(FILE *f, struct sample *s, int flags)
|
||||
int config_parse_cli(config_t *cfg, int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
json_t *json;
|
||||
char *str = NULL;
|
||||
|
||||
ret = sample_io_json_pack(&json, s, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (int i = 0; i < argc; i++)
|
||||
str = strcatf(&str, "%s", argv[i]);
|
||||
|
||||
ret = json_dumpf(json, f, 0);
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
json_decref(json);
|
||||
config_set_auto_convert(cfg, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sample_io_json_fscan(FILE *f, struct sample *s, int *flags)
|
||||
{
|
||||
int ret;
|
||||
json_t *json;
|
||||
json_error_t err;
|
||||
|
||||
json = json_loadf(f, JSON_DISABLE_EOF_CHECK, &err);
|
||||
if (!json)
|
||||
return -1;
|
||||
|
||||
ret = sample_io_json_unpack(json, s, flags);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
return ret;
|
||||
ret = config_read_string(cfg, str);
|
||||
|
||||
free(str);
|
||||
|
||||
return ret != CONFIG_TRUE;
|
||||
}
|
39
lib/hook.c
39
lib/hook.c
|
@ -31,6 +31,7 @@
|
|||
#include "utils.h"
|
||||
#include "node.h"
|
||||
#include "plugin.h"
|
||||
#include "config_helper.h"
|
||||
|
||||
int hook_init(struct hook *h, struct hook_type *vt, struct path *p)
|
||||
{
|
||||
|
@ -70,6 +71,38 @@ int hook_parse(struct hook *h, config_setting_t *cfg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int hook_parse_cli(struct hook *h, int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (h->_vt->parse_cli) {
|
||||
ret = h->_vt->parse_cli(h, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
h->state = STATE_PARSED;
|
||||
}
|
||||
else {
|
||||
config_t cfg;
|
||||
config_setting_t *cfg_root;
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
ret = config_parse_cli(&cfg, argc, argv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
cfg_root = config_root_setting(&cfg);
|
||||
|
||||
ret = hook_parse(h, cfg_root);
|
||||
|
||||
out:
|
||||
config_destroy(&cfg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hook_destroy(struct hook *h)
|
||||
{
|
||||
int ret;
|
||||
|
@ -112,14 +145,14 @@ int hook_periodic(struct hook *h)
|
|||
int hook_restart(struct hook *h)
|
||||
{
|
||||
debug(LOG_HOOK | 10, "Running hook %s: type=restart, priority=%d", plugin_name(h->_vt), h->priority);
|
||||
|
||||
|
||||
return h->_vt->restart ? h->_vt->restart(h) : 0;
|
||||
}
|
||||
|
||||
int hook_read(struct hook *h, struct sample *smps[], size_t *cnt)
|
||||
{
|
||||
debug(LOG_HOOK | 10, "Running hook %s: type=read, priority=%d, cnt=%zu", plugin_name(h->_vt), h->priority, *cnt);
|
||||
|
||||
|
||||
return h->_vt->read ? h->_vt->read(h, smps, cnt) : 0;
|
||||
}
|
||||
|
||||
|
@ -196,7 +229,7 @@ int hook_parse_list(struct list *list, config_setting_t *cfg, struct path *o)
|
|||
continue; /* We ignore all non hook settings in this libconfig object setting */
|
||||
|
||||
struct hook *h = alloc(sizeof(struct hook));
|
||||
|
||||
|
||||
ret = hook_init(h, &p->hook, o);
|
||||
if (ret)
|
||||
cerror(cfg_hook, "Failed to initialize hook");
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "plugin.h"
|
||||
#include "stats.h"
|
||||
#include "path.h"
|
||||
#include "super_node.h"
|
||||
|
||||
struct stats_send {
|
||||
struct node *dest;
|
||||
|
@ -60,7 +61,7 @@ static int stats_send_parse(struct hook *h, config_setting_t *cfg)
|
|||
|
||||
if (config_setting_lookup_string(cfg, "destination", &dest)) {
|
||||
assert(h->path);
|
||||
|
||||
|
||||
p->dest = list_lookup(&h->path->super_node->nodes, dest);
|
||||
if (!p->dest)
|
||||
cerror(cfg, "Invalid destination node '%s' for hook '%s'", dest, plugin_name(h->_vt));
|
||||
|
@ -145,4 +146,4 @@ static struct plugin p = {
|
|||
|
||||
REGISTER_PLUGIN(&p)
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
28
lib/node.c
28
lib/node.c
|
@ -28,6 +28,7 @@
|
|||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "plugin.h"
|
||||
#include "config_helper.h"
|
||||
|
||||
int node_init(struct node *n, struct node_type *vt)
|
||||
{
|
||||
|
@ -87,11 +88,30 @@ int node_parse_cli(struct node *n, int argc, char *argv[])
|
|||
n->vectorize = 1;
|
||||
n->name = "cli";
|
||||
|
||||
ret = n->_vt->parse_cli ? n->_vt->parse_cli(n, argc, argv) : 0;
|
||||
if (ret)
|
||||
error("Failed to parse node '%s'", node_name(n));
|
||||
if (n->_vt->parse_cli) {
|
||||
ret = n->_vt->parse_cli(n, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
n->state = STATE_PARSED;
|
||||
n->state = STATE_PARSED;
|
||||
}
|
||||
else {
|
||||
config_t cfg;
|
||||
config_setting_t *cfg_root;
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
ret = config_parse_cli(&cfg, argc, argv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
cfg_root = config_root_setting(&cfg);
|
||||
|
||||
ret = node_parse(n, cfg_root);
|
||||
|
||||
out:
|
||||
config_destroy(&cfg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "utils.h"
|
||||
#include "timing.h"
|
||||
#include "plugin.h"
|
||||
#include "super_node.h"
|
||||
|
||||
#include "fpga/card.h"
|
||||
|
||||
|
@ -291,4 +292,3 @@ static struct plugin p = {
|
|||
|
||||
REGISTER_PLUGIN(&p)
|
||||
LIST_INIT_STATIC(&p.node.instances)
|
||||
|
|
@ -22,9 +22,9 @@
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "json.h"
|
||||
#include "sample.h"
|
||||
#include "sample_io.h"
|
||||
#include "sample_io_json.h"
|
||||
#include "timing.h"
|
||||
|
||||
int sample_io_fprint(FILE *f, struct sample *s, enum sample_io_format fmt, int flags)
|
||||
|
@ -195,4 +195,3 @@ skip: if (fgets(line, sizeof(line), f) == NULL)
|
|||
|
||||
return sample_io_villas_scan(line, s, fl);
|
||||
}
|
||||
|
||||
|
|
123
lib/sample_io_json.c
Normal file
123
lib/sample_io_json.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/** JSON serializtion sample data.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASnode
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include "sample_io_json.h"
|
||||
|
||||
int sample_io_json_pack(json_t **j, struct sample *s, int flags)
|
||||
{
|
||||
json_error_t err;
|
||||
json_t *json_data = json_array();
|
||||
|
||||
for (int i = 0; i < s->length; i++) {
|
||||
json_t *json_value = sample_get_data_format(s, i)
|
||||
? json_integer(s->data[i].i)
|
||||
: json_real(s->data[i].f);
|
||||
|
||||
json_array_append(json_data, json_value);
|
||||
}
|
||||
|
||||
*j = json_pack_ex(&err, 0, "{ s: { s: [ I, I ], s: [ I, I ], s: [ I, I ] }, s: I, s: o }",
|
||||
"ts",
|
||||
"origin", s->ts.origin.tv_sec, s->ts.origin.tv_nsec,
|
||||
"received", s->ts.received.tv_sec, s->ts.received.tv_nsec,
|
||||
"sent", s->ts.sent.tv_sec, s->ts.sent.tv_nsec,
|
||||
"sequence", s->sequence,
|
||||
"data", json_data);
|
||||
|
||||
if (!*j)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sample_io_json_unpack(json_t *j, struct sample *s, int *flags)
|
||||
{
|
||||
int ret, i;
|
||||
json_t *json_data, *json_value;
|
||||
|
||||
ret = json_unpack(j, "{ s: { s: [ I, I ], s: [ I, I ], s: [ I, I ] }, s: I, s: o }",
|
||||
"ts",
|
||||
"origin", &s->ts.origin.tv_sec, &s->ts.origin.tv_nsec,
|
||||
"received", &s->ts.received.tv_sec, &s->ts.received.tv_nsec,
|
||||
"sent", &s->ts.sent.tv_sec, &s->ts.sent.tv_nsec,
|
||||
"sequence", &s->sequence,
|
||||
"data", &json_data);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
s->length = 0;
|
||||
|
||||
json_array_foreach(json_data, i, json_value) {
|
||||
switch (json_typeof(json_value)) {
|
||||
case JSON_REAL:
|
||||
s->data[i].f = json_real_value(json_value);
|
||||
sample_set_data_format(s, i, SAMPLE_DATA_FORMAT_FLOAT);
|
||||
break;
|
||||
|
||||
case JSON_INTEGER:
|
||||
s->data[i].f = json_integer_value(json_value);
|
||||
sample_set_data_format(s, i, SAMPLE_DATA_FORMAT_INT);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->length++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sample_io_json_fprint(FILE *f, struct sample *s, int flags)
|
||||
{
|
||||
int ret;
|
||||
json_t *json;
|
||||
|
||||
ret = sample_io_json_pack(&json, s, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = json_dumpf(json, f, 0);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sample_io_json_fscan(FILE *f, struct sample *s, int *flags)
|
||||
{
|
||||
int ret;
|
||||
json_t *json;
|
||||
json_error_t err;
|
||||
|
||||
json = json_loadf(f, JSON_DISABLE_EOF_CHECK, &err);
|
||||
if (!json)
|
||||
return -1;
|
||||
|
||||
ret = sample_io_json_unpack(json, s, flags);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -20,6 +20,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "stats.h"
|
||||
#include "hist.h"
|
||||
#include "timing.h"
|
||||
|
@ -58,7 +60,7 @@ int stats_destroy(struct stats *s)
|
|||
hist_destroy(&s->histograms[i]);
|
||||
|
||||
free(s->delta);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "plugin.h"
|
||||
#include "memory.h"
|
||||
#include "config.h"
|
||||
#include "json.h"
|
||||
#include "config_helper.h"
|
||||
|
||||
#include "kernel/rt.h"
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <libconfig.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "json.h"
|
||||
#include "config_helper.h"
|
||||
|
||||
const char *cfg_example = "test : \n"
|
||||
"{\n"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <jansson.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include <villas/json.h>
|
||||
#include <villas/config_helper.h>
|
||||
#include <villas/utils.h>
|
||||
|
||||
void usage()
|
||||
|
|
Loading…
Add table
Reference in a new issue