use std::ops::{DerefMut};
mod mmap;
pub use mmap::{Mmap};
pub trait Buffer: Sized + DerefMut<Target=[u8]> {
fn new() -> Self;
fn resize(&mut self, min_length: usize);
fn write_byte(&mut self, pos: usize, byte: u8) {
if pos >= self.len() {
self.resize(std::cmp::max(pos + 1, 0x1000).checked_next_power_of_two().unwrap());
}
self[pos] = byte;
}
fn write(&mut self, pos: usize, mut bytes: u64, len: usize) {
assert!(len <= 8);
for i in 0..len {
self.write_byte(pos + i, bytes as u8);
bytes >>= 8;
}
assert_eq!(bytes, 0);
}
fn read_byte(&self, pos: usize) -> u8 {
if pos < self.len() {
self[pos]
} else {
0
}
}
fn read(&self, pos: usize, len: usize) -> u64 {
assert!(len <= 8);
let mut bytes: u64 = 0;
for i in (0..len).rev() {
bytes <<= 8;
bytes |= u64::from(self.read_byte(pos + i));
}
bytes
}
}
impl Buffer for Vec<u8> {
fn new() -> Self { Vec::new() }
fn resize(&mut self, min_length: usize) {
self.resize(min_length, 0);
}
}
#[cfg(test)]
pub mod tests {
use super::*;
pub fn api(mut buffer: impl Buffer) {
buffer.resize(16);
let len = buffer.len();
buffer.write(4, 0x0001020304050607, 8);
assert_eq!(buffer.read(4, 8), 0x0001020304050607);
assert_eq!(buffer.read(len+4, 8), 0);
buffer.write(len+4, 0x08090A0B0C0D0E0F, 8);
assert!(buffer.len() >= len+12);
assert_eq!(buffer.read(4, 8), 0x0001020304050607);
assert_eq!(buffer.read(len+4, 8), 0x08090A0B0C0D0E0F);
}
#[test]
fn vec() {
api(Vec::<u8>::new());
}
}