blob: bb1798d422610753ab84b754c44ffe6a0d3a71fa [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)) {
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070038 CborError err;
Thiago Macieira54a0e102015-05-05 21:25:06 -070039 CborType type = cbor_value_get_type(it);
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070040
41 indent(nestingLevel);
Thiago Macieira54a0e102015-05-05 21:25:06 -070042 switch (type) {
43 case CborArrayType:
44 case CborMapType: {
45 // recursive type
46 CborValue recursed;
Thiago Macieira2312efd2015-05-06 16:07:48 -070047 assert(cbor_value_is_container(it));
Thiago Macieira54a0e102015-05-05 21:25:06 -070048 puts(type == CborArrayType ? "Array[" : "Map[");
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070049 err = cbor_value_enter_container(it, &recursed);
50 if (err)
51 return err; // parse error
52 err = dumprecursive(&recursed, nestingLevel + 1);
53 if (err)
54 return err; // parse error
55 err = cbor_value_leave_container(it, &recursed);
56 if (err)
57 return err; // parse error
Thiago Macieira54a0e102015-05-05 21:25:06 -070058 indent(nestingLevel);
59 puts("]");
60 continue;
61 }
62
63 case CborIntegerType: {
64 int64_t val;
65 cbor_value_get_int64(it, &val); // can't fail
66 printf("%lld\n", (long long)val);
67 break;
68 }
69
Thiago Macieira2312efd2015-05-06 16:07:48 -070070 case CborByteStringType:
Thiago Macieira54a0e102015-05-05 21:25:06 -070071 case CborTextStringType: {
72 char *buf;
Thiago Macieira2312efd2015-05-06 16:07:48 -070073 size_t n;
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070074 err = cbor_value_dup_string(it, &buf, &n, it);
75 if (err)
76 return err; // parse error
Thiago Macieira2312efd2015-05-06 16:07:48 -070077 if (type == CborByteStringType) {
78 dumpbytes(buf, n);
79 puts("");
80 } else {
81 puts(buf);
82 }
Thiago Macieira54a0e102015-05-05 21:25:06 -070083 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");
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700107 break;
Thiago Macieira54a0e102015-05-05 21:25:06 -0700108
109 case CborBooleanType: {
110 bool val;
111 cbor_value_get_boolean(it, &val); // can't fail
112 puts(val ? "true" : "false");
113 break;
114 }
115
116 case CborDoubleType: {
117 double val;
118 if (false) {
119 float f;
120 case CborFloatType:
121 cbor_value_get_float(it, &f);
122 val = f;
123 } else {
124 cbor_value_get_double(it, &val);
125 }
126 printf("%g\n", val);
127 break;
128 }
129 case CborHalfFloatType: {
130 uint16_t val;
131 cbor_value_get_half_float(it, &val);
132 printf("__f16(%04x)\n", val);
133 break;
134 }
135
136 case CborInvalidType:
137 assert(false); // can't happen
138 break;
139 }
140
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700141 err = cbor_value_advance_fixed(it);
142 if (err)
143 return err;
Thiago Macieira54a0e102015-05-05 21:25:06 -0700144 }
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700145 return CborNoError;
Thiago Macieira54a0e102015-05-05 21:25:06 -0700146}
147
148int main(int argc, char **argv)
149{
150 if (argc == 1) {
151 puts("simplereader <filename>");
152 return 0;
153 }
154
155 size_t length;
156 char *buf = readfile(argv[1], &length);
157 if (!buf) {
158 perror("readfile");
159 return 1;
160 }
161
162 CborParser parser;
163 CborValue it;
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700164 CborError err = cbor_parser_init(buf, length, 0, &parser, &it);
165 if (!err)
166 err = dumprecursive(&it, 0);
Thiago Macieira54a0e102015-05-05 21:25:06 -0700167 free(buf);
168
Thiago Macieira54a0e102015-05-05 21:25:06 -0700169 if (err) {
170 fprintf(stderr, "CBOR parsing failure at offset %ld: %s\n",
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700171 it.ptr - buf, cbor_error_string(err));
Thiago Macieira54a0e102015-05-05 21:25:06 -0700172 return 1;
173 }
174 return 0;
175}