+#include <stdint.h>\r
+#include <mongoose.h>\r
+#define STB_DS_IMPLEMENTATION\r
+#include <stb_ds.h>\r
+\r
+\r
+#define NAME_LEN 32\r
+#define CONTENT_LEN 1024\r
+#define HTML_LEN 1024*8\r
+\r
+typedef struct Post Post;\r
+typedef struct User User;\r
+\r
+User * UsersFind(struct mg_str name);\r
+\r
+// Post / User\r
+\r
+struct Post {\r
+ time_t timestamp;\r
+ User * user;\r
+ char content[CONTENT_LEN];\r
+ uint32_t likes;\r
+ Post * comments;\r
+ //Post * parent;\r
+};\r
+\r
+struct User {\r
+ char name[NAME_LEN];\r
+ Post * posts;\r
+ User ** following;\r
+};\r
+\r
+Post\r
+PostNew() {\r
+ Post result;\r
+ memset(&result, 0, sizeof(result));\r
+ return result;\r
+}\r
+\r
+void\r
+PostWrite(Post * post, FILE * f) {\r
+ fwrite(&post->timestamp, 8, 1, f);\r
+ fwrite(post->user->name, 1, sizeof(post->user->name), f);\r
+ fwrite(post->content, 1, sizeof(post->content), f);\r
+ fwrite(&post->likes, 4, 1, f);\r
+ uint32_t numComments = arrlen(post->comments);\r
+ fwrite(&numComments, 4, 1, f);\r
+ for (int i = 0; i < numComments; i++) {\r
+ PostWrite(&post->comments[i], f);\r
+ }\r
+}\r
+\r
+void\r
+PostRead(Post * post, FILE * f) {\r
+ fread(&post->timestamp, 8, 1, f);\r
+ char name[NAME_LEN];\r
+ fread(name, 1, sizeof(name), f);\r
+ post->user = UsersFind(mg_str(name));\r
+ fread(post->content, 1, sizeof(post->content), f);\r
+ fread(&post->likes, 4, 1, f);\r
+ uint32_t numComments;\r
+ fread(&numComments, 4, 1, f);\r
+ post->comments = NULL;\r
+ for (int i = 0; i < numComments; i++) {\r
+ Post newComment = PostNew();\r
+ PostRead(&newComment, f);\r
+ arrput(post->comments, newComment);\r
+ }\r
+}\r
+\r
+User\r
+UserNew(const char * name) {\r
+ User result;\r
+ memset(&result, 0, sizeof(result));\r
+ strcpy(result.name, name);\r
+ return result;\r
+}\r
+\r
+void\r
+UserWrite(User * user, FILE * f) {\r
+ fwrite(user->name, 1, sizeof(user->name), f);\r
+\r
+ uint32_t numFollowing = arrlen(user->following);\r
+ uint32_t numPosts = arrlen(user->posts);\r
+ fwrite(&numFollowing, 4, 1, f);\r
+ fwrite(&numPosts, 4, 1, f);\r
+\r
+ for (int i = 0; i < numFollowing; i++) {\r
+ fwrite(user->following[i]->name, 1, sizeof(user->following[i]->name), f);\r
+ }\r
+\r
+ for (int i = 0; i < numPosts; i++) {\r
+ PostWrite(&user->posts[i], f);\r
+ }\r
+}\r
+\r
+void\r
+UserRead(User * user, FILE * f) {\r
+ fread(user->name, 1, sizeof(user->name), f);\r
+\r
+ uint32_t numFollowing;\r
+ uint32_t numPosts;\r
+ fread(&numFollowing, 1, 4, f);\r
+ fread(&numPosts, 1, 4, f);\r
+\r
+ user->following = NULL;\r
+ for (int i = 0; i < numFollowing; i++) {\r
+ char name[NAME_LEN];\r
+ fread(name, 1, sizeof(name), f);\r
+ arrput(user->following, UsersFind(mg_str(name)));\r
+ }\r
+\r
+ user->posts = NULL;\r
+ for (int i = 0; i < numPosts; i++) {\r
+ Post post = PostNew();\r
+ PostRead(&post, f);\r
+ arrput(user->posts, post);\r
+ }\r
+}\r
+\r
+\r
+\r
+// Users\r
+\r
+User ** g_users;\r
+static User pat, yas, tof;\r
+\r
+void\r
+UsersSetup() {\r
+ pat = UserNew("pat");\r
+ yas = UserNew("yas");\r
+ tof = UserNew("tof");\r
+\r
+ arrput(pat.following, &yas);\r
+ arrput(yas.following, &pat);\r
+ arrput(tof.following, &yas);\r
+ arrput(tof.following, &pat);\r
+\r
+ arrput(g_users, &pat);\r
+ arrput(g_users, &yas);\r
+ arrput(g_users, &tof);\r
+}\r
+\r
+User *\r
+UsersFind(struct mg_str name) {\r
+ for (int i = 0; i < arrlen(g_users); i++) {\r
+ User * user = g_users[i];\r
+ if (strncmp(user->name, name.ptr, name.len) == 0)\r
+ return user;\r
+ }\r
+ return NULL;\r
+}\r
+\r