#include #include #include #include #include #include typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #define BUG_ON(x) \ if (unlikely(x)) { \ fprintf(stderr, "bug: " #x); \ fprintf(stderr, "\n"); \ exit(1); \ } #define EGGSFS_UDP_MTU 1472 static inline u64 get_unaligned_le64(const void* p) { u64 x; memcpy(&x, p, sizeof(x)); return x; } static inline u32 get_unaligned_le32(const void* p) { u32 x; memcpy(&x, p, sizeof(x)); return x; } static inline u16 get_unaligned_le16(const void* p) { u16 x; memcpy(&x, p, sizeof(x)); return x; } static inline u64 get_unaligned_be64(const void* p) { u64 x; memcpy(&x, p, sizeof(x)); return __bswap_64(x); } static inline u32 get_unaligned_be32(const void* p) { u32 x; memcpy(&x, p, sizeof(x)); return __bswap_32(x); } static inline void put_unaligned_le64(u64 x, void* p) { memcpy(p, &x, sizeof(x)); } static inline void put_unaligned_le32(u32 x, void* p) { memcpy(p, &x, sizeof(x)); } static inline void put_unaligned_le16(u16 x, void* p) { memcpy(p, &x, sizeof(x)); } static inline void put_unaligned_be64(u64 x, void* p) { x = __bswap_64(x); memcpy(p, &x, sizeof(x)); } static inline void put_unaligned_be32(u32 x, void* p) { x = __bswap_32(x); memcpy(p, &x, sizeof(x)); } #include "bincode.h" int main(void) { { char lookup_req[EGGSFS_LOOKUP_REQ_MAX_SIZE]; struct eggsfs_bincode_put_ctx put_ctx = { .start = lookup_req, .cursor = lookup_req, .end = lookup_req + sizeof(lookup_req), }; { eggsfs_lookup_req_put_start(&put_ctx, start); eggsfs_lookup_req_put_dir_id(&put_ctx, start, dir_id, 123); eggsfs_lookup_req_put_name(&put_ctx, dir_id, name, "foo", 3); eggsfs_lookup_req_put_end(&ctx, name, end); } struct eggsfs_bincode_get_ctx get_ctx = { .buf = put_ctx.start, .end = put_ctx.cursor, .err = 0, }; { eggsfs_lookup_req_get_start(&get_ctx, start); eggsfs_lookup_req_get_dir_id(&get_ctx, start, dir_id); eggsfs_lookup_req_get_name(&get_ctx, dir_id, name); eggsfs_lookup_req_get_end(&get_ctx, name, end); eggsfs_lookup_req_get_finish(&get_ctx, end); BUG_ON(get_ctx.err != 0); BUG_ON(dir_id.x != 123); BUG_ON(name.str.len != 3); BUG_ON(strncmp("foo", name.str.buf, 3) != 0); } } { char read_dir_resp[EGGSFS_UDP_MTU]; struct eggsfs_bincode_put_ctx put_ctx = { .start = read_dir_resp, .cursor = read_dir_resp, .end = read_dir_resp + sizeof(read_dir_resp), }; { eggsfs_read_dir_resp_put_start(&put_ctx, start); eggsfs_read_dir_resp_put_next_hash(&put_ctx, start, next_hash, 123); eggsfs_read_dir_resp_put_results(&put_ctx, next_hash, results, 3); for (int i = 0; i < 3; i++) { eggsfs_current_edge_put_start(&put_ctx, edge_start); eggsfs_current_edge_put_target_id(&put_ctx, edge_start, target_id, i); eggsfs_current_edge_put_name_hash(&put_ctx, target_id, name_hash, i + 42); char name_str[2]; snprintf(name_str, 2, "%d", i); eggsfs_current_edge_put_name(&put_ctx, name_hash, name, name_str, 1); eggsfs_current_edge_put_creation_time(&put_ctx, name, creation_time, i + 1000); eggsfs_current_edge_put_end(&put_ctx, creation_time, end); } eggsfs_read_dir_resp_put_end(&ctx, results, end); } struct eggsfs_bincode_get_ctx get_ctx = { .buf = put_ctx.start, .end = put_ctx.cursor, .err = 0, }; { eggsfs_read_dir_resp_get_start(&get_ctx, start); eggsfs_read_dir_resp_get_next_hash(&get_ctx, start, next_hash); eggsfs_read_dir_resp_get_results(&get_ctx, next_hash, results); for (int i = 0; i < results.len; i++) { eggsfs_current_edge_get_start(&get_ctx, edge_start); eggsfs_current_edge_get_target_id(&get_ctx, edge_start, target_id); eggsfs_current_edge_get_name_hash(&get_ctx, target_id, name_hash); eggsfs_current_edge_get_name(&get_ctx, name_hash, name); eggsfs_current_edge_get_creation_time(&get_ctx, name, creation_time); eggsfs_current_edge_get_end(&put_ctx, creation_time, end); eggsfs_bincode_get_finish_list_el(end); if (get_ctx.err == 0) { BUG_ON(target_id.x != i); BUG_ON(name_hash.x != i + 42); BUG_ON(name.str.len != 1); char name_str[11]; snprintf(name_str, 11, "%d", i); BUG_ON(strlen(name_str) != 1); BUG_ON(strncmp(name.str.buf, name_str, 1) != 0); BUG_ON(creation_time.x != i + 1000); } } eggsfs_read_dir_resp_get_end(&get_ctx, results, end); eggsfs_read_dir_resp_get_finish(&get_ctx, end); BUG_ON(get_ctx.err != 0); BUG_ON(next_hash.x != 123); } } return 0; }