blob: 51ef43689048106d050cce5800b09cbab98c6df5 [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
Thiago Macieira2312efd2015-05-06 16:07:48 -070029static void dumpbytes(const char *buf, size_t len)
Thiago Macieira54a0e102015-05-05 21:25:06 -070030{
31 while (len--)
Thiago Macieira2312efd2015-05-06 16:07:48 -070032 printf("%02X ", (unsigned char)*buf++);
Thiago Macieira54a0e102015-05-05 21:25:06 -070033}
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;
Thiago Macieira2312efd2015-05-06 16:07:48 -070046 assert(cbor_value_is_container(it));
Thiago Macieira54a0e102015-05-05 21:25:06 -070047 puts(type == CborArrayType ? "Array[" : "Map[");
Thiago Macieira2312efd2015-05-06 16:07:48 -070048 if (!cbor_value_enter_container(it, &recursed))
Thiago Macieira54a0e102015-05-05 21:25:06 -070049 return false; // parse error
50 if (!dumprecursive(&recursed, nestingLevel + 1))
51 return false; // parse error
Thiago Macieira2312efd2015-05-06 16:07:48 -070052 if (!cbor_value_leave_container(it, &recursed))
Thiago Macieira54a0e102015-05-05 21:25:06 -070053 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
Thiago Macieira2312efd2015-05-06 16:07:48 -070066 case CborByteStringType:
Thiago Macieira54a0e102015-05-05 21:25:06 -070067 case CborTextStringType: {
68 char *buf;
Thiago Macieira2312efd2015-05-06 16:07:48 -070069 size_t n;
70 if (!cbor_value_dup_string(it, &buf, &n, it))
Thiago Macieira54a0e102015-05-05 21:25:06 -070071 return false; // parse error
Thiago Macieira2312efd2015-05-06 16:07:48 -070072 if (type == CborByteStringType) {
73 dumpbytes(buf, n);
74 puts("");
75 } else {
76 puts(buf);
77 }
Thiago Macieira54a0e102015-05-05 21:25:06 -070078 free(buf);
79 continue;
80 }
81
82 case CborTagType: {
83 CborTag tag;
84 cbor_value_get_tag(it, &tag); // can't fail
85 printf("Tag(%lld)\n", (long long)tag);
86 break;
87 }
88
89 case CborSimpleType: {
90 uint8_t type;
91 cbor_value_get_simple_type(it, &type); // can't fail
92 printf("simple(%u)\n", type);
93 break;
94 }
95
96 case CborNullType:
97 puts("null");
98 break;
99
100 case CborUndefinedType:
101 puts("undefined");
102
103 case CborBooleanType: {
104 bool val;
105 cbor_value_get_boolean(it, &val); // can't fail
106 puts(val ? "true" : "false");
107 break;
108 }
109
110 case CborDoubleType: {
111 double val;
112 if (false) {
113 float f;
114 case CborFloatType:
115 cbor_value_get_float(it, &f);
116 val = f;
117 } else {
118 cbor_value_get_double(it, &val);
119 }
120 printf("%g\n", val);
121 break;
122 }
123 case CborHalfFloatType: {
124 uint16_t val;
125 cbor_value_get_half_float(it, &val);
126 printf("__f16(%04x)\n", val);
127 break;
128 }
129
130 case CborInvalidType:
131 assert(false); // can't happen
132 break;
133 }
134
135 if (!cbor_value_advance_fixed(it))
136 return false;
137 }
138 return NULL;
139}
140
141int main(int argc, char **argv)
142{
143 if (argc == 1) {
144 puts("simplereader <filename>");
145 return 0;
146 }
147
148 size_t length;
149 char *buf = readfile(argv[1], &length);
150 if (!buf) {
151 perror("readfile");
152 return 1;
153 }
154
155 CborParser parser;
156 CborValue it;
157 cbor_parser_init(buf, length, 0, &parser, &it);
158 dumprecursive(&it, 0);
159 free(buf);
160
161 CborParserError err = cbor_parser_get_error(&parser);
162 if (err) {
163 fprintf(stderr, "CBOR parsing failure at offset %ld: %s\n",
164 it.ptr - buf, cbor_parser_error_string(err));
165 return 1;
166 }
167 return 0;
168}