rust/hedgewars-server/src/protocol.rs
author alfadur
Fri, 12 Apr 2019 22:36:54 +0300
changeset 14795 add191d825f4
parent 14775 09d46ab83361
child 14796 f5d43f007970
permissions -rw-r--r--
add parser error handling
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
     1
use crate::protocol::parser::message;
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
     2
use log::*;
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
     3
use netbuf;
14775
09d46ab83361 port server parser to nom 5
alfadur
parents: 14457
diff changeset
     4
use nom::{Err, ErrorKind, IResult};
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
     5
use std::io::{Read, Result};
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
     6
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
     7
pub mod messages;
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
     8
mod parser;
13796
59ea2403f62d move everything test related into test cfg
alfadur
parents: 13438
diff changeset
     9
#[cfg(test)]
13416
cdf69667593b partial room implementation
alfadur
parents: 12136
diff changeset
    10
pub mod test;
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    11
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    12
pub struct ProtocolDecoder {
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    13
    buf: netbuf::Buf,
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    14
    consumed: usize,
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    15
    is_recovering: bool,
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    16
}
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    17
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    18
impl ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    19
    pub fn new() -> ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    20
        ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    21
            buf: netbuf::Buf::new(),
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    22
            consumed: 0,
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    23
            is_recovering: false,
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    24
        }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    25
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    26
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    27
    fn recover(&mut self) -> bool {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    28
        self.is_recovering = match parser::malformed_message(&self.buf[..]) {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    29
            Ok((tail, ())) => {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    30
                self.buf.consume(self.buf.len() - tail.len());
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    31
                false
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    32
            }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    33
            _ => {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    34
                self.buf.consume(self.buf.len());
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    35
                true
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    36
            }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    37
        };
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    38
        !self.is_recovering
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    39
    }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    40
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    41
    pub fn read_from<R: Read>(&mut self, stream: &mut R) -> Result<usize> {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    42
        let count = self.buf.read_from(stream)?;
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    43
        if count > 0 && self.is_recovering {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    44
            self.recover();
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    45
        }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    46
        Ok(count)
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    47
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    48
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    49
    pub fn extract_messages(&mut self) -> Vec<messages::HWProtocolMessage> {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    50
        let mut messages = vec![];
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    51
        let mut consumed = 0;
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    52
        if !self.is_recovering {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    53
            loop {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    54
                match parser::message(&self.buf[consumed..]) {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    55
                    Ok((tail, message)) => {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    56
                        messages.push(message);
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    57
                        consumed += self.buf.len() - tail.len();
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    58
                    }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    59
                    Err(nom::Err::Incomplete(_)) => break,
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    60
                    Err(nom::Err::Failure(e)) | Err(nom::Err::Error(e)) => {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    61
                        debug!("Invalid message: {:?}", e);
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    62
                        self.buf.consume(consumed);
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    63
                        consumed = 0;
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    64
                        if !self.recover() || self.buf.is_empty() {
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    65
                            break;
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    66
                        }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    67
                    }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    68
                }
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
    69
            }
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    70
        }
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    71
        self.buf.consume(consumed);
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    72
        messages
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    73
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    74
}