From 26b7150f6a82c551f5a3fb3021ecdb5d7536f050 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 4 Sep 2017 16:19:27 +0200 Subject: [PATCH] format: more refactoring --- include/villas/io/msg.h | 55 ++++++++++++++ include/villas/io/villas_binary.h | 40 ++--------- include/villas/io/villas_human.h | 8 +-- lib/io/Makefile.inc | 2 +- lib/io/msg.c | 115 ++++++++++++++++++++++++++++++ lib/io/villas_binary.c | 109 ++++------------------------ lib/io/villas_human.c | 50 ++++++------- tests/unit/advio.c | 4 +- 8 files changed, 219 insertions(+), 164 deletions(-) create mode 100644 include/villas/io/msg.h create mode 100644 lib/io/msg.c diff --git a/include/villas/io/msg.h b/include/villas/io/msg.h new file mode 100644 index 000000000..c10498c12 --- /dev/null +++ b/include/villas/io/msg.h @@ -0,0 +1,55 @@ +/** Message related functions. + * + * @author Steffen Vogel + * @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 . + *********************************************************************************/ + +#pragma once + +/* Forward declaration */ +struct msg; +struct sample; + +/** Convert msg from network to host byteorder */ +void msg_ntoh(struct msg *m); + +/** Convert msg from host to network byteorder */ +void msg_hton(struct msg *m); + +/** Convert msg header from network to host byteorder */ +void msg_hdr_hton(struct msg *m); + +/** Convert msg header from host to network byteorder */ +void msg_hdr_ntoh(struct msg *m); + +/** Check the consistency of a message. + * + * The functions checks the header fields of a message. + * + * @param m A pointer to the message + * @retval 0 The message header is valid. + * @retval <0 The message header is invalid. + */ +int msg_verify(struct msg *m); + +/** Copy fields from \p msg into \p smp. */ +int msg_to_sample(struct msg *msg, struct sample *smp); + +/** Copy fields form \p smp into \p msg. */ +int msg_from_sample(struct msg *msg, struct sample *smp); diff --git a/include/villas/io/villas_binary.h b/include/villas/io/villas_binary.h index 508b5be68..6f567ce61 100644 --- a/include/villas/io/villas_binary.h +++ b/include/villas/io/villas_binary.h @@ -26,46 +26,16 @@ #include /* Forward declarations. */ -struct msg; struct sample; +struct msg; struct io; -enum msg_flags { - MSG_WEB = (1 << 16) /**< Use webmsg format (everying little endian) */ +enum villas_binary_flags { + VILLAS_BINARY_WEB = (1 << 16) /**< Use webmsg format (everying little endian) */ }; -/** Swaps the byte-order of the message. - * - * Message are always transmitted in network (big endian) byte order. - * - * @param m A pointer to the message - */ -void msg_hdr_ntoh(struct msg *m); - -void msg_hdr_hton(struct msg *m); - -void msg_ntoh(struct msg *m); - -void msg_hton(struct msg *m); - -/** Check the consistency of a message. - * - * The functions checks the header fields of a message. - * - * @param m A pointer to the message - * @retval 0 The message header is valid. - * @retval <0 The message header is invalid. - */ -int msg_verify(struct msg *m); - -/** Copy fields from \p msg into \p smp. */ -int msg_to_sample(struct msg *msg, struct sample *smp); - -/** Copy fields form \p smp into \p msg. */ -int msg_from_sample(struct msg *msg, struct sample *smp); - /** Copy / read struct msg's from buffer \p buf to / fram samples \p smps. */ -int msg_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt, int flags); +int villas_binary_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt, int flags); /** Read struct sample's from buffer \p buf into samples \p smps. */ -int msg_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt, int flags); +int villas_binary_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt, int flags); diff --git a/include/villas/io/villas_human.h b/include/villas/io/villas_human.h index 34d248013..8619c9c0e 100644 --- a/include/villas/io/villas_human.h +++ b/include/villas/io/villas_human.h @@ -27,10 +27,10 @@ #include "io.h" -int villas_print(struct io *io, struct sample *smps[], unsigned cnt); +int villas_human_print(struct io *io, struct sample *smps[], unsigned cnt); -int villas_scan(struct io *io, struct sample *smps[], unsigned cnt); +int villas_human_scan(struct io *io, struct sample *smps[], unsigned cnt); -int villas_fprint(FILE *f, struct sample *smps[], unsigned cnt, int flags); +int villas_human_fprint(FILE *f, struct sample *smps[], unsigned cnt, int flags); -int villas_fscan(FILE *f, struct sample *smps[], unsigned cnt, int flags); +int villas_human_fscan(FILE *f, struct sample *smps[], unsigned cnt, int flags); diff --git a/lib/io/Makefile.inc b/lib/io/Makefile.inc index 822235ece..827679ed0 100644 --- a/lib/io/Makefile.inc +++ b/lib/io/Makefile.inc @@ -20,4 +20,4 @@ # along with this program. If not, see . ################################################################################### -LIB_SRCS += $(addprefix lib/io/,json.c villas.c csv.c raw.c msg.c) +LIB_SRCS += $(addprefix lib/io/,json.c villas_binary.c villas_human.c csv.c raw.c msg.c) diff --git a/lib/io/msg.c b/lib/io/msg.c new file mode 100644 index 000000000..286d7a77b --- /dev/null +++ b/lib/io/msg.c @@ -0,0 +1,115 @@ +/** Message related functions. + * + * @author Steffen Vogel + * @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 . + *********************************************************************************/ + +#include + +#include "io/msg.h" +#include "io/msg_format.h" +#include "sample.h" +#include "utils.h" + +void msg_ntoh(struct msg *m) +{ + msg_hdr_ntoh(m); + + for (int i = 0; i < m->length; i++) + m->data[i].i = ntohl(m->data[i].i); +} + +void msg_hton(struct msg *m) +{ + for (int i = 0; i < m->length; i++) + m->data[i].i = htonl(m->data[i].i); + + msg_hdr_hton(m); +} + +void msg_hdr_hton(struct msg *m) +{ + m->length = htons(m->length); + m->sequence = htonl(m->sequence); + m->ts.sec = htonl(m->ts.sec); + m->ts.nsec = htonl(m->ts.nsec); +} + +void msg_hdr_ntoh(struct msg *m) +{ + m->length = ntohs(m->length); + m->sequence = ntohl(m->sequence); + m->ts.sec = ntohl(m->ts.sec); + m->ts.nsec = ntohl(m->ts.nsec); +} + +int msg_verify(struct msg *m) +{ + if (m->version != MSG_VERSION) + return -1; + else if (m->type != MSG_TYPE_DATA) + return -2; + else if (m->rsvd1 != 0) + return -3; + else + return 0; +} + +int msg_to_sample(struct msg *msg, struct sample *smp) +{ + int ret; + + ret = msg_verify(msg); + if (ret) + return -1; + + smp->has = SAMPLE_ORIGIN | SAMPLE_SEQUENCE | SAMPLE_VALUES | SAMPLE_ID; + smp->length = MIN(msg->length, smp->capacity); + smp->sequence = msg->sequence; + smp->id = msg->id; + smp->ts.origin = MSG_TS(msg); + smp->format = 0; + + for (int i = 0; i < smp->length; i++) { + switch (sample_get_data_format(smp, i)) { + case SAMPLE_DATA_FORMAT_FLOAT: smp->data[i].f = msg->data[i].f; break; + case SAMPLE_DATA_FORMAT_INT: smp->data[i].i = msg->data[i].i; break; + } + } + + return 0; +} + +int msg_from_sample(struct msg *msg, struct sample *smp) +{ + *msg = MSG_INIT(smp->length, smp->sequence); + + msg->ts.sec = smp->ts.origin.tv_sec; + msg->ts.nsec = smp->ts.origin.tv_nsec; + msg->id = smp->id; + + for (int i = 0; i < smp->length; i++) { + switch (sample_get_data_format(smp, i)) { + case SAMPLE_DATA_FORMAT_FLOAT: msg->data[i].f = smp->data[i].f; break; + case SAMPLE_DATA_FORMAT_INT: msg->data[i].i = smp->data[i].i; break; + } + } + + return 0; +} diff --git a/lib/io/villas_binary.c b/lib/io/villas_binary.c index a56bcead3..55fa54432 100644 --- a/lib/io/villas_binary.c +++ b/lib/io/villas_binary.c @@ -23,99 +23,14 @@ #include #include "io/villas_binary.h" + +#include "io/msg.h" #include "io/msg_format.h" #include "sample.h" #include "utils.h" #include "plugin.h" -void msg_ntoh(struct msg *m) -{ - msg_hdr_ntoh(m); - - for (int i = 0; i < m->length; i++) - m->data[i].i = ntohl(m->data[i].i); -} - -void msg_hton(struct msg *m) -{ - for (int i = 0; i < m->length; i++) - m->data[i].i = htonl(m->data[i].i); - - msg_hdr_hton(m); -} - -void msg_hdr_hton(struct msg *m) -{ - m->length = htons(m->length); - m->sequence = htonl(m->sequence); - m->ts.sec = htonl(m->ts.sec); - m->ts.nsec = htonl(m->ts.nsec); -} - -void msg_hdr_ntoh(struct msg *m) -{ - m->length = ntohs(m->length); - m->sequence = ntohl(m->sequence); - m->ts.sec = ntohl(m->ts.sec); - m->ts.nsec = ntohl(m->ts.nsec); -} - -int msg_verify(struct msg *m) -{ - if (m->version != MSG_VERSION) - return -1; - else if (m->type != MSG_TYPE_DATA) - return -2; - else if (m->rsvd1 != 0) - return -3; - else - return 0; -} - -int msg_to_sample(struct msg *msg, struct sample *smp) -{ - int ret; - - ret = msg_verify(msg); - if (ret) - return -1; - - smp->has = SAMPLE_ORIGIN | SAMPLE_SEQUENCE | SAMPLE_VALUES | SAMPLE_ID; - smp->length = MIN(msg->length, smp->capacity); - smp->sequence = msg->sequence; - smp->id = msg->id; - smp->ts.origin = MSG_TS(msg); - smp->format = 0; - - for (int i = 0; i < smp->length; i++) { - switch (sample_get_data_format(smp, i)) { - case SAMPLE_DATA_FORMAT_FLOAT: smp->data[i].f = msg->data[i].f; break; - case SAMPLE_DATA_FORMAT_INT: smp->data[i].i = msg->data[i].i; break; - } - } - - return 0; -} - -int msg_from_sample(struct msg *msg, struct sample *smp) -{ - *msg = MSG_INIT(smp->length, smp->sequence); - - msg->ts.sec = smp->ts.origin.tv_sec; - msg->ts.nsec = smp->ts.origin.tv_nsec; - msg->id = smp->id; - - for (int i = 0; i < smp->length; i++) { - switch (sample_get_data_format(smp, i)) { - case SAMPLE_DATA_FORMAT_FLOAT: msg->data[i].f = smp->data[i].f; break; - case SAMPLE_DATA_FORMAT_INT: msg->data[i].i = smp->data[i].i; break; - } - } - - return 0; -} - -int msg_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt, int flags) +int villas_binary_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt, int flags) { int ret, i = 0; char *ptr = buf; @@ -131,7 +46,7 @@ int msg_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], uns if (ret) return ret; - if (flags & MSG_WEB) { + if (flags & VILLAS_BINARY_WEB) { /** @todo convert to little endian */ } else @@ -146,7 +61,7 @@ int msg_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], uns return i; } -int msg_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt, int flags) +int villas_binary_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt, int flags) { int ret, i = 0, values; char *ptr = buf; @@ -170,7 +85,7 @@ int msg_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsi break; } - values = (flags & MSG_WEB) ? msg->length : ntohs(msg->length); + values = (flags & VILLAS_BINARY_WEB) ? msg->length : ntohs(msg->length); /* Check if remainder of message is in buffer boundaries */ if (ptr + MSG_LEN(values) > buf + len) { @@ -178,7 +93,7 @@ int msg_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsi break; } - if (flags & MSG_WEB) + if (flags & VILLAS_BINARY_WEB) ; else msg_ntoh(msg); @@ -203,8 +118,8 @@ static struct plugin p1 = { .description = "VILLAS binary network format", .type = PLUGIN_TYPE_IO, .io = { - .sprint = msg_sprint, - .sscan = msg_sscan, + .sprint = villas_binary_sprint, + .sscan = villas_binary_sscan, .size = 0, .flags = IO_FORMAT_BINARY }, @@ -216,10 +131,10 @@ static struct plugin p2 = { .description = "VILLAS binary network format for WebSockets", .type = PLUGIN_TYPE_IO, .io = { - .sprint = msg_sprint, - .sscan = msg_sscan, + .sprint = villas_binary_sprint, + .sscan = villas_binary_sscan, .size = 0, - .flags = IO_FORMAT_BINARY | MSG_WEB + .flags = IO_FORMAT_BINARY | VILLAS_BINARY_WEB }, }; diff --git a/lib/io/villas_human.c b/lib/io/villas_human.c index 1cfed9637..7bdba26e5 100644 --- a/lib/io/villas_human.c +++ b/lib/io/villas_human.c @@ -36,7 +36,7 @@ struct villas_human { bool header_written; }; -size_t villas_sprint_single(char *buf, size_t len, struct sample *s, int flags) +size_t villas_human_sprint_single(char *buf, size_t len, struct sample *s, int flags) { size_t off = 0; @@ -69,7 +69,7 @@ size_t villas_sprint_single(char *buf, size_t len, struct sample *s, int flags) return off; } -size_t villas_sscan_single(const char *buf, size_t len, struct sample *s, int flags) +size_t villas_human_sscan_single(const char *buf, size_t len, struct sample *s, int flags) { char *end; const char *ptr = buf; @@ -163,13 +163,13 @@ size_t villas_sscan_single(const char *buf, size_t len, struct sample *s, int fl return end - buf; } -int villas_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt, int flags) +int villas_human_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt, int flags) { int i; size_t off = 0; for (i = 0; i < cnt && off < len; i++) - off += villas_sprint_single(buf + off, len - off, smps[i], flags); + off += villas_human_sprint_single(buf + off, len - off, smps[i], flags); if (wbytes) *wbytes = off; @@ -177,13 +177,13 @@ int villas_sprint(char *buf, size_t len, size_t *wbytes, struct sample *smps[], return i; } -int villas_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt, int flags) +int villas_human_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt, int flags) { int i; size_t off = 0; for (i = 0; i < cnt && off < len; i++) - off += villas_sscan_single(buf + off, len - off, smps[i], flags); + off += villas_human_sscan_single(buf + off, len - off, smps[i], flags); if (rbytes) *rbytes = off; @@ -191,7 +191,7 @@ int villas_sscan(char *buf, size_t len, size_t *rbytes, struct sample *smps[], u return i; } -int villas_fscan_single(FILE *f, struct sample *s, int flags) +int villas_human_fscan_single(FILE *f, struct sample *s, int flags) { char *ptr, line[4096]; @@ -203,15 +203,15 @@ skip: if (fgets(line, sizeof(line), f) == NULL) if (*ptr == '\0' || *ptr == '#') goto skip; - return villas_sscan_single(line, strlen(line), s, flags); + return villas_human_sscan_single(line, strlen(line), s, flags); } -int villas_fprint_single(FILE *f, struct sample *s, int flags) +int villas_human_fprint_single(FILE *f, struct sample *s, int flags) { int ret; char line[4096]; - ret = villas_sprint_single(line, sizeof(line), s, flags); + ret = villas_human_sprint_single(line, sizeof(line), s, flags); if (ret < 0) return ret; @@ -220,12 +220,12 @@ int villas_fprint_single(FILE *f, struct sample *s, int flags) return 0; } -int villas_fprint(FILE *f, struct sample *smps[], unsigned cnt, int flags) +int villas_human_fprint(FILE *f, struct sample *smps[], unsigned cnt, int flags) { int ret, i; for (i = 0; i < cnt; i++) { - ret = villas_fprint_single(f, smps[i], flags); + ret = villas_human_fprint_single(f, smps[i], flags); if (ret < 0) return ret; } @@ -233,7 +233,7 @@ int villas_fprint(FILE *f, struct sample *smps[], unsigned cnt, int flags) return i; } -int villas_print(struct io *io, struct sample *smps[], unsigned cnt) +int villas_human_print(struct io *io, struct sample *smps[], unsigned cnt) { struct villas_human *h = io->_vd; @@ -250,15 +250,15 @@ int villas_print(struct io *io, struct sample *smps[], unsigned cnt) h->header_written = true; } - return villas_fprint(f, smps, cnt, io->flags); + return villas_human_fprint(f, smps, cnt, io->flags); } -int villas_fscan(FILE *f, struct sample *smps[], unsigned cnt, int flags) +int villas_human_fscan(FILE *f, struct sample *smps[], unsigned cnt, int flags) { int ret, i; for (i = 0; i < cnt; i++) { - ret = villas_fscan_single(f, smps[i], flags); + ret = villas_human_fscan_single(f, smps[i], flags); if (ret < 0) return ret; } @@ -266,7 +266,7 @@ int villas_fscan(FILE *f, struct sample *smps[], unsigned cnt, int flags) return i; } -int villas_open(struct io *io, const char *uri) +int villas_human_open(struct io *io, const char *uri) { struct villas_human *h = io->_vd; int ret; @@ -280,7 +280,7 @@ int villas_open(struct io *io, const char *uri) return 0; } -void villas_rewind(struct io *io) +void villas_human_rewind(struct io *io) { struct villas_human *h = io->_vd; @@ -294,13 +294,13 @@ static struct plugin p = { .description = "VILLAS human readable format", .type = PLUGIN_TYPE_IO, .io = { - .open = villas_open, - .rewind = villas_rewind, - .print = villas_print, - .fprint = villas_fprint, - .fscan = villas_fscan, - .sprint = villas_sprint, - .sscan = villas_sscan, + .open = villas_human_open, + .rewind = villas_human_rewind, + .print = villas_human_print, + .fprint = villas_human_fprint, + .fscan = villas_human_fscan, + .sprint = villas_human_sprint, + .sscan = villas_human_sscan, .size = sizeof(struct villas_human) } }; diff --git a/tests/unit/advio.c b/tests/unit/advio.c index 0f3a4d591..a74bf96fe 100644 --- a/tests/unit/advio.c +++ b/tests/unit/advio.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include /** This URI points to a Sciebo share which contains some test files. * The Sciebo share is read/write accessible via WebDAV. */ @@ -95,7 +95,7 @@ Test(advio, download_large) af = afopen(BASE_URI "/download-large" , "r"); cr_assert(af, "Failed to download file"); - ret = villas_fscan(af->file, &smp, 1, 0); + ret = villas_human_fscan(af->file, &smp, 1, 0); cr_assert_eq(ret, 1); cr_assert_eq(smp->sequence, 0);