#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); }