power_play/src/byteio.h
2024-02-29 16:01:51 -06:00

144 lines
3.6 KiB
C

#ifndef BYTEIO_H
#define BYTEIO_H
struct byte_writer {
struct buffer buff;
b32 overflowed;
u8 *at;
};
struct byte_reader {
struct buffer buff;
b32 overflowed;
u8 *at;
};
/* ========================== *
* Constructor utils
* ========================== */
INLINE struct byte_writer bw_create_from_buffer(struct buffer buff)
{
return (struct byte_writer) {
.buff = buff,
.overflowed = false,
.at = buff.data
};
}
INLINE struct byte_reader br_create_from_buffer(struct buffer buff)
{
return (struct byte_reader) {
.buff = buff,
.overflowed = false,
.at = buff.data
};
}
INLINE struct byte_writer bw_copy(struct byte_writer *bw)
{
return *bw;
}
INLINE struct byte_reader br_copy(struct byte_reader *br)
{
return *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
};
}
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
* ========================== */
void bw_seek(struct byte_writer *bw, u64 amount);
void bw_seek_to(struct byte_writer *bw, u64 pos);
void bw_write_buffer(struct byte_writer *bw, struct buffer buff);
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);
INLINE u64 bw_bytes_left(struct byte_writer *bw)
{
return bw->overflowed ? 0 : bw->buff.size - (bw->at - bw->buff.data);
}
/* ========================== *
* Read
* ========================== */
void br_seek(struct byte_reader *br, u64 amount);
void br_seek_to(struct byte_reader *br, u64 pos);
/* Will not read any data on overflow */
#define br_read_to_struct(br_ptr, var_ptr) (br_read_to_buffer(br_ptr, BUFFER(sizeof(*var_ptr), (u8 *)var_ptr)))
void *br_read_raw(struct byte_reader *br, u64 size);
void br_read_to_buffer(struct byte_reader *br, struct buffer buff);
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);
INLINE u64 br_bytes_left(const struct byte_reader *br)
{
return br->overflowed ? 0 : br->buff.size - (br->at - br->buff.data);
}
INLINE u64 br_pos(struct byte_reader *br)
{
return br->at - br->buff.data;
}
#endif