diff --git a/CMakeLists.txt b/CMakeLists.txt index fa6af33..d6c0069 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ set(AMDUAT_UTIL_SRCS set(AMDUAT_ASL_SRCS src/kernel/asl/core.c + src/near_core/asl/io.c src/near_core/asl/parse.c src/near_core/asl/store.c src/near_core/asl/ref_text.c diff --git a/include/amduat/asl/io.h b/include/amduat/asl/io.h new file mode 100644 index 0000000..2d627ae --- /dev/null +++ b/include/amduat/asl/io.h @@ -0,0 +1,26 @@ +#ifndef AMDUAT_ASL_IO_H +#define AMDUAT_ASL_IO_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Caller owns any heap allocations returned in out_bytes. */ +bool amduat_asl_read_stream(FILE *stream, uint8_t **out_bytes, size_t *out_len); +bool amduat_asl_read_path(const char *path, uint8_t **out_bytes, size_t *out_len); + +bool amduat_asl_write_stream(FILE *stream, const uint8_t *bytes, size_t len); +bool amduat_asl_write_path(const char *path, const uint8_t *bytes, size_t len); + +bool amduat_asl_write_text_line(const char *path, const char *text); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* AMDUAT_ASL_IO_H */ diff --git a/src/near_core/asl/io.c b/src/near_core/asl/io.c new file mode 100644 index 0000000..9b4c1be --- /dev/null +++ b/src/near_core/asl/io.c @@ -0,0 +1,149 @@ +#include "amduat/asl/io.h" + +#include +#include + +enum { AMDUAT_ASL_IO_BUF_CHUNK = 4096 }; + +bool amduat_asl_read_stream(FILE *stream, uint8_t **out_bytes, size_t *out_len) { + uint8_t *buffer; + size_t cap; + size_t len; + + if (out_bytes == NULL || out_len == NULL) { + return false; + } + *out_bytes = NULL; + *out_len = 0; + + buffer = NULL; + cap = 0; + len = 0; + + while (true) { + if (len == cap) { + size_t new_cap = cap == 0 ? AMDUAT_ASL_IO_BUF_CHUNK : cap * 2u; + uint8_t *next; + if (new_cap < cap) { + free(buffer); + return false; + } + next = (uint8_t *)realloc(buffer, new_cap); + if (next == NULL) { + free(buffer); + return false; + } + buffer = next; + cap = new_cap; + } + + size_t nread = fread(buffer + len, 1u, cap - len, stream); + len += nread; + if (nread == 0u) { + if (ferror(stream)) { + free(buffer); + return false; + } + break; + } + } + + if (len == 0u) { + free(buffer); + buffer = NULL; + } + *out_bytes = buffer; + *out_len = len; + return true; +} + +bool amduat_asl_read_path(const char *path, + uint8_t **out_bytes, + size_t *out_len) { + FILE *stream; + bool ok; + + if (path == NULL || out_bytes == NULL || out_len == NULL) { + return false; + } + + if (strcmp(path, "-") == 0) { + return amduat_asl_read_stream(stdin, out_bytes, out_len); + } + + stream = fopen(path, "rb"); + if (stream == NULL) { + return false; + } + ok = amduat_asl_read_stream(stream, out_bytes, out_len); + if (fclose(stream) != 0) { + ok = false; + } + return ok; +} + +bool amduat_asl_write_stream(FILE *stream, const uint8_t *bytes, size_t len) { + size_t offset; + + if (len != 0u && bytes == NULL) { + return false; + } + + offset = 0u; + while (offset < len) { + size_t written = fwrite(bytes + offset, 1u, len - offset, stream); + if (written == 0u) { + return false; + } + offset += written; + } + return fflush(stream) == 0; +} + +bool amduat_asl_write_path(const char *path, + const uint8_t *bytes, + size_t len) { + FILE *stream; + bool ok; + + if (path == NULL) { + return false; + } + if (strcmp(path, "-") == 0) { + return amduat_asl_write_stream(stdout, bytes, len); + } + + stream = fopen(path, "wb"); + if (stream == NULL) { + return false; + } + ok = amduat_asl_write_stream(stream, bytes, len); + if (fclose(stream) != 0) { + ok = false; + } + return ok; +} + +bool amduat_asl_write_text_line(const char *path, const char *text) { + FILE *stream; + bool ok; + + if (path == NULL || text == NULL) { + return false; + } + if (strcmp(path, "-") == 0) { + stream = stdout; + } else { + stream = fopen(path, "wb"); + if (stream == NULL) { + return false; + } + } + + ok = fputs(text, stream) >= 0 && fputc('\n', stream) != EOF && + fflush(stream) == 0; + if (stream != stdout && fclose(stream) != 0) { + ok = false; + } + return ok; +} diff --git a/src/tools/amduat_asl_cli.c b/src/tools/amduat_asl_cli.c index 64575f2..487c0e7 100644 --- a/src/tools/amduat_asl_cli.c +++ b/src/tools/amduat_asl_cli.c @@ -1,5 +1,6 @@ #include "amduat/asl/asl_store_fs.h" #include "amduat/asl/asl_store_fs_meta.h" +#include "amduat/asl/io.h" #include "amduat/asl/parse.h" #include "amduat/asl/ref_text.h" #include "amduat/asl/store.h" @@ -21,10 +22,7 @@ enum { AMDUAT_ASL_CLI_EXIT_CONFIG = 8 }; -enum { - AMDUAT_ASL_CLI_STORE_ID_MAX = AMDUAT_ASL_STORE_FS_STORE_ID_MAX, - AMDUAT_ASL_CLI_BUF_CHUNK = 4096 -}; +enum { AMDUAT_ASL_CLI_STORE_ID_MAX = AMDUAT_ASL_STORE_FS_STORE_ID_MAX }; static const char *const AMDUAT_ASL_CLI_DEFAULT_ROOT = ".amduat-asl"; @@ -183,154 +181,6 @@ static bool amduat_asl_cli_parse_io_format( return false; } -static bool amduat_asl_cli_read_stream(FILE *stream, - uint8_t **out, - size_t *out_len) { - uint8_t *buffer; - size_t cap; - size_t len; - - if (out == NULL || out_len == NULL) { - return false; - } - *out = NULL; - *out_len = 0; - - buffer = NULL; - cap = 0; - len = 0; - - while (true) { - if (len == cap) { - size_t new_cap = cap == 0 ? AMDUAT_ASL_CLI_BUF_CHUNK : cap * 2u; - uint8_t *next; - if (new_cap < cap) { - free(buffer); - return false; - } - next = (uint8_t *)realloc(buffer, new_cap); - if (next == NULL) { - free(buffer); - return false; - } - buffer = next; - cap = new_cap; - } - - size_t nread = fread(buffer + len, 1u, cap - len, stream); - len += nread; - if (nread == 0u) { - if (ferror(stream)) { - free(buffer); - return false; - } - break; - } - } - - if (len == 0u) { - free(buffer); - buffer = NULL; - } - *out = buffer; - *out_len = len; - return true; -} - -static bool amduat_asl_cli_read_path(const char *path, - uint8_t **out, - size_t *out_len) { - FILE *stream; - bool ok; - - if (path == NULL || out == NULL || out_len == NULL) { - return false; - } - - if (strcmp(path, "-") == 0) { - return amduat_asl_cli_read_stream(stdin, out, out_len); - } - - stream = fopen(path, "rb"); - if (stream == NULL) { - return false; - } - ok = amduat_asl_cli_read_stream(stream, out, out_len); - if (fclose(stream) != 0) { - ok = false; - } - return ok; -} - -static bool amduat_asl_cli_write_stream(FILE *stream, - const uint8_t *bytes, - size_t len) { - size_t offset; - - if (len != 0u && bytes == NULL) { - return false; - } - - offset = 0u; - while (offset < len) { - size_t written = fwrite(bytes + offset, 1u, len - offset, stream); - if (written == 0u) { - return false; - } - offset += written; - } - return fflush(stream) == 0; -} - -static bool amduat_asl_cli_write_path(const char *path, - const uint8_t *bytes, - size_t len) { - FILE *stream; - bool ok; - - if (path == NULL) { - return false; - } - if (strcmp(path, "-") == 0) { - return amduat_asl_cli_write_stream(stdout, bytes, len); - } - - stream = fopen(path, "wb"); - if (stream == NULL) { - return false; - } - ok = amduat_asl_cli_write_stream(stream, bytes, len); - if (fclose(stream) != 0) { - ok = false; - } - return ok; -} - -static bool amduat_asl_cli_write_text_line(const char *path, - const char *text) { - FILE *stream; - bool ok; - - if (path == NULL || text == NULL) { - return false; - } - if (strcmp(path, "-") == 0) { - stream = stdout; - } else { - stream = fopen(path, "wb"); - if (stream == NULL) { - return false; - } - } - - ok = fputs(text, stream) >= 0 && fputc('\n', stream) != EOF && - fflush(stream) == 0; - if (stream != stdout && fclose(stream) != 0) { - ok = false; - } - return ok; -} - static void amduat_asl_cli_free_reference(amduat_reference_t *ref) { if (ref == NULL) { return; @@ -578,7 +428,7 @@ static int amduat_asl_cli_cmd_put(int argc, char **argv) { input_bytes = NULL; input_len = 0u; - if (!amduat_asl_cli_read_path(opts.input_path, &input_bytes, &input_len)) { + if (!amduat_asl_read_path(opts.input_path, &input_bytes, &input_len)) { fprintf(stderr, "error: failed to read input: %s\n", opts.input_path); return AMDUAT_ASL_CLI_EXIT_IO; } @@ -616,7 +466,7 @@ static int amduat_asl_cli_cmd_put(int argc, char **argv) { fprintf(stderr, "error: failed to encode reference\n"); exit_code = AMDUAT_ASL_CLI_EXIT_CODEC; } else { - if (!amduat_asl_cli_write_text_line(opts.output_path, hex_ref)) { + if (!amduat_asl_write_text_line(opts.output_path, hex_ref)) { fprintf(stderr, "error: failed to write output: %s\n", opts.output_path); exit_code = AMDUAT_ASL_CLI_EXIT_IO; @@ -628,7 +478,7 @@ static int amduat_asl_cli_cmd_put(int argc, char **argv) { fprintf(stderr, "error: failed to encode reference\n"); exit_code = AMDUAT_ASL_CLI_EXIT_CODEC; } else { - if (!amduat_asl_cli_write_path(opts.output_path, + if (!amduat_asl_write_path(opts.output_path, encoded_ref.data, encoded_ref.len)) { fprintf(stderr, "error: failed to write output: %s\n", @@ -770,7 +620,7 @@ static int amduat_asl_cli_cmd_get(int argc, char **argv) { } else { ref_bytes = NULL; ref_len = 0u; - if (!amduat_asl_cli_read_path(opts.ref, &ref_bytes, &ref_len)) { + if (!amduat_asl_read_path(opts.ref, &ref_bytes, &ref_len)) { fprintf(stderr, "error: failed to read reference: %s\n", opts.ref); return AMDUAT_ASL_CLI_EXIT_IO; } @@ -801,7 +651,7 @@ static int amduat_asl_cli_cmd_get(int argc, char **argv) { if (exit_code == AMDUAT_ASL_CLI_EXIT_OK) { if (opts.output_format == AMDUAT_ASL_CLI_IO_RAW) { - if (!amduat_asl_cli_write_path(opts.output_path, + if (!amduat_asl_write_path(opts.output_path, artifact.bytes.data, artifact.bytes.len)) { fprintf(stderr, "error: failed to write output: %s\n", @@ -814,7 +664,7 @@ static int amduat_asl_cli_cmd_get(int argc, char **argv) { fprintf(stderr, "error: failed to encode artifact\n"); exit_code = AMDUAT_ASL_CLI_EXIT_CODEC; } else { - if (!amduat_asl_cli_write_path(opts.output_path, + if (!amduat_asl_write_path(opts.output_path, encoded_artifact.data, encoded_artifact.len)) { fprintf(stderr, "error: failed to write output: %s\n",