diff --git a/src/buf/buf.rs b/src/buf/buf.rs index a8268f7049799992a8157eca653bfc709439e3c7..7b269043f05a50ccff8dbc3e133175589361d77c 100644 --- a/src/buf/buf.rs +++ b/src/buf/buf.rs @@ -720,3 +720,31 @@ impl<T: AsRef<[u8]>> Buf for io::Cursor<T> { self.set_position(pos as u64); } } + +impl Buf for Option<[u8; 1]> { + fn remaining(&self) -> usize { + if self.is_some() { + 1 + } else { + 0 + } + } + + fn bytes(&self) -> &[u8] { + self.as_ref().map(AsRef::as_ref) + .unwrap_or(Default::default()) + } + + fn advance(&mut self, cnt: usize) { + if cnt == 0 { + return; + } + + if self.is_none() { + panic!("overflow"); + } else { + assert_eq!(1, cnt); + *self = None; + } + } +} diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs index def898d5c5eca20185078c27c04d54c854dcb629..8259ccfc062a93f7f76dc70b7ae2daa5695a7cdb 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -1,4 +1,4 @@ -use super::{Source, Writer}; +use super::{IntoBuf, Writer}; use byteorder::ByteOrder; use iovec::IoVec; @@ -219,8 +219,30 @@ pub trait BufMut { /// # Panics /// /// Panics if `self` does not have enough capacity to contain `src`. - fn put<S: Source>(&mut self, src: S) where Self: Sized { - src.copy_to_buf(self); + fn put<T: IntoBuf>(&mut self, src: T) where Self: Sized { + use super::Buf; + + let mut src = src.into_buf(); + + assert!(self.remaining_mut() >= src.remaining()); + + while src.has_remaining() { + let l; + + unsafe { + let s = src.bytes(); + let d = self.bytes_mut(); + l = cmp::min(s.len(), d.len()); + + ptr::copy_nonoverlapping( + s.as_ptr(), + d.as_mut_ptr(), + l); + } + + src.advance(l); + unsafe { self.advance_mut(l); } + } } /// Transfer bytes into `self` from `src` and advance the cursor by the @@ -268,6 +290,52 @@ pub trait BufMut { } } + /// Writes an unsigned 8 bit integer to `self`. + /// + /// The current position is advanced by 1. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u8(0x01); + /// assert_eq!(buf, b"\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u8(&mut self, n: u8) { + let src = [n]; + self.put_slice(&src); + } + + /// Writes a signed 8 bit integer to `self`. + /// + /// The current position is advanced by 1. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i8(0x01); + /// assert_eq!(buf, b"\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i8(&mut self, n: i8) { + let src = [n as u8]; + self.put_slice(&src) + } + /// Writes an unsigned 16 bit integer to `self` in the specified byte order. /// /// The current position is advanced by 2. diff --git a/src/buf/into_buf.rs b/src/buf/into_buf.rs index 771fc09f183132a0db444feab0830fe3ef6cc241..1071908a2efcf5b0b612aded15c785942d873b77 100644 --- a/src/buf/into_buf.rs +++ b/src/buf/into_buf.rs @@ -79,6 +79,14 @@ impl IntoBuf for Vec<u8> { } } +impl<'a> IntoBuf for &'a Vec<u8> { + type Buf = io::Cursor<&'a [u8]>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(&self[..]) + } +} + // Kind of annoying... but this impl is required to allow passing `&'static // [u8]` where for<'a> &'a T: IntoBuf is required. impl<'a> IntoBuf for &'a &'static [u8] { @@ -97,14 +105,6 @@ impl<'a> IntoBuf for &'a &'static str { } } -impl<'a> IntoBuf for &'a Vec<u8> { - type Buf = io::Cursor<&'a [u8]>; - - fn into_buf(self) -> Self::Buf { - io::Cursor::new(&self[..]) - } -} - impl IntoBuf for String { type Buf = io::Cursor<Vec<u8>>; @@ -120,3 +120,19 @@ impl<'a> IntoBuf for &'a String { self.as_bytes().into_buf() } } + +impl IntoBuf for u8 { + type Buf = Option<[u8; 1]>; + + fn into_buf(self) -> Self::Buf { + Some([self]) + } +} + +impl IntoBuf for i8 { + type Buf = Option<[u8; 1]>; + + fn into_buf(self) -> Self::Buf { + Some([self as u8; 1]) + } +} diff --git a/src/buf/mod.rs b/src/buf/mod.rs index 7d7ce221e8fc26603ab322b4a44d7c7bdaf48d83..1f74e0ab40f78fd215bbf03e2d8c80da9958a562 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -23,7 +23,6 @@ mod chain; mod into_buf; mod iter; mod reader; -mod source; mod take; mod writer; @@ -34,6 +33,5 @@ pub use self::chain::Chain; pub use self::into_buf::IntoBuf; pub use self::iter::Iter; pub use self::reader::Reader; -pub use self::source::Source; pub use self::take::Take; pub use self::writer::Writer; diff --git a/src/buf/source.rs b/src/buf/source.rs deleted file mode 100644 index bb12057330d5ca2f929a7d03b095abdb7b579329..0000000000000000000000000000000000000000 --- a/src/buf/source.rs +++ /dev/null @@ -1,140 +0,0 @@ -use {Buf, BufMut, Bytes}; - -use std::{cmp, ptr}; - -/// A value that writes bytes from itself into a `BufMut`. -/// -/// Values that implement `Source` are used as an argument to -/// [`BufMut::put`](trait.BufMut.html#method.put). -/// -/// # Examples -/// -/// ``` -/// use bytes::{BufMut, Source}; -/// -/// struct Repeat { -/// num: usize, -/// str: String, -/// } -/// -/// impl Source for Repeat { -/// fn copy_to_buf<B: BufMut>(self, buf: &mut B) { -/// for _ in 0..self.num { -/// buf.put(&self.str); -/// } -/// } -/// } -/// -/// let mut dst = vec![]; -/// dst.put(Repeat { -/// num: 3, -/// str: "hello".into(), -/// }); -/// -/// assert_eq!(*dst, b"hellohellohello"[..]); -/// ``` -pub trait Source { - /// Copy data from self into destination buffer - /// - /// # Examples - /// - /// ``` - /// use bytes::{BufMut, Source}; - /// - /// let mut dst = vec![]; - /// - /// "hello".copy_to_buf(&mut dst); - /// - /// assert_eq!(*dst, b"hello"[..]); - /// ``` - /// - /// # Panics - /// - /// This function panis if `buf` does not have enough capacity for `self`. - fn copy_to_buf<B: BufMut>(self, buf: &mut B); -} - -impl Source for Vec<u8> { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - buf.put_slice(&self[..]); - } -} - -impl<'a> Source for &'a Vec<u8> { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - buf.put_slice(&self[..]); - } -} - -impl<'a> Source for &'a [u8] { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - buf.put_slice(self); - } -} - -impl Source for String { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - buf.put_slice(self.as_bytes()); - } -} - -impl<'a> Source for &'a String { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - buf.put_slice(self.as_bytes()); - } -} - -impl<'a> Source for &'a str { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - buf.put_slice(self.as_bytes()); - } -} - -impl Source for u8 { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - let src = [self]; - buf.put_slice(&src); - } -} - -impl Source for i8 { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - buf.put_slice(&[self as u8]) - } -} - -impl Source for Bytes { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - Source::copy_to_buf(self.as_ref(), buf); - } -} - -impl<'a> Source for &'a Bytes { - fn copy_to_buf<B: BufMut>(self, buf: &mut B) { - Source::copy_to_buf(self.as_ref(), buf); - } -} - -impl<T: Buf> Source for T { - fn copy_to_buf<B: BufMut>(mut self, buf: &mut B) { - assert!(buf.remaining_mut() >= self.remaining()); - - while self.has_remaining() { - let l; - - unsafe { - let s = self.bytes(); - let d = buf.bytes_mut(); - l = cmp::min(s.len(), d.len()); - - ptr::copy_nonoverlapping( - s.as_ptr(), - d.as_mut_ptr(), - l); - } - - self.advance(l); - unsafe { buf.advance_mut(l); } - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 13f17c5dc79a6365dca35f15d370d5f122f55d6c..fabba8a2c34f505f07956ae3e9be77c6bf5b3b7c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,7 +83,6 @@ pub use buf::{ #[deprecated(since = "0.4.1", note = "moved to `buf` module")] #[doc(hidden)] pub use buf::{ - Source, Reader, Writer, Take,