diff options
Diffstat (limited to 'prototype/fw/test/microcobs_test_sg.c')
-rw-r--r-- | prototype/fw/test/microcobs_test_sg.c | 94 |
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; +} |