#include #include #include #include #include #include "empack.h" #define USAGE \ "empack_cli [OPTIONS] \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); }