power_play/src/bitbuff.h
2025-02-23 02:14:06 -06:00

116 lines
3.4 KiB
C

#ifndef BITBUFF_H
#define BITBUFF_H
/* ========================== *
* Bitbuff
* ========================== */
struct bitbuff {
b32 is_backed_by_arena;
/* If `is_arena_bitbuff` is true, this dynamically-sized arena will be used for reading & writing (meaning writing cannot overflow) */
struct arena arena;
/* If `is_arena_bitbuff` is false, this fixed-sized buffer willl be used for reading & writing */
struct string fixed_buffer;
};
struct bitbuff bitbuff_alloc(u64 arena_reserve);
void bitbuff_release(struct bitbuff *bitbuff);
struct bitbuff bitbuff_from_string(struct string s);
/* ========================== *
* Writer
* ========================== */
/* NOTE: base_len is not stored in writer (as it is in the reader) since a dynamic arena-backed bitbuff could grow meaning len needs to be re-checked */
struct bitbuff_writer {
b32 overflowed;
struct bitbuff *bb;
u8 *base;
u64 cur_bit;
#if BITBUFF_DEBUG
b32 debug_enabled;
#endif
};
struct bitbuff_writer bw_from_bitbuff(struct bitbuff *bb);
struct bitbuff_writer bw_from_bitbuff_no_debug(struct bitbuff *bb);
u64 bw_num_bits_written(struct bitbuff_writer *bw);
u64 bw_num_bytes_written(struct bitbuff_writer *bw);
struct string bw_get_written(struct arena *arena, struct bitbuff_writer *bw);
u8 *bw_get_written_raw(struct bitbuff_writer *bw);
b32 bw_check_overflow_bits(struct bitbuff_writer *bw, u64 num_bits);
void bw_align(struct bitbuff_writer *bw);
void bw_write_ubits(struct bitbuff_writer *bw, u64 value, u8 num_bits);
void bw_write_ibits(struct bitbuff_writer *bw, i64 value, u8 num_bits);
void bw_write_bit(struct bitbuff_writer *bw, u8 value);
void bw_write_uv(struct bitbuff_writer *bw, u64 value);
void bw_write_iv(struct bitbuff_writer *bw, i64 value);
void bw_write_f32(struct bitbuff_writer *bw, f32 value);
void bw_write_f64(struct bitbuff_writer *bw, f64 value);
void bw_write_uid(struct bitbuff_writer *bw, struct uid value);
void bw_write_string(struct bitbuff_writer *bw, struct string s);
void bw_write_bytes(struct bitbuff_writer *bw, struct string bytes);
/* ========================== *
* Reader
* ========================== */
struct bitbuff_reader {
b32 overflowed;
u64 base_len;
u8 *base;
u64 cur_bit;
#if BITBUFF_DEBUG
b32 debug_enabled;
#endif
};
struct bitbuff_reader br_from_bitbuff(struct bitbuff *bb);
struct bitbuff_reader br_from_bitbuff_no_debug(struct bitbuff *bb);
u64 br_cur_bit(struct bitbuff_reader *br);
u64 br_cur_byte(struct bitbuff_reader *br);
u64 br_num_bits_left(struct bitbuff_reader *br);
u64 br_num_bytes_left(struct bitbuff_reader *br);
b32 br_check_overflow_bits(struct bitbuff_reader *br, u64 num_bits);
void br_align(struct bitbuff_reader *br);
u64 br_read_ubits(struct bitbuff_reader *br, u8 num_bits);
i64 br_read_ibits(struct bitbuff_reader *br, u8 num_bits);
u8 br_read_bit(struct bitbuff_reader *br);
u64 br_read_uv(struct bitbuff_reader *br);
i64 br_read_iv(struct bitbuff_reader *br);
f32 br_read_f32(struct bitbuff_reader *br);
f64 br_read_f64(struct bitbuff_reader *br);
struct uid br_read_uid(struct bitbuff_reader *br);
struct string br_read_string(struct arena *arena, struct bitbuff_reader *br);
void br_read_bytes(struct bitbuff_reader *br, struct string dst);
u8 *br_read_bytes_raw(struct bitbuff_reader *br, u64 num_bytes);
void br_seek_bytes(struct bitbuff_reader *br, u64 num_bytes);
void br_seek_to_byte(struct bitbuff_reader *br, u64 pos);
#if BITBUFF_TEST
void bitbuff_test(void);
#endif
#endif