Author: Pavl G.
This document establishes a constructional design for a low-level IO API that operates on filesystems of all types; the constructional design is completely based on the computational automata theory, that focuses particularly on designing machines that automate algorithms with {predefined set of states on_eof_reached and on_error_encountered); the language
Note
In this API; the language could be all the available strings for read/write IO operations from and to a filesystem. In which, the start string (or char depending on the implementation of the state machines) is the
The following is the an example for the implementation of the file_read algorithm that utilizes a dynamic way of determining the number of bytes to read using the file stat attributes:
/**
* @brief A tech=demo for the implementation of the file reading algorithm that provides a dynamic algorithm of determining the number of bytes to read out of a file using the file stat attributes from the Unix Standard library by requesting a call to the file status utility.
* @author pavl_g.
* @date 10-2025
*/
#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
static inline void update_file_postprocessor(file_mem *mem) {
if (NULL == mem || mem->fd < 0) {
return;
}
if (mem->n_bytes <= 0) {
mem->n_bytes = 1;
}
fprintf(stdout, "Size of memory buffer (in bytes) = %zd\n",
mem->n_bytes);
mem->buffer = calloc(mem->n_bytes, sizeof (char));
if (NULL == mem->buffer) {
return;
}
}
static inline void on_read_bytes(file_mem *mem, ssize_t bytes) {
fprintf(stdout, "Read Bytes: %s", mem->buffer);
}
static inline void on_eof_reached(file_mem *mem) {
fprintf(stdout, "Read Bytes after EOF: %s\n", mem->buffer);
fprintf(stdout, "EOF Reached!\n");
// deallocates memory here!
if (NULL != mem->buffer) {
free(mem->buffer);
mem->buffer = NULL;
}
}
int main() {
fprintf(stdout, "Hello Fle Read Automata!\n");
int fd = open("/home/pavl-g/Desktop/Glossary_for_AI", O_RDWR);
if (fd < 0) {
fprintf(stderr, "Error Encountered: %s\n", strerror(errno));
exit(errno);
}
file_mem _file_mem = {
.fd = fd,
.trailing = '9',
.buffer = NULL,
.n_bytes = -1,
.file_size = -1,
.file_pos = -1
};
file_op_processor __processor = {
.update_file_postprocessor = &update_file_postprocessor,
.on_read_bytes = &on_read_bytes,
.on_eof_reached = &on_eof_reached
};
status_code __status = read_into_mem(&_file_mem, &__processor);
if (PASS != __status) {
fprintf(stderr, "Error Encountered: %s\n", strerror(__status));
exit(__status);
}
return 0;
}[file_read.c]
#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>
#include <electrostatic/electronetsoft/util/filesystem/file_status.h>
status_code read_into_mem(file_mem *mem, file_op_processor *processor) {
// pre-processing automata -- Input validation
if (mem->fd < 0) {
return EUNDEFINEDBUFFER;
}
if (NULL != mem->buffer) {
return -1;
}
// pre-processing automata -- Calculating the file size, current position,
// and the number of bytes to read
status_code ___status = update_file_attrs(mem, processor);
if (PASS != ___status) {
return ___status;
}
if (NULL == mem->buffer) {
return EUNDEFINEDBUFFER;
}
// processing automata -- Reading n_bytes into heap buffer
// starting from the current file position
while (1) {
ssize_t read_bytes = 0;
read_bytes = read(mem->fd, (mem->buffer + read_bytes), (mem->n_bytes - 1));
// post processing automata
if (-1 == read_bytes) {
// terminated with error; report error!
if (NULL != processor && NULL != processor->on_error_encountered) {
processor->on_error_encountered(mem, errno);
}
return errno;
} else if (0 == read_bytes) {
// EOF terminate!
mem->buffer[mem->n_bytes - 1] = mem->trailing; /* add a null-terminating character */
if (NULL != processor && NULL != processor->on_eof_reached) {
processor->on_eof_reached(mem);
}
return PASS;
} else if (read_bytes > 0) {
// execute on_read
if (NULL != processor && NULL != processor->on_read_bytes) {
processor->on_read_bytes(mem, read_bytes);
}
}
}
return ASSERTION_FAILURE;
}