From 7f25c3510e1865a9200bd54293303c97e36cb700 Mon Sep 17 00:00:00 2001 From: HimbeerserverDE Date: Tue, 5 Oct 2021 23:42:47 +0200 Subject: [PATCH] Add full (de)serializer generator --- recv.c | 60 +---------- recv.h | 12 +-- send.c | 57 +--------- send.h | 12 +-- typegen/main.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 290 insertions(+), 136 deletions(-) diff --git a/recv.c b/recv.c index 9276020..e4ed1df 100644 --- a/recv.c +++ b/recv.c @@ -1,6 +1,6 @@ #include -static void rcv(DragonnetPeer *p, const void *buf, size_t n) +void recv_raw(DragonnetPeer *p, const void *buf, size_t n) { pthread_rwlock_rdlock(&p->mu); int sock = p->sock; @@ -24,61 +24,3 @@ static void rcv(DragonnetPeer *p, const void *buf, size_t n) pthread_rwlock_unlock(&p->mu); } } - -u8 recv_u8(DragonnetPeer *p) -{ - u8 v; - rcv(p, &v, sizeof v); - return v; -} - -s8 recv_s8(DragonnetPeer *p) -{ - return (s8) recv_u8(p); -} - -u16 recv_u16(DragonnetPeer *p) -{ - u16 be; - rcv(p, &be, sizeof be); - return be16toh(be); -} - -s16 recv_s16(DragonnetPeer *p) -{ - return (s16) recv_u16(p); -} - -u32 recv_u32(DragonnetPeer *p) -{ - u32 be; - rcv(p, &be, sizeof be); - return be32toh(be); -} - -s32 recv_s32(DragonnetPeer *p) -{ - return (s32) recv_u32(p); -} - -u64 recv_u64(DragonnetPeer *p) -{ - u64 be; - rcv(p, &be, sizeof be); - return be64toh(be); -} - -s64 recv_s64(DragonnetPeer *p) -{ - return (s64) recv_u64(p); -} - -f32 recv_f32(DragonnetPeer *p) -{ - return (f32) recv_u32(p); -} - -f64 recv_f64(DragonnetPeer *p) -{ - return (f64) recv_u64(p); -} diff --git a/recv.h b/recv.h index 748ec5f..61ddc86 100644 --- a/recv.h +++ b/recv.h @@ -1,18 +1,8 @@ #ifndef _DRAGONNET_RECV_H_ #define _DRAGONNET_RECV_H_ -#include #include -u8 recv_u8(DragonnetPeer *p); -s8 recv_s8(DragonnetPeer *p); -u16 recv_u16(DragonnetPeer *p); -s16 recv_s16(DragonnetPeer *p); -u32 recv_u32(DragonnetPeer *p); -s32 recv_s32(DragonnetPeer *p); -u64 recv_u64(DragonnetPeer *p); -s64 recv_s64(DragonnetPeer *p); -f32 recv_f32(DragonnetPeer *p); -f64 recv_f64(DragonnetPeer *p); +void recv_raw(DragonnetPeer *p, const void *buf, size_t n); #endif diff --git a/send.c b/send.c index b28625b..89408e4 100644 --- a/send.c +++ b/send.c @@ -3,13 +3,13 @@ #include -static void snd(DragonnetPeer *p, bool confirm, const void *buf, size_t n) +void send_raw(DragonnetPeer *p, bool submit, const void *buf, size_t n) { pthread_rwlock_rdlock(&p->mu); int sock = p->sock; pthread_rwlock_unlock(&p->mu); - ssize_t len = send(sock, buf, n, MSG_NOSIGNAL | (confirm ? 0 : MSG_MORE)); + ssize_t len = send(sock, buf, n, MSG_NOSIGNAL | (submit ? 0 : MSG_MORE)); if (len < 0) { if (errno == EPIPE) { dragonnet_peer_close(p); @@ -20,56 +20,3 @@ static void snd(DragonnetPeer *p, bool confirm, const void *buf, size_t n) dragonnet_peer_delete(p); } } - -void send_u8(DragonnetPeer *p, bool confirm, u8 v) -{ - snd(p, confirm, &v, sizeof v); -} - -void send_s8(DragonnetPeer *p, bool confirm, s8 v) -{ - send_u8(p, confirm, (u8) v); -} - -void send_u16(DragonnetPeer *p, bool confirm, u16 v) -{ - u16 be = htobe16(v); - snd(p, confirm, &be, sizeof be); -} - -void send_s16(DragonnetPeer *p, bool confirm, s16 v) -{ - send_u16(p, confirm, (u16) v); -} - -void send_u32(DragonnetPeer *p, bool confirm, u32 v) -{ - u32 be = htobe32(v); - snd(p, confirm, &be, sizeof be); -} - -void send_s32(DragonnetPeer *p, bool confirm, s32 v) -{ - send_u32(p, confirm, (u32) v); -} - -void send_u64(DragonnetPeer *p, bool confirm, u64 v) -{ - u64 be = htobe64(v); - snd(p, confirm, &be, sizeof be); -} - -void send_s64(DragonnetPeer *p, bool confirm, s64 v) -{ - send_u64(p, confirm, (u64) v); -} - -void send_f32(DragonnetPeer *p, bool confirm, f32 v) -{ - send_u32(p, confirm, (u32) v); -} - -void send_f64(DragonnetPeer *p, bool confirm, f64 v) -{ - send_u64(p, confirm, (u64) v); -} diff --git a/send.h b/send.h index c37c420..0a3a8b1 100644 --- a/send.h +++ b/send.h @@ -3,18 +3,8 @@ #include -#include #include -void send_u8(DragonnetPeer *p, bool confirm, u8 v); -void send_s8(DragonnetPeer *p, bool confirm, s8 v); -void send_u16(DragonnetPeer *p, bool confirm, u16 v); -void send_s16(DragonnetPeer *p, bool confirm, s16 v); -void send_u32(DragonnetPeer *p, bool confirm, u32 v); -void send_s32(DragonnetPeer *p, bool confirm, s32 v); -void send_u64(DragonnetPeer *p, bool confirm, u64 v); -void send_s64(DragonnetPeer *p, bool confirm, s64 v); -void send_f32(DragonnetPeer *p, bool confirm, f32 v); -void send_f64(DragonnetPeer *p, bool confirm, f64 v); +void send_raw(DragonnetPeer *p, bool submit, const void *buf, size_t n); #endif diff --git a/typegen/main.c b/typegen/main.c index 86cc706..cbaa111 100644 --- a/typegen/main.c +++ b/typegen/main.c @@ -32,6 +32,286 @@ static void free_split(char **strs, size_t n) free(strs); } +static void gen_serializers(FILE *c_fp, FILE *h_fp) +{ + fprintf(h_fp, "typedef char *string;\n"); + fprintf(h_fp, "typedef struct {\n\tu32 siz;\n\tu8 *data;\n} Blob;\n\n"); + + for (u8 bits = 8; bits <= 64; bits *= 2) { + char *fmt_u = "void send_u%d(DragonnetPeer *p, bool submit, u%d v)%s\n"; + char *fmt_s = "void send_s%d(DragonnetPeer *p, bool submit, s%d v)%s\n"; + + fprintf(h_fp, fmt_u, bits, bits, ";"); + fprintf(h_fp, fmt_s, bits, bits, ";"); + + fprintf(c_fp, fmt_u, bits, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tu%d be = htobe%d(v);\n", bits, bits); + fprintf(c_fp, "\tsend_raw(p, submit, &be, sizeof be);\n"); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_s, bits, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits); + fprintf(c_fp, "}\n\n"); + + if (bits >= 32) { + char *fmt_f = "void send_f%d(DragonnetPeer *p, bool submit, f%d v)%s\n"; + fprintf(h_fp, fmt_f, bits, bits, ";"); + + fprintf(c_fp, fmt_f, bits, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits); + fprintf(c_fp, "}\n\n"); + } + } + + fprintf(h_fp, "\n"); + + for (u8 elems = 2; elems <= 4; ++elems) { + for (u8 bits = 8; bits <= 64; bits *= 2) { + char *fmt_u = "void send_v%du%d(DragonnetPeer *p, bool submit, v%du%d v)%s\n"; + char *fmt_s = "void send_v%ds%d(DragonnetPeer *p, bool submit, v%ds%d v)%s\n"; + + fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";"); + fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_u, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); + fprintf(c_fp, "\t\tsend_u%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems); + fprintf(c_fp, "\t}\n"); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_s, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); + fprintf(c_fp, "\t\tsend_s%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems); + fprintf(c_fp, "\t}\n"); + fprintf(c_fp, "}\n\n"); + + if (bits >= 32) { + char *fmt_f = "void send_v%df%d(DragonnetPeer *p, bool submit, v%df%d v)%s\n"; + fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_f, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); + fprintf(c_fp, "\t\tsend_s%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems); + fprintf(c_fp, "\t}\n"); + fprintf(c_fp, "}\n\n"); + } + } + } + + fprintf(h_fp, "\n"); + + for (u8 elems = 2; elems <= 4; ++elems) { + for (u8 bits = 8; bits <= 64; bits *= 2) { + char *fmt_u = "void send_aabb%du%d(DragonnetPeer *p, bool submit, aabb%du%d v)\n"; + char *fmt_s = "void send_aabb%ds%d(DragonnetPeer *p, bool submit, aabb%ds%d v)\n"; + + fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";"); + fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_u, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); + fprintf(c_fp, "\t\tsend_v%du%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits); + fprintf(c_fp, "\t}\n"); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_s, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); + fprintf(c_fp, "\t\tsend_v%ds%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits); + fprintf(c_fp, "\t}\n"); + fprintf(c_fp, "}\n\n"); + + if (bits >= 32) { + char *fmt_f = "void send_aabb%df%d(DragonnetPeer *p, bool submit, aabb%df%d v);\n"; + fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_f, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); + fprintf(c_fp, "\t\tsend_v%df%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits); + fprintf(c_fp, "\t}\n"); + fprintf(c_fp, "}\n\n"); + } + } + } + + fprintf(h_fp, "\n"); + + char *fmt_str = "void send_string(DragonnetPeer *p, bool submit, string v)%s\n"; + char *fmt_blob = "void send_Blob(DragonnetPeer *p, bool submit, Blob *v)%s\n\n"; + + fprintf(h_fp, fmt_str, ";"); + fprintf(h_fp, fmt_blob, ";"); + + fprintf(c_fp, fmt_str, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tsend_raw(p, submit, v, strlen(v));\n"); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_blob, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tsend_u32(p, false, v->siz);\n"); + fprintf(c_fp, "\tsend_raw(p, submit, v->data, v->siz);\n"); + fprintf(c_fp, "}\n\n"); +} + +static void gen_deserializers(FILE *c_fp, FILE *h_fp) +{ + c_fp = c_fp; + for (u8 bits = 8; bits <= 64; bits *= 2) { + char *fmt_u = "u%d recv_u%d(DragonnetPeer *p)%s\n"; + char *fmt_s = "s%d recv_s%d(DragonnetPeer *p)%s\n"; + + fprintf(h_fp, fmt_u, bits, bits, ";"); + fprintf(h_fp, fmt_s, bits, bits, ";"); + + fprintf(c_fp, fmt_u, bits, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tu%d be = recv_raw(p, &be, sizeof be);\n", bits); + fprintf(c_fp, "\treturn be%dtoh(be);\n", bits); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_s, bits, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\treturn (s%d) recv_u%d(p);\n", bits, bits); + fprintf(c_fp, "}\n\n"); + + if (bits >= 32) { + char *fmt_f = "f%d recv_f%d(DragonnetPeer *p)%s\n"; + fprintf(h_fp, fmt_f, bits, bits, ";"); + + fprintf(c_fp, fmt_f, bits, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\treturn (f%d) recv_u%d(p);\n", bits, bits); + fprintf(c_fp, "}\n\n"); + } + } + + fprintf(h_fp, "\n"); + + for (u8 elems = 2; elems <= 4; ++elems) { + for (u8 bits = 8; bits <= 64; bits *= 2) { + char *fmt_u = "v%du%d recv_v%du%d(DragonnetPeer *p)%s\n"; + char *fmt_s = "v%ds%d recv_v%ds%d(DragonnetPeer *p)%s\n"; + + fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";"); + fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_u, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tv%du%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); + fprintf(c_fp, "\t\tv[i] = recv_u%d(p);\n", bits); + fprintf(c_fp, "\t}\n\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_s, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tv%ds%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); + fprintf(c_fp, "\t\tv[i] = recv_s%d(p);\n", bits); + fprintf(c_fp, "\t}\n\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); + + if (bits >= 32) { + char *fmt_f = "v%df%d recv_v%df%d(DragonnetPeer *p)%s\n"; + fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_f, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tv%df%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); + fprintf(c_fp, "\t\tv[i] = recv_f%d(p);\n", bits); + fprintf(c_fp, "\t}\n\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); + } + } + } + + fprintf(h_fp, "\n"); + + for (u8 elems = 2; elems <= 4; ++elems) { + for (u8 bits = 8; bits <= 64; bits *= 2) { + char *fmt_u = "aabb%du%d recv_aabb%du%d(DragonnetPeer *p)%s\n"; + char *fmt_s = "aabb%ds%d recv_aabb%ds%d(DragonnetPeer *p)%s\n"; + + fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";"); + fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_u, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\taabb%du%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); + fprintf(c_fp, "\t\tv[i] = recv_v%du%d(p);\n", elems, bits); + fprintf(c_fp, "\t}\n\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_s, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\taabb%ds%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); + fprintf(c_fp, "\t\tv[i] = recv_v%ds%d(p);\n", elems, bits); + fprintf(c_fp, "\t}\n\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); + + if (bits >= 32) { + char *fmt_f = "aabb%df%d recv_aabb%df%d(DragonnetPeer *p)%s\n"; + fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";"); + + fprintf(c_fp, fmt_f, elems, bits, elems, bits, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\taabb%df%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); + fprintf(c_fp, "\t\tv[i] = recv_v%ds%d(p);\n", elems, bits); + fprintf(c_fp, "\t}\n\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); + } + } + } + + fprintf(h_fp, "\n"); + + char *fmt_str = "string recv_string(DragonnetPeer *p)%s\n"; + char *fmt_blob = "Blob *recv_Blob(DragonnetPeer *p)%s\n\n"; + + fprintf(h_fp, fmt_str, ";"); + fprintf(h_fp, fmt_blob, ";"); + + fprintf(c_fp, fmt_str, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tstring v = malloc(sizeof(u16));\n\n"); + fprintf(c_fp, "\tchar ch;\n"); + fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n"); + fprintf(c_fp, "\t\tch = recv_s8(p);\n"); + fprintf(c_fp, "\t\tv[i] = ch;\n"); + fprintf(c_fp, "\t}\n\n"); + fprintf(c_fp, "\tv = realloc(v, strlen(v));\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); + + fprintf(c_fp, fmt_blob, ""); + fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tBlob *v = malloc(sizeof *v);\n"); + fprintf(c_fp, "\tv->siz = recv_u32(p, false, v->siz);\n"); + fprintf(c_fp, "\tv->data = malloc(v->siz);\n"); + fprintf(c_fp, "\trecv_raw(p, v->data, v->siz);\n\n"); + fprintf(c_fp, "\treturn v;\n"); + fprintf(c_fp, "}\n\n"); +} + int main(__attribute((unused)) int argc, __attribute((unused)) char **argv) { FILE *fp = fopen("types.dnet", "r"); @@ -50,6 +330,11 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv) FILE *h_fp = fopen("dnet-types.h", "w"); fprintf(h_fp, "#include \n\n"); + fprintf(h_fp, "#define htobe8(x) (x)\n"); + fprintf(h_fp, "#define be8toh(x) (x)\n\n"); + + gen_serializers(c_fp, h_fp); + gen_deserializers(c_fp, h_fp); char **msgs; size_t msgs_len = split(&msgs, data, "\n"); -- 2.44.0