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 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);
|
||||||
|
|
||||||
|
|||||||
82
src/byteio.c
82
src/byteio.c
@ -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;
|
||||||
|
|||||||
70
src/byteio.h
70
src/byteio.h
@ -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
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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 */
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user