144 lines
3.6 KiB
C
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
|