From 464dbe8e1797e35c2e8649e5e28bae0bde426d20 Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Thu, 8 Jan 2026 16:15:29 +0100 Subject: [PATCH] feat: finished io_backend --- src/io_backend/io_backend.c | 88 ++++++++++++++++++++++++++++++++----- src/io_backend/io_backend.h | 24 ++++++++-- 2 files changed, 98 insertions(+), 14 deletions(-) diff --git a/src/io_backend/io_backend.c b/src/io_backend/io_backend.c index ee6b09b..7e7c1c3 100644 --- a/src/io_backend/io_backend.c +++ b/src/io_backend/io_backend.c @@ -1,34 +1,102 @@ #include "io_backend.h" #include +#include +#include + +// === Static variables static struct iob_context context; -static FILE *input; +static FILE *input = NULL; +static char *stream_buf = NULL; +static size_t stream_buf_size = 0; +static enum iob_state state = IOB_STATE_NOT_INITIALIZED; + +// === Functions int iob_init(struct iob_context *ctx) { + if (state != IOB_STATE_NOT_INITIALIZED) + return IOB_ERROR_MODULE_NOT_INITIALIZED; + context = *ctx; switch (context.mode) { - IOB_MODE_STDIN: + case IOB_MODE_STDIN: input = stdin; + state = IOB_STATE_READY; return 0; - IOB_MODE_SCRIPT: + case IOB_MODE_SCRIPT: if (context.args == NULL) - return -2; + return IOB_ERROR_BAD_ARG; input = fopen(context.args, "r"); if (input == NULL) - return -4; + return IOB_ERROR_CANNOT_OPEN_FILE; + state = IOB_STATE_READY; + return 0; - IOB_MODE_CMD: + case IOB_MODE_CMD: if (context.args != NULL) - return -2; - else - return 0; + return IOB_ERROR_BAD_ARG; + state = IOB_STATE_READY; + return 0; default: - return -1; + return IOB_ERROR_BAD_ARG; + } +} + +void iob_close(void) +{ + fclose(input); + if ((context.mode == IOB_MODE_STDIN || context.mode == IOB_MODE_SCRIPT) + && stream_buf != NULL) + { + free(stream_buf); + stream_buf_size = 0; + } + state = IOB_STATE_NOT_INITIALIZED; +} + +ssize_t stream_read(char **stream) +{ + // Check args + if (stream == NULL) + return IOB_ERROR_BAD_ARG; + + // Check env + if (state == IOB_STATE_NOT_INITIALIZED) + return IOB_ERROR_MODULE_NOT_INITIALIZED; + if (state == IOB_STATE_FINISHED) + return 0; + if (state == IOB_STATE_ERROR) + return IOB_ERROR_GENERIC; + + // Use input + if (context.mode == IOB_MODE_STDIN || context.mode == IOB_MODE_SCRIPT) + { + ssize_t nread = getline(&stream_buf, &stream_buf_size, input); + if (nread == -1) + { + state = IOB_STATE_FINISHED; + return 0; + } + else if (nread < 0) + state = IOB_STATE_ERROR; + + return nread; + } + // Use args + else if (context.mode == IOB_MODE_CMD) + { + *stream = context.args; + return strlen(context.args); + } + else + { + *stream = NULL; + return IOB_ERROR_GENERIC; } } diff --git a/src/io_backend/io_backend.h b/src/io_backend/io_backend.h index 0bcfdca..c2079f0 100644 --- a/src/io_backend/io_backend.h +++ b/src/io_backend/io_backend.h @@ -3,6 +3,13 @@ #include +// Error codes +#define IOB_ERROR_GENERIC -1 +#define IOB_ERROR_BAD_ARG -2 +#define IOB_ERROR_MODULE_NOT_INITIALIZED -3 +#define IOB_ERROR_MODULE_ALREADY_INITALIZED -4 +#define IOB_ERROR_CANNOT_OPEN_FILE -5 + enum iob_mode { IOB_MODE_NULL = 0, IOB_MODE_STDIN, @@ -10,11 +17,18 @@ enum iob_mode { IOB_MODE_CMD }; +enum iob_state { + IOB_STATE_NOT_INITIALIZED, + IOB_STATE_READY, + IOB_STATE_FINISHED, + IOB_STATE_ERROR +}; + /* @struct iob_context * @var mode * @var args contains - * the script name when mode is set to IOB_SCRIPT, - * the command to execute when mode is set to IOB_CMD, + * the script name when mode is set to IOB_MODE_SCRIPT, + * the command to execute when mode is set to IOB_MODE_CMD */ struct iob_context { enum iob_mode mode; @@ -29,14 +43,16 @@ struct iob_context { */ int iob_init(struct iob_context *context); -/* @brief Closes the opened buffers and exits the modules gracefully +/* @brief Closes the opened buffers and the module gracefully */ void iob_close(void); /* @brief reads at most one line of the input and stores it into *stream * * @param stream is a pointer that will be set to a string to parse - * @return the number of read characters if positive, the error code otherwise + * @return the number of read characters if positive, + * zero if finished (reached EOF), + * the error code otherwise */ ssize_t stream_read(char** stream);