234 lines
4.5 KiB
C
234 lines
4.5 KiB
C
#include "byteio.h"
|
|
#include "memory.h"
|
|
|
|
/* ========================== *
|
|
* Writer
|
|
* ========================== */
|
|
|
|
void bw_seek(struct byte_writer *bw, u64 amount)
|
|
{
|
|
if (bw_overflow_check(bw, amount)) {
|
|
return;
|
|
}
|
|
bw->at += amount;
|
|
}
|
|
|
|
void bw_seek_to(struct byte_writer *bw, u64 pos)
|
|
{
|
|
if (pos > bw->buff.size) {
|
|
ASSERT(false);
|
|
bw->overflowed = true;
|
|
}
|
|
bw->at = bw->buff.data + pos;
|
|
}
|
|
|
|
INTERNAL void write_unsafe(struct byte_writer *bw, void *v, u64 size)
|
|
{
|
|
MEMCPY(bw->at, v, size);
|
|
bw->at += size;
|
|
}
|
|
|
|
INTERNAL void write(struct byte_writer *bw, void *v, u64 size)
|
|
{
|
|
if (bw_overflow_check(bw, sizeof(v))) {
|
|
return;
|
|
}
|
|
write_unsafe(bw, v, size);
|
|
}
|
|
|
|
void bw_write_buffer(struct byte_writer *bw, struct buffer buff)
|
|
{
|
|
write(bw, buff.data, buff.size);
|
|
}
|
|
|
|
void bw_write_u8(struct byte_writer *bw, u8 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_u16(struct byte_writer *bw, u16 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_u32(struct byte_writer *bw, u32 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_u64(struct byte_writer *bw, u64 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_i8(struct byte_writer *bw, i8 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_i16(struct byte_writer *bw, i16 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_i32(struct byte_writer *bw, i32 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_i64(struct byte_writer *bw, i64 v)
|
|
{
|
|
write(bw, &v, sizeof(v));
|
|
}
|
|
|
|
void bw_write_var_uint(struct byte_writer *bw, u64 v)
|
|
{
|
|
/* TODO: real varint write */
|
|
bw_write_u64(bw, v);
|
|
}
|
|
|
|
void bw_write_var_sint(struct byte_writer *bw, i64 v)
|
|
{
|
|
/* TODO: real varint write */
|
|
bw_write_i64(bw, v);
|
|
}
|
|
|
|
/* ========================== *
|
|
* Reader
|
|
* ========================== */
|
|
|
|
void br_seek(struct byte_reader *br, u64 amount)
|
|
{
|
|
if (br_overflow_check(br, amount)) {
|
|
return;
|
|
}
|
|
br->at += amount;
|
|
}
|
|
|
|
void br_seek_to(struct byte_reader *br, u64 pos)
|
|
{
|
|
if (pos > br->buff.size) {
|
|
ASSERT(false);
|
|
br->overflowed = true;
|
|
}
|
|
br->at = br->buff.data + pos;
|
|
}
|
|
|
|
INTERNAL void *read_unsafe(struct byte_reader *br, u64 size)
|
|
{
|
|
void *prev = br->at;
|
|
br->at += size;
|
|
return prev;
|
|
}
|
|
|
|
/* Will return NULL on overflow */
|
|
void *br_read_raw(struct byte_reader *br, u64 size)
|
|
{
|
|
if (br_overflow_check(br, size)) {
|
|
return NULL;
|
|
}
|
|
return read_unsafe(br, size);
|
|
}
|
|
|
|
/* Will not read any data on overflow */
|
|
void br_read_to_buffer(struct byte_reader *br, struct buffer buff)
|
|
{
|
|
if (br_overflow_check(br, buff.size)) {
|
|
return;
|
|
}
|
|
u8 *bytes = read_unsafe(br, buff.size);
|
|
MEMCPY(buff.data, bytes, buff.size);
|
|
}
|
|
|
|
u8 br_read_u8(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(u8))) {
|
|
return 0;
|
|
}
|
|
u8 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(u8)), sizeof(u8));
|
|
return res;
|
|
}
|
|
|
|
u16 br_read_u16(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(u16))) {
|
|
return 0;
|
|
}
|
|
u16 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(u16)), sizeof(u16));
|
|
return res;
|
|
}
|
|
|
|
u32 br_read_u32(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(u32))) {
|
|
return 0;
|
|
}
|
|
u32 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(u32)), sizeof(u32));
|
|
return res;
|
|
}
|
|
|
|
u64 br_read_u64(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(u64))) {
|
|
return 0;
|
|
}
|
|
u64 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(u64)), sizeof(u64));
|
|
return res;
|
|
}
|
|
|
|
i8 br_read_i8(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(i8))) {
|
|
return 0;
|
|
}
|
|
i8 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(i8)), sizeof(i8));
|
|
return res;
|
|
}
|
|
|
|
i16 br_read_i16(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(i16))) {
|
|
return 0;
|
|
}
|
|
i16 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(i16)), sizeof(i16));
|
|
return res;
|
|
}
|
|
|
|
i32 br_read_i32(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(i32))) {
|
|
return 0;
|
|
}
|
|
i32 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(i32)), sizeof(i32));
|
|
return res;
|
|
}
|
|
|
|
i64 br_read_i64(struct byte_reader *br)
|
|
{
|
|
if (br_overflow_check(br, sizeof(i64))) {
|
|
return 0;
|
|
}
|
|
i64 res = 0;
|
|
MEMCPY(&res, read_unsafe(br, sizeof(i64)), sizeof(i64));
|
|
return res;
|
|
}
|
|
|
|
u64 br_read_var_uint(struct byte_reader *br)
|
|
{
|
|
/* TODO: real varint read */
|
|
return br_read_u64(br);
|
|
}
|
|
|
|
i64 br_read_var_sint(struct byte_reader *br)
|
|
{
|
|
/* TODO: real varint read */
|
|
return br_read_i64(br);
|
|
}
|