#include "../src/cbor.h" #include #include #include #include #include static uint8_t *readfile(const char *fname, size_t *size) { struct stat st; FILE *f = fopen(fname, "rb"); if (!f) return NULL; if (fstat(fileno(f), &st) == -1) return NULL; uint8_t *buf = malloc(st.st_size); if (buf == NULL) return NULL; *size = fread(buf, st.st_size, 1, f) == 1 ? st.st_size : 0; fclose(f); return buf; } static void indent(int nestingLevel) { while (nestingLevel--) printf(" "); } static void dumpbytes(const uint8_t *buf, size_t len) { printf("\""); while (len--) printf("\\x%02X", *buf++); printf("\""); } static CborError dumprecursive(CborValue *it, int nestingLevel) { while (!cbor_value_at_end(it)) { CborError err; CborType type = cbor_value_get_type(it); indent(nestingLevel); switch (type) { case CborArrayType: case CborMapType: { // recursive type CborValue recursed; assert(cbor_value_is_container(it)); puts(type == CborArrayType ? "Array[" : "Map["); err = cbor_value_enter_container(it, &recursed); if (err) return err; // parse error err = dumprecursive(&recursed, nestingLevel + 1); if (err) return err; // parse error err = cbor_value_leave_container(it, &recursed); if (err) return err; // parse error indent(nestingLevel); puts("]"); continue; } case CborIntegerType: { int64_t val; cbor_value_get_int64(it, &val); // can't fail printf("%lld\n", (long long)val); break; } case CborByteStringType: { uint8_t *buf; size_t n; err = cbor_value_dup_byte_string(it, &buf, &n, it); if (err) return err; // parse error dumpbytes(buf, n); puts(""); free(buf); continue; } case CborTextStringType: { char *buf; size_t n; err = cbor_value_dup_text_string(it, &buf, &n, it); if (err) return err; // parse error printf("\"%s\"\n", buf); free(buf); continue; } case CborTagType: { CborTag tag; cbor_value_get_tag(it, &tag); // can't fail printf("Tag(%lld)\n", (long long)tag); break; } case CborSimpleType: { uint8_t type; cbor_value_get_simple_type(it, &type); // can't fail printf("simple(%u)\n", type); break; } case CborNullType: puts("null"); break; case CborUndefinedType: puts("undefined"); break; case CborBooleanType: { bool val; cbor_value_get_boolean(it, &val); // can't fail puts(val ? "true" : "false"); break; } case CborDoubleType: { double val; if (false) { float f; case CborFloatType: cbor_value_get_float(it, &f); val = f; } else { cbor_value_get_double(it, &val); } printf("%g\n", val); break; } case CborHalfFloatType: { uint16_t val; cbor_value_get_half_float(it, &val); printf("__f16(%04x)\n", val); break; } case CborInvalidType: assert(false); // can't happen break; } err = cbor_value_advance_fixed(it); if (err) return err; } return CborNoError; } int main(int argc, char **argv) { if (argc != 2) { puts("simplereader "); return 1; } size_t length; uint8_t *buf = readfile(argv[1], &length); if (!buf) { perror("readfile"); return 1; } CborParser parser; CborValue it; CborError err = cbor_parser_init(buf, length, 0, &parser, &it); if (!err) err = dumprecursive(&it, 0); free(buf); if (err) { fprintf(stderr, "CBOR parsing failure at offset %ld: %s\n", it.ptr - buf, cbor_error_string(err)); return 1; } return 0; }