IPC implementation
authorunC0Rr
Wed, 21 Nov 2018 15:49:16 +0100
changeset 14281 f0c0d2d217c3
parent 14280 7d7f7483459e
child 14282 1b8c889027a3
IPC implementation
rust/hedgewars-engine-messages/src/lib.rs
rust/hedgewars-engine-messages/src/parser.rs
rust/lib-hedgewars-engine/src/ipc.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;
-
--- 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<EngineMessage> >, 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))));
 }
--- 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<usize> {
+        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<usize> {
+        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<Self::Item> {
+        let (consumed, message) = extract_message(&self.in_buffer[..])?;
+
+        self.in_buffer.consume(consumed);
+
+        Some(message)
+    }
+}