mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-03 00:00:05 +02:00
changed CodecUdp::decode to return Self::In instead of Option<Self::In>
This commit is contained in:
+16
-9
@@ -25,20 +25,27 @@ use std::str;
|
|||||||
/// so that it can respond back.
|
/// so that it can respond back.
|
||||||
/// In the real world, one would probably
|
/// In the real world, one would probably
|
||||||
/// want an associative of remote peers to their state
|
/// want an associative of remote peers to their state
|
||||||
|
///
|
||||||
|
/// Note that this takes a pretty draconian stance by returning
|
||||||
|
/// an error if it can't find a newline in the datagram it received
|
||||||
pub struct LineCodec {
|
pub struct LineCodec {
|
||||||
addr : Option<SocketAddr>
|
addr : Option<SocketAddr>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodecUdp for LineCodec {
|
impl CodecUdp for LineCodec {
|
||||||
type In = Vec<u8>;
|
type In = Vec<Vec<u8>>;
|
||||||
type Out = Vec<u8>;
|
type Out = Vec<u8>;
|
||||||
|
|
||||||
fn decode(&mut self, addr : &SocketAddr, buf: &[u8]) -> Result<Option<Self::In>, io::Error> {
|
fn decode(&mut self, addr : &SocketAddr, buf: &[u8]) -> Result<Self::In, io::Error> {
|
||||||
trace!("decoding {} - {}", str::from_utf8(buf).unwrap(), addr);
|
trace!("decoding {} - {}", str::from_utf8(buf).unwrap(), addr);
|
||||||
self.addr = Some(*addr);
|
self.addr = Some(*addr);
|
||||||
match buf.iter().position(|&b| b == b'\n') {
|
let res : Vec<Vec<u8>> = buf.split(|c| *c == b'\n').map(|s| s.into()).collect();
|
||||||
Some(i) => Ok(Some(buf[.. i].into())),
|
if res.len() > 0 {
|
||||||
None => Ok(None),
|
Ok(res)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Err(io::Error::new(io::ErrorKind::Other,
|
||||||
|
"failed to find newline in datagram"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +90,8 @@ fn main() {
|
|||||||
//Note that we pass srvsink into fold, so that it can be
|
//Note that we pass srvsink into fold, so that it can be
|
||||||
//supplied to every iteration. The reason for this is
|
//supplied to every iteration. The reason for this is
|
||||||
//sink.send moves itself into `send` and then returns itself
|
//sink.send moves itself into `send` and then returns itself
|
||||||
let srvloop = srvstream.fold(srvsink, move |sink, buf| {
|
let srvloop = srvstream.fold(srvsink, move |sink, lines| {
|
||||||
println!("{}", str::from_utf8(buf.as_slice()).unwrap());
|
println!("{}", str::from_utf8(lines[0].as_slice()).unwrap());
|
||||||
sink.send(b"PONG".to_vec())
|
sink.send(b"PONG".to_vec())
|
||||||
}).map(|_| ());
|
}).map(|_| ());
|
||||||
|
|
||||||
@@ -92,8 +99,8 @@ fn main() {
|
|||||||
let (clistream, clisink) = client.framed(clicodec).split();
|
let (clistream, clisink) = client.framed(clicodec).split();
|
||||||
|
|
||||||
//And another infinite iteration
|
//And another infinite iteration
|
||||||
let cliloop = clistream.fold(clisink, move |sink, buf| {
|
let cliloop = clistream.fold(clisink, move |sink, lines| {
|
||||||
println!("{}", str::from_utf8(buf.as_slice()).unwrap());
|
println!("{}", str::from_utf8(lines[0].as_slice()).unwrap());
|
||||||
sink.send(b"PING".to_vec())
|
sink.send(b"PING".to_vec())
|
||||||
}).map(|_| ());
|
}).map(|_| ());
|
||||||
|
|
||||||
|
|||||||
+4
-11
@@ -45,17 +45,11 @@ pub trait CodecUdp {
|
|||||||
/// decode, as the next poll_read that occurs will write the next datagram
|
/// decode, as the next poll_read that occurs will write the next datagram
|
||||||
/// into the buffer, without regard for what is already there.
|
/// into the buffer, without regard for what is already there.
|
||||||
///
|
///
|
||||||
/// If the bytes look valid, but a frame isn't fully available yet, then
|
|
||||||
/// `Ok(None)` is returned. This indicates to the `Framed` instance that
|
|
||||||
/// it needs to read some more bytes before calling this method again.
|
|
||||||
/// In such a case, it is decode's responsibility to copy the data
|
|
||||||
/// into their own internal buffer for future use.
|
|
||||||
///
|
|
||||||
/// Finally, if the bytes in the buffer are malformed then an error is
|
/// Finally, if the bytes in the buffer are malformed then an error is
|
||||||
/// returned indicating why. This informs `Framed` that the stream is now
|
/// returned indicating why. This informs `Framed` that the stream is now
|
||||||
/// corrupt and should be terminated.
|
/// corrupt and should be terminated.
|
||||||
///
|
///
|
||||||
fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> Result<Option<Self::In>, io::Error>;
|
fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> Result<Self::In, io::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A unified `Stream` and `Sink` interface to an underlying `Io` object, using
|
/// A unified `Stream` and `Sink` interface to an underlying `Io` object, using
|
||||||
@@ -82,10 +76,9 @@ impl<C : CodecUdp> Stream for FramedUdp<C> {
|
|||||||
Ok((n, addr)) => {
|
Ok((n, addr)) => {
|
||||||
trace!("read {} bytes", n);
|
trace!("read {} bytes", n);
|
||||||
trace!("attempting to decode a frame");
|
trace!("attempting to decode a frame");
|
||||||
if let Some(frame) = try!(self.codec.decode(&addr, & self.rd[.. n])) {
|
let frame = try!(self.codec.decode(&addr, & self.rd[.. n]));
|
||||||
trace!("frame decoded from buffer");
|
trace!("frame decoded from buffer");
|
||||||
return Ok(Async::Ready(Some(frame)));
|
return Ok(Async::Ready(Some(frame)));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
|
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||||
return Ok(Async::NotReady)
|
return Ok(Async::NotReady)
|
||||||
|
|||||||
Reference in New Issue
Block a user