2 #include <dragonport/asprintf.h>
3 #include <dragontype/number.h>
8 #define FUNC "__attribute__((unused)) static inline "
10 static size_t split(char ***strs, char *s, const char *delim)
13 *strs = malloc((1+i) * sizeof(char *));
15 // Can't be allocated on the stack for some reason
16 char *str = malloc(1+strlen(s));
19 char *tok = strtok(str, delim);
21 *strs = realloc(*strs, (1+i) * sizeof(char *));
22 (*strs)[i++] = strdup(tok);
23 tok = strtok(NULL, delim);
30 static void free_split(char **strs, size_t n)
32 for (size_t i = 0; i < n; ++i)
38 #define INDENT for (size_t i = 0; i < lvls + 1; i++) fprintf(fp, "\t")
40 static char *process_array(FILE *fp, char *src)
45 char *str = malloc(1);
49 for (; *src != '\0'; src++) {
54 src += sscanf(src, "%lu", &arrlen);
56 INDENT; fprintf(fp, "for (size_t i%lu = 0; i%lu < %lu; i%lu++)\n", lvls, lvls, arrlen, lvls);
59 str = realloc(str, len += asprintf(&buf, "[i%lu]", lvls));
74 static void gen_serializers(FILE *c_fp)
76 for (u8 bits = 8; bits <= 64; bits *= 2) {
77 char *fmt_u = FUNC "void send_u%d(DragonnetPeer *p, bool submit, u%d v)\n";
78 char *fmt_s = FUNC "void send_s%d(DragonnetPeer *p, bool submit, s%d v)\n";
80 fprintf(c_fp, fmt_u, bits, bits);
82 fprintf(c_fp, "\tu%d be = htobe%d(v);\n", bits, bits);
83 fprintf(c_fp, "\tdragonnet_send_raw(p, submit, &be, sizeof be);\n");
84 fprintf(c_fp, "}\n\n");
86 fprintf(c_fp, fmt_s, bits, bits, "");
88 fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
89 fprintf(c_fp, "}\n\n");
92 char *fmt_f = FUNC "void send_f%d(DragonnetPeer *p, bool submit, f%d v)\n";
94 fprintf(c_fp, fmt_f, bits, bits);
96 fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
97 fprintf(c_fp, "}\n\n");
101 for (u8 elems = 2; elems <= 4; ++elems) {
102 for (u8 bits = 8; bits <= 64; bits *= 2) {
103 char *fmt_u = FUNC "void send_v%du%d(DragonnetPeer *p, bool submit, v%du%d v)\n";
104 char *fmt_s = FUNC "void send_v%ds%d(DragonnetPeer *p, bool submit, v%ds%d v)\n";
106 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
107 fprintf(c_fp, "{\n");
108 fprintf(c_fp, "\tu%d *ptr = &v.x;\n", bits);
109 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
110 fprintf(c_fp, "\t\tsend_u%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems);
111 fprintf(c_fp, "\t}\n");
112 fprintf(c_fp, "}\n\n");
114 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
115 fprintf(c_fp, "{\n");
116 fprintf(c_fp, "\ts%d *ptr = &v.x;\n", bits);
117 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
118 fprintf(c_fp, "\t\tsend_s%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems);
119 fprintf(c_fp, "\t}\n");
120 fprintf(c_fp, "}\n\n");
123 char *fmt_f = FUNC "void send_v%df%d(DragonnetPeer *p, bool submit, v%df%d v)\n";
125 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
126 fprintf(c_fp, "{\n");
127 fprintf(c_fp, "\tf%d *ptr = &v.x;\n", bits);
128 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
129 fprintf(c_fp, "\t\tsend_f%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems);
130 fprintf(c_fp, "\t}\n");
131 fprintf(c_fp, "}\n\n");
136 for (u8 elems = 2; elems <= 4; ++elems) {
137 for (u8 bits = 8; bits <= 64; bits *= 2) {
138 char *fmt_u = FUNC "void send_aabb%du%d(DragonnetPeer *p, bool submit, aabb%du%d v)\n";
139 char *fmt_s = FUNC "void send_aabb%ds%d(DragonnetPeer *p, bool submit, aabb%ds%d v)\n";
141 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
142 fprintf(c_fp, "{\n");
143 fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n", elems, bits);
144 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
145 fprintf(c_fp, "\t\tsend_v%du%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits);
146 fprintf(c_fp, "\t}\n");
147 fprintf(c_fp, "}\n\n");
149 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
150 fprintf(c_fp, "{\n");
151 fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n", elems, bits);
152 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
153 fprintf(c_fp, "\t\tsend_v%ds%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits);
154 fprintf(c_fp, "\t}\n");
155 fprintf(c_fp, "}\n\n");
158 char *fmt_f = FUNC "void send_aabb%df%d(DragonnetPeer *p, bool submit, aabb%df%d v)\n";
160 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
161 fprintf(c_fp, "{\n");
162 fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n", elems, bits);
163 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
164 fprintf(c_fp, "\t\tsend_v%df%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits);
165 fprintf(c_fp, "\t}\n");
166 fprintf(c_fp, "}\n\n");
171 fprintf(c_fp, FUNC "void send_string(DragonnetPeer *p, bool submit, string v)\n");
172 fprintf(c_fp, "{\n");
173 fprintf(c_fp, "\tdragonnet_send_raw(p, submit, v, strlen(v));\n");
174 fprintf(c_fp, "}\n\n");
176 fprintf(c_fp, FUNC "void send_Blob(DragonnetPeer *p, bool submit, Blob v)\n");
177 fprintf(c_fp, "{\n");
178 fprintf(c_fp, "\tsend_u32(p, false, v->siz);\n");
179 fprintf(c_fp, "\tdragonnet_send_raw(p, submit, v->data, v->siz);\n");
180 fprintf(c_fp, "}\n\n");
182 fprintf(c_fp, FUNC "void send_CompressedBlob(DragonnetPeer *p, bool submit, CompressedBlob v)\n\n");
183 fprintf(c_fp, "{\n");
184 fprintf(c_fp, "\tchar compr[2 + v->blob->siz];\n\n");
185 fprintf(c_fp, "\tz_stream s;\n");
186 fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
187 fprintf(c_fp , "\ts.zfree = Z_NULL;\n");
188 fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
189 fprintf(c_fp, "\ts.avail_in = v->blob->siz;\n");
190 fprintf(c_fp, "\ts.avail_out = 3 + v->blob->siz;\n");
191 fprintf(c_fp, "\ts.next_in = (Bytef *) v->blob->data;\n");
192 fprintf(c_fp, "\ts.next_out = (Bytef *) compr;\n\n");
193 fprintf(c_fp, "\tdeflateInit(&s, Z_BEST_COMPRESSION);\n");
194 fprintf(c_fp, "\tdeflate(&s, Z_FINISH);\n");
195 fprintf(c_fp, "\tdeflateEnd(&s);\n\n");
196 fprintf(c_fp, "\tv->siz = s.total_out;\n");
197 fprintf(c_fp, "\tsend_u32(p, false, v->siz);\n");
198 fprintf(c_fp, "\tsend_u32(p, false, v->blob->siz);\n");
199 fprintf(c_fp, "\tdragonnet_send_raw(p, submit, compr, v->siz);\n");
200 fprintf(c_fp, "}\n\n");
203 static void gen_deserializers(FILE *c_fp)
205 for (u8 bits = 8; bits <= 64; bits *= 2) {
206 char *fmt = FUNC "void recv_n%d(DragonnetPeer *p, void *buf)\n";
208 fprintf(c_fp, fmt, bits);
209 fprintf(c_fp, "{\n");
210 fprintf(c_fp, "\tu%d be;\n", bits);
211 fprintf(c_fp, "\tdragonnet_recv_raw(p, &be, sizeof be);\n");
212 fprintf(c_fp, "\tbe = be%dtoh(be);\n", bits);
213 fprintf(c_fp, "\tmemcpy(buf, &be, sizeof be);\n");
214 fprintf(c_fp, "}\n\n");
217 for (u8 elems = 2; elems <= 4; ++elems) {
218 for (u8 bits = 8; bits <= 64; bits *= 2) {
219 char *fmt = FUNC "void recv_v%dn%d(DragonnetPeer *p, void *buf)\n";
221 fprintf(c_fp, fmt, elems, bits);
222 fprintf(c_fp, "{\n");
223 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i)\n", elems);
224 fprintf(c_fp, "\t\trecv_n%d(p, buf);\n", bits);
225 fprintf(c_fp, "}\n\n");
229 for (u8 elems = 2; elems <= 4; ++elems) {
230 for (u8 bits = 8; bits <= 64; bits *= 2) {
231 char *fmt = FUNC "void recv_aabb%dn%d(DragonnetPeer *p, void *buf)\n";
233 fprintf(c_fp, fmt, elems, bits);
234 fprintf(c_fp, "{\n");
235 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i)\n");
236 fprintf(c_fp, "\t\trecv_v%dn%d(p, buf);\n", elems, bits);
237 fprintf(c_fp, "}\n\n");
241 fprintf(c_fp, FUNC "void recv_string(DragonnetPeer *p, void *buf)\n");
242 fprintf(c_fp, "{\n");
243 fprintf(c_fp, "\tstring v = malloc(1 + (1 << 16));\n\n");
244 fprintf(c_fp, "\tchar ch;\n");
245 fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n");
246 fprintf(c_fp, "\t\trecv_n8(p, &ch);\n");
247 fprintf(c_fp, "\t\tv[i] = ch;\n");
248 fprintf(c_fp, "\t}\n\n");
249 fprintf(c_fp, "\tv = realloc(v, strlen(v));\n");
250 fprintf(c_fp, "\tmemcpy(buf, v, strlen(v));\n");
251 fprintf(c_fp, "}\n\n");
253 fprintf(c_fp, FUNC "void recv_Blob(DragonnetPeer *p, void *buf)\n");
254 fprintf(c_fp, "{\n");
255 fprintf(c_fp, "\tBlob v = (Blob) buf;\n");
256 fprintf(c_fp, "\trecv_n32(p, &v->siz);\n");
257 fprintf(c_fp, "\tv->data = malloc(v->siz);\n");
258 fprintf(c_fp, "\tdragonnet_recv_raw(p, v->data, v->siz);\n\n");
259 fprintf(c_fp, "\tmemcpy(buf, v, v->siz + sizeof v);\n");
260 fprintf(c_fp, "}\n\n");
262 fprintf(c_fp, FUNC "void recv_CompressedBlob(DragonnetPeer *p, void *buf)\n");
263 fprintf(c_fp, "{\n");
264 fprintf(c_fp, "\tCompressedBlob v = *(CompressedBlob *) buf;\n");
265 fprintf(c_fp, "\tv->blob = malloc(sizeof *v->blob);\n\n");
266 fprintf(c_fp, "\trecv_n32(p, &v->siz);\n");
267 fprintf(c_fp, "\trecv_n32(p, &v->blob->siz);\n");
268 fprintf(c_fp, "\tv->blob->data = malloc(v->blob->siz);\n\n");
269 fprintf(c_fp, "\tchar compr[v->siz];\n");
270 fprintf(c_fp, "\tdragonnet_recv_raw(p, compr, sizeof compr);\n\n");
271 fprintf(c_fp, "\tz_stream s;\n");
272 fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
273 fprintf(c_fp, "\ts.zfree = Z_NULL;\n");
274 fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
275 fprintf(c_fp, "\ts.avail_in = v->siz;\n");
276 fprintf(c_fp, "\ts.next_in = (Bytef *) compr;\n");
277 fprintf(c_fp, "\ts.avail_out = v->blob->siz;\n");
278 fprintf(c_fp, "\ts.next_out = (Bytef *) v->blob->data;\n\n");
279 fprintf(c_fp, "\tinflateInit(&s);\n");
280 fprintf(c_fp, "\tinflate(&s, Z_NO_FLUSH);\n");
281 fprintf(c_fp, "\tinflateEnd(&s);\n");
282 fprintf(c_fp, "}\n\n");
287 static void gen_buffer_serializers(FILE *c_fp)
289 for (u8 bits = 8; bits <= 64; bits *= 2) {
290 char *fmt_u = FUNC "void buf_write_u%d(u8 **buf, size_t *n, u%d v)\n";
291 char *fmt_s = FUNC "void buf_write_s%d(u8 **buf, size_t *n, s%d v)\n";
293 fprintf(c_fp, fmt_u, bits, bits);
294 fprintf(c_fp, "{\n");
295 fprintf(c_fp, "\tu%d be = htobe%d(v);\n", bits, bits);
296 fprintf(c_fp, "\tdragonnet_write_raw(buf, n, &be, sizeof be);\n");
297 fprintf(c_fp, "}\n\n");
299 fprintf(c_fp, fmt_s, bits, bits, "");
300 fprintf(c_fp, "{\n");
301 fprintf(c_fp, "\tbuf_write_u%d(buf, n, (u%d) v);\n", bits, bits);
302 fprintf(c_fp, "}\n\n");
305 char *fmt_f = FUNC "void buf_write_f%d(u8 **buf, size_t *n, f%d v)\n";
307 fprintf(c_fp, fmt_f, bits, bits);
308 fprintf(c_fp, "{\n");
309 fprintf(c_fp, "\tbuf_write_u%d(buf, n, (u%d) v);\n", bits, bits);
310 fprintf(c_fp, "}\n\n");
314 for (u8 elems = 2; elems <= 4; ++elems) {
315 for (u8 bits = 8; bits <= 64; bits *= 2) {
316 char *fmt_u = FUNC "void buf_write_v%du%d(u8 **buf, size_t *n, v%du%d v)\n";
317 char *fmt_s = FUNC "void buf_write_v%ds%d(u8 **buf, size_t *n, v%ds%d v)\n";
319 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
320 fprintf(c_fp, "{\n");
321 fprintf(c_fp, "\tu%d *ptr = &v.x;\n", bits);
322 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
323 fprintf(c_fp, "\t\tbuf_write_u%d(buf, n, *ptr++);\n", bits);
324 fprintf(c_fp, "\t}\n");
325 fprintf(c_fp, "}\n\n");
327 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
328 fprintf(c_fp, "{\n");
329 fprintf(c_fp, "\ts%d *ptr = &v.x;\n", bits);
330 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
331 fprintf(c_fp, "\t\tbuf_write_s%d(buf, n, *ptr++);\n", bits);
332 fprintf(c_fp, "\t}\n");
333 fprintf(c_fp, "}\n\n");
336 char *fmt_f = FUNC "void buf_write_v%df%d(u8 **buf, size_t *n, v%df%d v)\n";
338 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
339 fprintf(c_fp, "{\n");
340 fprintf(c_fp, "\tf%d *ptr = &v.x;\n", bits);
341 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
342 fprintf(c_fp, "\t\tbuf_write_f%d(buf, n, *ptr++);\n", bits);
343 fprintf(c_fp, "\t}\n");
344 fprintf(c_fp, "}\n\n");
349 for (u8 elems = 2; elems <= 4; ++elems) {
350 for (u8 bits = 8; bits <= 64; bits *= 2) {
351 char *fmt_u = FUNC "void buf_write_aabb%du%d(u8 **buf, size_t *n, aabb%du%d v)\n";
352 char *fmt_s = FUNC "void buf_write_aabb%ds%d(u8 **buf, size_t *n, aabb%ds%d v)\n";
354 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
355 fprintf(c_fp, "{\n");
356 fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n", elems, bits);
357 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
358 fprintf(c_fp, "\t\tbuf_write_v%du%d(buf, n, *ptr++);\n", elems, bits);
359 fprintf(c_fp, "\t}\n");
360 fprintf(c_fp, "}\n\n");
362 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
363 fprintf(c_fp, "{\n");
364 fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n", elems, bits);
365 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
366 fprintf(c_fp, "\t\tbuf_write_v%ds%d(buf, n, *ptr++);\n", elems, bits);
367 fprintf(c_fp, "\t}\n");
368 fprintf(c_fp, "}\n\n");
371 char *fmt_f = FUNC "void buf_write_aabb%df%d(u8 **buf, size_t *n, aabb%df%d v)\n";
373 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
374 fprintf(c_fp, "{\n");
375 fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n", elems, bits);
376 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
377 fprintf(c_fp, "\t\tbuf_write_v%df%d(buf, n, *ptr++);\n", elems, bits);
378 fprintf(c_fp, "\t}\n");
379 fprintf(c_fp, "}\n\n");
384 fprintf(c_fp, FUNC "void buf_write_string(u8 **buf, size_t *n, string v)\n");
385 fprintf(c_fp, "{\n");
386 fprintf(c_fp, "\tdragonnet_write_raw(buf, n, v, strlen(v));\n");
387 fprintf(c_fp, "}\n\n");
389 fprintf(c_fp, FUNC "void buf_write_Blob(u8 **buf, size_t *n, Blob v)\n\n");
390 fprintf(c_fp, "{\n");
391 fprintf(c_fp, "\tbuf_write_u32(buf, n, v->siz);\n");
392 fprintf(c_fp, "\tdragonnet_write_raw(buf, n, v->data, v->siz);\n");
393 fprintf(c_fp, "}\n\n");
395 fprintf(c_fp, FUNC "void buf_write_CompressedBlob(u8 **buf, size_t *n, CompressedBlob v)\n\n");
396 fprintf(c_fp, "{\n");
397 fprintf(c_fp, "\tchar compr[2 + v->blob->siz];\n\n");
398 fprintf(c_fp, "\tz_stream s;\n");
399 fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
400 fprintf(c_fp , "\ts.zfree = Z_NULL;\n");
401 fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
402 fprintf(c_fp, "\ts.avail_in = v->blob->siz;\n");
403 fprintf(c_fp, "\ts.avail_out = 3 + v->blob->siz;\n");
404 fprintf(c_fp, "\ts.next_in = (Bytef *) v->blob->data;\n");
405 fprintf(c_fp, "\ts.next_out = (Bytef *) compr;\n\n");
406 fprintf(c_fp, "\tdeflateInit(&s, Z_BEST_COMPRESSION);\n");
407 fprintf(c_fp, "\tdeflate(&s, Z_FINISH);\n");
408 fprintf(c_fp, "\tdeflateEnd(&s);\n\n");
409 fprintf(c_fp, "\tv->siz = s.total_out;\n");
410 fprintf(c_fp, "\tbuf_write_u32(buf, n, v->siz);\n");
411 fprintf(c_fp, "\tbuf_write_u32(buf, n, v->blob->siz);\n");
412 fprintf(c_fp, "\tdragonnet_write_raw(buf, n, compr, v->siz);\n");
413 fprintf(c_fp, "}\n\n");
416 static void gen_buffer_deserializers(FILE *c_fp)
418 for (u8 bits = 8; bits <= 64; bits *= 2) {
419 char *fmt_u = FUNC "u%d buf_read_u%d(u8 **buf, size_t *n)\n";
420 char *fmt_s = FUNC "s%d buf_read_s%d(u8 **buf, size_t *n)\n";
422 fprintf(c_fp, fmt_u, bits, bits);
423 fprintf(c_fp, "{\n");
424 fprintf(c_fp, "\tu%d be;\n", bits);
425 fprintf(c_fp, "\tdragonnet_read_raw(buf, n, &be, sizeof be);\n");
426 fprintf(c_fp, "\treturn be%dtoh(be);\n", bits);
427 fprintf(c_fp, "}\n\n");
429 fprintf(c_fp, fmt_s, bits, bits);
430 fprintf(c_fp, "{\n");
431 fprintf(c_fp, "\treturn (s%d) buf_read_u%d(buf, n);\n", bits, bits);
432 fprintf(c_fp, "}\n\n");
435 char *fmt_f = FUNC "f%d buf_read_f%d(u8 **buf, size_t *n)\n";
437 fprintf(c_fp, fmt_f, bits, bits);
438 fprintf(c_fp, "{\n");
439 fprintf(c_fp, "\treturn (f%d) buf_read_u%d(buf, n);\n", bits, bits);
440 fprintf(c_fp, "}\n\n");
444 for (u8 elems = 2; elems <= 4; ++elems) {
445 for (u8 bits = 8; bits <= 64; bits *= 2) {
446 char *fmt_u = FUNC "v%du%d buf_read_v%du%d(u8 **buf, size_t *n)\n";
447 char *fmt_s = FUNC "v%ds%d buf_read_v%ds%d(u8 **buf, size_t *n)\n";
449 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
450 fprintf(c_fp, "{\n");
451 fprintf(c_fp, "\tv%du%d v = {0};\n", elems, bits);
452 fprintf(c_fp, "\tu%d *ptr = &v.x;\n\n", bits);
453 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
454 fprintf(c_fp, "\t\t*ptr++ = buf_read_u%d(buf, n);\n", bits);
455 fprintf(c_fp, "\t}\n\n");
456 fprintf(c_fp, "\treturn v;\n");
457 fprintf(c_fp, "}\n\n");
459 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
460 fprintf(c_fp, "{\n");
461 fprintf(c_fp, "\tv%ds%d v = {0};\n", elems, bits);
462 fprintf(c_fp, "\ts%d *ptr = &v.x;\n\n", bits);
463 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
464 fprintf(c_fp, "\t\t*ptr++ = buf_read_s%d(buf, n);\n", bits);
465 fprintf(c_fp, "\t}\n\n");
466 fprintf(c_fp, "\treturn v;\n");
467 fprintf(c_fp, "}\n\n");
470 char *fmt_f = FUNC "v%df%d buf_read_v%df%d(u8 **buf, size_t *n)\n";
472 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
473 fprintf(c_fp, "{\n");
474 fprintf(c_fp, "\tv%df%d v = {0};\n", elems, bits);
475 fprintf(c_fp, "\tf%d *ptr = &v.x;\n\n", bits);
476 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
477 fprintf(c_fp, "\t\t*ptr++ = buf_read_f%d(buf, n);\n", bits);
478 fprintf(c_fp, "\t}\n\n");
479 fprintf(c_fp, "\treturn v;\n");
480 fprintf(c_fp, "}\n\n");
485 for (u8 elems = 2; elems <= 4; ++elems) {
486 for (u8 bits = 8; bits <= 64; bits *= 2) {
487 char *fmt_u = FUNC "aabb%du%d buf_read_aabb%du%d(u8 **buf, size_t *n)\n";
488 char *fmt_s = FUNC "aabb%ds%d buf_read_aabb%ds%d(u8 **buf, size_t *n)\n";
490 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
491 fprintf(c_fp, "{\n");
492 fprintf(c_fp, "\taabb%du%d v = {0};\n", elems, bits);
493 fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n\n", elems, bits);
494 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
495 fprintf(c_fp, "\t\t*ptr++ = buf_read_v%du%d(buf, n);\n", elems, bits);
496 fprintf(c_fp, "\t}\n\n");
497 fprintf(c_fp, "\treturn v;\n");
498 fprintf(c_fp, "}\n\n");
500 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
501 fprintf(c_fp, "{\n");
502 fprintf(c_fp, "\taabb%ds%d v = {0};\n", elems, bits);
503 fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n\n", elems, bits);
504 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
505 fprintf(c_fp, "\t\t*ptr++ = buf_read_v%ds%d(buf, n);\n", elems, bits);
506 fprintf(c_fp, "\t}\n\n");
507 fprintf(c_fp, "\treturn v;\n");
508 fprintf(c_fp, "}\n\n");
511 char *fmt_f = FUNC "aabb%df%d buf_read_aabb%df%d(u8 **buf, size_t *n)\n";
513 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
514 fprintf(c_fp, "{\n");
515 fprintf(c_fp, "\taabb%df%d v = {0};\n", elems, bits);
516 fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n\n", elems, bits);
517 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
518 fprintf(c_fp, "\t\t*ptr++ = buf_read_v%df%d(buf, n);\n", elems, bits);
519 fprintf(c_fp, "\t}\n\n");
520 fprintf(c_fp, "\treturn v;\n");
521 fprintf(c_fp, "}\n\n");
526 fprintf(c_fp, FUNC "string buf_read_string(u8 **buf, size_t *n)\n");
527 fprintf(c_fp, "{\n");
528 fprintf(c_fp, "\tstring v = malloc(sizeof(u16));\n\n");
529 fprintf(c_fp, "\tchar ch;\n");
530 fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n");
531 fprintf(c_fp, "\t\tch = buf_read_s8(buf, n);\n");
532 fprintf(c_fp, "\t\tv[i] = ch;\n");
533 fprintf(c_fp, "\t}\n\n");
534 fprintf(c_fp, "\tv = realloc(v, strlen(v));\n");
535 fprintf(c_fp, "\treturn v;\n");
536 fprintf(c_fp, "}\n\n");
538 fprintf(c_fp, FUNC "Blob buf_read_Blob(u8 **buf, size_t *n)\n");
539 fprintf(c_fp, "{\n");
540 fprintf(c_fp, "\tBlob v = malloc(sizeof *v);\n");
541 fprintf(c_fp, "\tv->siz = buf_read_u32(buf, n);\n");
542 fprintf(c_fp, "\tv->data = malloc(v->siz);\n");
543 fprintf(c_fp, "\tdragonnet_read_raw(buf, n, v->data, v->siz);\n\n");
544 fprintf(c_fp, "\treturn v;\n");
545 fprintf(c_fp, "}\n\n");
547 fprintf(c_fp, FUNC "CompressedBlob buf_read_CompressedBlob(u8 **buf, size_t *n)\n");
548 fprintf(c_fp, "{\n");
549 fprintf(c_fp, "\tCompressedBlob v = malloc(sizeof *v);\n");
550 fprintf(c_fp, "\tv->blob = malloc(sizeof *v->blob);\n\n");
551 fprintf(c_fp, "\tv->siz = buf_read_u32(buf, n);\n");
552 fprintf(c_fp, "\tv->blob->siz = buf_read_u32(buf, n);\n");
553 fprintf(c_fp, "\tv->blob->data = malloc(v->blob->siz);\n\n");
554 fprintf(c_fp, "\tchar compr[v->siz];\n");
555 fprintf(c_fp, "\tdragonnet_read_raw(buf, n, compr, sizeof compr);\n\n");
556 fprintf(c_fp, "\tz_stream s;\n");
557 fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
558 fprintf(c_fp, "\ts.zfree = Z_NULL;\n");
559 fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
560 fprintf(c_fp, "\ts.avail_in = v->siz;\n");
561 fprintf(c_fp, "\ts.next_in = (Bytef *) compr;\n");
562 fprintf(c_fp, "\ts.avail_out = v->blob->siz;\n");
563 fprintf(c_fp, "\ts.next_out = (Bytef *) v->blob->data;\n\n");
564 fprintf(c_fp, "\tinflateInit(&s);\n");
565 fprintf(c_fp, "\tinflate(&s, Z_NO_FLUSH);\n");
566 fprintf(c_fp, "\tinflateEnd(&s);\n\n");
567 fprintf(c_fp, "\treturn v;\n");
568 fprintf(c_fp, "}\n\n");
571 int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
573 FILE *fp = fopen("types.dnet", "r");
576 memset(data, '\0', sizeof data);
577 fread(data, sizeof *data, sizeof data, fp);
582 FILE *c_fp = fopen("dnet-types.c", "w");
583 fprintf(c_fp, "/*\n");
584 fprintf(c_fp, "\tThis file was automatically generated by Dragonnet.\n");
585 fprintf(c_fp, "\tDo NOT edit it manually. Instead, edit types.dnet and re-run DragonnetTypegen.\n");
586 fprintf(c_fp, "*/\n\n");
587 fprintf(c_fp, "#include <dragonnet/recv.h>\n");
588 fprintf(c_fp, "#include <dragonnet/send.h>\n");
589 fprintf(c_fp, "#include <endian.h/endian.h>\n");
590 fprintf(c_fp, "#include <stdbool.h>\n");
591 fprintf(c_fp, "#include <stdlib.h>\n");
592 fprintf(c_fp, "#include <string.h>\n");
593 fprintf(c_fp, "#include <zlib.h>\n\n");
594 fprintf(c_fp, "#define htobe8(x) (x)\n");
595 fprintf(c_fp, "#define be8toh(x) (x)\n\n");
596 fprintf(c_fp, "#include \"dnet-types.h\"\n\n");
598 FILE *h_fp = fopen("dnet-types.h", "w");
599 fprintf(h_fp, "/*\n");
600 fprintf(h_fp, "\tThis file was automatically generated by Dragonnet.\n");
601 fprintf(h_fp, "\tDo NOT edit it manually. Instead, edit types.dnet and re-run DragonnetTypegen.\n");
602 fprintf(h_fp, "*/\n\n");
603 fprintf(h_fp, "#include <dragonnet/peer.h>\n");
604 fprintf(h_fp, "#include <dragontype/number.h>\n");
605 fprintf(h_fp, "#include <stddef.h>\n");
606 fprintf(h_fp, "typedef char *string;\n\n");
607 fprintf(h_fp, "typedef struct {\n\tu32 siz;\n\tu8 *data;\n} *Blob;\n\n");
608 fprintf(h_fp, "typedef struct {\n");
609 fprintf(h_fp, "\tu32 siz;\n");
610 fprintf(h_fp, "\tBlob blob;\n");
611 fprintf(h_fp, "} *CompressedBlob;\n\n");
613 gen_serializers(c_fp);
614 gen_deserializers(c_fp);
616 gen_buffer_serializers(c_fp);
617 gen_buffer_deserializers(c_fp);
620 size_t msgs_len = split(&msgs, data, "\n");
624 for (size_t i = 0; i < msgs_len; ++i) {
625 if (msgs[i][0] != '\t') {
627 fprintf(h_fp, "} %s;\n\n", msg);
630 fprintf(h_fp, "typedef struct {\n");
633 size_t tokens_len = split(&tokens, msgs[i], " ");
635 fprintf(h_fp, "\t%s %s;\n", &tokens[0][1], tokens[1]);
636 free_split(tokens, tokens_len);
641 fprintf(h_fp, "} %s;\n\n", msg);
644 // Create (de)serialization functions
645 for (size_t i = 0; i < msgs_len; ++i) {
646 if (msgs[i][0] != '\t') {
648 fprintf(c_fp, "}\n\n");
651 fprintf(c_fp, FUNC "void send_%s(DragonnetPeer *p, bool submit, %s type)\n{\n", msg, msg);
654 size_t tokens_len = split(&tokens, msgs[i], " ");
656 char *arr = process_array(c_fp, tokens[1]);
657 fprintf(c_fp, "send_%s(p, %s, type.%s%s);\n", &tokens[0][1], (i == msgs_len - 1 || msgs[i + 1][0] != '\t') ? "submit" : "false", tokens[1], arr);
660 free_split(tokens, tokens_len);
665 fprintf(c_fp, "}\n\n");
668 for (size_t i = 0; i < msgs_len; ++i) {
669 if (msgs[i][0] != '\t') {
671 fprintf(c_fp, "}\n\n");
674 fprintf(h_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s *type);\n", msg, msg);
675 fprintf(c_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s *type)\n{\n", msg, msg);
677 char upper[1 + strlen(msgs[i])];
681 while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
684 fprintf(c_fp, "\tsend_u16(p, false, DRAGONNET_TYPE_%s);\n", upper);
687 size_t tokens_len = split(&tokens, msgs[i], " ");
689 char *arr = process_array(c_fp, tokens[1]);
690 if (i >= msgs_len-1 || msgs[1+i][0] != '\t')
691 fprintf(c_fp, "send_%s(p, true, type->%s%s);\n", &tokens[0][1], tokens[1], arr);
693 fprintf(c_fp, "send_%s(p, false, type->%s%s);\n", &tokens[0][1], tokens[1], arr);
696 free_split(tokens, tokens_len);
701 fprintf(c_fp, "}\n\n");
704 for (size_t i = 0; i < msgs_len; ++i) {
705 if (msgs[i][0] != '\t') {
707 fprintf(c_fp, "}\n\n");
711 fprintf(c_fp, FUNC "void dragonnet_peer_recv_%s(DragonnetPeer *p, void *buf)\n{\n", msg);
712 fprintf(c_fp, "\t%s *type = (%s *) buf;\n", msg, msg);
715 size_t tokens_len = split(&tokens, msgs[i], " ");
717 char type[strlen(&tokens[0][1])];
718 strcpy(type, &tokens[0][1]);
720 for (char *tptr = type; *tptr != '\0'; tptr++) {
721 for (size_t bits = 8; bits <= 64; bits *= 2) {
722 const char *fmt[] = {"u%d", "s%d", "f%d"};
723 for (size_t j = 0; j < sizeof fmt / sizeof *fmt; ++j) {
725 asprintf(&cmp, fmt[j], bits);
726 size_t diff = strcmp(tptr, cmp);
730 sprintf(tptr, "n%ld", bits);
739 char *arr = process_array(c_fp, tokens[1]);
740 fprintf(c_fp, "recv_%s(p, &type->%s%s);\n", type, tokens[1], arr);
743 free_split(tokens, tokens_len);
748 fprintf(c_fp, "}\n\n");
751 // Buffer (de)serialization
752 for (size_t i = 0; i < msgs_len; ++i) {
753 if (msgs[i][0] != '\t') {
755 fprintf(c_fp, "}\n\n");
758 fprintf(c_fp, "void dragonnet_buf_write_%s(u8 **buf, size_t *n, %s type)\n{\n", msg, msg);
761 size_t tokens_len = split(&tokens, msgs[i], " ");
763 char *arr = process_array(c_fp, tokens[1]);
764 fprintf(c_fp, "buf_write_%s(buf, n, type.%s%s);\n", &tokens[0][1], tokens[1], arr);
767 free_split(tokens, tokens_len);
772 fprintf(c_fp, "}\n\n");
775 for (size_t i = 0; i < msgs_len; ++i) {
776 if (msgs[i][0] != '\t') {
778 fprintf(c_fp, "\treturn type;\n");
779 fprintf(c_fp, "}\n\n");
783 fprintf(h_fp, "%s dragonnet_buf_read_%s(u8 **buf, size_t *n);\n", msg, msg);
784 fprintf(c_fp, "%s dragonnet_buf_read_%s(u8 **buf, size_t *n)\n{\n", msg, msg);
785 fprintf(c_fp, "\t%s type = {0};\n", msg);
788 size_t tokens_len = split(&tokens, msgs[i], " ");
790 char *arr = process_array(c_fp, tokens[1]);
791 fprintf(c_fp, "type.%s%s = buf_read_%s(buf, n);\n", tokens[1], arr, &tokens[0][1]);
794 free_split(tokens, tokens_len);
800 fprintf(c_fp, "\treturn type;\n");
801 fprintf(c_fp, "}\n\n");
805 fprintf(h_fp, "typedef enum {\n");
806 for (size_t i = 0; i < msgs_len; ++i) {
807 if (msgs[i][0] == '\t')
810 char upper[1 + strlen(msgs[i])];
812 strcpy(upper, msgs[i]);
814 while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
817 fprintf(h_fp, "\tDRAGONNET_TYPE_%s,\n", upper);
820 fprintf(h_fp, "\tDRAGONNET_NUM_TYPES\n");
821 fprintf(h_fp, "} DragonnetTypeNum;\n");
824 fprintf(c_fp, "u16 dragonnet_num_types = DRAGONNET_NUM_TYPES;\n");
825 fprintf(c_fp, "DragonnetType dragonnet_types[] = {\n");
827 for (size_t i = 0; i < msgs_len; ++i) {
828 if (msgs[i][0] == '\t')
831 fprintf(c_fp, "\t{\n");
832 fprintf(c_fp, "\t\t.siz = sizeof(%s),\n", msgs[i]);
833 fprintf(c_fp, "\t\t.deserialize = &dragonnet_peer_recv_%s\n", msgs[i]);
834 fprintf(c_fp, "\t},\n");
837 fprintf(c_fp, "};\n");
839 free_split(msgs, msgs_len);