
#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 buf_size = 1024;
	uint8_t *data_buf = malloc(buf_size);
	if (!data_buf)
		return -99;
	size_t total_bytes = 0;
	
	do {
		ssize_t nread = fread(buf, 1, 2, stdin);
		if (nread < 2) {
			fprintf(stderr, "bk %d\n", nread);
			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 (total_bytes >= buf_size) {
			buf_size += 1024;
			data_buf = realloc(data_buf, buf_size);
			if (!data_buf)
				return -99;
		}

		data_buf[total_bytes] = byte;
		total_bytes += 1;
	} while(23);

	/* Terminate list */
	fprintf(stderr, "Got %d bytes\n", total_bytes);

	 /* 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*2 + 100;
	uint8_t *output_buf = malloc(output_size);

	ssize_t rv = cobs_encode(data_buf, total_bytes, 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;
}
