#ifndef BYTEIO_H #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 string buff; b32 overflowed; u8 *at; }; struct byte_reader { struct string buff; b32 overflowed; u8 *at; }; /* ========================== * * Writer * ========================== */ struct byte_writer bw_from_buffer(struct string buff); struct byte_writer bw_from_arena(struct arena *arena); struct byte_writer bw_branch(struct byte_writer *bw, u64 size); void bw_seek(struct byte_writer *bw, u64 amount); void bw_seek_to(struct byte_writer *bw, u64 pos); void br_write_bytes(struct byte_writer *bw, struct string bytes); void bw_write_u8(struct byte_writer *bw, u8 v); void bw_write_u16(struct byte_writer *bw, u16 v); void bw_write_u32(struct byte_writer *bw, u32 v); void bw_write_u64(struct byte_writer *bw, u64 v); void bw_write_i8(struct byte_writer *bw, i8 v); void bw_write_i16(struct byte_writer *bw, i16 v); void bw_write_i32(struct byte_writer *bw, i32 v); 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); void bw_write_f32(struct byte_writer *bw, f32 v); void bw_write_f64(struct byte_writer *bw, f64 v); void bw_write_v2(struct byte_writer *bw, struct v2 v); void bw_write_string(struct byte_writer *bw, struct string str); /* Returns a string containing written bytes only */ INLINE struct string bw_get_written(struct byte_writer *bw) { struct string buff = ZI; buff.text = bw->buff.text; buff.len = bw->at - bw->buff.text; return buff; } INLINE u64 bw_pos(struct byte_writer *bw) { return bw->at - bw->buff.text; } /* ========================== * * Reader * ========================== */ /* Will fill struct with zeroes on overflow */ #define br_read_to_struct(br_ptr, var_ptr) (br_read_to_buffer(br_ptr, STRING(sizeof(*var_ptr), (u8 *)var_ptr))) struct byte_reader br_from_buffer(struct string buff); void *br_seek(struct byte_reader *br, u64 amount); void *br_seek_to(struct byte_reader *br, u64 pos); void br_read_to_buffer(struct byte_reader *br, struct string s); u8 br_read_u8(struct byte_reader *br); u16 br_read_u16(struct byte_reader *br); u32 br_read_u32(struct byte_reader *br); u64 br_read_u64(struct byte_reader *br); i8 br_read_i8(struct byte_reader *br); i16 br_read_i16(struct byte_reader *br); i32 br_read_i32(struct byte_reader *br); i64 br_read_i64(struct byte_reader *br); u64 br_read_var_uint(struct byte_reader *br); i64 br_read_var_sint(struct byte_reader *br); f32 br_read_f32(struct byte_reader *br); f64 br_read_f64(struct byte_reader *br); struct v2 br_read_v2(struct byte_reader *br); struct string br_read_string(struct arena *arena, struct byte_reader *br); INLINE u64 br_bytes_left(const struct byte_reader *br) { return br->overflowed ? 0 : br->buff.len - (br->at - br->buff.text); } INLINE u64 br_pos(struct byte_reader *br) { return br->at - br->buff.text; } #endif