give byte writer option to be backed by an arena

This commit is contained in:
jacob 2025-01-30 11:38:35 -06:00
parent eea9c978c9
commit 7d0826b57b
5 changed files with 87 additions and 76 deletions

View File

@ -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 temp_arena scratch = scratch_begin(arena);
struct ase_decode_image_result res = ZI; 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; struct ase_header ase_header;
br_read_to_struct(&br, &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 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; struct ase_header ase_header;
br_read_to_struct(&br, &ase_header); br_read_to_struct(&br, &ase_header);

View File

@ -1,13 +1,47 @@
#include "byteio.h" #include "byteio.h"
#include "memory.h" #include "memory.h"
#include "arena.h"
/* ========================== * /* ========================== *
* Writer * 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) void bw_seek(struct byte_writer *bw, u64 amount)
{ {
if (bw_overflow_check(bw, amount)) { if (write_check_overflow(bw, amount)) {
return; return;
} }
bw->at += amount; bw->at += amount;
@ -22,20 +56,6 @@ void bw_seek_to(struct byte_writer *bw, u64 pos)
bw->at = bw->buff.data + 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) void bw_write_buffer(struct byte_writer *bw, struct buffer buff)
{ {
write(bw, buff.data, buff.size); write(bw, buff.data, buff.size);
@ -97,9 +117,19 @@ void bw_write_var_sint(struct byte_writer *bw, i64 v)
* Reader * 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) void br_seek(struct byte_reader *br, u64 amount)
{ {
if (br_overflow_check(br, amount)) { if (read_check_overflow(br, amount)) {
return; return;
} }
br->at += amount; br->at += amount;
@ -124,7 +154,7 @@ INTERNAL void *read_unsafe(struct byte_reader *br, u64 size)
/* Will return NULL on overflow */ /* Will return NULL on overflow */
void *br_read_raw(struct byte_reader *br, u64 size) 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 NULL;
} }
return read_unsafe(br, size); 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 */ /* Will not read any data on overflow */
void br_read_to_buffer(struct byte_reader *br, struct buffer buff) 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; return;
} }
u8 *bytes = read_unsafe(br, buff.size); 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) u8 br_read_u8(struct byte_reader *br)
{ {
if (br_overflow_check(br, sizeof(u8))) { if (read_check_overflow(br, sizeof(u8))) {
return 0; return 0;
} }
u8 res = 0; u8 res = 0;
@ -152,7 +182,7 @@ u8 br_read_u8(struct byte_reader *br)
u16 br_read_u16(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; return 0;
} }
u16 res = 0; u16 res = 0;
@ -162,7 +192,7 @@ u16 br_read_u16(struct byte_reader *br)
u32 br_read_u32(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; return 0;
} }
u32 res = 0; u32 res = 0;
@ -172,7 +202,7 @@ u32 br_read_u32(struct byte_reader *br)
u64 br_read_u64(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; return 0;
} }
u64 res = 0; u64 res = 0;
@ -182,7 +212,7 @@ u64 br_read_u64(struct byte_reader *br)
i8 br_read_i8(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; return 0;
} }
i8 res = 0; i8 res = 0;
@ -192,7 +222,7 @@ i8 br_read_i8(struct byte_reader *br)
i16 br_read_i16(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; return 0;
} }
i16 res = 0; i16 res = 0;
@ -202,7 +232,7 @@ i16 br_read_i16(struct byte_reader *br)
i32 br_read_i32(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; return 0;
} }
i32 res = 0; i32 res = 0;
@ -212,7 +242,7 @@ i32 br_read_i32(struct byte_reader *br)
i64 br_read_i64(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; return 0;
} }
i64 res = 0; i64 res = 0;

View File

@ -2,6 +2,7 @@
#define BYTEIO_H #define BYTEIO_H
struct byte_writer { 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; struct buffer buff;
b32 overflowed; b32 overflowed;
u8 *at; u8 *at;
@ -17,22 +18,30 @@ struct byte_reader {
* Constructor utils * 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) { struct byte_writer bw = ZI;
.buff = buff, bw.buff = buff;
.overflowed = false, bw.at = buff.data;
.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) { struct byte_writer bw = ZI;
.buff = buff, bw.arena = arena;
.overflowed = false, bw.buff.data = arena->base;
.at = buff.data 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) 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 */ /* Generate a buffer struct containing written bytes only */
INLINE struct buffer bw_get_written_buffer(struct byte_writer *bw) INLINE struct buffer bw_get_written_buffer(struct byte_writer *bw)
{ {
return (struct buffer) { struct buffer buff = ZI;
.data = bw->buff.data, buff.data = bw->buff.data;
.size = bw->at - bw->buff.data buff.size = bw->at - bw->buff.data;
}; return buff;
} }
INLINE u64 bw_pos(struct byte_reader *bw) 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; 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 * 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_uint(struct byte_writer *bw, u64 v);
void bw_write_var_sint(struct byte_writer *bw, i64 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 * Read
* ========================== */ * ========================== */

View File

@ -70,7 +70,7 @@ struct tar_archive tar_parse(struct arena *arena, struct buffer data, struct str
__prof; __prof;
struct tar_archive archive = ZI; 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; u64 num_files = 0;
while (br_bytes_left(&br) > 1024) { while (br_bytes_left(&br) > 1024) {

View File

@ -936,7 +936,7 @@ INTERNAL void user_update(void)
b32 skip_debug_draw = !G.debug_camera && ent == active_camera; b32 skip_debug_draw = !G.debug_camera && ent == active_camera;
b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_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; 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 ui_viewport = RECT_FROM_V2(V2(0, 0), G.ui_size);
struct rect backbuffer_viewport = RECT_FROM_V2(V2(0, 0), G.screen_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 ui_resolution = v2_round_to_int(ui_viewport.size);
struct v2i32 backbuffer_resolution = v2_round_to_int(backbuffer_viewport.size); struct v2i32 backbuffer_resolution = v2_round_to_int(backbuffer_viewport.size);
struct v2i32 world_resolution = ui_resolution; 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 */ /* Draw world texture to final */
{ {