diff --git a/src/imp/buf/bound.rs b/src/imp/buf/bound.rs new file mode 100644 index 0000000000000000000000000000000000000000..66cc2cac7e6afa9c15a482b9f8fded5195917319 --- /dev/null +++ b/src/imp/buf/bound.rs @@ -0,0 +1,55 @@ +use {Buf, IntoBuf}; +use std::mem; + +/// Takes a `T` that can be iterated as a buffer and provides buffer with a +/// 'static lifetime +pub struct BoundBuf<T> + where T: 'static, + &'static T: IntoBuf +{ + data: T, // This should never be mutated + buf: <&'static T as IntoBuf>::Buf, // This buf should never leak out +} + +impl<T> BoundBuf<T> + where &'static T: IntoBuf, +{ + /// Creates a new `BoundBuf` wrapping the provided data + pub fn new(data: T) -> BoundBuf<T> { + let buf = unsafe { + let r: &'static T = mem::transmute(&data); + r.into_buf() + }; + + BoundBuf { + data: data, + buf: buf, + } + } + + /// Consumes this BoundBuf, returning the underlying value. + pub fn into_inner(self) -> T { + self.data + } + + /// Gets a reference to the underlying value + pub fn get_ref(&self) -> &T { + &self.data + } +} + +impl<T> Buf for BoundBuf<T> + where &'static T: IntoBuf +{ + fn remaining(&self) -> usize { + self.buf.remaining() + } + + fn bytes(&self) -> &[u8] { + self.buf.bytes() + } + + fn advance(&mut self, cnt: usize) { + self.buf.advance(cnt) + } +} diff --git a/src/imp/buf/mod.rs b/src/imp/buf/mod.rs index 118cc478c69f61073843ff38af09695fb9fadea0..44c20f08f8dea92ce5608aaccd5c55708416dad2 100644 --- a/src/imp/buf/mod.rs +++ b/src/imp/buf/mod.rs @@ -1,5 +1,6 @@ pub mod append; pub mod block; +pub mod bound; pub mod slice; pub mod ring; pub mod take;