power_play/src/base/base_bitbuff.h

191 lines
5.2 KiB
C

////////////////////////////////////////////////////////////
//~ Bitbuff types
Struct(BB_Buff)
{
b32 is_backed_by_arena;
// If `is_arena_bitbuff` is 1, this dynamically-sized arena will be used for reading & writing (meaning writing cannot overflow)
Arena *arena;
// If `is_arena_bitbuff` is 0, this fixed-sized buffer willl be used for reading & writing
String fixed_buffer;
};
// NOTE: base_len is not stored with the writer (as it is with the reader) since a dynamic arena-backed bitbuff could grow, meaning len needs to be re-checked
#define BB_WriterOverflowArenaPushSize 4096
Struct(BB_Writer)
{
b32 overflowed;
BB_Buff *bb;
u8 *base;
u64 cur_bit;
#if BITBUFF_DEBUG
b32 debug_enabled;
#endif
};
Struct(BB_Reader)
{
b32 overflowed;
u64 base_len;
u8 *base;
u64 cur_bit;
#if BITBUFF_DEBUG
b32 debug_enabled;
#endif
};
////////////////////////////////////////////////////////////
//~ Debug types
#if BITBUFF_DEBUG
// Magic numbers inserted to verify read/write type & length
Enum(BB_DebugMagicKind)
{
BB_DebugMagicKind_AlignBytes = 0x20A4,
BB_DebugMagicKind_AlignToNextByte = 0x379A,
BB_DebugMagicKind_UBits = 0xCB4A,
BB_DebugMagicKind_IBits = 0xB30D,
BB_DebugMagicKind_UV = 0xE179,
BB_DebugMagicKind_IV = 0x981f,
BB_DebugMagicKind_F32 = 0x56F9,
BB_DebugMagicKind_F64 = 0x7053,
BB_DebugMagicKind_Uid = 0xA24E,
BB_DebugMagicKind_String = 0x7866
};
#endif
////////////////////////////////////////////////////////////
//~ Buff management
//- Growable-arena backed bitbuff
BB_Buff BB_AcquireDynamicBuff(u64 arena_reserve);
void BB_ReleaseDynamicBuff(BB_Buff *bitbuff);
//- Fixed-buffer backed bitbuff
BB_Buff BB_BuffFromString(String s);
////////////////////////////////////////////////////////////
//~ Writer management
BB_Writer BB_WriterFromBuff(BB_Buff *bb);
BB_Writer BB_WriterFromBuffNoDebug(BB_Buff *bb);
u64 BB_GetNumBitsWritten(BB_Writer *bw);
u64 BB_GetNumBytesWritten(BB_Writer *bw);
String BB_GetWritten(Arena *arena, BB_Writer *bw);
u8 *BB_GetWrittenRaw(BB_Writer *bw);
b32 BB_CheckWriterOverflowBits(BB_Writer *bw, u64 num_bits);
////////////////////////////////////////////////////////////
//~ Writer ops
//- Align
void BB_WriteAlignToNextByte(BB_Writer *bw);
void BB_WriteAlignBytes(BB_Writer *bw, u64 align);
//- Bits
void BB_WriteUBitsNoMagic(BB_Writer *bw, u64 value, u8 num_bits);
void BB_WriteUBits(BB_Writer *bw, u64 value, u8 num_bits);
void BB_WriteIBits(BB_Writer *bw, i64 value, u8 num_bits);
b32 BB_WriteBit(BB_Writer *bw, u8 value);
//- Variable length integers
void BB_WriteUV(BB_Writer *bw, u64 value);
void BB_WriteIV(BB_Writer *bw, i64 value);
//- Floating point
void BB_WriteF32(BB_Writer *bw, f32 value);
void BB_WriteF64(BB_Writer *bw, f64 value);
//- Uid
void BB_WriteUid(BB_Writer *bw, Uid value);
//- Raw data
void BB_WriteString(BB_Writer *bw, String s);
void BB_WriteBytes(BB_Writer *bw, String bytes);
void BB_WriteSeekBytes(BB_Writer *bw, u64 num_bytes);
////////////////////////////////////////////////////////////
//~ Writer debug
#if BITBUFF_DEBUG
void BB_WriteDebugMagic(BB_Writer *bw, BB_DebugMagicKind magic, u8 num_bits);
void BB_WriteDebugMarker(BB_Writer *bw, String name);
#else
#define BB_WriteDebugMagic(bw, magic, num_bits)
#define BB_WriteDebugMarker(bw, name)
#endif
////////////////////////////////////////////////////////////
//~ Reader management
BB_Reader BB_ReaderFromBuff(BB_Buff *bb);
BB_Reader BB_ReaderFromBuffNoDebug(BB_Buff *bb);
u64 BB_GetCurrentReaderBit(BB_Reader *br);
u64 BB_GetCurrentReaderByte(BB_Reader *br);
u64 BB_NumBitsRemaining(BB_Reader *br);
u64 BB_NumBytesRemaining(BB_Reader *br);
b32 BB_CheckReaderOverflowBits(BB_Reader *br, u64 num_bits);
////////////////////////////////////////////////////////////
//~ Reader ops
//- Align
void BB_ReadAlignToNextByte(BB_Reader *br);
void BB_ReadAlignBytes(BB_Reader *br, u64 align);
//- Bits
u64 BB_ReadUBitsNoMagic(BB_Reader *br, u8 num_bits);
u64 BB_ReadUBits(BB_Reader *br, u8 num_bits);
i64 BB_ReadIBits(BB_Reader *br, u8 num_bits);
u8 BB_ReadBit(BB_Reader *br);
//- Variable length integers
u64 BB_ReadUV(BB_Reader *br);
i64 BB_ReadIV(BB_Reader *br);
//- Floating point
f32 BB_ReadF32(BB_Reader *br);
f64 BB_ReadF64(BB_Reader *br);
//- Uid
Uid BB_ReadUid(BB_Reader *br);
//- Raw data
String BB_ReadString(Arena *arena, BB_Reader *br);
void BB_ReadBytes(BB_Reader *br, String dst);
u8 *BB_ReadBytesRaw(BB_Reader *br, u64 num_bytes);
void BB_ReadSeekBytes(BB_Reader *br, u64 num_bytes);
void BB_ReadSeekToByte(BB_Reader *br, u64 pos);
////////////////////////////////////////////////////////////
//~ Reader debug
#if BITBUFF_DEBUG
void BB_ReadDebugMagic(BB_Reader *br, BB_DebugMagicKind expected_magic, u8 expected_num_bits);
void BB_ReadDebugMarker(BB_Reader *br, String name);
#else
#define BB_ReadDebugMagic(br, expected_magic, expected_num_bits)
#define BB_ReadDebugMarker(br, name)
#endif
////////////////////////////////////////////////////////////
//~ Utils
u64 BB_TwosComplimentFromUint(u64 value, u8 num_bits);
i64 BB_IntFromTwosCompliment(u64 tc, u8 num_bits);
////////////////////////////////////////////////////////////
//~ Test
void BB_Test(void);