1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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;
}
|