diff --git a/include/msg.h b/include/msg.h index afce6df70..efbaae047 100644 --- a/include/msg.h +++ b/include/msg.h @@ -55,12 +55,11 @@ int msg_verify(struct msg *m); * @param m A pointer to the message. * @param flags See msg_flags. * @param offset A optional offset in seconds. Only used if flags contains MSG_PRINT_OFFSET. - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. + * @return Number of bytes written to buf. */ -int msg_fprint(FILE *f, struct msg *m, int flags, double offset); +int msg_print(char *buf, size_t len, struct msg *m, int flags, double offset); -/** Read a message from a file stream. +/** Read a message from a character buffer. * * @param f The file handle from fopen() or stdin. * @param m A pointer to the message. @@ -69,6 +68,18 @@ int msg_fprint(FILE *f, struct msg *m, int flags, double offset); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ +int msg_scan(const char *line, struct msg *m, int *fl, double *off); + +/** Print a raw message in human readable form to a file stream. + * + * @see msg_print() + */ +int msg_fprint(FILE *f, struct msg *m, int flags, double offset); + +/** Read a message from a file stream. + * + * @see msg_scan() + */ int msg_fscan(FILE *f, struct msg *m, int *flags, double *offset); /** Change the values of an existing message in a random fashion. diff --git a/lib/msg.c b/lib/msg.c index 837bd75a6..25b350c61 100644 --- a/lib/msg.c +++ b/lib/msg.c @@ -49,34 +49,34 @@ int msg_verify(struct msg *m) return 0; } -int msg_fprint(FILE *f, struct msg *m, int flags, double offset) +int msg_print(char *buf, size_t len, struct msg *m, int flags, double offset) { - fprintf(f, "%u", m->ts.sec); + size_t off = snprintf(buf, len, "%u", m->ts.sec); if (flags & MSG_PRINT_NANOSECONDS) - fprintf(f, ".%09u", m->ts.nsec); + off += snprintf(buf + off, len - off, ".%09u", m->ts.nsec); if (flags & MSG_PRINT_OFFSET) - fprintf(f, "%+g", offset); + off += snprintf(buf + off, len - off, "%+g", offset); if (flags & MSG_PRINT_SEQUENCE) - fprintf(f, "(%u)", m->sequence); + off += snprintf(buf + off, len - off, "(%u)", m->sequence); if (flags & MSG_PRINT_VALUES) { for (int i = 0; i < m->length; i++) - fprintf(f, "\t%.6f", m->data[i].f); + off += snprintf(buf + off, len - off, "\t%.6f", m->data[i].f); } - fprintf(f, "\n"); + off += snprintf(buf + off, len - off, "\n"); - return 0; + return off + 1; /* trailing '\0' */ } -/** @todo Currently only floating point values are supported */ -int msg_fscan(FILE *f, struct msg *m, int *fl, double *off) +int msg_scan(const char *line, struct msg *m, int *fl, double *off) { - char line[MSG_VALUES * 16]; - char *end, *ptr = line; + char *end; + const char *ptr = line; + int flags = 0; double offset; @@ -90,14 +90,6 @@ int msg_fscan(FILE *f, struct msg *m, int *fl, double *off) * Please note that only the seconds and at least one value are mandatory */ -skip: if (fgets(line, sizeof(line), f) == NULL) - return -1; /* An error occured */ - - /* Skip whitespaces, empty and comment lines */ - for (ptr = line; isspace(*ptr); ptr++); - if (*ptr == '\0' || *ptr == '#') - goto skip; - /* Mandatory: seconds */ m->ts.sec = (uint32_t) strtoul(ptr, &end, 10); if (ptr == end) @@ -166,6 +158,32 @@ skip: if (fgets(line, sizeof(line), f) == NULL) return m->length; } +int msg_fprint(FILE *f, struct msg *m, int flags, double offset) +{ + char line[4096]; + + int len = msg_print(line, sizeof(line), m, flags, offset); + + fputs(line, f); + + return len; +} + +int msg_fscan(FILE *f, struct msg *m, int *fl, double *off) +{ + char *ptr, line[4096]; + +skip: if (fgets(line, sizeof(line), f) == NULL) + return -1; /* An error occured */ + + /* Skip whitespaces, empty and comment lines */ + for (ptr = line; isspace(*ptr); ptr++); + if (*ptr == '\0' || *ptr == '#') + goto skip; + + return msg_scan(line, m, fl, off); +} + void msg_random(struct msg *m) { for (int i = 0; i < m->length; i++)