Created
August 3, 2014 19:32
-
-
Save Noxivs/b4d7b1095d66af3a90c0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ascii::{AsciiCast, AsciiStr}; | |
use std::comm::TryRecvError; | |
use std::io::net::tcp::TcpStream; | |
static NEW_LINE_CHAR: u8 = 0x0a; | |
static END_LINE_CHAR: u8 = 0x00; | |
static MAX_BUFFER_LENGHT: uint = 8192; | |
#[deriving(PartialEq, Clone)] | |
pub enum ClientId { | |
Id(uint), | |
Unassigned | |
} | |
pub struct Client<'a> { | |
id: ClientId, | |
stream: TcpStream, | |
input_receiver: Option<Receiver<ClientMessage<'a>>> | |
} | |
pub enum ClientMessage<'a> { | |
StrInput(ClientId, &'a str), | |
Disconnect(ClientId) | |
} | |
impl<'a> Client<'a> { | |
pub fn new(id: ClientId, stream: TcpStream) -> Client<'a> { | |
Client { | |
id: id, | |
stream: stream, | |
input_receiver: None | |
} | |
} | |
pub fn listen (&mut self) { | |
let (input_sender, input_receiver) = channel::<ClientMessage>(); | |
let id = self.id.clone(); | |
let stream = self.stream.clone(); | |
self.input_receiver = Some(input_receiver); | |
spawn(proc() { | |
client_input_handler(id, stream, input_sender); | |
}); | |
} | |
pub fn send(&mut self, s: String) { | |
assert!(self.stream.write_str(s.append("\x0000").as_slice()).is_ok()); | |
} | |
pub fn try_recv(&self) -> Option<Result<ClientMessage<'a>, TryRecvError>> { | |
match self.input_receiver { | |
Some(ref r) => Some(r.try_recv()), | |
_ => None // TODO : if input_receiver is none (fn listen not called) | |
} | |
} | |
} | |
fn client_input_handler(id: ClientId, mut stream: TcpStream, s: Sender<ClientMessage>) { | |
let mut buffer = [0u8, ..(MAX_BUFFER_LENGHT - 1)]; | |
let mut index = 0; | |
let mut last_is_nl = false; | |
loop { | |
let byte = stream.read_byte(); | |
if byte.is_err() || index > (MAX_BUFFER_LENGHT - 1) { // TODO : Add disconnection reason | |
s.send(Disconnect(id)); | |
break; | |
} | |
let byte = byte.unwrap(); | |
match byte { | |
NEW_LINE_CHAR => last_is_nl = true, | |
END_LINE_CHAR if last_is_nl => { | |
match buffer.slice_to(index).to_ascii_opt() { | |
Some(r) => s.send(StrInput(id, r.as_str_ascii())), | |
_ => { } | |
} | |
index = 0; | |
last_is_nl = false; | |
}, | |
_ => { | |
buffer[index] = byte; | |
index += 1; | |
last_is_nl = false; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment