use std::io::{self, Error, ErrorKind, Read, Result, Write};
pub trait ReadExt: Read {
#[inline]
fn read_u8(&mut self) -> Result<u8> {
let mut buf = [0; 1];
self.read_exact(&mut buf)?;
Ok(buf[0])
}
#[inline]
fn read_u8_add(&mut self) -> Result<u8> {
Ok(self.read_u8()?.wrapping_sub(128))
}
#[inline]
fn read_u8_neg(&mut self) -> Result<u8> {
Ok(0u8.wrapping_sub(self.read_u8()?))
}
#[inline]
fn read_u8_sub(&mut self) -> Result<u8> {
Ok(128u8.wrapping_sub(self.read_u8()?))
}
#[inline]
fn read_i8(&mut self) -> Result<i8> {
Ok(self.read_u8()? as i8)
}
#[inline]
fn read_i8_add(&mut self) -> Result<i8> {
Ok(self.read_u8_add()? as i8)
}
#[inline]
fn read_i8_neg(&mut self) -> Result<i8> {
Ok(self.read_u8_neg()? as i8)
}
#[inline]
fn read_i8_sub(&mut self) -> Result<i8> {
Ok(self.read_u8_sub()? as i8)
}
#[inline]
fn read_bool(&mut self) -> Result<bool> {
let mut buf = [0; 1];
self.read_exact(&mut buf)?;
Ok(buf[0] != 0)
}
#[inline]
fn read_u16(&mut self) -> Result<u16> {
let mut buf = [0; 2];
self.read_exact(&mut buf)?;
Ok(u16::from_be_bytes(buf))
}
#[inline]
fn read_u16_le(&mut self) -> Result<u16> {
let mut buf = [0; 2];
self.read_exact(&mut buf)?;
Ok(u16::from_le_bytes(buf))
}
#[inline]
fn read_u16_smart(&mut self) -> Result<u16> {
let peek = self.read_u8()?;
if peek & 128 == 0 {
Ok(peek as u16)
} else {
Ok(((peek as u16 & 0x7F) << 8) | (self.read_u8()? as u16))
}
}
#[inline]
fn read_u16_add(&mut self) -> Result<u16> {
Ok(((self.read_u8()? as u16) << 8) | ((self.read_u8()?.wrapping_sub(128)) as u16))
}
#[inline]
fn read_u16_add_le(&mut self) -> Result<u16> {
Ok(((self.read_u8()?.wrapping_sub(128)) as u16) | ((self.read_u8()? as u16) << 8))
}
#[inline]
fn read_i16(&mut self) -> Result<i16> {
Ok(self.read_u16()? as i16)
}
#[inline]
fn read_i16_le(&mut self) -> Result<i16> {
Ok(self.read_u16_le()? as i16)
}
#[inline]
fn read_i16_smart(&mut self) -> Result<i16> {
let peek = self.read_u8()?;
if peek & 128 == 0 {
Ok(peek as i16 - 64)
} else {
Ok((((peek as i16 & 0x7F) << 8) | (self.read_u8()? as i16) & 0x7FFF) - 16384)
}
}
#[inline]
fn read_i16_add(&mut self) -> Result<i16> {
Ok(self.read_u16_add()? as i16)
}
#[inline]
fn read_i16_add_le(&mut self) -> Result<i16> {
Ok(self.read_u16_add_le()? as i16)
}
#[inline]
fn read_u24(&mut self) -> Result<u32> {
let mut buf = [0; 3];
self.read_exact(&mut buf)?;
Ok(u32::from_be_bytes([0, buf[0], buf[1], buf[2]]))
}
#[inline]
fn read_u24_le(&mut self) -> Result<u32> {
let mut buf = [0; 3];
self.read_exact(&mut buf)?;
Ok(u32::from_le_bytes([buf[0], buf[1], buf[2], 0]))
}
#[inline]
fn read_i24(&mut self) -> Result<i32> {
Ok(self.read_u24()? as i32)
}
#[inline]
fn read_i24_le(&mut self) -> Result<i32> {
Ok(self.read_u24_le()? as i32)
}
#[inline]
fn read_u32(&mut self) -> Result<u32> {
let mut buf = [0; 4];
self.read_exact(&mut buf)?;
Ok(u32::from_be_bytes(buf))
}
#[inline]
fn read_u32_smart(&mut self) -> Result<u32> {
let peek = self.read_u8()?;
if peek & 128 == 0 {
Ok(((peek as u32 & 0x7F) << 8) | (self.read_u8()? as u32) & 0x7FFF)
} else {
Ok((((peek as u32 & 0x7F) << 24)
| ((self.read_u8()? as u32) << 16)
| ((self.read_u8()? as u32) << 8)
| (self.read_u8()? as u32))
& 0x7FFFFFFF)
}
}
#[inline]
fn read_u32_le(&mut self) -> Result<u32> {
let mut buf = [0; 4];
self.read_exact(&mut buf)?;
Ok(u32::from_le_bytes(buf))
}
#[inline]
fn read_u32_me(&mut self) -> Result<u32> {
Ok((self.read_u16_le()? as u32) << 16 | (self.read_u16_le()? as u32))
}
#[inline]
fn read_u32_ime(&mut self) -> Result<u32> {
Ok((self.read_u16()? as u32) | ((self.read_u16()? as u32) << 16))
}
#[inline]
fn read_i32(&mut self) -> Result<i32> {
Ok(self.read_u32()? as i32)
}
#[inline]
fn read_i32_smart(&mut self) -> Result<i32> {
let peek = self.read_u8()?;
if peek & 128 == 0 {
Ok((((peek as i32 & 0x7F) << 8) | (self.read_u8()? as i32) & 0x7FFF) - 0x4000)
} else {
Ok(((((peek as i32 & 0x7F) << 24)
| ((self.read_u8()? as i32) << 16)
| ((self.read_u8()? as i32) << 8)
| (self.read_u8()? as i32))
& 0x7FFFFFFF)
- 0x40000000)
}
}
#[inline]
fn read_i32_le(&mut self) -> Result<i32> {
Ok(self.read_u32_le()? as i32)
}
#[inline]
fn read_i32_me(&mut self) -> Result<i32> {
Ok(self.read_u32_me()? as i32)
}
#[inline]
fn read_i32_ime(&mut self) -> Result<i32> {
Ok(self.read_u32_ime()? as i32)
}
#[inline]
fn read_u64(&mut self) -> Result<u64> {
let mut buf = [0; 8];
self.read_exact(&mut buf)?;
Ok(u64::from_be_bytes(buf))
}
#[inline]
fn read_i64(&mut self) -> Result<i64> {
Ok(self.read_u64()? as i64)
}
#[inline]
fn read_string_cp1252(&mut self) -> Result<String> {
let mut str = Vec::new();
while let Ok(x) = self.read_u8() {
if x != 0 {
str.push(x);
} else {
break;
}
}
let s = match std::str::from_utf8(&str) {
Ok(v) => v,
Err(e) => {
return Err(Error::new(
ErrorKind::Other,
format!("Invalid UTF-8 sequence: {}", e),
))
}
};
Ok(s.to_owned())
}
}
impl<R: io::Read + ?Sized> ReadExt for R {}
pub trait WriteExt: Write {
#[inline]
fn write_u8(&mut self, n: u8) -> Result<()> {
self.write_all(&[n])
}
#[inline]
fn write_u8_add(&mut self, n: u8) -> Result<()> {
self.write_u8(n.wrapping_add(128))
}
#[inline]
fn write_u8_neg(&mut self, n: u8) -> Result<()> {
self.write_u8(0u8.wrapping_sub(n))
}
#[inline]
fn write_u8_sub(&mut self, n: u8) -> Result<()> {
self.write_u8(128u8.wrapping_sub(n))
}
#[inline]
fn write_i8(&mut self, n: i8) -> Result<()> {
self.write_u8(n as u8)
}
#[inline]
fn write_i8_sub(&mut self, n: i8) -> Result<()> {
self.write_u8_sub(n as u8)
}
#[inline]
fn write_i8_add(&mut self, n: i8) -> Result<()> {
self.write_u8_add(n as u8)
}
#[inline]
fn write_i8_neg(&mut self, n: i8) -> Result<()> {
self.write_u8_neg(n as u8)
}
#[inline]
fn write_bool(&mut self, b: bool) -> Result<()> {
self.write_all(&[b as u8])
}
#[inline]
fn write_u16(&mut self, n: u16) -> Result<()> {
self.write_all(&n.to_be_bytes())
}
#[inline]
fn write_u16_le(&mut self, n: u16) -> Result<()> {
self.write_all(&n.to_le_bytes())
}
#[inline]
fn write_u16_smart(&mut self, n: u16) -> Result<()> {
match n {
0..=127 => self.write_u8(n as u8),
128..=32767 => self.write_u16(n + 32768),
_ => Err(Error::new(
ErrorKind::Other,
format!("Failed writing smart, value is {}", n),
)),
}
}
#[inline]
fn write_i16(&mut self, n: i16) -> Result<()> {
self.write_u16(n as u16)
}
#[inline]
fn write_i16_le(&mut self, n: i16) -> Result<()> {
self.write_u16_le(n as u16)
}
#[inline]
fn write_i16_add(&mut self, n: i16) -> Result<()> {
self.write_i8((n >> 8) as i8)?;
self.write_i8((n + 128) as i8)
}
#[inline]
fn write_i16_add_le(&mut self, n: i16) -> Result<()> {
self.write_i8((n + 128) as i8)?;
self.write_i8((n >> 8) as i8)
}
#[inline]
fn write_u32(&mut self, n: u32) -> Result<()> {
self.write_all(&n.to_be_bytes())
}
#[inline]
fn write_u32_le(&mut self, n: u32) -> Result<()> {
self.write_all(&n.to_le_bytes())
}
#[inline]
fn write_i32(&mut self, n: i32) -> Result<()> {
self.write_u32(n as u32)
}
#[inline]
fn write_i32_le(&mut self, n: i32) -> Result<()> {
self.write_u32_le(n as u32)
}
#[inline]
fn write_i32_me(&mut self, n: i32) -> Result<()> {
self.write_i16_le((n >> 16) as i16)?;
self.write_i16_le(n as i16)
}
#[inline]
fn write_i32_ime(&mut self, n: i32) -> Result<()> {
self.write_i16(n as i16)?;
self.write_i16((n >> 16) as i16)
}
#[inline]
fn write_u64(&mut self, n: u64) -> Result<()> {
self.write_all(&n.to_be_bytes())
}
#[inline]
fn write_i64(&mut self, n: i64) -> Result<()> {
self.write_u64(n as u64)
}
#[inline]
fn write_string_cp1252<T: AsRef<str>>(&mut self, s: T) -> Result<()> {
for b in s.as_ref().as_bytes() {
self.write_u8(*b)?;
}
self.write_i8(0)
}
#[inline]
fn write_bytes_reversed_add(&mut self, buf: &[u8]) -> Result<()> {
for b in buf.iter().rev() {
self.write_u8_add(*b)?;
}
Ok(())
}
}
impl<W: io::Write + ?Sized> WriteExt for W {}