Add stream structure and utilities

This commit is contained in:
2026-08-30 02:18:30 +01:00
parent a51686c8f0
commit c1b2e29c07
9 changed files with 237 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "stream.h"
#include "../../common/aliases/aliases.h"
#include "../../common/assert/assert.h"
void _streamValidate(const WpStream *stream, u64 item_size);
b8 _streamAtEnd(const WpStream *stream, u64 item_size) {
_streamValidate(stream, item_size);
return stream->position >= stream->count;
}
b8 _streamHasNext(const WpStream *stream, u64 item_size) {
_streamValidate(stream, item_size);
return stream->position + 1 < stream->count;
}
void *_streamPeek(const WpStream *stream, u64 item_size) {
if (_streamHasNext(stream, item_size)) {
u64 index = (stream->position + 1) * stream->item_size;
return (void *)(&((u8 *)(stream->data))[index]);
}
return NULL;
}
void *_streamConsume(WpStream *stream, u64 item_size) {
if (!_streamAtEnd(stream, item_size)) {
u64 index = stream->position++ * stream->item_size;
return (void *)(&((u8 *)(stream->data))[index]);
}
return NULL;
}
void _streamValidate(const WpStream *stream, u64 item_size) {
wpDebugAssert(stream != NULL, "`stream` should not be NULL");
wpRuntimeAssert(stream->item_size == item_size, "Invalid item type provided");
}
+75
View File
@@ -0,0 +1,75 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef STREAM_H
#define STREAM_H
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP
typedef struct {
void *data;
u64 count;
u64 position;
u64 item_size;
} WpStream;
// NOTE (Abdelrahman): WpStream typedefs for readability
typedef WpStream WpVoidPtrStream;
typedef WpStream WpC8Stream;
typedef WpStream WpC16Stream;
typedef WpStream WpC32Stream;
typedef WpStream WpU8Stream;
typedef WpStream WpU16Stream;
typedef WpStream WpU32Stream;
typedef WpStream WpU64Stream;
typedef WpStream WpB8Stream;
typedef WpStream WpI8Stream;
typedef WpStream WpI16Stream;
typedef WpStream WpI32Stream;
typedef WpStream WpI64Stream;
typedef WpStream WpF32Stream;
typedef WpStream WpF64Stream;
typedef WpStream WpF128Stream;
typedef WpStream WpUptrStream;
typedef WpStream WpIptrStream;
typedef WpStream WpStr8Stream;
#ifdef WP_PLATFORM_CPP
#define wpStream(TYPE, DATA, SIZE) ([&]() { \
return WpStream{ \
DATA, \
SIZE / sizeof(TYPE), \
0, \
sizeof(TYPE) \
}; \
}())
#else
#define wpStream(TYPE, DATA, SIZE) ( \
(WpStream){ \
.data = DATA, \
.count = SIZE / sizeof(TYPE), \
.position = 0, \
.item_size = sizeof(TYPE) \
} \
)
#endif
#define wpStreamAtEnd(TYPE, STREAM) _streamAtEnd(STREAM, sizeof(TYPE))
#define wpStreamHasNext(TYPE, STREAM) _streamHasNext(STREAM, sizeof(TYPE))
#define wpStreamPeek(TYPE, STREAM) ((TYPE *)_streamPeek(STREAM, sizeof(TYPE)))
#define wpStreamConsume(TYPE, STREAM) ((TYPE *)_streamConsume(STREAM, sizeof(TYPE)))
b8 _streamAtEnd(const WpStream *stream, u64 item_size);
b8 _streamHasNext(const WpStream *stream, u64 item_size);
void *_streamPeek(const WpStream *stream, u64 item_size);
void *_streamConsume(WpStream *stream, u64 item_size);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WP_PLATFORM_CPP
#endif // !STREAM_H
+1
View File
@@ -7,6 +7,7 @@
#include "array/array.c" #include "array/array.c"
#include "dbl_list/dbl_list.c" #include "dbl_list/dbl_list.c"
#include "queue/queue.c" #include "queue/queue.c"
#include "stream/stream.c"
#include "mem/allocator/mem_allocator.c" #include "mem/allocator/mem_allocator.c"
#include "mem/utils/mem_utils.c" #include "mem/utils/mem_utils.c"
#include "strings/str8/str8.c" #include "strings/str8/str8.c"
+1
View File
@@ -6,6 +6,7 @@
#include "array/array.h" #include "array/array.h"
#include "dbl_list/dbl_list.h" #include "dbl_list/dbl_list.h"
#include "queue/queue.h" #include "queue/queue.h"
#include "stream/stream.h"
#include "mem/allocator/mem_allocator.h" #include "mem/allocator/mem_allocator.h"
#include "mem/utils/mem_utils.h" #include "mem/utils/mem_utils.h"
#include "strings/str8/str8.h" #include "strings/str8/str8.h"
+50
View File
@@ -0,0 +1,50 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_stream.h"
#define COUNT 3
WpTestFuncResult test_stream_at_end(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
for (u32 i = 0; i < COUNT; ++i) {
wpStreamConsume(c8, &stream);
result = result && (i == 2 ? wpStreamAtEnd(c8, &stream) : !wpStreamAtEnd(c8, &stream));
}
return wpTesterResult(result);
}
WpTestFuncResult test_stream_peek(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = NULL;
while (!wpStreamAtEnd(c8, &stream)) {
c = wpStreamPeek(c8, &stream);
wpStreamConsume(c8, &stream);
result = result && (wpStreamAtEnd(c8, &stream) ? c == NULL : c != NULL);
}
return wpTesterResult(result);
}
WpTestFuncResult test_stream_consume(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = NULL;
for (u32 i = 0; i <= COUNT; ++i) {
c = wpStreamConsume(c8, &stream);
result = result && (i == COUNT ? c == NULL : c != NULL);
}
return wpTesterResult(result);
}
+50
View File
@@ -0,0 +1,50 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_stream.h"
#define COUNT 3
WpTestFuncResult test_stream_at_end(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
for (u32 i = 0; i < COUNT; ++i) {
wpStreamConsume(c8, &stream);
result = result && (i == 2 ? wpStreamAtEnd(c8, &stream) : !wpStreamAtEnd(c8, &stream));
}
return wpTesterResult(result);
}
WpTestFuncResult test_stream_peek(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = NULL;
while (!wpStreamAtEnd(c8, &stream)) {
c = wpStreamPeek(c8, &stream);
wpStreamConsume(c8, &stream);
result = result && (wpStreamAtEnd(c8, &stream) ? c == NULL : c != NULL);
}
return wpTesterResult(result);
}
WpTestFuncResult test_stream_consume(void) {
b8 result = true;
c8 characters[COUNT] = {'a', 'b', 'c'};
WpC8Stream stream = wpStream(c8, characters, COUNT);
c8 *c = NULL;
for (u32 i = 0; i <= COUNT; ++i) {
c = wpStreamConsume(c8, &stream);
result = result && (i == COUNT ? c == NULL : c != NULL);
}
return wpTesterResult(result);
}
+12
View File
@@ -0,0 +1,12 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TEST_STREAM_H
#define TEST_STREAM_H
#include "wapp.h"
WpTestFuncResult test_stream_at_end(void);
WpTestFuncResult test_stream_peek(void);
WpTestFuncResult test_stream_consume(void);
#endif // !TEST_STREAM_H
+4
View File
@@ -5,6 +5,7 @@
#include "test_str8_array.h" #include "test_str8_array.h"
#include "test_i32_array.h" #include "test_i32_array.h"
#include "test_queue.h" #include "test_queue.h"
#include "test_stream.h"
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h" #include "test_file.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
@@ -47,6 +48,9 @@ int main(void) {
test_queue_push, test_queue_push,
test_queue_push_alloc, test_queue_push_alloc,
test_queue_pop, test_queue_pop,
test_stream_at_end,
test_stream_peek,
test_stream_consume,
test_str8_lit, test_str8_lit,
test_str8_lit_ro, test_str8_lit_ro,
test_str8_buf, test_str8_buf,
+4
View File
@@ -5,6 +5,7 @@
#include "test_str8_array.h" #include "test_str8_array.h"
#include "test_i32_array.h" #include "test_i32_array.h"
#include "test_queue.h" #include "test_queue.h"
#include "test_stream.h"
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h" #include "test_file.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
@@ -47,6 +48,9 @@ int main(void) {
test_queue_push, test_queue_push,
test_queue_push_alloc, test_queue_push_alloc,
test_queue_pop, test_queue_pop,
test_stream_at_end,
test_stream_peek,
test_stream_consume,
test_str8_lit, test_str8_lit,
test_str8_lit_ro, test_str8_lit_ro,
test_str8_buf, test_str8_buf,