Skip to content

Commit

Permalink
udpframed: ptr eq check
Browse files Browse the repository at this point in the history
  • Loading branch information
leshow committed Nov 2, 2020
1 parent 1e5113d commit fc4be61
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions tokio-util/src/udp/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::pin::Pin;
use std::task::{Context, Poll};
use std::{io, mem::MaybeUninit};

/// A unified `Stream` and `Sink` interface to an underlying `UdpSocket`, using
/// A unified [`Stream`] and [`Sink`] interface to an underlying `UdpSocket`, using
/// the `Encoder` and `Decoder` traits to encode and decode frames.
///
/// Raw UDP sockets work with datagrams, but higher-level code usually wants to
Expand All @@ -19,13 +19,17 @@ use std::{io, mem::MaybeUninit};
/// handle encoding and decoding of messages frames. Note that the incoming and
/// outgoing frame types may be distinct.
///
/// This function returns a *single* object that is both `Stream` and `Sink`;
/// This function returns a *single* object that is both [`Stream`] and [`Sink`];
/// grouping this into a single object is often useful for layering things which
/// require both read and write access to the underlying object.
///
/// If you want to work more directly with the streams and sink, consider
/// calling `split` on the `UdpFramed` returned by this method, which will break
/// calling [`split`] on the `UdpFramed` returned by this method, which will break
/// them into separate objects, allowing them to interact more easily.
///
/// [`Stream`]: tokio::stream::Stream
/// [`Sink`]: futures_sink::Sink
/// [`split`]: https://docs.rs/futures/0.3/futures/stream/trait.StreamExt.html#method.split
#[must_use = "sinks do nothing unless polled"]
#[cfg_attr(docsrs, doc(all(feature = "codec", feature = "udp")))]
#[derive(Debug)]
Expand Down Expand Up @@ -73,8 +77,10 @@ impl<C: Decoder + Unpin> Stream for UdpFramed<C> {
// writing to it via `poll_recv_from` and therefore initializing the memory.
let buf = &mut *(pin.rd.bytes_mut() as *mut _ as *mut [MaybeUninit<u8>]);
let mut read = ReadBuf::uninit(buf);
let ptr = read.filled().as_ptr();
let res = ready!(Pin::new(&mut pin.socket).poll_recv_from(cx, &mut read));

assert_eq!(ptr, read.filled().as_ptr());
let addr = res?;
pin.rd.advance_mut(read.filled().len());
addr
Expand Down Expand Up @@ -193,4 +199,32 @@ impl<C> UdpFramed<C> {
pub fn into_inner(self) -> UdpSocket {
self.socket
}

/// Returns a reference to the underlying codec wrapped by
/// `Framed`.
///
/// Note that care should be taken to not tamper with the underlying codec
/// as it may corrupt the stream of frames otherwise being worked with.
pub fn codec(&self) -> &C {
&self.codec
}

/// Returns a mutable reference to the underlying codec wrapped by
/// `UdpFramed`.
///
/// Note that care should be taken to not tamper with the underlying codec
/// as it may corrupt the stream of frames otherwise being worked with.
pub fn codec_mut(&mut self) -> &mut C {
&mut self.codec
}

/// Returns a reference to the read buffer.
pub fn read_buffer(&self) -> &BytesMut {
&self.rd
}

/// Returns a mutable reference to the read buffer.
pub fn read_buffer_mut(&mut self) -> &mut BytesMut {
&mut self.rd
}
}

0 comments on commit fc4be61

Please sign in to comment.