summaryrefslogtreecommitdiff
path: root/prototype/fw/test/microcobs_test_sg.c
diff options
context:
space:
mode:
Diffstat (limited to 'prototype/fw/test/microcobs_test_sg.c')
-rw-r--r--prototype/fw/test/microcobs_test_sg.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/prototype/fw/test/microcobs_test_sg.c b/prototype/fw/test/microcobs_test_sg.c
new file mode 100644
index 0000000..592dfc5
--- /dev/null
+++ b/prototype/fw/test/microcobs_test_sg.c
@@ -0,0 +1,94 @@
+
+#include <stdint.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "microcobs.h"
+
+static int parse_hex(char c) {
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 0xa;
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 0xA;
+ return -1;
+}
+
+int main(void) {
+ char buf[2];
+
+ size_t sgl_len = 100;
+ struct sg_entry *sgl = calloc(sgl_len, sizeof(struct sg_entry));
+
+ size_t sg_i = 0;
+ size_t sgi_size = 1024;
+ size_t total_bytes = 0;
+
+ do {
+ ssize_t nread = fread(buf, 1, 1, stdin);
+ if (nread == 0)
+ break;
+ fprintf(stderr, "read: %d\n", nread);
+
+ if (buf[0] == '\n') {
+ fprintf(stderr, "Found newline for chunk %d\n", sg_i);
+ sg_i += 1;
+ sgi_size = 1024;
+ if (sg_i+1 >= sgl_len) { /* always keep last entry free for termination */
+ size_t old_sgl_len = sgl_len;
+ sgl_len += 50;
+ sgl = reallocarray(sgl, sgl_len, sizeof(struct sg_entry));
+ if (!sgl)
+ return -99;
+ memset(sgl+old_sgl_len, 0, (sgl_len - old_sgl_len) * sizeof(struct sg_entry));
+ }
+ continue;
+ }
+
+ nread = fread(buf + 1, 1, 1, stdin);
+ if (nread == 0)
+ break;
+ fprintf(stderr, "read: %d\n", nread);
+
+ int a = parse_hex(buf[0]), b = parse_hex(buf[1]);
+ if (a < 0 || b < 0)
+ fprintf(stderr, "Error: even number of hex digits expected\n");
+
+ int byte = a<<4 | b;
+ if (sgl[sg_i].target == 0) {
+ sgl[sg_i].target = malloc(sgi_size);
+ } else if (sgl[sg_i].size == sgi_size) {
+ sgi_size += 1024;
+ sgl[sg_i].target = realloc(sgl[sg_i].target, sgi_size);
+ if (!sgl[sg_i].target)
+ return -99;
+ }
+ sgl[sg_i].target[sgl[sg_i].size] = byte;
+ sgl[sg_i].size += 1;
+ total_bytes += 1;
+ } while(23);
+
+ /* Terminate list */
+ sg_i += 1;
+ sgl[sg_i].size = -1;
+ fprintf(stderr, "Got %d chunks\n", sg_i);
+
+ /* Reserve extra bytes for long input lines. Arbitrary length support means this cobs implemenetation is no longer
+ * fixed overhead of 1 byte, but instead variable overhead of worst-case O(1 + n/254) for input length n. */
+ size_t output_size = total_bytes + 10000;
+ uint8_t *output_buf = malloc(output_size);
+
+ ssize_t rv = cobs_encode_sg(sgl, output_buf, output_size);
+ if (rv > 0) {
+ for (size_t i=0; i<rv; i++) {
+ printf("%02x", output_buf[i]);
+ }
+ } else {
+ printf("NONZERO RETURN VALUE: %d\n", rv);
+ }
+ printf("\n");
+
+ return 0;
+}