AxlStream — byte-stream abstraction
AxlStream — byte-stream abstraction
AxlStream is the polymorphic byte-source/sink — modeled on POSIX
<stdio.h>’s FILE *. It wraps a vtable over file handles, memory
buffers, the console, the BOM-detecting text decoder, etc. All
public functions that take AxlStream * live in this module.
For path-based filesystem operations (read whole file, dir walk,
volume enumerate, stat), see the sibling AxlFs module
(<axl/axl-fs.h>, source in src/fs/).
Three-layer API shape:
Simple helpers (GLib-style):
axl_print,axl_printerrStream I/O (POSIX-style):
axl_fopen,axl_fread,axl_fprintf,axl_fgets,axl_readline,axl_walk_linesLow-level:
axl_read,axl_write,axl_pread,axl_pwrite
All strings are UTF-8. Paths in axl_fopen are converted to UCS-2
internally. Per-stream wire encoding (UCS-2 LE/BE/ASCII) is
available via axl_stream_set_encoding.
Header: <axl/axl-stream.h>
Overview
AXL provides familiar POSIX-style I/O on top of UEFI’s file protocols.
Paths use UTF-8 with forward slashes (fs0:/path/to/file.txt); AXL
converts to UCS-2 and backslashes internally.
Console Output
axl_printf writes to the UEFI console (ConOut). It’s available
immediately after AXL_APP or axl_driver_init:
axl_printf("Hello %s, value=%d\n", name, 42);
axl_printerr("Error: %s\n", msg); // writes to ConErr
File Read/Write
The simplest way to read or write files:
// Read entire file into memory
void *data;
size_t len;
if (axl_file_get_contents("fs0:/config.json", &data, &len) == 0) {
// process data...
axl_free(data);
}
// Write entire file
axl_file_set_contents("fs0:/output.txt", buf, buf_len);
Stream I/O
For line-by-line reading or incremental writes:
AxlStream *f = axl_fopen("fs0:/log.txt", "r");
if (f != NULL) {
char *line;
while ((line = axl_readline(f)) != NULL) {
axl_printf(" %s\n", line);
axl_free(line);
}
axl_fclose(f);
}
Buffer Streams
In-memory streams for building data without files:
AxlStream *buf = axl_open_buffer();
axl_fprintf(buf, "name=%s\n", name);
axl_fprintf(buf, "value=%d\n", value);
void *data;
size_t len;
axl_stream_get_bufdata(buf, &data, &len);
// data contains the formatted text
axl_fclose(buf);
Standard Streams
axl_stream_init populates four globals:
Stream |
Direction |
Encoding |
Backed by |
|---|---|---|---|
|
out |
text (UTF-8 in → UCS-2 to console) |
firmware console (ConOut) |
|
out |
text (same path as stdout) |
firmware console |
|
in |
raw bytes |
|
|
out |
raw bytes |
|
For shell pipe invocations (tool1 | tool2) the LHS output is
captured by the shell into a stream that becomes the RHS’s StdIn, so
axl_read(axl_stdin, ...) consumes the piped bytes.
When the shell-params protocol isn’t published (cross-volume
launches, BDS contexts, non-Shell-2.0 launches), axl_stdin reads
return EOF (0 bytes) and axl_stdout_raw writes return -1 — tools
that opt in should fall back to a file argument or print a clear
error.
Output: text vs binary
The split is symmetric with stdin (raw bytes vs axl_text_stream_wrap
for text decoding):
Use case |
API |
|---|---|
Text output (the common case) |
|
Binary output (RAM-disk dump, captured SPD blob, etc.) |
|
Don’t use axl_stdout_raw for text; the firmware console only knows
UCS-2, so writing raw 8-bit bytes to it (when no shell redirection
is in play) would mangle the display. The raw path is only useful
when the caller knows the shell wired their StdOut to a file or pipe.
Text-Decoding Stream Wrapper
UEFI Shell pipes carry text as UCS-2 LE with a FF FE BOM (because
shell built-ins write to console handles that wrap text that way).
A tool reading axl_stdin directly sees raw UCS-2 bytes. To get
UTF-8 text regardless of source encoding, wrap any byte stream with
axl_text_stream_wrap:
AxlStream *in = axl_text_stream_wrap(axl_stdin); /* or any other AxlStream */
char *line;
while ((line = axl_readline(in)) != NULL) {
/* `line` is UTF-8 — search, parse, etc. */
axl_free(line);
}
axl_fclose(in); /* does NOT close the wrapped src */
BOM detection happens lazily on the first read:
Leading bytes |
Mode |
Behavior |
|---|---|---|
|
UTF-16 LE |
BOM consumed, body transcoded to UTF-8 |
|
UTF-16 BE |
BOM consumed, body transcoded to UTF-8 |
|
UTF-8 BOM |
BOM stripped, body returned verbatim |
anything else |
passthrough |
raw bytes returned as-is |
Transcoding is incremental and bounded-memory regardless of source size — wrap a multi-MB pipe and read line by line. The wrapper holds back partial transcoded sequences when the caller’s buffer cuts mid-character, so reads return valid UTF-8 even for tiny buffers.
The wrapper does not take ownership of src — the caller closes
both eventually. Use this when the source might be UCS-2; pass
binary data through the raw stream (e.g. hexdump reads axl_stdin
directly so it shows wire bytes including the BOM).
Codepoints above U+FFFF (surrogate pairs) round-trip as their UTF-16 code-unit shape, not the proper UTF-8 4-byte form. Almost all real-world UEFI Shell content is BMP-only ASCII / Latin-1 / common scripts; a follow-up can add full SMP support if a real consumer needs it.
File Operations
bool exists = axl_file_exists("fs0:/data.bin");
bool is_dir = axl_file_is_dir("fs0:/logs");
axl_file_delete("fs0:/temp.txt");
axl_file_rename("fs0:/old.txt", "fs0:/new.txt");
axl_dir_mkdir("fs0:/output");
API Reference
Defines
-
axl_printf
Alias for axl_print. Matches the design-doc name.
-
AXL_SEEK_SET
seek from beginning
-
AXL_SEEK_CUR
seek from current position
-
AXL_SEEK_END
seek from end of file
Typedefs
-
typedef struct AxlStream AxlStream
axl-stream.h:
AxlStream — the byte-stream abstraction. Modeled on POSIX
<stdio.h>’sFILE *: a polymorphic handle that backs onto a file, a memory buffer, the console, or any other byte sink/source via an internal vtable. All public functions that take or returnAxlStream *live here.Three-layer API shape:
Simple helpers (GLib-style): axl_print, axl_printerr.
Stream I/O (POSIX-style): axl_fopen, axl_fread, axl_fprintf, axl_fgets, axl_readline, etc.
Low-level: axl_read, axl_write, axl_pread, axl_pwrite.
Filesystem operations (read-whole-file, dir walk, volume enumerate, stat) live in
<axl/axl-fs.h>— they’re path-based, not stream-based. AxlStream only knows about bytes.All strings are UTF-8. Paths in axl_fopen are converted to UCS-2 internally. Per-stream wire encoding (UCS-2 LE/BE/ASCII) is available via axl_stream_set_encoding.
-
typedef long long axl_ssize_t
-
typedef int (*AxlLineFn)(const char *line, size_t len, bool truncated, void *user)
Per-line callback for axl_walk_lines.
linepoints into the caller’s working buffer — valid only for the duration of this callback invocation.lenexcludes the trailing\\n; a\\rimmediately before is left inlinefor callers that want to keep CRLF context (most strip it).truncatedis true when the logical line exceeded the working buffer; in that caselineholds the leadinglenbytes and the rest of the line was discarded from the stream before this callback fired.Return 0 to continue, any non-zero value to stop iteration — the value is propagated back from
axl_walk_lines.
Enums
-
enum AxlEncoding
Wire-side encoding for a stream. The caller always works in UTF-8 —
axl_readreturns UTF-8,axl_writeaccepts UTF-8 — andaxl_stream_set_encodingdeclares what’s on the wire underneath.Default is AXL_ENC_UTF8, which is a passthrough (no transcoding) — existing behavior is unchanged for any stream the consumer doesn’t explicitly configure.
Transcoding is permissive — bad input never produces an error:
Invalid UTF-8 in writes → encoded byte-for-byte as Latin-1.
Invalid wire bytes / surrogate halves in reads → transcoded in their BMP shape (U+D800..U+DFFF round-trip as a 3-byte UTF-8 sequence; lone wire byte at end of stream is dropped).
Codepoints above U+FFFF on encode to UCS-2/ASCII → replaced with
?.
Values:
-
enumerator AXL_ENC_UTF8
default — passthrough, no transcoding
-
enumerator AXL_ENC_UCS2_LE
native UEFI; what the shell pipes use
-
enumerator AXL_ENC_UCS2_BE
network-byte-order UCS-2; rare
-
enumerator AXL_ENC_ASCII
7-bit; high bytes replaced with
?
Functions
-
void axl_stream_init(void)
Initialize the standard stream globals.
Sets up axl_stdout, axl_stderr, axl_stdin, and axl_stdout_raw. Call once at startup (before any axl_print/axl_fprintf or axl_read on axl_stdin). Invoked automatically by axl_runtime_init — most consumers don’t call it directly.
axl_stdin is backed by
EFI_SHELL_PARAMETERS_PROTOCOL.StdInwhen the shell publishes it (the typical case for shell-launched apps including the right-hand side of a|pipe). Reading from axl_stdin then consumes the bytes the shell captured from the left-hand side of the pipe.If the shell-params protocol isn’t published on this image (cross-volume launches, BDS contexts, non-Shell-2.0 launches), axl_stdin reads return EOF (0 bytes). Callers that need to detect “stdin not connected” can issue a single zero-length read and check the result.
-
int axl_print(const char *fmt, ...)
Print to stdout. Like g_print().
- Parameters:
fmt – printf-style format string
- Returns:
number of bytes written, or -1 on error.
-
int axl_printerr(const char *fmt, ...)
Print to stderr. Like g_printerr().
- Parameters:
fmt – printf-style format string
- Returns:
number of bytes written, or -1 on error.
-
AxlStream *axl_fopen(const char *path, const char *mode)
Open a file stream.
Path is converted to UCS-2 internally.
- Parameters:
path – file path (UTF-8, e.g. “fs0:/data.txt”)
mode – “r” (read), “w” (write/create), “a” (append)
- Returns:
stream, or NULL on error. Close with axl_fclose().
-
void axl_fclose(AxlStream *s)
Close a stream and free resources. NULL-safe.
- Parameters:
s – stream, or NULL
-
size_t axl_fread(void *buf, size_t size, size_t count, AxlStream *s)
Read size*count bytes from stream.
Returns number of complete items read (may be less than count at EOF or on error). Returns 0 on both EOF and error — use axl_read() if you need to distinguish them (-1 = error, 0 = EOF).
- Parameters:
buf – destination buffer
size – item size in bytes
count – number of items
s – stream
-
size_t axl_fwrite(const void *buf, size_t size, size_t count, AxlStream *s)
Write size*count bytes to stream.
Returns number of complete items written.
- Parameters:
buf – source buffer
size – item size in bytes
count – number of items
s – stream
-
int axl_fprintf(AxlStream *s, const char *fmt, ...)
Write formatted text to a stream.
- Parameters:
s – stream
fmt – printf-style format string
- Returns:
number of bytes written, or -1 on error.
-
char *axl_readline(AxlStream *s)
Read one line (up to and including ‘\n’).
Unbounded — grows the internal buffer until ‘\n’ or EOF. For arbitrary input (untrusted files, network streams, output piped from another tool) prefer axl_readline_max so a single oversized line cannot exhaust memory.
Caller frees with axl_free(). Returns NULL at EOF or on error.
- Parameters:
s – stream
-
char *axl_readline_max(AxlStream *s, size_t max_bytes)
Read one line with a memory cap.
Like axl_readline but bounded: stops appending after
max_bytes-1bytes have been buffered. The returned string is always NUL-terminated.Truncation semantics: when the cap is hit before a
\\n, the remaining bytes of that logical line are silently consumed from the stream up to (and including) the next\\nor EOF. The nextaxl_readline_maxcall therefore reads the next logical line — line counting stays meaningful even when individual lines are truncated.Detect truncation via “last char != `\n`”: a complete line ends in
\\n; a truncated one doesn’t (and the byte count equalsmax_bytes-1).Caller frees with axl_free(). Returns NULL at EOF (no bytes read) or on error.
- Parameters:
s – stream
max_bytes – maximum heap-buffered bytes (incl. trailing NUL)
-
void axl_line_reader_init(AxlLineReader *r, AxlStream *s, char *buf, size_t buf_size)
Initialize a line reader.
- Parameters:
r – caller-allocated reader struct
s – source stream (caller-owned)
buf – working buffer (caller-owned, must outlive the reader)
buf_size – buffer size; must be ≥ 2 and is the max line length
-
bool axl_line_reader_next(AxlLineReader *r, const char **line, size_t *len, bool *truncated)
Read the next line from the stream.
On a successful return,
*linepoints into the reader’s working buffer (valid until the next_nextcall) and*lenis the byte count, excluding any trailing\n(a\rfrom a CRLF pair is left for the caller to strip if desired). On truncation,*truncatedis set to true and the rest of the logical line has already been drained from the stream — line counts in the caller stay consistent.- Returns:
true if a line was read, false at EOF or on backend read error. Use axl_line_reader_error to distinguish.
-
bool axl_line_reader_error(const AxlLineReader *r)
True if the most recent read returned a backend error.
Distinguishes EOF (false return + this returns false) from a real read failure (false return + this returns true).
-
int axl_walk_lines(AxlStream *s, char *buf, size_t buf_size, AxlLineFn fn, void *user)
Callback wrapper around AxlLineReader.
Convenience for callers that prefer callback dispatch over iterator-style
while (next(...))loops. Equivalent to:AxlLineReader r; axl_line_reader_init(&r, s, buf, buf_size); while (axl_line_reader_next(&r, &line, &len, &truncated)) { int rc = fn(line, len, truncated, user); if (rc != 0) return rc; } return axl_line_reader_error(&r) ? -1 : 0;Most callers should prefer the reader-struct form for its normal-scope local variables and standard control flow. Use this wrapper only when the per-line work is genuinely stateless or when the dispatch shape simplifies a generic API.
- Parameters:
s – stream
buf – working buffer (caller-owned)
buf_size – buffer capacity (>= 2; doubles as max line length)
fn – per-line callback
user – opaque user pointer for the callback
- Returns:
0 on full traversal to EOF, the callback’s non-zero return if it stopped, or -1 on backend read error or invalid arguments.
-
int axl_fseek(AxlStream *s, int64_t offset, int whence)
Set the stream position.
- Parameters:
s – stream
offset – byte offset (may be negative for CUR/END)
whence – AXL_SEEK_SET, AXL_SEEK_CUR, or AXL_SEEK_END
- Returns:
0 on success, -1 on error or if not supported.
-
int64_t axl_ftell(AxlStream *s)
Get the current stream position.
- Parameters:
s – stream
- Returns:
position in bytes, or -1 on error.
-
bool axl_feof(AxlStream *s)
Check if the stream has reached end-of-file.
Set when read returns 0 bytes. Cleared by axl_fseek.
- Parameters:
s – stream
- Returns:
true if at EOF.
-
int axl_fflush(AxlStream *s)
Flush pending writes to the underlying file. NULL-safe.
- Parameters:
s – stream
- Returns:
0 on success, -1 on error.
-
int axl_stream_set_encoding(AxlStream *s, AxlEncoding enc)
Set the wire-side encoding for a stream.
Applies to the byte-I/O primitives — axl_read, axl_write, axl_fread, axl_fwrite, axl_readline, axl_fgets. Does not affect axl_print / axl_printf / axl_printerr — those go through the console_write path which does its own UTF-8→UCS-2 conversion.
Switching encoding mid-stream discards any partial multi-byte sequence that was being buffered under the previous encoding. That avoids silently splicing stale partial bytes onto the new encoding’s byte stream. Likewise, axl_fseek discards transcode buffers — they describe state at the pre-seek position.
- Parameters:
s – stream
enc – wire-side encoding
- Returns:
0 on success, -1 if
sis NULL orencis out of range.
-
AxlEncoding axl_stream_get_encoding(AxlStream *s)
Get the current wire-side encoding for a stream.
- Parameters:
s – stream
- Returns:
current encoding (defaults to AXL_ENC_UTF8).
-
char *axl_fgets(char *buf, int size, AxlStream *stream)
Read up to
size-1bytes fromstreamintobuf, stopping at end-of-line or EOF, and NUL-terminate.Like POSIX
fgets(): reads at most one less thansizebytes, stopping after the first newline (which is included inbuf), at EOF, or on error. The buffer is always NUL-terminated when a non-NULL return is delivered.- Parameters:
buf – destination buffer (must be at least
sizebytes)size – buffer size in bytes (incl. NUL)
stream – source stream
- Returns:
bufon success, NULL at EOF (with no bytes read) or on error (use axl_ferror to distinguish).
-
int axl_vfprintf(AxlStream *stream, const char *fmt, va_list ap)
Write formatted text to a stream (va_list variant).
Like POSIX
vfprintf(). The axl_fprintf entry point wraps this for the variadic case.- Parameters:
stream – stream
fmt – printf-style format string
ap – argument list
- Returns:
number of bytes written, or -1 on error.
-
bool axl_ferror(AxlStream *stream)
Test the sticky error indicator on a stream.
Set by any backend read/write/seek error. Mirror of POSIX
ferror(). Cleared by axl_clearerr.- Parameters:
stream – stream
- Returns:
true if an error has been signaled on
stream.
-
void axl_clearerr(AxlStream *stream)
Clear both the EOF and error indicators on
stream.Mirror of POSIX
clearerr().- Parameters:
stream – stream
-
AxlStream *axl_text_stream_wrap(AxlStream *src)
Wrap a raw byte stream as a UTF-8 text stream.
Source encoding is classified at construction time. In priority:
BOM:
FF FE→ UTF-16 LE; BOM consumed, body transcoded to UTF-8FE FF→ UTF-16 BE; BOM consumed, body transcoded to UTF-8EF BB BF→ UTF-8 BOM; consumed, body returned verbatim
Headerless UCS-2 sniff (≥16 bytes available, no BOM): if every odd-position byte is 0x00 the source is treated as UCS-2 LE; if every even-position byte is 0x00, UCS-2 BE. The sniffed bytes are non-consuming and re-emerge on the first read. This catches UEFI shells that write UCS-2 LE without a BOM (
some-cmd > out.txt). UTF-8 ASCII text never matches (no NULs anywhere); the remaining false-positive risk is binary content with NULs at every alternate byte — wrap such streams only if they’re known to be text.Otherwise → passthrough (raw bytes returned as-is).
Transcoding is incremental and bounded-memory regardless of source size — wrap a multi-MB pipe and read line by line. Returned reads are valid UTF-8 even when the caller’s buffer cuts mid-character (the wrapper holds back partial transcoded sequences for the next call).
Useful for shell-pipe consumers in UEFI: the shell wraps text output as UCS-2 LE, so wrapping
axl_stdingives every text- oriented tool transparent UTF-8 input regardless of whether the upstream is a built-in (UCS-2), an AXL tool that wrote viaaxl_print(UCS-2 after console conversion), or a binary tool that wrote raw UTF-8 (passthrough).The wrapper does not take ownership of
src— the caller is responsible for closing both eventually.Surrogate-half caveat. Codepoints above U+FFFF are encoded in UTF-16 as a pair of surrogate code units (U+D800-U+DFFF). This wrapper transcodes each code unit independently as a 3-byte UTF-8 sequence rather than combining the pair into the proper UTF-8 4-byte form. The output is not strictly valid UTF-8 for codepoints > U+FFFF: lone-surrogate sequences will be rejected by strict UTF-8 validators (axl_utf8_validate, JSON encoders, MultiByteToWideChar-style decoders). Lenient consumers (grep, substring search, console display) tolerate it. Almost all real-world UEFI Shell content is BMP-only ASCII / Latin-1 / common scripts, so this hasn’t bitten in practice; if a real consumer needs proper SMP support, a follow-up can add the surrogate-pair combiner.
- Parameters:
src – source byte stream (caller-owned)
- Returns:
wrapper stream (free with axl_fclose), or NULL on OOM or NULL
src.
-
AxlStream *axl_bufopen(void)
Create an in-memory buffer stream.
Supports read, write, pread, pwrite.
- Returns:
stream, or NULL on allocation failure.
-
const void *axl_bufdata(AxlStream *s, size_t *size)
Peek at buffer contents without consuming.
The returned pointer is owned by the stream and invalidated by writes or close.
- Parameters:
s – buffer stream
size – (out, optional): buffer size
-
void *axl_bufsteal(AxlStream *s, size_t *size)
Transfer ownership of buffer to caller.
Stream becomes empty. Caller frees with axl_free().
- Parameters:
s – buffer stream
size – (out, optional): buffer size
-
axl_ssize_t axl_read(AxlStream *s, void *buf, size_t count)
Read up to count bytes from stream at current position.
- Parameters:
s – stream
buf – destination buffer
count – max bytes to read
- Returns:
bytes read, 0 at EOF, -1 on error.
-
axl_ssize_t axl_write(AxlStream *s, const void *buf, size_t count)
Write count bytes to stream at current position.
- Parameters:
s – stream
buf – source buffer
count – bytes to write
- Returns:
bytes written, -1 on error.
-
axl_ssize_t axl_pread(AxlStream *s, void *buf, size_t count, size_t offset)
Read up to count bytes at offset without changing stream position.
- Parameters:
s – stream
buf – destination buffer
count – max bytes to read
offset – byte offset to read from
- Returns:
bytes read, -1 on error or if not supported.
-
axl_ssize_t axl_pwrite(AxlStream *s, const void *buf, size_t count, size_t offset)
Write count bytes at offset without changing stream position.
- Parameters:
s – stream
buf – source buffer
count – bytes to write
offset – byte offset to write at
- Returns:
bytes written, -1 on error or if not supported.
Variables
-
AxlStream *axl_stdout_raw
axl_stdout_raw — sibling of axl_stdout for binary output. Writes via
EFI_SHELL_PARAMETERS_PROTOCOL.StdOut->WriteFiledirectly, bypassing the UTF-8→UCS-2 conversion that axl_stdout (and axl_print / axl_fprintf) does for console output. Use when a tool needs bytes to traverse a pipe intact (dumping a RAM-disk image, SPD blob, etc.).Symmetric with axl_stdin (which is also raw bytes); axl_stdout remains the text-output path.
axl_write(axl_stdout_raw, ...)returns -1 if the shell-params protocol isn’t published — there’s no sensible console fallback for binary bytes (the firmware console mangles non-CHAR16 input). Tools that opt in should print a clear error in that case.
-
struct AxlLineReader
- #include <axl-stream.h>
Stateful line reader for chunk-buffered streams.
Iterate line-by-line over a stream using a caller-supplied working buffer. Constant memory regardless of input size; the line slice on each
nextcall points into the working buffer and is invalidated by the next call.AxlLineReader r; char buf[64 * 1024]; axl_line_reader_init(&r, stream, buf, sizeof(buf)); const char *line; size_t len; bool truncated; while (axl_line_reader_next(&r, &line, &len, &truncated)) { // use line[0..len) — invalidated by next call }Lines longer than
buf_size-1fire onenextcall withtruncated == truecarrying the prefix; the rest of the logical line is consumed before the next call. The buffer doubles as the maximum line length.Fields are internal — callers must not touch them. Stack- allocate the struct and pass &reader to the API. No teardown function is needed; ownership of the working buffer stays with the caller.
AxlFs — filesystem operations
Typedefs
-
typedef void (*AxlProgressFunc)(uint64_t done, uint64_t total, void *ctx)
Progress callback for long-running I/O operations.
- Param done:
bytes transferred so far
- Param total:
total bytes (0 if unknown)
- Param ctx:
caller context pointer
-
typedef int (*AxlDirWalkFn)(const char *full_path, const AxlDirEntry *entry, void *user)
Per-entry callback for axl_dir_walk.
Return codes:
0 continue walking
>0 stop (propagated as the walk’s return value)
<0 stop with error (propagated)
- Param full_path:
full path to the entry (root + separator + name)
- Param entry:
the AxlDirEntry, including name, size, is_dir
- Param user:
opaque user pointer passed through from caller
Functions
-
int axl_file_get_contents(const char *path, void **buf, size_t *len)
Read entire file into memory. Like g_file_get_contents().
axl-fs.h:
Filesystem operations — path-based file and directory APIs, volume enumeration, file metadata. Mirrors the POSIX split:
<axl/axl-stream.h>is the<stdio.h>analog (FILE * / streams); this header is the<sys/stat.h>+<dirent.h>+<sys/statvfs.h>analog.All paths are UTF-8; backend converts to UCS-2 internally. High-level convenience wrappers (
axl_file_get_contents) layer on top of axl_fopen — they’re path-based shortcuts, not stream primitives.- Parameters:
path – file path (UTF-8)
buf – (out): file contents (caller frees with axl_free)
len – (out): file size in bytes
- Returns:
AXL_OK on success, AXL_ERR on error.
-
int axl_file_set_contents(const char *path, const void *buf, size_t len)
Write entire buffer to file (creates or overwrites).
Like g_file_set_contents().
- Parameters:
path – file path (UTF-8)
buf – data to write
len – data size in bytes
- Returns:
AXL_OK on success, AXL_ERR on error.
-
bool axl_file_is_dir(const char *path)
Check if a path refers to a directory.
- Parameters:
path – file path (UTF-8)
- Returns:
true if directory, false otherwise or on error.
-
int axl_file_info(const char *path, AxlFileInfo *info)
Get file metadata. Wraps UEFI EFI_FILE_INFO.
- Parameters:
path – file path (UTF-8)
info – [out] receives file metadata
- Returns:
0 on success, -1 on error.
-
int axl_file_delete(const char *path)
Delete a file.
- Parameters:
path – file path (UTF-8)
- Returns:
0 on success, -1 on error.
-
int axl_file_rename(const char *old_path, const char *new_path)
Rename or move a file.
- Parameters:
old_path – current path (UTF-8)
new_path – new path (UTF-8)
- Returns:
0 on success, -1 on error.
-
int axl_dir_mkdir(const char *path)
Create a directory.
- Parameters:
path – directory path (UTF-8)
- Returns:
0 on success, -1 on error (including if it already exists).
-
int axl_dir_rmdir(const char *path)
Remove an empty directory.
- Parameters:
path – directory path (UTF-8)
- Returns:
0 on success, -1 on error (including if not empty).
-
AxlDir *axl_dir_open(const char *path)
Open a directory for iteration.
- Parameters:
path – directory path (UTF-8)
- Returns:
directory handle, or NULL on error.
-
bool axl_dir_read(AxlDir *dir, AxlDirEntry *entry)
Read the next directory entry.
- Parameters:
dir – directory handle
entry – [out] receives entry
- Returns:
true if an entry was read, false at end of directory.
-
void axl_dir_close(AxlDir *dir)
Close a directory handle. NULL-safe.
- Parameters:
dir – directory handle
-
int axl_dir_walk(const char *root, AxlDirWalkFn fn, void *user, int max_depth)
Recursively walk a directory tree.
Calls
fnon every entry (excluding.and..) underroot, descending into subdirectories automatically. Each entry’s full path is constructed with separator deduplication so the callback sees clean paths regardless of whetherroothas a trailing/or\. Recursion is post-callback — the walker invokesfnon a directory entry first, then descends into it.max_depthmatches POSIXfind -maxdepth: it caps the deepest level the callback runs at, where root’s immediate children are level 1, their children are level 2, and so on.max_depth = 1lists root’s immediate children only.max_depth = Nlists at most N levels of nesting below root.max_depth <= 0is rejected (returns -1).
- Parameters:
root – starting directory
fn – per-entry callback
user – opaque user pointer for the callback
max_depth – maximum nesting level visited (>=1)
- Returns:
0 on a clean traversal, the callback’s non-zero return value if it stopped the walk, or -1 if
rootcould not be opened or arguments are invalid.
-
int axl_dir_list_json(const AxlDirEntry *entries, size_t count, char *buf, size_t buf_size)
Serialize directory entries to a JSON array.
Writes a JSON array of objects into
buf. Each object has: “name” (string), “size” (uint64), “dir” (boolean).Example output: [{“name”:”foo.txt”,”size”:1024,”dir”:false}]
- Parameters:
entries – array of directory entries
count – number of entries
buf – output buffer
buf_size – output buffer size
- Returns:
0 on success, -1 on error or buffer overflow.
-
char *axl_volume_get_label(const char *path)
Get the filesystem volume label for a path.
Returns a UTF-8 copy of the label. Caller frees with axl_free().
- Parameters:
path – filesystem path (e.g., “fs0:”, “fs1:\”)
- Returns:
label string, or NULL on error.
-
char *axl_volume_get_label_by_handle(void *handle)
Get the filesystem volume label for a handle.
Use with handles from axl_service_enumerate(“simple-fs”, …). Returns a UTF-8 copy of the label. Caller frees with axl_free().
- Parameters:
handle – filesystem handle from axl_service_enumerate
- Returns:
label string, or NULL on error.
-
int axl_volume_enumerate(AxlVolume *out, size_t max, size_t *count)
Enumerate mounted filesystem volumes.
Fills
outwith up tomaxdescriptors, each with a stable name (“fs0”, “fs1”, …) and an opaque handle. On return,countreceives the number of entries filled.- Parameters:
out – output array (may be NULL to query count)
max – capacity of
outcount – [out] number of volumes found
- Returns:
0 on success, -1 on error.
-
struct AxlFileInfo
- #include <axl-fs.h>
File metadata (UEFI EFI_FILE_INFO equivalent).
-
struct AxlDirEntry
- #include <axl-fs.h>
Directory entry returned by axl_dir_read.
-
struct AxlVolume
- #include <axl-fs.h>
Volume descriptor for axl_volume_enumerate.