Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .studio-run-configs/test-fileread.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="test-fileread" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/helper-scripts/ci-cd/test-electrostatic.sh" />
<option name="SCRIPT_OPTIONS" value="&quot;linux/hello_file_read.c&quot; &quot;hello_file_read&quot;" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/bash" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="true" />
<envs />
<method v="2" />
</configuration>
</component>
17 changes: 17 additions & 0 deletions .studio-run-configs/test-filewrite.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="test-filewrite" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/helper-scripts/ci-cd/test-electrostatic.sh" />
<option name="SCRIPT_OPTIONS" value="&quot;linux/hello_file_write.c&quot; &quot;hello_file_write&quot;" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/bash" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="true" />
<envs />
<method v="2" />
</configuration>
</component>
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@
extern "C" {
#endif

enum list_type {
CONTIGUOUS_BUFFER,
LINKED_BUFFER
};

struct list_element {
void *data;
void *metadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@
extern "C" { // disables the C++ name mangling
#endif

enum linked_buffer_type {
SINGLE_ENDED,
DOUBLE_ENDED,
};

struct linked_buffer {
// no alignment issues
// 64-bit (8 bytes) aligned structure
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
* @brief A completely memory-safe not internally synchronized API that provides a dynamic
* way of reading and writing to files without a [realloc] overhead; by delegating memory
* allocation as a part of the pre-processor states to the caller, and the memory deallocation or further reallocation calls
* as a part of the accepting states to another function of the caller API or Application.
* @note Synchronization (using polling or mutexes) could be introduced through the lifecycle struct
* [file_op_processor] for file operation processor.
* @author pavl_g.
* @date 2025-10
*/
#ifndef _FILE_OPERATIONS_H_
#define _FILE_OPERATIONS_H_

#ifndef _ELECTRO_MIO

#ifdef __ANDROID__
#define __off_t size_t
#endif

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <electrostatic/electronetsoft/util/utilities.h>

struct read_op_processor {
void (*on_bytes_processed)(file_mem *, ssize_t, void *); /* Executed on each successful read operation. */
void (*on_eof_reached)(file_mem *); /* Executed when EOF is reached. Could be used to chain calls to memory deallocators. */
void (*on_last_char_sampled)(file_mem *, void *caller);
void (*on_error_encountered)(file_mem *, int, void *caller);
};

struct write_op_processor {
void (*on_bytes_processed)(file_mem *, ssize_t, void *); /* Executed on each successful read operation. */
void (*on_eob_reached)(file_mem *);
void (*on_last_char_sampled)(file_mem *, void *caller);
void (*on_error_encountered)(file_mem *, int, void *caller);
};

struct update_op_processor {
void (*on_update_nbytes)(file_mem *, ssize_t); /* Executed when updating the number of bytes attr (of the buffer for the file mem model) is commenced */
void (*on_update_size)(file_mem *, __off_t); /* Executed when updating size is commenced. */
void (*on_update_pos)(file_mem *, __off_t); /* Executed when updating the position is commenced. */
void (*update_model_preprocessor)(file_mem *, void *caller); /* Executed */
void (*update_model_postprocessor)(file_mem *, void *caller); /* Executed after the file mem model attrs update has finished. Could be used to chain calls to memory allocators. */
};

struct serializer_op_processor {
void (*serializer_init_preprocessor)(pipe_serializer *);
void (*serializer_init_postprocessor)(pipe_serializer *);
};

struct file_mem {
int fd;
char trailing; /* The trailing byte of the buffer.*/
ssize_t n_bytes; /* Total number of bytes to allocate for the buffer in memory
* including the number of read or write bytes
* starting from the current pos based on
* the file size, and the trailing byte. */
ssize_t bytes_processed;
char *buffer;
__off_t file_size; /* Cached file size in bytes */
__off_t file_pos; /* Cached file position */
uint8_t __auto_update_attrs; /* Conditional flag to specify whether auto-update
* in the pre-processing stage is enabled. */
uint8_t __continue_after_eof; /* Conditional flag to specify whether to continue after the EOF. */
};

/**
* @brief A pipe-serializer object creates a pipe that has
* a write end and read end; both ends are mapped to the same
* filesystems, in which the write operations are available to be read
* by the memory model processor. Therefore, both memory models utilize
* a shared memory buffer, but they possess different filesystems and thus
* different file positions.
*/
struct pipe_serializer {
file_mem read_end;
file_mem write_end;
};


/**
* @brief Delegates to allocate a heap buffer and reads a file identified by this file descriptor
* into the heap memory; returning the memory address into the
* [buffer] pointer of the file memory model object.
*
* @param mem a pointer to the file memory model struct.
* @param _processor a pointer to the file read operations processor; that links the API to the user application.
* @param __processor a pointer to the file attrs update processors.
*/
status_code read_into_mem(file_mem *, read_op_processor *, update_op_processor *);

status_code update_file_attrs(file_mem *, update_op_processor *);

/**
* @brief Writes a pre-allocated buffer to a file identified by a file descriptor from
* the file memory model structure; until reaching the trailing character which is excluded
* from the this write operation and marks the accepting state of this machine.
*
* @param mem a pointer to the file memory model struct.
* @param processor a pointer to the file operations processor; that links the API to the user application.
*/
status_code write_from_mem(file_mem *, write_op_processor *, update_op_processor *);

status_code init_serializer(pipe_serializer *, serializer_op_processor *, update_op_processor *);

#ifdef __cplusplus
}
#endif

#endif
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef _FILE_ATTRS_H_
#define _FILE_ATTRS_H_

#ifndef _ELECTRO_MIO

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <electrostatic/electronetsoft/util/utilities.h>

static inline status_code get_file_bytes(int fd, __off_t *__size) {
if (fd < 0 || NULL == __size) {
return EUNDEFINEDBUFFER;
}
struct stat statbuf;
int __status = fstat(fd, &statbuf);
if (__status != 0) {
return errno;
}
*__size = statbuf.st_size;

return PASS;
}

static inline status_code get_file_pos(int fd, off_t *__offset) {
if (fd < 0 || NULL == __offset) {
return EUNDEFINEDBUFFER;
}
*__offset = lseek(fd, 0, SEEK_CUR);
if (*__offset < 0) {
return errno;
}
return PASS;
}

#ifdef __cplusplus
}
#endif

#endif
#endif
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef _FILE_VERIFY_H_
#define _FILE_VERIFY_H_

#ifndef _ELECTRO_MIO

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -145,4 +147,5 @@ static inline int is_fsymbolic_link(int fd) {
}
#endif

#endif
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,31 @@
#ifndef __TYPES_H_
#define __TYPES_H_

#include <inttypes.h>

#ifdef __cplusplus
extern "C" { // disables C++ Name Mangling
#endif

// Abstract Data Types for Lists
typedef struct list (list);
typedef struct list_info (list_info);
typedef enum list_type (list_type);

typedef enum list_type {
CONTIGUOUS_BUFFER,
LINKED_BUFFER
} list_type;

typedef struct list_element (list_element);
typedef struct list_function_table (list_function_table);

// Concretized types for linked buffers
typedef struct linked_buffer (linked_buffer);
typedef enum linked_buffer_type (linked_buffer_type);

typedef enum linked_buffer_type {
SINGLE_ENDED,
DOUBLE_ENDED,
} linked_buffer_type;

// Abstract types for Mathematical Graph Structures
typedef struct vertex (vertex);
Expand All @@ -45,8 +56,23 @@ typedef struct dijkstra_structure (dijkstra_structure);
typedef struct api_lifecycle (api_lifecycle);
typedef struct typed_pointer (typed_pointer);
typedef union pointer (pointer);
typedef enum pointer_type (pointer_type);
typedef enum status_code (status_code);

typedef enum status_code {
PASS = INT32_MAX,
EUNDEFINEDBUFFER = INT32_MIN,
EEMPTYBUFFER = (EUNDEFINEDBUFFER + 1),
EFULLBUFFER = (EEMPTYBUFFER + 1),
EINCOMPATTYPE = (EFULLBUFFER + 1),
ENOELEMENT = (EINCOMPATTYPE + 1),
EBUFFERTURNCATION = (ENOELEMENT + 1),
EBUFFEROVERFLOW = (EBUFFERTURNCATION + 1),
EDLLOPENFAIL = (EBUFFEROVERFLOW + 1),
EDLLSYMFAIL = (EDLLOPENFAIL + 1),
EDLLCONVENTIONCALLRETURN = (EDLLSYMFAIL + 1),
UNEXPECTED_ERROR = (EDLLCONVENTIONCALLRETURN + 1),
ASSERTION_SUCCESS = 1,
ASSERTION_FAILURE = 0
} status_code;

typedef struct memory_partition (memory_partition);

Expand All @@ -55,6 +81,14 @@ typedef struct routine_data (routine_data);
typedef struct dll_function_table (dll_function_table);
typedef struct routine_callbacks (routine_callbacks);

typedef struct write_op_processor (write_op_processor);
typedef struct read_op_processor (read_op_processor);
typedef struct update_op_processor (update_op_processor);

typedef struct serializer_op_processor (serializer_op_processor);
typedef struct file_mem (file_mem);
typedef struct pipe_serializer (pipe_serializer);

// Types for Vector Maths Libraries
typedef struct vector2d (vector2d);

Expand Down
Loading