brzeszczot

brzeszczot.git
git clone git://git.lenczewski.org/brzeszczot.git
Log | Files | Refs

commit 832771c343663cb1fc025c5ae6879b9cbe3e9d1b
parent 1a90e43cf4c4a6578c2888a7a023d88ce82261a6
Author: MikoĊ‚aj Lenczewski <mblenczewski@gmail.com>
Date:   Sun, 12 Feb 2023 17:40:18 +0000

Add initial dump functionality for testing brzeszczot

Diffstat:
Mbrzeszczot/include/brzeszczot.h | 4++++
Mbrzeszczot/src/brzeszczot.c | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 189 insertions(+), 4 deletions(-)

diff --git a/brzeszczot/include/brzeszczot.h b/brzeszczot/include/brzeszczot.h @@ -4,5 +4,9 @@ #include "common.h" #include "libriot.h" +#include "libriot/wad.h" +#include "libriot/inibin.h" + +#include <unistd.h> #endif /* BRZESZCZOT_H */ diff --git a/brzeszczot/src/brzeszczot.c b/brzeszczot/src/brzeszczot.c @@ -1,11 +1,192 @@ #include "brzeszczot.h" +#include "brzeszczot/argparse.h" + +static inline u64 +read_file(char const *fp, u8 **out) { + FILE *f = fopen(fp, "rb"); + if (!f) return 0; + + u64 len; + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + + u8 *buf = malloc(len); + if (!buf) { fclose(f); return 0; } + + int fd = fileno(f); + + u64 total_read = 0; + do { + u64 curr = read(fd, buf + total_read, len - total_read); + if (!curr) { free(buf); fclose(f); return 0; } + + total_read += curr; + } while (total_read < len); + + fclose(f); + + *out = buf; + + return total_read; +} + +static inline u64 +write_file(char const *fp, u64 len, u8 *buf) { + FILE *f = fopen(fp, "wb"); + if (!f) return 0; + + int fd = fileno(f); + + u64 total_written = 0; + do { + u64 curr = write(fd, buf + total_written, len - total_written); + if (!curr) { fclose(f); return total_written; } + + total_written += curr; + } while (total_written < len); + + fclose(f); + + return total_written; +} + +static s32 +wad_dump(struct opts *opts) { + assert(opts); + + u8 *filebuf; + u64 filelen = read_file(opts->src, &filebuf); + if (!filelen) { + errlog("Failed to read source file: %s", opts->src); + return 1; + } + + struct mem_stream in = { + .ptr = filebuf, + .len = filelen, + .cur = 0, + }; + + struct riot_wad_ctx wadctx; + if (!riot_wad_ctx_init(&wadctx)) { + errlog("Failed to initialise WAD context"); + free(filebuf); + return 1; + } + + if (!riot_wad_read(&wadctx, in)) { + errlog("Failed to read WAD file"); + riot_wad_ctx_free(&wadctx); + free(filebuf); + return 1; + } + + riot_wad_print(&wadctx, stdout); + + struct mem_stream out = { + .ptr = filebuf, + .len = filelen, + .cur = 0, + }; + + if (!riot_wad_write(&wadctx, out)) { + errlog("Failed to write WAD file"); + riot_wad_ctx_free(&wadctx); + free(filebuf); + return 1; + } + + riot_wad_ctx_free(&wadctx); + + u64 written = write_file(opts->dst, filelen, filebuf); + if (!written || written < filelen) { + errlog("Failed to write destination file: %s", opts->dst); + free(filebuf); + return 1; + } + + free(filebuf); + + return 0; +} + +static s32 +inibin_dump(struct opts *opts) { + assert(opts); + + u8 *filebuf; + u64 filelen = read_file(opts->src, &filebuf); + if (!filelen) { + errlog("Failed to read source file: %s", opts->src); + return 1; + } + + struct mem_stream in = { + .ptr = filebuf, + .len = filelen, + .cur = 0, + }; + + struct riot_inibin_ctx inibinctx; + if (!riot_inibin_ctx_init(&inibinctx)) { + errlog("Failed to initialise INIBIN context"); + free(filebuf); + return 1; + } + + if (!riot_inibin_read(&inibinctx, in)) { + errlog("Failed to read INIBIN file"); + riot_inibin_ctx_free(&inibinctx); + free(filebuf); + return 1; + } + + riot_inibin_print(&inibinctx, stdout); + + struct mem_stream out = { + .ptr = filebuf, + .len = filelen, + .cur = 0, + }; + + if (!riot_inibin_write(&inibinctx, out)) { + errlog("Failed to write INIBIN file"); + riot_inibin_ctx_free(&inibinctx); + free(filebuf); + return 1; + } + + riot_inibin_ctx_free(&inibinctx); + + u64 written = write_file(opts->dst, filelen, filebuf); + if (!written || written < filelen) { + errlog("Failed to write destination file: %s", opts->dst); + free(filebuf); + return 1; + } + + free(filebuf); + + return 0; +} s32 main(s32 argc, char **argv) { - (void) argc; - (void) argv; + dbglog("Version: " BRZESZCZOT_VERSION); - dbglog("Version: " BRZESZCZOT_VERSION "\n"); + struct opts opts; + if (!argparse(argc, argv, &opts)) return 1; - return 0; + switch (opts.mode) { + case WAD_DUMP: + return wad_dump(&opts); + + case INIBIN_DUMP: + return inibin_dump(&opts); + + default: + errlog("Unknown mode: %d", opts.mode); + return 1; + } }