139 lines
4.9 KiB
Rust
139 lines
4.9 KiB
Rust
use std::cmp::min;
|
|
use std::io;
|
|
use std::io::prelude::*;
|
|
|
|
pub trait SimpleCommunicator {
|
|
fn send_bool(&mut self, b: bool) -> io::Result<usize>;
|
|
fn send_2bytes(&mut self, v: &[u8; 2]) -> io::Result<usize>;
|
|
fn send_32bytes(&mut self, v: &[u8; 32]) -> io::Result<usize>;
|
|
fn send_u16(&mut self, number: u16) -> io::Result<usize>;
|
|
fn send_u32(&mut self, number: u32) -> io::Result<usize>;
|
|
fn send_u64(&mut self, number: u64) -> io::Result<usize>;
|
|
fn send_string_small(&mut self, text: &str) -> io::Result<usize>;
|
|
fn send_bytes_short(&mut self, bytes: &[u8]) -> io::Result<usize>;
|
|
fn send_bytes_large(&mut self, bytes: &[u8]) -> io::Result<usize>;
|
|
fn recv_bool(&mut self) -> io::Result<bool>;
|
|
fn recv_2bytes(&mut self) -> io::Result<[u8; 2]>;
|
|
fn recv_32bytes(&mut self) -> io::Result<[u8; 32]>;
|
|
fn recv_u16(&mut self) -> io::Result<u16>;
|
|
fn recv_u32(&mut self) -> io::Result<u32>;
|
|
fn recv_u64(&mut self) -> io::Result<u64>;
|
|
fn recv_string_small(&mut self) -> io::Result<String>;
|
|
fn recv_bytes_short(&mut self) -> io::Result<Vec<u8>>;
|
|
fn recv_bytes_large(&mut self) -> io::Result<Vec<u8>>;
|
|
}
|
|
|
|
impl<T> SimpleCommunicator for T
|
|
where
|
|
T: io::Read + io::Write,
|
|
{
|
|
fn send_bool(&mut self, b: bool) -> io::Result<usize> {
|
|
Ok(if b {
|
|
self.write(&[255])?
|
|
} else {
|
|
self.write(&[0])?
|
|
})
|
|
}
|
|
fn send_2bytes(&mut self, v: &[u8; 2]) -> io::Result<usize> {
|
|
Ok(self.write(v)?)
|
|
}
|
|
fn send_32bytes(&mut self, v: &[u8; 32]) -> io::Result<usize> {
|
|
Ok(self.write(v)?)
|
|
}
|
|
fn send_u16(&mut self, number: u16) -> io::Result<usize> {
|
|
Ok(self.write(&number.to_be_bytes())?)
|
|
}
|
|
fn send_u32(&mut self, number: u32) -> io::Result<usize> {
|
|
Ok(self.write(&number.to_be_bytes())?)
|
|
}
|
|
fn send_u64(&mut self, number: u64) -> io::Result<usize> {
|
|
Ok(self.write(&number.to_be_bytes())?)
|
|
}
|
|
fn send_string_small(&mut self, text: &str) -> io::Result<usize> {
|
|
Ok(self.send_bytes_short(text.as_bytes())?)
|
|
}
|
|
fn send_bytes_short(&mut self, bytes: &[u8]) -> io::Result<usize> {
|
|
let s1 = self.send_u16(bytes.len() as u16)?;
|
|
let s2 = self.write(bytes)?;
|
|
Ok(s1 + s2)
|
|
}
|
|
fn send_bytes_large(&mut self, bytes: &[u8]) -> io::Result<usize> {
|
|
let bl = bytes.len();
|
|
let s1 = self.send_u64(bytes.len() as u64)?;
|
|
let mut s2: usize = 0;
|
|
let bucketsz: usize = 1 << 14;
|
|
while s2 < bl {
|
|
s2 += self.write(
|
|
&bytes
|
|
.iter()
|
|
.skip(s2)
|
|
.take(bucketsz)
|
|
.copied()
|
|
.collect::<Vec<u8>>(),
|
|
)?;
|
|
self.flush()?;
|
|
}
|
|
Ok(s1 + s2)
|
|
}
|
|
fn recv_bool(&mut self) -> io::Result<bool> {
|
|
let mut bytes = [0u8; 1];
|
|
self.read_exact(&mut bytes)?;
|
|
match bytes[0] {
|
|
255 => Ok(true),
|
|
0 => Ok(false),
|
|
_ => Err(io::Error::from(io::ErrorKind::InvalidData)),
|
|
}
|
|
}
|
|
fn recv_2bytes(&mut self) -> io::Result<[u8; 2]> {
|
|
let mut bytes = [0u8; 2];
|
|
self.read_exact(&mut bytes)?;
|
|
Ok(bytes)
|
|
}
|
|
fn recv_32bytes(&mut self) -> io::Result<[u8; 32]> {
|
|
let mut bytes = [0u8; 32];
|
|
self.read_exact(&mut bytes)?;
|
|
Ok(bytes)
|
|
}
|
|
fn recv_u16(&mut self) -> io::Result<u16> {
|
|
let mut u16_bytes = [0u8; 2];
|
|
self.read_exact(&mut u16_bytes)?;
|
|
Ok(u16::from_be_bytes(u16_bytes))
|
|
}
|
|
fn recv_u32(&mut self) -> io::Result<u32> {
|
|
let mut u32_bytes = [0u8; 4];
|
|
self.read_exact(&mut u32_bytes)?;
|
|
Ok(u32::from_be_bytes(u32_bytes))
|
|
}
|
|
fn recv_u64(&mut self) -> io::Result<u64> {
|
|
let mut u64_bytes = [0u8; 8];
|
|
self.read_exact(&mut u64_bytes)?;
|
|
Ok(u64::from_be_bytes(u64_bytes))
|
|
}
|
|
fn recv_string_small(&mut self) -> io::Result<String> {
|
|
let size: u16 = self.recv_u16()?;
|
|
let mut small_string: String = String::new();
|
|
self.take(size as u64).read_to_string(&mut small_string)?;
|
|
Ok(small_string)
|
|
}
|
|
fn recv_bytes_short(&mut self) -> io::Result<Vec<u8>> {
|
|
let size: u16 = self.recv_u16()?;
|
|
let mut small_vec: Vec<u8> = vec![0u8; size as usize];
|
|
self.read(&mut small_vec)?;
|
|
Ok(small_vec)
|
|
}
|
|
fn recv_bytes_large(&mut self) -> io::Result<Vec<u8>> {
|
|
let size: usize = self.recv_u64()? as usize;
|
|
let mut large_vec: Vec<u8> = vec![0u8; size as usize];
|
|
let mut already_read = 0usize;
|
|
let bucketsz: usize = 1 << 14;
|
|
while already_read < size {
|
|
let to_take = min(size - already_read, bucketsz);
|
|
already_read += self
|
|
.take(to_take as u64)
|
|
.read(&mut large_vec[already_read..(already_read + to_take)])?;
|
|
self.flush()?;
|
|
}
|
|
Ok(large_vec)
|
|
}
|
|
}
|