From b25f8217c2feb600f275ece927ece4384cb5e4c7 Mon Sep 17 00:00:00 2001 From: HimbeerserverDE Date: Sat, 9 Oct 2021 10:53:01 +0200 Subject: [PATCH] Add buffer based (de)serialization --- recv.c | 11 ++ recv.h | 1 + send.c | 9 ++ send.h | 1 + typegen/main.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 322 insertions(+), 5 deletions(-) diff --git a/recv.c b/recv.c index 5bb20e8..eb47af7 100644 --- a/recv.c +++ b/recv.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include @@ -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 09f9586..22b3b97 100644 --- a/recv.h +++ b/recv.h @@ -4,5 +4,6 @@ #include 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 1a2ca9d..7e08c87 100644 --- a/send.c +++ b/send.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include @@ -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 4988f0c..bb16319 100644 --- a/send.h +++ b/send.h @@ -6,5 +6,6 @@ #include 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 diff --git a/typegen/main.c b/typegen/main.c index acf9f73..183d7f3 100644 --- a/typegen/main.c +++ b/typegen/main.c @@ -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 \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) -- 2.44.0