Skip to content

Commit 72318c7

Browse files
committed
electrostatic-examples: added electrostatic examples for the File Memory Model API
1 parent e36943b commit 72318c7

5 files changed

Lines changed: 373 additions & 0 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="test-fileread" type="ShConfigurationType">
3+
<option name="SCRIPT_TEXT" value="" />
4+
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
5+
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/helper-scripts/ci-cd/test-electrostatic.sh" />
6+
<option name="SCRIPT_OPTIONS" value="&quot;linux/hello_file_read.c&quot; &quot;hello_file_read&quot;" />
7+
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
8+
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
9+
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
10+
<option name="INTERPRETER_PATH" value="/bin/bash" />
11+
<option name="INTERPRETER_OPTIONS" value="" />
12+
<option name="EXECUTE_IN_TERMINAL" value="true" />
13+
<option name="EXECUTE_SCRIPT_FILE" value="true" />
14+
<envs />
15+
<method v="2" />
16+
</configuration>
17+
</component>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="test-filewrite" type="ShConfigurationType">
3+
<option name="SCRIPT_TEXT" value="" />
4+
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
5+
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/helper-scripts/ci-cd/test-electrostatic.sh" />
6+
<option name="SCRIPT_OPTIONS" value="&quot;linux/hello_file_write.c&quot; &quot;hello_file_write&quot;" />
7+
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
8+
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
9+
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
10+
<option name="INTERPRETER_PATH" value="/bin/bash" />
11+
<option name="INTERPRETER_OPTIONS" value="" />
12+
<option name="EXECUTE_IN_TERMINAL" value="true" />
13+
<option name="EXECUTE_SCRIPT_FILE" value="true" />
14+
<envs />
15+
<method v="2" />
16+
</configuration>
17+
</component>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* @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.
3+
* @author pavl_g.
4+
* @date 10-2025
5+
*/
6+
#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>
7+
#include <errno.h>
8+
#include <string.h>
9+
#include <stdio.h>
10+
#include <unistd.h>
11+
#include <stdlib.h>
12+
#include <fcntl.h>
13+
14+
static inline void update_model_preprocessor(file_mem *mem, void *caller) {
15+
if (caller != &read_into_mem) {
16+
return;
17+
}
18+
19+
int fd = open("/etc/bash.bashrc", O_RDONLY);
20+
21+
if (fd < 0) {
22+
fprintf(stderr, "Error Encountered: %s\n", strerror(errno));
23+
exit(errno);
24+
}
25+
26+
mem->fd = fd;
27+
}
28+
29+
static inline void update_model_postprocessor(file_mem *mem, void *caller) {
30+
if (caller != &read_into_mem) {
31+
return;
32+
}
33+
34+
if (mem->fd == STDIN_FILENO) {
35+
mem->n_bytes = 2; // two bytes are given; the leading and the trailing byte.
36+
// marking the start and the end of the string buffer
37+
}
38+
fprintf(stdout, "Size of memory buffer (in bytes) = %zd\n",
39+
mem->n_bytes);
40+
mem->buffer = calloc(mem->n_bytes, sizeof (char));
41+
42+
if (NULL == mem->buffer) {
43+
return;
44+
}
45+
}
46+
47+
static inline void on_bytes_processed(file_mem *mem,
48+
ssize_t bytes, void *caller) {
49+
if (caller != &read_into_mem) {
50+
return;
51+
}
52+
fprintf(stdout, "Read bytes = %s\n", mem->buffer);
53+
}
54+
55+
static inline void on_eof_reached(file_mem *mem) {
56+
// support for stdin
57+
if (mem->fd == STDIN_FILENO && mem->n_bytes < 20) {
58+
mem->n_bytes += mem->n_bytes;
59+
mem->buffer = realloc(mem->buffer, mem->n_bytes);
60+
return;
61+
}
62+
fprintf(stdout, "Read Bytes after EOF: %s\n", mem->buffer);
63+
fprintf(stdout, "EOF Reached!\n");
64+
// deallocates memory here!
65+
if (NULL != mem->buffer) {
66+
free(mem->buffer);
67+
mem->buffer = NULL;
68+
}
69+
int __status = close(mem->fd);
70+
if (0 != __status) {
71+
fprintf(stderr, "Error Encountered: %s\n", strerror(__status));
72+
exit(__status);
73+
}
74+
}
75+
76+
int main() {
77+
fprintf(stdout, "Hello File Read Automata!\n");
78+
79+
file_mem _file_mem = {
80+
.fd = -1,
81+
.trailing = '\0',
82+
.buffer = NULL,
83+
.n_bytes = -1,
84+
.file_size = -1,
85+
.file_pos = -1,
86+
.__auto_update_attrs = 1,
87+
.__continue_after_eof = 0
88+
};
89+
90+
read_op_processor _processor = {
91+
.on_bytes_processed = &on_bytes_processed,
92+
.on_eof_reached = &on_eof_reached
93+
};
94+
95+
update_op_processor __processor = {
96+
.update_model_preprocessor = &update_model_preprocessor,
97+
.update_model_postprocessor = &update_model_postprocessor,
98+
};
99+
100+
status_code __status = read_into_mem(&_file_mem, &_processor, &__processor);
101+
102+
if (PASS != __status) {
103+
fprintf(stderr, "Error Encountered: %s\n", strerror(__status));
104+
exit(__status);
105+
}
106+
107+
return 0;
108+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* @brief A tech-demo for the implementation of the file writing algorithm using polling that provides an algorithm to write out a buffer to a file and a post processing automata to update the file attributes using the file stat attributes from the Unix Standard library by requesting a call to the file status utility.
3+
* @author pavl_g.
4+
* @date 10-2025
5+
*/
6+
#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>
7+
#include <errno.h>
8+
#include <string.h>
9+
#include <stdio.h>
10+
#include <unistd.h>
11+
#include <stdlib.h>
12+
#include <fcntl.h>
13+
14+
static inline void update_model_preprocessor(file_mem *mem,
15+
void *caller) {
16+
if (caller != &write_from_mem) {
17+
return;
18+
}
19+
20+
int fd = open("/home/pavl-g/Desktop/test.txt", O_RDWR | O_CREAT);
21+
22+
if (fd < 0) {
23+
fprintf(stderr, "Error Encountered: %s\n", strerror(errno));
24+
exit(errno);
25+
}
26+
27+
mem->fd = fd;
28+
lseek(mem->fd, 0, SEEK_END); // append!
29+
30+
mem->buffer = "Hello from Project: ElectroNetSoft, File Memory Modelling API.\n";
31+
mem->n_bytes = strlen(mem->buffer) + 1;
32+
33+
fprintf(stdout, "Size of memory buffer (in bytes) = %zd\n",
34+
mem->n_bytes);
35+
}
36+
37+
static inline void on_bytes_processed(file_mem *mem, ssize_t bytes,
38+
void *caller) {
39+
if (caller != &write_from_mem) {
40+
return;
41+
}
42+
43+
fprintf(stdout, "%s", mem->buffer);
44+
}
45+
46+
static inline void on_eob_reached(file_mem *mem) {
47+
fprintf(stdout, "EOB Reached!\n");
48+
}
49+
50+
static inline void update_model_postprocessor(file_mem *mem,
51+
void *caller) {
52+
if (caller != &write_from_mem) {
53+
return;
54+
}
55+
close(mem->fd);
56+
mem->fd = -1;
57+
}
58+
59+
int main() {
60+
fprintf(stdout, "Hello File Write Automata!\n");
61+
62+
file_mem _file_mem = {
63+
.fd = -1,
64+
.trailing = '\0',
65+
.buffer = NULL,
66+
.n_bytes = -1,
67+
.file_size = -1,
68+
.file_pos = -1,
69+
.__auto_update_attrs = 1,
70+
};
71+
72+
write_op_processor _processor = {
73+
.on_bytes_processed = &on_bytes_processed,
74+
.on_eob_reached = &on_eob_reached,
75+
};
76+
77+
update_op_processor __processor = {
78+
.update_model_preprocessor = &update_model_preprocessor,
79+
.update_model_postprocessor = &update_model_postprocessor,
80+
};
81+
82+
status_code __status = write_from_mem(&_file_mem, &_processor, &__processor);
83+
84+
if (PASS != __status) {
85+
fprintf(stderr, "Error Encountered: %s\n", strerror(__status));
86+
exit(__status);
87+
}
88+
89+
return 0;
90+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* @brief This example creates a physical pipe and serializes data
3+
* between 2 processes over the off-heap memory. Synchronization and concurrency
4+
* is implemented utilizing Polling over a boolean flag on the lifecycle pattern
5+
* of the read_op component.
6+
*
7+
* @author pavl_g.
8+
*/
9+
#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
#include <fcntl.h>
13+
#include <string.h>
14+
#include <time.h>
15+
16+
static inline void on_error_encountered(file_mem *mem, int err, void *caller) {
17+
fprintf(stderr, "%s\n", strerror(err));
18+
}
19+
20+
static inline void on_eof_reached(file_mem *mem) {
21+
// -------- Start the polling block --------
22+
uint8_t __predicate = mem->bytes_processed == 0;
23+
if (__predicate) {
24+
mem->__continue_after_eof = 1;
25+
// -------- Connect the polling block to the read automaton --------
26+
return;
27+
}
28+
// -------- End of the polling block --------
29+
fprintf(stdout, "Read process = %s\n", mem->buffer);
30+
free(mem->buffer);
31+
mem->buffer = NULL;
32+
mem->__continue_after_eof = 0;
33+
34+
close(mem->fd);
35+
}
36+
37+
static inline void on_eob_reached(file_mem *mem) {
38+
fprintf(stdout, "Write process = %s", mem->buffer);
39+
close(mem->fd);
40+
}
41+
42+
static inline void on_last_char_sampled(file_mem *mem, void *caller) {
43+
mem->n_bytes += mem->n_bytes;
44+
mem->buffer = realloc(mem->buffer, sizeof (char) * (mem->n_bytes));
45+
}
46+
47+
static inline void on_bytes_processed(file_mem *mem, ssize_t bytes,
48+
void *caller) {
49+
}
50+
51+
static inline void writing_process(pipe_serializer *serializer) {
52+
53+
serializer->write_end.buffer = "Hello From the Electrostatic-Sandbox SDK Pipe Serializer...\n";
54+
serializer->write_end.n_bytes = strlen(serializer->write_end.buffer) + 1;
55+
56+
sleep(10); // simulate jobs by sleeping the process
57+
58+
write_from_mem(&serializer->write_end, &(write_op_processor ) {
59+
.on_eob_reached = &on_eob_reached,
60+
.on_bytes_processed = &on_bytes_processed
61+
}, NULL);
62+
}
63+
64+
static inline void reading_process(pipe_serializer *serializer) {
65+
66+
serializer->read_end.n_bytes = 2;
67+
serializer->read_end.buffer = calloc(serializer->read_end.n_bytes, sizeof (char));
68+
69+
if (serializer->read_end.buffer == NULL) {
70+
fprintf(stderr, "Error: %s\n", strerror(errno));
71+
exit(errno);
72+
}
73+
74+
status_code __status = read_into_mem(&serializer->read_end, &(read_op_processor) {
75+
.on_eof_reached = &on_eof_reached,
76+
.on_last_char_sampled = &on_last_char_sampled,
77+
.on_bytes_processed = &on_bytes_processed,
78+
.on_error_encountered = &on_error_encountered
79+
}, NULL);
80+
81+
if (PASS != __status) {
82+
fprintf(stderr, "%s\n", strerror(__status));
83+
exit(errno);
84+
}
85+
}
86+
87+
static inline void serializer_init_preprocessor(pipe_serializer *serializer) {
88+
// preprocessing check the file and remove it if it exists
89+
// for the test and the showcase
90+
91+
}
92+
93+
static inline void serializer_init_postprocessor(pipe_serializer *serializer) {
94+
// do the read/write testing here!
95+
serializer->write_end.fd = open("/home/pavl-g/Desktop/test.txt", O_RDWR | O_CREAT);
96+
serializer->read_end.fd = open("/home/pavl-g/Desktop/test.txt", O_RDONLY);
97+
98+
// start another process
99+
pid_t pid = fork();
100+
if (pid > 0) { // parent process
101+
writing_process(serializer);
102+
} else if (pid == 0) { // subprocess
103+
reading_process(serializer);
104+
} else {
105+
106+
}
107+
}
108+
109+
110+
int main() {
111+
pipe_serializer serializer = {
112+
.read_end = (file_mem) {
113+
.fd = -1,
114+
.trailing = '\0',
115+
.buffer = NULL,
116+
.n_bytes = -1,
117+
.__auto_update_attrs = 0
118+
},
119+
.write_end = (file_mem) {
120+
.fd = -1,
121+
.trailing = '\0',
122+
.buffer = NULL,
123+
.n_bytes = -1
124+
}
125+
};
126+
127+
serializer_op_processor _processor = {
128+
.serializer_init_preprocessor = &serializer_init_preprocessor,
129+
.serializer_init_postprocessor = &serializer_init_postprocessor
130+
};
131+
132+
update_op_processor __processor = {
133+
};
134+
135+
status_code __status_code = init_serializer(&serializer, &_processor, &__processor);
136+
if (PASS != __status_code) {
137+
return __status_code;
138+
}
139+
140+
return 0;
141+
}

0 commit comments

Comments
 (0)