]> git.lizzy.rs Git - dragonnet.git/commitdiff
Add buffer based (de)serialization
authorHimbeerserverDE <himbeerserverde@gmail.com>
Sat, 9 Oct 2021 08:53:01 +0000 (10:53 +0200)
committerHimbeerserverDE <himbeerserverde@gmail.com>
Sat, 9 Oct 2021 08:53:01 +0000 (10:53 +0200)
recv.c
recv.h
send.c
send.h
typegen/main.c

diff --git a/recv.c b/recv.c
index 5bb20e8a71cf61c5010ee7448fb851703a4b715c..eb47af7440bd12db8243cfc4828e98196ad2fdeb 100644 (file)
--- a/recv.c
+++ b/recv.c
@@ -1,4 +1,6 @@
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <dragonnet/recv.h>
@@ -27,3 +29,12 @@ void dragonnet_recv_raw(DragonnetPeer *p, void *buf, size_t n)
                pthread_rwlock_unlock(&p->mu);
        }
 }
+
+void dragonnet_read_raw(u8 **buf, size_t *n, void *data, size_t len)
+{
+       memcpy(data, *buf, len);
+       memcpy(*buf, &((*buf)[len]), -len + *n);
+
+       *buf = realloc(*buf, -len + *n);
+       *n -= len;
+}
diff --git a/recv.h b/recv.h
index 09f958699a0c7559d4a4398430f444b8f2311369..22b3b9733d37519257694ed1055d51e37e35dde8 100644 (file)
--- a/recv.h
+++ b/recv.h
@@ -4,5 +4,6 @@
 #include <dragonnet/peer.h>
 
 void dragonnet_recv_raw(DragonnetPeer *p, void *buf, size_t n);
+void dragonnet_read_raw(u8 **buf, size_t *n, void *data, size_t len);
 
 #endif
diff --git a/send.c b/send.c
index 1a2ca9dca3c3e806328452847f31b3d4bc5af12a..7e08c87904315726c261707d3fffdf7e30410847 100644 (file)
--- a/send.c
+++ b/send.c
@@ -1,5 +1,7 @@
 #include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <dragonnet/send.h>
 
@@ -20,3 +22,10 @@ void dragonnet_send_raw(DragonnetPeer *p, bool submit, const void *buf, size_t n
                dragonnet_peer_delete(p);
        }
 }
+
+void dragonnet_write_raw(u8 **buf, size_t *n, const void *data, size_t len)
+{
+       *buf = realloc(*buf, len + *n);
+       memcpy(&((*buf)[*n]), data, len);
+       *n += len;
+}
diff --git a/send.h b/send.h
index 4988f0c8dea64ecc94f5ff1be4db4e599c80f318..bb163193186caa122048a55ebfdfbf397ffe98df 100644 (file)
--- a/send.h
+++ b/send.h
@@ -6,5 +6,6 @@
 #include <dragonnet/peer.h>
 
 void dragonnet_send_raw(DragonnetPeer *p, bool submit, const void *buf, size_t n);
+void dragonnet_write_raw(u8 **buf, size_t *n, const void *data, size_t len);
 
 #endif
index acf9f73c58b32734bc93ae5fbd81f87a94e71036..183d7f322cbf8517b8d05cb2f95c634189f494dc 100644 (file)
@@ -32,11 +32,10 @@ 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");
+// Socket based
 
