Skip to content

Instantly share code, notes, and snippets.

@Noxivs
Created August 3, 2014 19:32
Show Gist options
  • Save Noxivs/b4d7b1095d66af3a90c0 to your computer and use it in GitHub Desktop.
Save Noxivs/b4d7b1095d66af3a90c0 to your computer and use it in GitHub Desktop.
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