From fd421e32780cad46782c16cd4e15947f295a08c7 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Fri, 27 Mar 2020 22:47:57 +0100 Subject: Initial, untested version of controller and worker Worker has been tested to a marginal extent, but the controller is litereally untested. --- utils/src/enums.rs | 11 +++++++++++ utils/src/error.rs | 27 +++++++++++++++++++++++++++ utils/src/idgen.rs | 16 ++++++++++++++++ utils/src/lib.rs | 4 ++++ utils/src/protocol.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ utils/src/read_ext.rs | 38 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 utils/src/enums.rs create mode 100644 utils/src/error.rs create mode 100644 utils/src/idgen.rs create mode 100644 utils/src/lib.rs create mode 100644 utils/src/protocol.rs create mode 100644 utils/src/read_ext.rs (limited to 'utils/src') diff --git a/utils/src/enums.rs b/utils/src/enums.rs new file mode 100644 index 0000000..d08c7ea --- /dev/null +++ b/utils/src/enums.rs @@ -0,0 +1,11 @@ +pub enum MessageBody { + Version(u32), + NewCore(String, Vec), + Job(u64, Vec), +} + +pub enum Reply { + Version(bool), + NewCore, + Job(i32, Vec), +} diff --git a/utils/src/error.rs b/utils/src/error.rs new file mode 100644 index 0000000..f25bc5d --- /dev/null +++ b/utils/src/error.rs @@ -0,0 +1,27 @@ +use std::io; + +pub trait IntoIOError { + fn ioerr(self) -> io::Error; + fn perror(self, parent: io::Error) -> io::Error; +} + +// This impl bound is taken directly from the io::Error::new function. +impl>> IntoIOError for E { + fn ioerr(self) -> io::Error { + io::Error::new(io::ErrorKind::Other, self) + } + + fn perror(self, parent: io::Error) -> io::Error { + io::Error::new(parent.kind(), format!("{}: {}", self.into(), parent)) + } +} + +pub trait IntoIOResult { + fn iores(self) -> io::Result; +} + +impl IntoIOResult for Result { + fn iores(self) -> io::Result { + self.map_err(|e| e.ioerr()) + } +} diff --git a/utils/src/idgen.rs b/utils/src/idgen.rs new file mode 100644 index 0000000..20f13ff --- /dev/null +++ b/utils/src/idgen.rs @@ -0,0 +1,16 @@ +#[derive(Debug)] +pub struct IdGen { + next: u64, +} + +impl IdGen { + pub fn new(start: u64) -> Self { + IdGen { next: start } + } + + pub fn gen(&mut self) -> u64 { + let res = self.next; + self.next += 1; + res + } +} diff --git a/utils/src/lib.rs b/utils/src/lib.rs new file mode 100644 index 0000000..867fd97 --- /dev/null +++ b/utils/src/lib.rs @@ -0,0 +1,4 @@ +pub mod error; +pub mod idgen; +pub mod protocol; +pub mod read_ext; diff --git a/utils/src/protocol.rs b/utils/src/protocol.rs new file mode 100644 index 0000000..4820f79 --- /dev/null +++ b/utils/src/protocol.rs @@ -0,0 +1,44 @@ +use std::convert::TryInto; +use std::io::{self, BufReader, ErrorKind, Read}; +use std::net::TcpStream; + +pub enum MessageBody { + Version(u32), + NewCore(String, Vec), + Job(u64, Vec), +} + +pub enum Reply { + Version(bool), + NewCore, + Job(i32, Vec), +} + +pub struct RawMessage { + pub typ: u8, + pub id: u64, + pub payload: Vec, +} + +impl RawMessage { + pub fn receive(reader: &mut BufReader) -> io::Result> { + let mut header = [0u8; 17]; + if let Err(e) = reader.read(&mut header) { + if e.kind() == ErrorKind::UnexpectedEof { return Ok(None); } + else { return Err(e); } + } + + let typ = header[0]; + let id = u64::from_le_bytes(header[1..9].try_into().unwrap()); + let length = usize::from_le_bytes(header[9..17].try_into().unwrap()); + + let mut payload = Vec::new(); + payload.resize(length, 0u8); + if let Err(e) = reader.read(&mut payload) { + if e.kind() == ErrorKind::UnexpectedEof { return Ok(None); } + else { return Err(e); } + } + + Ok(Some(Self { typ, id, payload })) + } +} diff --git a/utils/src/read_ext.rs b/utils/src/read_ext.rs new file mode 100644 index 0000000..7695ada --- /dev/null +++ b/utils/src/read_ext.rs @@ -0,0 +1,38 @@ +use std::convert::TryInto; + +pub trait ReadExt { + fn read_exact(&mut self, n: usize) -> Option<&[u8]>; + + fn read_le_i32(&mut self) -> Option { + self.read_exact(4).map(|bytes| i32::from_le_bytes(bytes.try_into().unwrap())) + } + + fn read_le_u32(&mut self) -> Option { + self.read_exact(4).map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap())) + } + + fn read_le_u64(&mut self) -> Option { + self.read_exact(8).map(|bytes| u64::from_le_bytes(bytes.try_into().unwrap())) + } + + fn read_pascal_blob(&mut self) -> Option<&[u8]> { + let len = self.read_le_u64()?; + self.read_exact(len as usize) + } + + fn read_pascal_string(&mut self) -> Option> { + self.read_pascal_blob().map(|b| String::from_utf8(b.to_vec())) + } +} + +impl ReadExt for &[u8] { + fn read_exact(&mut self, n: usize) -> Option<&[u8]> { + if self.len() >= n { + let (res, newlist) = self.split_at(n); + *self = newlist; + Some(res) + } else { + None + } + } +} -- cgit v1.2.3-54-g00ecf