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 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);

View File

@ -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;

View File

@ -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
* ========================== */

View File

@ -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) {

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_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 */
{