blob: 1f0099003a776a975308a96c2812311ffea44207 [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
Thiago Macieiraddd99e42016-04-12 10:30:30 -07009static uint8_t *readfile(const char *fname, size_t *size)
Thiago Macieira54a0e102015-05-05 21:25:06 -070010{
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;
Thiago Macieiraddd99e42016-04-12 10:30:30 -070017 uint8_t *buf = malloc(st.st_size);
Mahavir Jain7c349db2021-02-24 11:00:43 +053018 if (buf == NULL)
19 return NULL;
Svyatoslav Phirsov2b267842018-10-13 22:06:15 +030020 *size = fread(buf, st.st_size, 1, f) == 1 ? st.st_size : 0;
Thiago Macieira54a0e102015-05-05 21:25:06 -070021 fclose(f);
22 return buf;
23}
24
25static void indent(int nestingLevel)
26{
27 while (nestingLevel--)
28 puts(" ");
29}
30
Thiago Macieiraddd99e42016-04-12 10:30:30 -070031static void dumpbytes(const uint8_t *buf, size_t len)
Thiago Macieira54a0e102015-05-05 21:25:06 -070032{
33 while (len--)
Thiago Macieiraddd99e42016-04-12 10:30:30 -070034 printf("%02X ", *buf++);
Thiago Macieira54a0e102015-05-05 21:25:06 -070035}
36
Svyatoslav Phirsov1db99f92018-10-23 15:10:17 +030037static CborError dumprecursive(CborValue *it, int nestingLevel)
Thiago Macieira54a0e102015-05-05 21:25:06 -070038{
39 while (!cbor_value_at_end(it)) {
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070040 CborError err;
Thiago Macieira54a0e102015-05-05 21:25:06 -070041 CborType type = cbor_value_get_type(it);
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070042
43 indent(nestingLevel);
Thiago Macieira54a0e102015-05-05 21:25:06 -070044 switch (type) {
45 case CborArrayType:
46 case CborMapType: {
47 // recursive type
48 CborValue recursed;
Thiago Macieira2312efd2015-05-06 16:07:48 -070049 assert(cbor_value_is_container(it));
Thiago Macieira54a0e102015-05-05 21:25:06 -070050 puts(type == CborArrayType ? "Array[" : "Map[");
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070051 err = cbor_value_enter_container(it, &recursed);
52 if (err)
53 return err; // parse error
54 err = dumprecursive(&recursed, nestingLevel + 1);
55 if (err)
56 return err; // parse error
57 err = cbor_value_leave_container(it, &recursed);
58 if (err)
59 return err; // parse error
Thiago Macieira54a0e102015-05-05 21:25:06 -070060 indent(nestingLevel);
61 puts("]");
62 continue;
63 }
64
65 case CborIntegerType: {
66 int64_t val;
67 cbor_value_get_int64(it, &val); // can't fail
68 printf("%lld\n", (long long)val);
69 break;
70 }
71
Thiago Macieiraddd99e42016-04-12 10:30:30 -070072 case CborByteStringType: {
73 uint8_t *buf;
74 size_t n;
75 err = cbor_value_dup_byte_string(it, &buf, &n, it);
76 if (err)
77 return err; // parse error
78 dumpbytes(buf, n);
79 puts("");
80 free(buf);
81 continue;
82 }
83
Thiago Macieira54a0e102015-05-05 21:25:06 -070084 case CborTextStringType: {
85 char *buf;
Thiago Macieira2312efd2015-05-06 16:07:48 -070086 size_t n;
Thiago Macieiraddd99e42016-04-12 10:30:30 -070087 err = cbor_value_dup_text_string(it, &buf, &n, it);
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -070088 if (err)
89 return err; // parse error
Thiago Macieiraddd99e42016-04-12 10:30:30 -070090 puts(buf);
Thiago Macieira54a0e102015-05-05 21:25:06 -070091 free(buf);
92 continue;
93 }
94
95 case CborTagType: {
96 CborTag tag;
97 cbor_value_get_tag(it, &tag); // can't fail
98 printf("Tag(%lld)\n", (long long)tag);
99 break;
100 }
101
102 case CborSimpleType: {
103 uint8_t type;
104 cbor_value_get_simple_type(it, &type); // can't fail
105 printf("simple(%u)\n", type);
106 break;
107 }
108
109 case CborNullType:
110 puts("null");
111 break;
112
113 case CborUndefinedType:
114 puts("undefined");
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700115 break;
Thiago Macieira54a0e102015-05-05 21:25:06 -0700116
117 case CborBooleanType: {
118 bool val;
119 cbor_value_get_boolean(it, &val); // can't fail
120 puts(val ? "true" : "false");
121 break;
122 }
123
124 case CborDoubleType: {
125 double val;
126 if (false) {
127 float f;
128 case CborFloatType:
129 cbor_value_get_float(it, &f);
130 val = f;
131 } else {
132 cbor_value_get_double(it, &val);
133 }
134 printf("%g\n", val);
135 break;
136 }
137 case CborHalfFloatType: {
138 uint16_t val;
139 cbor_value_get_half_float(it, &val);
140 printf("__f16(%04x)\n", val);
141 break;
142 }
143
144 case CborInvalidType:
145 assert(false); // can't happen
146 break;
147 }
148
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700149 err = cbor_value_advance_fixed(it);
150 if (err)
151 return err;
Thiago Macieira54a0e102015-05-05 21:25:06 -0700152 }
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700153 return CborNoError;
Thiago Macieira54a0e102015-05-05 21:25:06 -0700154}
155
156int main(int argc, char **argv)
157{
158 if (argc == 1) {
159 puts("simplereader <filename>");
160 return 0;
161 }
162
163 size_t length;
Thiago Macieiraddd99e42016-04-12 10:30:30 -0700164 uint8_t *buf = readfile(argv[1], &length);
Thiago Macieira54a0e102015-05-05 21:25:06 -0700165 if (!buf) {
166 perror("readfile");
167 return 1;
168 }
169
170 CborParser parser;
171 CborValue it;
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700172 CborError err = cbor_parser_init(buf, length, 0, &parser, &it);
173 if (!err)
174 err = dumprecursive(&it, 0);
Thiago Macieira54a0e102015-05-05 21:25:06 -0700175 free(buf);
176
Thiago Macieira54a0e102015-05-05 21:25:06 -0700177 if (err) {
178 fprintf(stderr, "CBOR parsing failure at offset %ld: %s\n",
Thiago Macieiraa43a4ef2015-05-06 20:25:18 -0700179 it.ptr - buf, cbor_error_string(err));
Thiago Macieira54a0e102015-05-05 21:25:06 -0700180 return 1;
181 }
182 return 0;
183}