use std::io::{self, Read, Write, Cursor};
use std::net::{SocketAddrV4, Ipv4Addr};
use byteorder::{ReadBytesExt, WriteBytesExt, LE, BE};
use glam::Vec3A;
pub trait WgReadExt: Read {
#[inline]
fn read_u8(&mut self) -> io::Result<u8> {
ReadBytesExt::read_u8(self)
}
#[inline]
fn read_i8(&mut self) -> io::Result<i8> {
ReadBytesExt::read_i8(self)
}
#[inline]
fn skip<const N: usize>(&mut self) -> io::Result<()> {
let mut buf = [0; N];
self.read_exact(&mut buf)?;
Ok(())
}
#[inline]
fn read_u16(&mut self) -> io::Result<u16> {
ReadBytesExt::read_u16::<LE>(self)
}
#[inline]
fn read_i16(&mut self) -> io::Result<i16> {
ReadBytesExt::read_i16::<LE>(self)
}
#[inline]
fn read_u24(&mut self) -> io::Result<u32> {
ReadBytesExt::read_u24::<LE>(self)
}
#[inline]
fn read_i24(&mut self) -> io::Result<i32> {
ReadBytesExt::read_i24::<LE>(self)
}
#[inline]
fn read_u32(&mut self) -> io::Result<u32> {
ReadBytesExt::read_u32::<LE>(self)
}
#[inline]
fn read_i32(&mut self) -> io::Result<i32> {
ReadBytesExt::read_i32::<LE>(self)
}
#[inline]
fn read_packed_u32(&mut self) -> io::Result<u32> {
match self.read_u8()? {
255 => self.read_u24(),
n => Ok(n as u32)
}
}
#[inline]
fn read_u64(&mut self) -> io::Result<u64> {
ReadBytesExt::read_u64::<LE>(self)
}
#[inline]
fn read_i64(&mut self) -> io::Result<i64> {
ReadBytesExt::read_i64::<LE>(self)
}
#[inline]
fn read_f32(&mut self) -> io::Result<f32> {
ReadBytesExt::read_f32::<LE>(self)
}
#[inline]
fn read_bool(&mut self) -> io::Result<bool> {
Ok(self.read_u8()? != 0)
}
#[inline]
fn check_exact<const N: usize>(&mut self, bytes: &[u8; N]) -> io::Result<bool> {
let mut buf = [0; N];
self.read_exact(&mut buf[..])?;
Ok(&buf == bytes)
}
fn read_blob(&mut self, len: usize) -> io::Result<Vec<u8>> {
let mut buf = vec![0; len];
self.read_exact(&mut buf[..])?;
Ok(buf)
}
fn read_blob_variable(&mut self) -> io::Result<Vec<u8>> {
let len = self.read_packed_u32()? as usize;
let mut buf = vec![0; len];
self.read_exact(&mut buf[..])?;
Ok(buf)
}
fn read_string(&mut self, len: usize) -> io::Result<String> {
String::from_utf8(self.read_blob(len)?)
.map_err(|_| io::ErrorKind::InvalidData.into())
}
fn read_string_variable(&mut self) -> io::Result<String> {
let blob = self.read_blob_variable()?;
match String::from_utf8(blob) {
Ok(s) => Ok(s),
Err(_) => Err(io::Error::new(io::ErrorKind::InvalidData, "invalid utf8 string"))
}
}
fn read_cstring(&mut self, len: usize) -> io::Result<String> {
let mut buf = self.read_blob(len)?;
let pos = buf.iter().position(|&o| o == 0)
.ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?;
buf.truncate(pos); String::from_utf8(buf).map_err(|_| io::ErrorKind::InvalidData.into())
}
fn read_cstring_variable(&mut self) -> io::Result<String> {
let mut buf = Vec::new();
loop {
let b = self.read_u8()?;
if b == 0 {
break
}
buf.push(b);
}
String::from_utf8(buf).map_err(|_| io::ErrorKind::InvalidData.into())
}
fn read_sock_addr_v4(&mut self) -> io::Result<SocketAddrV4> {
let mut ip_raw = [0; 4];
self.read_exact(&mut ip_raw[..])?;
let port = ReadBytesExt::read_u16::<BE>(self)?;
let _salt = ReadBytesExt::read_u16::<LE>(self)?;
Ok(SocketAddrV4::new(Ipv4Addr::from(ip_raw), port))
}
#[inline]
fn read_vec3(&mut self) -> io::Result<Vec3A> {
Ok(Vec3A::new(
self.read_f32()?,
self.read_f32()?,
self.read_f32()?,
))
}
fn read_pickle<'de, T: serde::Deserialize<'de>>(&mut self) -> io::Result<T> {
use serde_pickle::DeOptions;
let length = self.read_packed_u32()?;
Ok(serde_pickle::from_reader(self.take(length as _), DeOptions::new().decode_strings()).unwrap())
}
fn read_single_head(&mut self) -> io::Result<usize> {
Ok(self.read_u32()? as usize)
}
fn read_vector_head(&mut self) -> io::Result<(usize, usize)> {
let sec_size = self.read_u32()? as usize;
let sec_count = self.read_u32()? as usize;
Ok((sec_size, sec_count))
}
fn read_vector<F, T>(&mut self, mut func: F) -> io::Result<Vec<T>>
where
F: FnMut(&mut Cursor<&Vec<u8>>) -> io::Result<T>
{
let (sec_size, sec_count) = self.read_vector_head()?;
let mut buf = Vec::with_capacity(sec_size);
buf.resize(sec_size, 0);
let mut data = Vec::with_capacity(sec_count);
for _ in 0..sec_count {
self.read_exact(&mut buf[..])?;
data.push((func)(&mut Cursor::new(&buf))?);
}
Ok(data)
}
}
pub trait WgWriteExt: Write {
#[inline]
fn write_u8(&mut self, n: u8) -> io::Result<()> {
WriteBytesExt::write_u8(self, n)
}
#[inline]
fn write_i8(&mut self, n: i8) -> io::Result<()> {
WriteBytesExt::write_i8(self, n)
}
#[inline]
fn write_u16(&mut self, n: u16) -> io::Result<()> {
WriteBytesExt::write_u16::<LE>(self, n)
}
#[inline]
fn write_i16(&mut self, n: i16) -> io::Result<()> {
WriteBytesExt::write_i16::<LE>(self, n)
}
#[inline]
fn write_u24(&mut self, n: u32) -> io::Result<()> {
WriteBytesExt::write_u24::<LE>(self, n)
}
#[inline]
fn write_i24(&mut self, n: i32) -> io::Result<()> {
WriteBytesExt::write_i24::<LE>(self, n)
}
#[inline]
fn write_u32(&mut self, n: u32) -> io::Result<()> {
WriteBytesExt::write_u32::<LE>(self, n)
}
#[inline]
fn write_i32(&mut self, n: i32) -> io::Result<()> {
WriteBytesExt::write_i32::<LE>(self, n)
}
fn write_packed_u32(&mut self, n: u32) -> io::Result<()> {
if n >= 255 {
self.write_u8(255)?;
self.write_u24(n)
} else {
self.write_u8(n as u8)
}
}
#[inline]
fn write_u64(&mut self, n: u64) -> io::Result<()> {
WriteBytesExt::write_u64::<LE>(self, n)
}
#[inline]
fn write_i64(&mut self, n: i64) -> io::Result<()> {
WriteBytesExt::write_i64::<LE>(self, n)
}
#[inline]
fn write_f32(&mut self, n: f32) -> io::Result<()> {
WriteBytesExt::write_f32::<LE>(self, n)
}
#[inline]
fn write_bool(&mut self, b: bool) -> io::Result<()> {
self.write_u8(b as _)
}
#[inline]
fn write_blob(&mut self, data: &[u8]) -> io::Result<()> {
self.write_all(data)
}
fn write_blob_variable(&mut self, data: &[u8]) -> io::Result<()> {
self.write_packed_u32(data.len() as u32)?;
self.write_blob(data)
}
#[inline]
fn write_string<S: AsRef<str>>(&mut self, s: S) -> io::Result<()> {
self.write_blob(s.as_ref().as_bytes())
}
#[inline]
fn write_string_variable(&mut self, s: &str) -> io::Result<()> {
self.write_blob_variable(s.as_bytes())
}
#[inline]
fn write_cstring<S: AsRef<str>>(&mut self, s: S) -> io::Result<()> {
self.write_string(s)?;
self.write_u8(0)
}
fn write_single_head(&mut self, n: usize) -> io::Result<()> {
self.write_u32(n as u32)
}
fn write_sock_addr_v4(&mut self, addr: SocketAddrV4) -> io::Result<()> {
self.write_all(&addr.ip().octets()[..])?;
WriteBytesExt::write_u16::<BE>(self, addr.port())?;
WriteBytesExt::write_u16::<LE>(self, 0)?; Ok(())
}
fn write_vec3(&mut self, vec: Vec3A) -> io::Result<()> {
self.write_f32(vec.x)?;
self.write_f32(vec.y)?;
self.write_f32(vec.z)?;
Ok(())
}
fn write_pickle<T: serde::Serialize>(&mut self, value: &T) -> io::Result<()> {
use serde_pickle::SerOptions;
self.write_blob_variable(&serde_pickle::to_vec(value, SerOptions::new().proto_v2()).unwrap())
}
fn write_vector_head(&mut self, size: usize, count: usize) -> io::Result<()> {
self.write_u32(size as u32)?;
self.write_u32(count as u32)
}
fn write_vector<T, I, F>(&mut self, vec: &[T], size: usize, mut func: F) -> io::Result<()>
where
F: FnMut(&T, &mut Self),
{
self.write_vector_head(size, vec.len())?;
for elt in vec {
(func)(elt, self);
}
Ok(())
}
}
impl<R: Read> WgReadExt for R {}
impl<W: Write> WgWriteExt for W {}
pub struct IoCounter<I> {
inner: I,
count: usize,
}
impl<I> IoCounter<I> {
#[inline]
pub fn new(inner: I) -> Self {
Self {
inner,
count: 0,
}
}
#[inline]
pub fn count(&self) -> usize {
self.count
}
#[inline]
pub fn into_inner(self) -> I {
self.inner
}
}
impl<R: Read> Read for IoCounter<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let len = self.inner.read(buf)?;
self.count += len;
Ok(len)
}
}
impl<W: Write> Write for IoCounter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let len = self.inner.write(buf)?;
self.count += len;
Ok(len)
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.inner.write_all(buf)?;
self.count += buf.len();
Ok(())
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}