+static void gen_serializers(FILE *c_fp)
+{
        for (u8 bits = 8; bits <= 64; bits *= 2) {
                char *fmt_u = "__attribute__((unused)) static void send_u%d(DragonnetPeer *p, bool submit, u%d v)\n";
                char *fmt_s = "__attribute__((unused)) static void send_s%d(DragonnetPeer *p, bool submit, s%d v)\n";
@@ -276,6 +275,249 @@ static void gen_deserializers(FILE *c_fp)
        fprintf(c_fp, "}\n\n");
 }
 
+// Buffer based
+
+static void gen_buffer_serializers(FILE *c_fp)
+{
+       for (u8 bits = 8; bits <= 64; bits *= 2) {
+               char *fmt_u = "__attribute__((unused)) static void buf_write_u%d(u8 **buf, size_t *n, u%d v)\n";
+               char *fmt_s = "__attribute__((unused)) static void buf_write_s%d(u8 **buf, size_t *n, s%d v)\n";
+
+               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, "\tdragonnet_write_raw(buf, n, &be, sizeof be);\n");
+               fprintf(c_fp, "}\n\n");
+
+               fprintf(c_fp, fmt_s, bits, bits, "");
+               fprintf(c_fp, "{\n");
+               fprintf(c_fp, "\tbuf_write_u%d(buf, n, (u%d) v);\n", bits, bits);
+               fprintf(c_fp, "}\n\n");
+
+               if (bits >= 32) {
+                       char *fmt_f = "static void buf_write_f%d(u8 **buf, size_t *n, f%d v)\n";
+
+                       fprintf(c_fp, fmt_f, bits, bits);
+                       fprintf(c_fp, "{\n");
+                       fprintf(c_fp, "\tbuf_write_u%d(buf, n, (u%d) v);\n", bits, bits);
+                       fprintf(c_fp, "}\n\n");
+               }
+       }
+
+       for (u8 elems = 2; elems <= 4; ++elems) {
+               for (u8 bits = 8; bits <= 64; bits *= 2) {
+                       char *fmt_u = "__attribute__((unused)) static void buf_write_v%du%d(u8 **buf, size_t *n, v%du%d v)\n";
+                       char *fmt_s = "__attribute__((unused)) static void buf_write_v%ds%d(u8 **buf, size_t *n, v%ds%d v)\n";
+
+                       fprintf(c_fp, fmt_u, elems, bits, elems, bits);
+                       fprintf(c_fp, "{\n");
+                       fprintf(c_fp, "\tu%d *ptr = &v.x;\n", bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
+                       fprintf(c_fp, "\t\tbuf_write_u%d(buf, n, *ptr++);\n", 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, "\ts%d *ptr = &v.x;\n", bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
+                       fprintf(c_fp, "\t\tbuf_write_s%d(buf, n, *ptr++);\n", bits);
+                       fprintf(c_fp, "\t}\n");
+                       fprintf(c_fp, "}\n\n");
+
+                       if (bits >= 32) {
+                               char *fmt_f = "__attribute__((unused)) static void buf_write_v%df%d(u8 **buf, size_t *n, v%df%d v)\n";
+
+                               fprintf(c_fp, fmt_f, elems, bits, elems, bits);
+                               fprintf(c_fp, "{\n");
+                               fprintf(c_fp, "\tf%d *ptr = &v.x;\n", bits);
+                               fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
+                               fprintf(c_fp, "\t\tbuf_write_f%d(buf, n, *ptr++);\n", bits);
+                               fprintf(c_fp, "\t}\n");
+                               fprintf(c_fp, "}\n\n");
+                       }
+               }
+       }
+
+       for (u8 elems = 2; elems <= 4; ++elems) {
+               for (u8 bits = 8; bits <= 64; bits *= 2) {
+                       char *fmt_u = "__attribute__((unused)) static void buf_write_aabb%du%d(u8 **buf, size_t *n, aabb%du%d v)\n";
+                       char *fmt_s = "__attribute__((unused)) static void buf_write_aabb%ds%d(u8 **buf, size_t *n, aabb%ds%d v)\n";
+
+                       fprintf(c_fp, fmt_u, elems, bits, elems, bits);
+                       fprintf(c_fp, "{\n");
+                       fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n", elems, bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
+                       fprintf(c_fp, "\t\tbuf_write_v%du%d(buf, n, *ptr++);\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, "\tv%ds%d *ptr = &v.min;\n", elems, bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
+                       fprintf(c_fp, "\t\tbuf_write_v%ds%d(buf, n, *ptr++);\n", elems, bits);
+                       fprintf(c_fp, "\t}\n");
+                       fprintf(c_fp, "}\n\n");
+
+                       if (bits >= 32) {
+                               char *fmt_f = "__attribute__((unused)) static void buf_write_aabb%df%d(u8 **buf, size_t *n, aabb%df%d v)\n";
+
+                               fprintf(c_fp, fmt_f, elems, bits, elems, bits);
+                               fprintf(c_fp, "{\n");
+                               fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n", elems, bits);
+                               fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
+                               fprintf(c_fp, "\t\tbuf_write_v%df%d(buf, n, *ptr++);\n", elems, bits);
+                               fprintf(c_fp, "\t}\n");
+                               fprintf(c_fp, "}\n\n");
+                       }
+               }
+       }
+
+       fprintf(c_fp, "__attribute__((unused)) static void buf_write_string(u8 **buf, size_t *n, string v)\n");
+       fprintf(c_fp, "{\n");
+       fprintf(c_fp, "\tdragonnet_write_raw(buf, n, v, strlen(v));\n");
+       fprintf(c_fp, "}\n\n");
+
+       fprintf(c_fp, "__attribute__((unused)) static void buf_write_Blob(u8 **buf, size_t *n, Blob *v)\n\n");
+       fprintf(c_fp, "{\n");
+       fprintf(c_fp, "\tbuf_write_u32(buf, n, v->siz);\n");
+       fprintf(c_fp, "\tdragonnet_write_raw(buf, n, v->data, v->siz);\n");
+       fprintf(c_fp, "}\n\n");
+}
+
+static void gen_buffer_deserializers(FILE *c_fp)
+{
+       for (u8 bits = 8; bits <= 64; bits *= 2) {
+               char *fmt_u = "__attribute__((unused)) static u%d buf_read_u%d(u8 **buf, size_t *n)\n";
+               char *fmt_s = "__attribute__((unused)) static s%d buf_read_s%d(u8 **buf, size_t *n)\n";
+
+               fprintf(c_fp, fmt_u, bits, bits);
+               fprintf(c_fp, "{\n");
+               fprintf(c_fp, "\tu%d be;\n", bits);
+               fprintf(c_fp, "\tdragonnet_read_raw(buf, n, &be, sizeof be);\n");
+               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) buf_read_u%d(buf, n);\n", bits, bits);
+               fprintf(c_fp, "}\n\n");
+
+               if (bits >= 32) {
+                       char *fmt_f = "__attribute__((unused)) static f%d buf_read_f%d(u8 **buf, size_t *n)\n";
+
+                       fprintf(c_fp, fmt_f, bits, bits);
+                       fprintf(c_fp, "{\n");
+                       fprintf(c_fp, "\treturn (f%d) buf_read_u%d(buf, n);\n", bits, bits);
+                       fprintf(c_fp, "}\n\n");
+               }
+       }
+
+       for (u8 elems = 2; elems <= 4; ++elems) {
+               for (u8 bits = 8; bits <= 64; bits *= 2) {
+                       char *fmt_u = "__attribute__((unused)) static v%du%d buf_read_v%du%d(u8 **buf, size_t *n)\n";
+                       char *fmt_s = "__attribute__((unused)) static v%ds%d buf_read_v%ds%d(u8 **buf, size_t *n)\n";
+
+                       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, "\tu%d *ptr = &v.x;\n\n", bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
+                       fprintf(c_fp, "\t\t*ptr++ = buf_read_u%d(buf, n);\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, "\ts%d *ptr = &v.x;\n\n", bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
+                       fprintf(c_fp, "\t\t*ptr++ = buf_read_s%d(buf, n);\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 = "__attribute__((unused)) static v%df%d buf_read_v%df%d(u8 **buf, size_t *n)\n";
+
+                               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, "\tf%d *ptr = &v.x;\n\n", bits);
+                               fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
+                               fprintf(c_fp, "\t\t*ptr++ = buf_read_f%d(buf, n);\n", bits);
+                               fprintf(c_fp, "\t}\n\n");
+                               fprintf(c_fp, "\treturn v;\n");
+                               fprintf(c_fp, "}\n\n");
+                       }
+               }
+       }
+
+       for (u8 elems = 2; elems <= 4; ++elems) {
+               for (u8 bits = 8; bits <= 64; bits *= 2) {
+                       char *fmt_u = "__attribute__((unused)) static aabb%du%d buf_read_aabb%du%d(u8 **buf, size_t *n)\n";
+                       char *fmt_s = "__attribute__((unused)) static aabb%ds%d buf_read_aabb%ds%d(u8 **buf, size_t *n)\n";
+
+                       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, "\tv%du%d *ptr = &v.min;\n\n", elems, bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
+                       fprintf(c_fp, "\t\t*ptr++ = buf_read_v%du%d(buf, n);\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, "\tv%ds%d *ptr = &v.min;\n\n", elems, bits);
+                       fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
+                       fprintf(c_fp, "\t\t*ptr++ = buf_read_v%ds%d(buf, n);\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 = "__attribute__((unused)) static aabb%df%d buf_read_aabb%df%d(u8 **buf, size_t *n)\n";
+
+                               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, "\tv%df%d *ptr = &v.min;\n\n", elems, bits);
+                               fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
+                               fprintf(c_fp, "\t\t*ptr++ = buf_read_v%df%d(buf, n);\n", elems, bits);
+                               fprintf(c_fp, "\t}\n\n");
+                               fprintf(c_fp, "\treturn v;\n");
+                               fprintf(c_fp, "}\n\n");
+                       }
+               }
+       }
+
+       fprintf(c_fp, "__attribute__((unused)) static string buf_read_string(u8 **buf, size_t *n)\n");
+       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 = buf_read_s8(buf, n);\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, "__attribute__((unused)) static Blob *buf_read_Blob(u8 **buf, size_t *n)\n\n");
+       fprintf(c_fp, "{\n");
+       fprintf(c_fp, "\tBlob *v = malloc(sizeof *v);\n");
+       fprintf(c_fp, "\tv->siz = buf_read_u32(buf, n);\n");
+       fprintf(c_fp, "\tv->data = malloc(v->siz);\n");
+       fprintf(c_fp, "\tdragonnet_read_raw(buf, n, 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");
@@ -298,10 +540,15 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
        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");
+       fprintf(h_fp, "typedef char *string;\n");
+       fprintf(h_fp, "typedef struct {\n\tu32 siz;\n\tu8 *data;\n} Blob;\n\n");
 
-       gen_serializers(c_fp, h_fp);
+       gen_serializers(c_fp);
        gen_deserializers(c_fp);
 
+       gen_buffer_serializers(c_fp);
+       gen_buffer_deserializers(c_fp);
+
        char **msgs;
        size_t msgs_len = split(&msgs, data, "\n");
 
@@ -409,6 +656,54 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
        fprintf(c_fp, "}\n");
        msg = NULL;
 
+       // Buffer (de)serialization
+       for (size_t i = 0; i < msgs_len; ++i) {
+               if (msgs[i][0] != '\t') {
+                       if (msg != NULL)
+                               fprintf(c_fp, "}\n\n");
+
+                       msg = msgs[i];
+                       fprintf(c_fp, "void dragonnet_buf_write_%s(u8 **buf, size_t *n, %s type)\n{\n", msg, msg);
+               } else {
+                       char **tokens;
+                       size_t tokens_len = split(&tokens, msgs[i], " ");
+
+                       fprintf(c_fp, "\tbuf_write_%s(buf, n, type.%s);\n", &tokens[0][1], tokens[1]);
+
+                       free_split(tokens, tokens_len);
+                       tokens = NULL;
+               }
+       }
+
+       fprintf(c_fp, "}\n\n");
+       msg = NULL;
+
+       for (size_t i = 0; i < msgs_len; ++i) {
+               if (msgs[i][0] != '\t') {
+                       if (msg != NULL) {
+                               fprintf(c_fp, "\treturn type;\n");
+                               fprintf(c_fp, "}\n\n");
+                       }
+
+                       msg = msgs[i];
+                       fprintf(h_fp, "%s dragonnet_buf_read_%s(u8 **buf, size_t *n);\n", msg, msg);
+                       fprintf(c_fp, "%s dragonnet_buf_read_%s(u8 **buf, size_t *n)\n{\n", msg, msg);
+                       fprintf(c_fp, "\t%s type = {0};\n", msg);
+               } else {
+                       char **tokens;
+                       size_t tokens_len = split(&tokens, msgs[i], " ");
+
+                       fprintf(c_fp, "\ttype.%s = buf_read_%s(buf, n);\n", tokens[1], &tokens[0][1]);
+                       free_split(tokens, tokens_len);
+                       tokens = NULL;
+               }
+       }
+
+       fprintf(h_fp, "\n");
+       fprintf(c_fp, "\treturn type;\n");
+       fprintf(c_fp, "}\n");
+       msg = NULL;
+
        // Create type enum
        size_t last_msg = 0;
        for (size_t i = 0; i < msgs_len; ++i)