149 lines
3.8 KiB
C
149 lines
3.8 KiB
C
#include <sys/stat.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
|
|
#include "empack.h"
|
|
|
|
|
|
|
|
#define USAGE \
|
|
"empack_cli [OPTIONS] <file | msgpack hex>\r\n" \
|
|
" file: File to read binary Msgpack data from, \"-\" for stdin\r\n" \
|
|
" msgpack hex: Hex string of Msgpack data\r\n" \
|
|
"\r\n" \
|
|
"OPTIONS\r\n" \
|
|
" -h/--help: Print this message\r\n"
|
|
|
|
|
|
|
|
static int
|
|
char_to_nibble(char c, uint8_t *nibble)
|
|
{
|
|
if ((c >= '0') && (c <= '9')) {
|
|
(*nibble) = c - '0';
|
|
} else if ((c >= 'a') && (c <= 'f')) {
|
|
(*nibble) = c - 'a' + 0x0a;
|
|
} else if ((c >= 'A') && (c <= 'F')) {
|
|
(*nibble) = c - 'A' + 0x0a;
|
|
} else {
|
|
return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void
|
|
print_func(const char *buf, uint32_t buflen, void *arg)
|
|
{
|
|
printf("%.*s", buflen, buf);
|
|
}
|
|
|
|
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
empack_t empack;
|
|
uint8_t arena[0x4000];
|
|
struct stat file_stat;
|
|
uint8_t *input = NULL;
|
|
size_t input_len = 0;
|
|
size_t input_bufsz = 0;
|
|
uint32_t chars_printed = 0;
|
|
|
|
if (argc != 2) {
|
|
fprintf(stderr, USAGE);
|
|
return (-1);
|
|
}
|
|
|
|
if ((!strcmp(argv[1], "-h")) || (!strcmp(argv[1], "--help"))) {
|
|
printf(USAGE);
|
|
return (0);
|
|
}
|
|
|
|
if (!strcmp(argv[1], "-")) {
|
|
/* read bytes from stdin */
|
|
while (1) {
|
|
size_t read;
|
|
|
|
input_bufsz += 1024;
|
|
input = realloc(input, input_bufsz);
|
|
|
|
read = fread(&input[input_len], 1, input_bufsz, stdin);
|
|
if (read == 0) {
|
|
break;
|
|
}
|
|
|
|
input_len += read;
|
|
}
|
|
} else if (stat(argv[1], &file_stat) == 0) {
|
|
/* read bytes from a file */
|
|
FILE *fd = fopen(argv[1], "r");
|
|
if (fd == NULL) {
|
|
fprintf(stderr, "Failed to open file \"%s\"\r\n", argv[1]);
|
|
return (-1);
|
|
}
|
|
|
|
input_bufsz = file_stat.st_size;
|
|
input = malloc(input_bufsz);
|
|
input_len = fread(input, 1, input_bufsz, fd);
|
|
fclose(fd);
|
|
|
|
if (input_len != input_bufsz) {
|
|
fprintf(stderr, "Failed to read file \"%s\"\r\n", argv[1]);
|
|
return (-1);
|
|
}
|
|
} else {
|
|
/* interpret argument as hex data */
|
|
size_t arg_sz = strlen(argv[1]);
|
|
if ((arg_sz % 2) != 0) {
|
|
fprintf(stderr, "Invalid hex data - odd number of characters\r\n");
|
|
return (-1);
|
|
}
|
|
|
|
input_bufsz = arg_sz / 2;
|
|
input = malloc(input_bufsz);
|
|
if (input == NULL) {
|
|
fprintf(stderr, "Failed to allocate appropriate resources\r\n");
|
|
return (-1);
|
|
}
|
|
|
|
for (size_t i = 0; i < arg_sz; i += 2) {
|
|
uint8_t hi;
|
|
uint8_t lo;
|
|
|
|
if (char_to_nibble(argv[1][i], &hi) ||
|
|
char_to_nibble(argv[1][i+1], &lo)) {
|
|
fprintf(stderr, "Invalid hex byte at offset %u\r\n", (uint32_t)(i / 2));
|
|
free(input);
|
|
return (-1);
|
|
}
|
|
|
|
input[input_len] = (hi << 4) | lo;
|
|
input_len++;
|
|
}
|
|
}
|
|
|
|
empack_init(&empack, arena, sizeof(arena));
|
|
|
|
if (empack_parse(&empack, input, input_len)) {
|
|
fprintf(stderr, "Parsing error\r\n");
|
|
free(input);
|
|
return (-1);
|
|
}
|
|
|
|
chars_printed = empack_print(&empack, print_func, NULL, " ");
|
|
printf("\r\n-- Stats --\r\n"
|
|
"Characters Printed: %u\r\n"
|
|
"Arena Memory Used: %u/%uB (%u%%)\r\n"
|
|
"-----------\r\n",
|
|
chars_printed,
|
|
empack.arena_used,
|
|
empack.arena_sz,
|
|
(empack.arena_used * 100) / empack.arena_sz);
|
|
|
|
free(input);
|
|
return (0);
|
|
}
|