give byte writer option to be backed by an arena
This commit is contained in:
parent
eea9c978c9
commit
7d0826b57b
@ -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);
|
||||
|
||||
|
||||
82
src/byteio.c
82
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;
|
||||
|
||||
70
src/byteio.h
70
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
|
||||
* ========================== */
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 */
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user