AxlIO – Stream I/O

Stream-based I/O with three layers:

  1. Simple helpers (GLib-style): axl_print, axl_file_get_contents

  2. Stream I/O (POSIX-style): axl_fopen, axl_fread, axl_fprintf

  3. Low-level: axl_read, axl_write, axl_pread, axl_pwrite

All strings are UTF-8. Paths are converted to UCS-2 internally.

Header: <axl/axl-io.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);

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
typedef long long axl_ssize_t
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 struct AxlDir AxlDir

Functions

void axl_io_init(void)

Initialize the I/O subsystem.

Sets up axl_stdout and axl_stderr. Call once at startup (before any axl_print/axl_fprintf).

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.

AXL_WARN_UNUSED int axl_file_get_contents (const char *path, void **buf, size_t *len)

Read entire file into memory. Like g_file_get_contents().

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.

AXL_WARN_UNUSED 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.

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 &#8212; 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’).

Caller frees with axl_free(). Returns NULL at EOF or on error.

Parameters:
  • s – stream

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.

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.

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_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 out with up to max descriptors, each with a stable name (“fs0”, “fs1”, …) and an opaque handle. On return, count receives the number of entries filled.

Parameters:
  • out – output array (may be NULL to query count)

  • max – capacity of out

  • count – [out] number of volumes found

Returns:

0 on success, -1 on error.

Variables

AxlStream *axl_stdout
AxlStream *axl_stderr
struct AxlFileInfo
#include <axl-io.h>

File metadata (UEFI EFI_FILE_INFO equivalent).

Public Members

uint64_t size

file size in bytes

uint64_t alloc_size

physical allocation size on disk

bool is_dir

true if directory

bool read_only

true if read-only attribute set

struct AxlDirEntry
#include <axl-io.h>

Directory entry returned by axl_dir_read.

Public Members

char name[256]

filename (UTF-8, not full path)

uint64_t size

file size in bytes (0 for directories)

bool is_dir

true if this entry is a directory

struct AxlVolume
#include <axl-io.h>

Volume descriptor for axl_volume_enumerate.

Public Members

void *handle

opaque filesystem handle

char name[16]

stable name (“fs0”, “fs1”, …)