From 7d0826b57bc01bc0968ac933e81e74baab1cb318 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 30 Jan 2025 11:38:35 -0600 Subject: [PATCH] give byte writer option to be backed by an arena --- src/ase.c | 4 +-- src/byteio.c | 82 +++++++++++++++++++++++++++++++++++----------------- src/byteio.h | 70 ++++++++++++++++---------------------------- src/tar.c | 2 +- src/user.c | 5 ++-- 5 files changed, 87 insertions(+), 76 deletions(-) diff --git a/src/ase.c b/src/ase.c index 36c7caaa..7a425165 100644 --- a/src/ase.c +++ b/src/ase.c @@ -558,7 +558,7 @@ struct ase_decode_image_result ase_decode_image(struct arena *arena, struct buff struct temp_arena scratch = scratch_begin(arena); struct ase_decode_image_result res = ZI; - struct byte_reader br = br_create_from_buffer(encoded); + struct byte_reader br = br_from_buffer(encoded); struct ase_header ase_header; br_read_to_struct(&br, &ase_header); @@ -817,7 +817,7 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct buff struct ase_decode_sheet_result res = ZI; - struct byte_reader br = br_create_from_buffer(encoded); + struct byte_reader br = br_from_buffer(encoded); struct ase_header ase_header; br_read_to_struct(&br, &ase_header); diff --git a/src/byteio.c b/src/byteio.c index d990ecc1..9b50d4b6 100644 --- a/src/byteio.c +++ b/src/byteio.c @@ -1,13 +1,47 @@ #include "byteio.h" #include "memory.h" +#include "arena.h" /* ========================== * * Writer * ========================== */ +INTERNAL b32 write_check_overflow(struct byte_writer *bw, u64 amount) +{ + b32 overflowed = bw->overflowed; + i64 new_space_left = (bw->at + amount) - (bw->buff.data + bw->buff.size); + if (!overflowed && new_space_left < 0) { + if (bw->arena) { + arena_push_array(bw->arena, u8, -new_space_left); + bw->buff.size += -new_space_left; + /* Writer memory should be contiguous in arena */ + ASSERT((bw->buff.data + bw->buff.size) == (bw->arena->base + bw->arena->pos)); + } else { + bw->overflowed = true; + overflowed = true; + } + } + ASSERT(!overflowed); + return overflowed; +} + +INTERNAL void write_unsafe(struct byte_writer *bw, void *v, u64 size) +{ + MEMCPY(bw->at, v, size); + bw->at += size; +} + +INTERNAL void write(struct byte_writer *bw, void *v, u64 size) +{ + if (write_check_overflow(bw, sizeof(v))) { + return; + } + write_unsafe(bw, v, size); +} + void bw_seek(struct byte_writer *bw, u64 amount) { - if (bw_overflow_check(bw, amount)) { + if (write_check_overflow(bw, amount)) { return; } bw->at += amount; @@ -22,20 +56,6 @@ void bw_seek_to(struct byte_writer *bw, u64 pos) bw->at = bw->buff.data + pos; } -INTERNAL void write_unsafe(struct byte_writer *bw, void *v, u64 size) -{ - MEMCPY(bw->at, v, size); - bw->at += size; -} - -INTERNAL void write(struct byte_writer *bw, void *v, u64 size) -{ - if (bw_overflow_check(bw, sizeof(v))) { - return; - } - write_unsafe(bw, v, size); -} - void bw_write_buffer(struct byte_writer *bw, struct buffer buff) { write(bw, buff.data, buff.size); @@ -97,9 +117,19 @@ void bw_write_var_sint(struct byte_writer *bw, i64 v) * Reader * ========================== */ +INTERNAL b32 read_check_overflow(struct byte_reader *br, u64 amount) +{ + if (br->overflowed || br->at + amount > br->buff.data + br->buff.size) { + ASSERT(false); + br->overflowed = true; + return true; + } + return false; +} + void br_seek(struct byte_reader *br, u64 amount) { - if (br_overflow_check(br, amount)) { + if (read_check_overflow(br, amount)) { return; } br->at += amount; @@ -124,7 +154,7 @@ INTERNAL void *read_unsafe(struct byte_reader *br, u64 size) /* Will return NULL on overflow */ void *br_read_raw(struct byte_reader *br, u64 size) { - if (br_overflow_check(br, size)) { + if (read_check_overflow(br, size)) { return NULL; } return read_unsafe(br, size); @@ -133,7 +163,7 @@ void *br_read_raw(struct byte_reader *br, u64 size) /* Will not read any data on overflow */ void br_read_to_buffer(struct byte_reader *br, struct buffer buff) { - if (br_overflow_check(br, buff.size)) { + if (read_check_overflow(br, buff.size)) { return; } u8 *bytes = read_unsafe(br, buff.size); @@ -142,7 +172,7 @@ void br_read_to_buffer(struct byte_reader *br, struct buffer buff) u8 br_read_u8(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(u8))) { + if (read_check_overflow(br, sizeof(u8))) { return 0; } u8 res = 0; @@ -152,7 +182,7 @@ u8 br_read_u8(struct byte_reader *br) u16 br_read_u16(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(u16))) { + if (read_check_overflow(br, sizeof(u16))) { return 0; } u16 res = 0; @@ -162,7 +192,7 @@ u16 br_read_u16(struct byte_reader *br) u32 br_read_u32(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(u32))) { + if (read_check_overflow(br, sizeof(u32))) { return 0; } u32 res = 0; @@ -172,7 +202,7 @@ u32 br_read_u32(struct byte_reader *br) u64 br_read_u64(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(u64))) { + if (read_check_overflow(br, sizeof(u64))) { return 0; } u64 res = 0; @@ -182,7 +212,7 @@ u64 br_read_u64(struct byte_reader *br) i8 br_read_i8(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(i8))) { + if (read_check_overflow(br, sizeof(i8))) { return 0; } i8 res = 0; @@ -192,7 +222,7 @@ i8 br_read_i8(struct byte_reader *br) i16 br_read_i16(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(i16))) { + if (read_check_overflow(br, sizeof(i16))) { return 0; } i16 res = 0; @@ -202,7 +232,7 @@ i16 br_read_i16(struct byte_reader *br) i32 br_read_i32(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(i32))) { + if (read_check_overflow(br, sizeof(i32))) { return 0; } i32 res = 0; @@ -212,7 +242,7 @@ i32 br_read_i32(struct byte_reader *br) i64 br_read_i64(struct byte_reader *br) { - if (br_overflow_check(br, sizeof(i64))) { + if (read_check_overflow(br, sizeof(i64))) { return 0; } i64 res = 0; diff --git a/src/byteio.h b/src/byteio.h index e139b9af..dea6ac81 100644 --- a/src/byteio.h +++ b/src/byteio.h @@ -2,6 +2,7 @@ #define BYTEIO_H struct byte_writer { + struct arena *arena; /* If arena is set, then the writer cannot overflow and will instead allocate more memory as it grows */ struct buffer buff; b32 overflowed; u8 *at; @@ -17,22 +18,30 @@ struct byte_reader { * Constructor utils * ========================== */ -INLINE struct byte_writer bw_create_from_buffer(struct buffer buff) +INLINE struct byte_writer bw_from_buffer(struct buffer buff) { - return (struct byte_writer) { - .buff = buff, - .overflowed = false, - .at = buff.data - }; + struct byte_writer bw = ZI; + bw.buff = buff; + bw.at = buff.data; + return bw; } -INLINE struct byte_reader br_create_from_buffer(struct buffer buff) +INLINE struct byte_writer bw_from_arena(struct arena *arena) { - return (struct byte_reader) { - .buff = buff, - .overflowed = false, - .at = buff.data - }; + struct byte_writer bw = ZI; + bw.arena = arena; + bw.buff.data = arena->base; + bw.buff.size = 0; + bw.at = bw.buff.data; + return bw; +} + +INLINE struct byte_reader br_from_buffer(struct buffer buff) +{ + struct byte_reader br = ZI; + br.buff = buff; + br.at = buff.data; + return br; } INLINE struct byte_writer bw_copy(struct byte_writer *bw) @@ -48,10 +57,10 @@ INLINE struct byte_reader br_copy(struct byte_reader *br) /* Generate a buffer struct containing written bytes only */ INLINE struct buffer bw_get_written_buffer(struct byte_writer *bw) { - return (struct buffer) { - .data = bw->buff.data, - .size = bw->at - bw->buff.data - }; + struct buffer buff = ZI; + buff.data = bw->buff.data; + buff.size = bw->at - bw->buff.data; + return buff; } INLINE u64 bw_pos(struct byte_reader *bw) @@ -59,30 +68,6 @@ INLINE u64 bw_pos(struct byte_reader *bw) return bw->at - bw->buff.data; } -/* ========================== * - * Overflow utils - * ========================== */ - -INLINE b32 bw_overflow_check(struct byte_writer *bw, u64 amount) -{ - if (bw->overflowed || bw->at + amount > bw->buff.data + bw->buff.size) { - ASSERT(false); - bw->overflowed = true; - return true; - } - return false; -} - -INLINE b32 br_overflow_check(struct byte_reader *br, u64 amount) -{ - if (br->overflowed || br->at + amount > br->buff.data + br->buff.size) { - ASSERT(false); - br->overflowed = true; - return true; - } - return false; -} - /* ========================== * * Write * ========================== */ @@ -102,11 +87,6 @@ void bw_write_i64(struct byte_writer *bw, i64 v); void bw_write_var_uint(struct byte_writer *bw, u64 v); void bw_write_var_sint(struct byte_writer *bw, i64 v); -INLINE u64 bw_bytes_left(struct byte_writer *bw) -{ - return bw->overflowed ? 0 : bw->buff.size - (bw->at - bw->buff.data); -} - /* ========================== * * Read * ========================== */ diff --git a/src/tar.c b/src/tar.c index 90bc462c..ab99393d 100644 --- a/src/tar.c +++ b/src/tar.c @@ -70,7 +70,7 @@ struct tar_archive tar_parse(struct arena *arena, struct buffer data, struct str __prof; struct tar_archive archive = ZI; - struct byte_reader br = br_create_from_buffer(data); + struct byte_reader br = br_from_buffer(data); u64 num_files = 0; while (br_bytes_left(&br) > 1024) { diff --git a/src/user.c b/src/user.c index b51fd6c5..59d353da 100644 --- a/src/user.c +++ b/src/user.c @@ -936,7 +936,7 @@ INTERNAL void user_update(void) b32 skip_debug_draw = !G.debug_camera && ent == active_camera; b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_CAMERA); - //skip_debug_draw_transform = true; + skip_debug_draw_transform = true; struct xform sprite_xform = xf; @@ -1612,7 +1612,7 @@ INTERNAL void user_update(void) struct rect ui_viewport = RECT_FROM_V2(V2(0, 0), G.ui_size); struct rect backbuffer_viewport = RECT_FROM_V2(V2(0, 0), G.screen_size); - /* Allocate rt textures */ + /* Allocate render textures */ struct v2i32 ui_resolution = v2_round_to_int(ui_viewport.size); struct v2i32 backbuffer_resolution = v2_round_to_int(backbuffer_viewport.size); struct v2i32 world_resolution = ui_resolution; @@ -1645,6 +1645,7 @@ INTERNAL void user_update(void) } } + /* Combine render textures w/ quad draw cmds */ { /* Draw world texture to final */ {