blob: 14a9c87ad664b7ae09bdfd019770f1c93fe24195 [file] [log] [blame]
Thiago Macieira54a0e102015-05-05 21:25:06 -07001#include "../src/cbor.h"
2
3#include <sys/stat.h>
4#include <assert.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8
9static char *readfile(const char *fname, size_t *size)
10{
11 struct stat st;
12 FILE *f = fopen(fname, "rb");
13 if (!f)
14 return NULL;
15 if (fstat(fileno(f), &st) == -1)
16 return NULL;
17 char *buf = malloc(st.st_size);
18 *size = fread(buf, st.st_size, 1, f);
19 fclose(f);
20 return buf;
21}
22
23static void indent(int nestingLevel)
24{
25 while (nestingLevel--)
26 puts(" ");
27}
28
29static void dumpbytes(const unsigned char *buf, size_t len)
30{
31 while (len--)
32 printf("%02X ", *buf++);
33}
34
35static bool dumprecursive(CborValue *it, int nestingLevel)
36{
37 while (!cbor_value_at_end(it)) {
38 indent(nestingLevel);
39
40 CborType type = cbor_value_get_type(it);
41 switch (type) {
42 case CborArrayType:
43 case CborMapType: {
44 // recursive type
45 CborValue recursed;
46 assert(cbor_value_is_recursive(it));
47 puts(type == CborArrayType ? "Array[" : "Map[");
48 if (!cbor_value_begin_recurse(it, &recursed))
49 return false; // parse error
50 if (!dumprecursive(&recursed, nestingLevel + 1))
51 return false; // parse error
52 if (!cbor_value_end_recurse(it, &recursed))
53 return false; // parse error
54 indent(nestingLevel);
55 puts("]");
56 continue;
57 }
58
59 case CborIntegerType: {
60 int64_t val;
61 cbor_value_get_int64(it, &val); // can't fail
62 printf("%lld\n", (long long)val);
63 break;
64 }
65
66 case CborByteStringType: {
67 unsigned char *buf;
68 size_t n = cbor_value_dup_byte_string(it, &buf, it);
69 if (n == SIZE_MAX)
70 return false; // parse error
71 dumpbytes(buf, n);
72 puts("");
73 free(buf);
74 continue;
75 }
76
77 case CborTextStringType: {
78 char *buf;
79 size_t n = cbor_value_dup_text_string(it, &buf, it);
80 if (n == SIZE_MAX)
81 return false; // parse error
82 printf("%s\n", buf);
83 free(buf);
84 continue;
85 }
86
87 case CborTagType: {
88 CborTag tag;
89 cbor_value_get_tag(it, &tag); // can't fail
90 printf("Tag(%lld)\n", (long long)tag);
91 break;
92 }
93
94 case CborSimpleType: {
95 uint8_t type;
96 cbor_value_get_simple_type(it, &type); // can't fail
97 printf("simple(%u)\n", type);
98 break;
99 }
100
101 case CborNullType:
102 puts("null");
103 break;
104
105 case CborUndefinedType:
106 puts("undefined");
107
108 case CborBooleanType: {
109 bool val;
110 cbor_value_get_boolean(it, &val); // can't fail
111 puts(val ? "true" : "false");
112 break;
113 }
114
115 case CborDoubleType: {
116 double val;
117 if (false) {
118 float f;
119 case CborFloatType:
120 cbor_value_get_float(it, &f);
121 val = f;
122 } else {
123 cbor_value_get_double(it, &val);
124 }
125 printf("%g\n", val);
126 break;
127 }
128 case CborHalfFloatType: {
129 uint16_t val;
130 cbor_value_get_half_float(it, &val);
131 printf("__f16(%04x)\n", val);
132 break;
133 }
134
135 case CborInvalidType:
136 assert(false); // can't happen
137 break;
138 }
139
140 if (!cbor_value_advance_fixed(it))
141 return false;
142 }
143 return NULL;
144}
145
146int main(int argc, char **argv)
147{
148 if (argc == 1) {
149 puts("simplereader <filename>");
150 return 0;
151 }
152
153 size_t length;
154 char *buf = readfile(argv[1], &length);
155 if (!buf) {
156 perror("readfile");
157 return 1;
158 }
159
160 CborParser parser;
161 CborValue it;
162 cbor_parser_init(buf, length, 0, &parser, &it);
163 dumprecursive(&it, 0);
164 free(buf);
165
166 CborParserError err = cbor_parser_get_error(&parser);
167 if (err) {
168 fprintf(stderr, "CBOR parsing failure at offset %ld: %s\n",
169 it.ptr - buf, cbor_parser_error_string(err));
170 return 1;
171 }
172 return 0;
173}