# HG changeset patch # User unC0Rr # Date 1542811756 -3600 # Node ID f0c0d2d217c30d830269c6367e0e3b1370db64aa # Parent 7d7f7483459ee8107dd5739626799ca0e7912b2f IPC implementation diff -r 7d7f7483459e -r f0c0d2d217c3 rust/hedgewars-engine-messages/src/lib.rs --- a/rust/hedgewars-engine-messages/src/lib.rs Wed Nov 21 17:28:28 2018 +0300 +++ b/rust/hedgewars-engine-messages/src/lib.rs Wed Nov 21 15:49:16 2018 +0100 @@ -1,3 +1,2 @@ pub mod messages; pub mod parser; - diff -r 7d7f7483459e -r f0c0d2d217c3 rust/hedgewars-engine-messages/src/parser.rs --- a/rust/hedgewars-engine-messages/src/parser.rs Wed Nov 21 17:28:28 2018 +0300 +++ b/rust/hedgewars-engine-messages/src/parser.rs Wed Nov 21 15:49:16 2018 +0100 @@ -3,7 +3,7 @@ use super::messages::{ ConfigEngineMessage::*, EngineMessage::*, KeystrokeAction::*, SyncedEngineMessage::*, - UnorderedEngineMessage::*, UnsyncedEngineMessage::*, *, + UnorderedEngineMessage::*, *, }; macro_rules! eof_slice ( @@ -121,6 +121,19 @@ named!(pub extract_messages<&[u8], Vec >, many0!(complete!(message))); +pub fn extract_message(buf: &[u8]) -> Option<(usize, EngineMessage)> { + let parse_result = message(buf); + match parse_result { + Ok((tail, msg)) => { + let consumed = buf.len() - tail.len(); + + Some((consumed, msg)) + }, + Err(Err::Incomplete(_)) => None, + Err(Err::Error(_)) | Err(Err::Failure(_)) => unreachable!(), + } +} + #[test] fn parse_length() { assert_eq!(length_specifier(b"\x01"), Ok((&b""[..], 1))); @@ -139,6 +152,7 @@ message(b"\x03L\x01\x02"), Ok((&b""[..], Synced(Left(Press), 258))) ); + assert_eq!(message(b"\x01#"), Ok((&b""[..], Synced(TimeWrap, 65535)))); assert_eq!(message(&vec![9, b'p', 255, 133, 151, 1, 0, 2, 0, 0]), Ok((&b""[..], Synced(Put(-31337, 65538), 0)))); @@ -169,4 +183,7 @@ #[test] fn parse_test_general() { assert_eq!(string_tail(b"abc"), Ok((&b""[..], String::from("abc")))); + + assert_eq!(extract_message(b"\x02#"), None); + assert_eq!(extract_message(b"\x01#"), Some((2, Synced(TimeWrap, 65535)))); } diff -r 7d7f7483459e -r f0c0d2d217c3 rust/lib-hedgewars-engine/src/ipc.rs --- a/rust/lib-hedgewars-engine/src/ipc.rs Wed Nov 21 17:28:28 2018 +0300 +++ b/rust/lib-hedgewars-engine/src/ipc.rs Wed Nov 21 15:49:16 2018 +0100 @@ -1,5 +1,6 @@ -use hedgewars_engine_messages::{messages::*, parser}; +use hedgewars_engine_messages::{messages::*, parser::extract_message}; use netbuf::*; +use std::io::*; pub struct IPC { in_buffer: Buf, @@ -8,6 +9,47 @@ impl IPC { pub fn new() -> Self { + Self { + in_buffer: Buf::new(), + out_buffer: Buf::new(), + } + } + pub fn send_message(&mut self, message: &EngineMessage) { + self.out_buffer.write(&message.to_bytes()).unwrap(); + } +} + +impl Write for IPC { + fn write(&mut self, buf: &[u8]) -> Result { + self.in_buffer.write(buf) + } + + fn flush(&mut self) -> Result<()> { + self.in_buffer.flush() } } + +impl Read for IPC { + fn read(&mut self, buf: &mut [u8]) -> Result { + let result = self.out_buffer.as_ref().read(buf); + + if let Ok(read_bytes) = result { + self.out_buffer.consume(read_bytes); + } + + result + } +} + +impl Iterator for IPC { + type Item = EngineMessage; + + fn next(&mut self) -> Option { + let (consumed, message) = extract_message(&self.in_buffer[..])?; + + self.in_buffer.consume(consumed); + + Some(message) + } +}