Promote ASL IO helpers

This commit is contained in:
Carl Niklas Rydberg 2025-12-20 11:19:08 +01:00
parent f48b73b75f
commit edc81beb9b
4 changed files with 184 additions and 158 deletions

View file

@ -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

26
include/amduat/asl/io.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef AMDUAT_ASL_IO_H
#define AMDUAT_ASL_IO_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#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 */

149
src/near_core/asl/io.c Normal file
View file

@ -0,0 +1,149 @@
#include "amduat/asl/io.h"
#include <stdlib.h>
#include <string.h>
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;
}

View file

@ -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",