O2S C Library 1.8.2
Provide high-level data-structures and other fundamental tools for C projects
Loading...
Searching...
No Matches
read.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* ____ _ _____ ____ _ _ _ _____ _ _ ____ ____ */
3/* / ___| / \ | ___| _ \ / \ | \ | | |_ _| || | | _ \/ ___| */
4/* \___ \ / _ \ | |_ | |_) | / _ \ | \| | | | | || |_| | | \___ \ */
5/* ___) / ___ \| _| | _ < / ___ \| |\ | | | |__ _| |_| |___) | */
6/* |____/_/ \_|_| |_| \_/_/ \_|_| \_| |_| |_| |____/|____/ */
7/* */
14/* ************************************************************************** */
15
17#include "o2s/log.h"
18
19#include <errno.h>
20#include <iso646.h> // not, and
21#include <string.h> // strerror
22#include <unistd.h> // read
23#include <stdbool.h>
24
25#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 202300L
26# warning including threads.h to have thread_local before C23
27# include <threads.h> // thread_local
28#endif
29
31static thread_local bool keep_reading = true;
32
39{
40 queue_t* queue = &file->stream.buffer;
41 const size_t room = queue_room(queue);
42 uint8_t buffer[room];
43 const ssize_t result = read(file->descriptor, buffer, room);
44
45 if (result < 0)
46 log_error("read returned %zi: %s", result, strerror(errno));
47 else if (result > 0 and not queue_push_n(queue, buffer, result))
48 { /* This branch is impossible to reach if this thread has exclusive access to the queue, which it should */
49 log_error("cannot add %zi characters to the queue, %zu / %zu bytes used", result, queue_count(queue), queue_capacity(queue));
50 return -1;
51 }
52 return result;
53}
54
69bool file_accumulate_infinite(ifstream_t* file, size_t count)
70{
71 while (not istream_has_at_least(&file->stream, count))
72 if (not keep_reading or file_single_read(file) < 0)
73 return false;
74 return true;
75}
76
87bool file_accumulate(ifstream_t* file, size_t count)
88{
89 while (not istream_has_at_least(&file->stream, count))
90 if (file_single_read(file) <= 0)
91 return false;
92 return true;
93}
94
101{
102 keep_reading = false;
103}
104
107{
108 keep_reading = true;
109}
110
112void file_default_signal_handler(int, siginfo_t*, void*)
113{
115}
Buffered file reader.
bool istream_has_at_least(const istream_t *self, size_t count)
Test if enough characters are available.
Definition input.c:37
Simplistic logging utilities.
#define log_error(...)
Report a condition causing the current operation to abort.
Definition log.h:83
size_t queue_capacity(const queue_t *self)
Number of elements that can be stored in the queue.
Definition queue.c:61
bool queue_push_n(queue_t *self, const void *elements, size_t count)
Add count elements to the queue.
Definition queue.c:31
size_t queue_count(const queue_t *self)
Number of elements currently in the queue.
Definition queue.c:55
size_t queue_room(const queue_t *self)
Number of elements that can be added.
Definition queue.c:49
deque_t queue_t
A queue is First In First Out.
Definition queue.h:21
void file_default_signal_handler(int, siginfo_t *, void *)
Default signal handler.
Definition read.c:112
void file_resume_reading(void)
Resume calling read in this thread.
Definition read.c:106
void file_stop_reading(void)
Prevent the accumulate function from calling read in this thread.
Definition read.c:100
bool file_accumulate_infinite(ifstream_t *file, size_t count)
If possible, accumulate count bytes before returning.
Definition read.c:69
bool file_accumulate(ifstream_t *file, size_t count)
If possible, accumulate count bytes before returning.
Definition read.c:87
ssize_t file_single_read(ifstream_t *file)
Read as much as possible.
Definition read.c:38
Dynamic string implementation.
File Input Stream.
int descriptor
Underlying file.
istream_t stream
Inherit from input stream.
queue_t buffer
Circular buffer of bytes.