]> git.lizzy.rs Git - dragonnet.git/commitdiff
Add full (de)serializer generator
authorHimbeerserverDE <himbeerserverde@gmail.com>
Tue, 5 Oct 2021 21:42:47 +0000 (23:42 +0200)
committerHimbeerserverDE <himbeerserverde@gmail.com>
Tue, 5 Oct 2021 21:42:47 +0000 (23:42 +0200)
recv.c
recv.h
send.c
send.h
typegen/main.c

diff --git a/recv.c b/recv.c
index 927602068a78c736d24f50a0ad551fe2640255a1..e4ed1dfcf4980567775510835a2356ee7ebd9fb6 100644 (file)
--- a/recv.c
+++ b/recv.c
@@ -1,6 +1,6 @@
 #include <dragonnet/recv.h>
 
-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 748ec5f8800430f27ac57fd08e3282c5cf69e9d8..61ddc8688a0e5048782f244afdd1865adbc65994 100644 (file)
--- a/recv.h
+++ b/recv.h
@@ -1,18 +1,8 @@
 #ifndef _DRAGONNET_RECV_H_
 #define _DRAGONNET_RECV_H_
 
-#include <dragontype/number.h>
 #include <dragonnet/peer.h>
 
-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 b28625beeab0bfb8054f13c7e900328ca241ab62..89408e49ba7cfe2f34439fdbfa9d5df1f1ec470e 100644 (file)
--- a/send.c
+++ b/send.c
@@ -3,13 +3,13 @@
 
 #include <dragonnet/send.h>
 
-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 c37c4209f392f5deefc29fe821d58c5d3fd76a81..0a3a8b1446802666f78a85a93120780251caddd1 100644 (file)
--- a/send.h
+++ b/send.h
@@ -3,18 +3,8 @@
 
 #include <stdbool.h>
 
-#include <dragontype/number.h>
 #include <dragonnet/peer.h>
 
-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
index 86cc706dd1cae72ffedf7d626cc61babb29bd15d..cbaa11104136b6267964e02ab6e9afa9d19c3e53 100644 (file)
@@ -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 <dragontype/number.h>\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");