commit 510edcd900399f361760979a7136fea8e7f57dcd
parent a6d69e947371ca75994abf3a78bda79458b9be03
Author: MikoĊaj Lenczewski <mblenczewski@gmail.com>
Date: Mon, 13 Feb 2023 00:41:56 +0000
Enable writing to `struct mem_stream`, and add riot mem_stream helpers
Diffstat:
4 files changed, 185 insertions(+), 0 deletions(-)
diff --git a/include/utils.h b/include/utils.h
@@ -75,6 +75,33 @@ mem_stream_consume(struct mem_stream *self, void *buf, u64 len) {
return mem_stream_peek(self, 0, buf, len) && mem_stream_skip(self, len);
}
+static inline bool
+mem_stream_resize(struct mem_stream *self, u64 capacity) {
+ assert(self);
+
+ u8 *ptr = realloc(self->ptr, capacity);
+ if (!ptr) return false;
+
+ self->ptr = ptr;
+ self->len = capacity;
+
+ return true;
+}
+
+static inline u64
+mem_stream_push(struct mem_stream *self, void *buf, u64 len) {
+ assert(self);
+ assert(buf);
+
+ if (self->len - self->cur < len && !mem_stream_resize(self, self->cur + len))
+ return 0;
+
+ memcpy(self->ptr + self->cur, buf, len);
+ self->cur += len;
+
+ return len;
+}
+
struct mem_pool {
u8 *ptr;
u64 cap, len;
diff --git a/libriot/include/libriot/utils.h b/libriot/include/libriot/utils.h
@@ -0,0 +1,95 @@
+#ifndef LIBRIOT_UTILS_H
+#define LIBRIOT_UTILS_H
+
+#include "common.h"
+#include "utils.h"
+
+#include "libriot.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* extension methods to `struct mem_stream` to read riot primitives
+ */
+
+extern b32
+riot_mem_stream_read_chr8(struct mem_stream *self, char *out);
+
+extern b32
+riot_mem_stream_read_b8(struct mem_stream *self, b8 *out);
+
+extern b32
+riot_mem_stream_read_s8(struct mem_stream *self, s8 *out);
+
+extern b32
+riot_mem_stream_read_s16(struct mem_stream *self, s16 *out);
+
+extern b32
+riot_mem_stream_read_s32(struct mem_stream *self, s32 *out);
+
+extern b32
+riot_mem_stream_read_s64(struct mem_stream *self, s64 *out);
+
+extern b32
+riot_mem_stream_read_u8(struct mem_stream *self, u8 *out);
+
+extern b32
+riot_mem_stream_read_u16(struct mem_stream *self, u16 *out);
+
+extern b32
+riot_mem_stream_read_u32(struct mem_stream *self, u32 *out);
+
+extern b32
+riot_mem_stream_read_u64(struct mem_stream *self, u64 *out);
+
+extern b32
+riot_mem_stream_read_fnv1a_u32(struct mem_stream *self, fnv1a_u32 *out);
+
+extern b32
+riot_mem_stream_read_xxh64_u64(struct mem_stream *self, xxh64_u64 *out);
+
+/* extension methods to `struct mem_stream` to write riot primitives
+ */
+
+extern b32
+riot_mem_stream_write_chr8(struct mem_stream *self, char val);
+
+extern b32
+riot_mem_stream_write_b8(struct mem_stream *self, b8 val);
+
+extern b32
+riot_mem_stream_write_s8(struct mem_stream *self, s8 val);
+
+extern b32
+riot_mem_stream_write_s16(struct mem_stream *self, s16 val);
+
+extern b32
+riot_mem_stream_write_s32(struct mem_stream *self, s32 val);
+
+extern b32
+riot_mem_stream_write_s64(struct mem_stream *self, s64 val);
+
+extern b32
+riot_mem_stream_write_u8(struct mem_stream *self, u8 val);
+
+extern b32
+riot_mem_stream_write_u16(struct mem_stream *self, u16 val);
+
+extern b32
+riot_mem_stream_write_u32(struct mem_stream *self, u32 val);
+
+extern b32
+riot_mem_stream_write_u64(struct mem_stream *self, u64 val);
+
+extern b32
+riot_mem_stream_write_fnv1a_u32(struct mem_stream *self, fnv1a_u32 val);
+
+extern b32
+riot_mem_stream_write_xxh64_u64(struct mem_stream *self, xxh64_u64 val);
+
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
+#endif /* LIBRIOT_UTILS_H */
diff --git a/libriot/makefile.mk b/libriot/makefile.mk
@@ -19,6 +19,7 @@ LIBRIOT_FLAGS := \
$(LDFLAGS)
LIBRIOT_SOURCES := libriot/src/libriot.c \
+ libriot/src/utils.c \
libriot/src/wad.c \
libriot/src/wad_reader.c \
libriot/src/wad_writer.c \
diff --git a/libriot/src/utils.c b/libriot/src/utils.c
@@ -0,0 +1,62 @@
+#include "libriot/utils.h"
+
+#define READ_BYTES(stream, type, out) \
+do { \
+ type _tmp = 0; \
+ u8 buf; \
+ for (u64 i = 0; i < sizeof(type); i++) { \
+ if (!mem_stream_consume(stream, &buf, 1)) return false; \
+ _tmp |= ((type)buf << (i * 8)); \
+ } \
+ *out = _tmp; \
+} while (0);
+
+#define MAKE_READ_FN(name, type) \
+b32 name(struct mem_stream *self, type *out) { \
+ assert(self); \
+ assert(out); \
+ READ_BYTES(self, type, out) \
+ return true; \
+}
+
+MAKE_READ_FN(riot_mem_stream_read_chr8, char)
+MAKE_READ_FN(riot_mem_stream_read_b8, b8)
+MAKE_READ_FN(riot_mem_stream_read_s8, s8)
+MAKE_READ_FN(riot_mem_stream_read_s16, s16)
+MAKE_READ_FN(riot_mem_stream_read_s32, s32)
+MAKE_READ_FN(riot_mem_stream_read_s64, s64)
+MAKE_READ_FN(riot_mem_stream_read_u8, u8)
+MAKE_READ_FN(riot_mem_stream_read_u16, u16)
+MAKE_READ_FN(riot_mem_stream_read_u32, u32)
+MAKE_READ_FN(riot_mem_stream_read_u64, u64)
+MAKE_READ_FN(riot_mem_stream_read_fnv1a_u32, fnv1a_u32)
+MAKE_READ_FN(riot_mem_stream_read_xxh64_u64, xxh64_u64)
+
+#define WRITE_BYTES(stream, type, val) \
+do { \
+ u8 buf; \
+ for (u64 i = 0; i < sizeof(type); i++) { \
+ buf = ((val >> (i * 8)) & 0xff); \
+ if (!mem_stream_push(stream, &buf, 1)) return false; \
+ } \
+} while (0);
+
+#define MAKE_WRITE_FN(name, type) \
+b32 name(struct mem_stream *self, type val) { \
+ assert(self); \
+ WRITE_BYTES(self, type, val) \
+ return true; \
+}
+
+MAKE_WRITE_FN(riot_mem_stream_write_chr8, char)
+MAKE_WRITE_FN(riot_mem_stream_write_b8, b8)
+MAKE_WRITE_FN(riot_mem_stream_write_s8, s8)
+MAKE_WRITE_FN(riot_mem_stream_write_s16, s16)
+MAKE_WRITE_FN(riot_mem_stream_write_s32, s32)
+MAKE_WRITE_FN(riot_mem_stream_write_s64, s64)
+MAKE_WRITE_FN(riot_mem_stream_write_u8, u8)
+MAKE_WRITE_FN(riot_mem_stream_write_u16, u16)
+MAKE_WRITE_FN(riot_mem_stream_write_u32, u32)
+MAKE_WRITE_FN(riot_mem_stream_write_u64, u64)
+MAKE_WRITE_FN(riot_mem_stream_write_fnv1a_u32, fnv1a_u32)
+MAKE_WRITE_FN(riot_mem_stream_write_xxh64_u64, xxh64_u64)