//! Utilities for working with buffers. //! //! A buffer is any structure that contains a sequence of bytes. The bytes may //! or may not be stored in contiguous memory. This module contains traits used //! to abstract over buffers as well as utilities for working with buffer types. //! //! # `Buf`, `BufMut` //! //! These are the two foundational traits for abstractly working with buffers. //! They can be thought as iterators for byte structures. They offer additional //! performance over `Iterator` by providing an API optimized for byte slices. //! //! See [`Buf`] and [`BufMut`] for more details. //! //! [rope]: https://en.wikipedia.org/wiki/Rope_(data_structure) //! [`Buf`]: trait.Buf.html //! [`BufMut`]: trait.BufMut.html use std::{cmp, io, usize}; mod buf; mod buf_mut; mod from_buf; mod into_buf; mod iter; mod reader; mod source; mod take; mod writer; pub use self::buf::Buf; pub use self::buf_mut::BufMut; pub use self::from_buf::FromBuf; 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; /* * * ===== Buf impls ===== * */ impl<'a, T: Buf> Buf for &'a mut T { fn remaining(&self) -> usize { (**self).remaining() } fn bytes(&self) -> &[u8] { (**self).bytes() } fn advance(&mut self, cnt: usize) { (**self).advance(cnt) } } impl<'a, T: BufMut> BufMut for &'a mut T { fn remaining_mut(&self) -> usize { (**self).remaining_mut() } unsafe fn bytes_mut(&mut self) -> &mut [u8] { (**self).bytes_mut() } unsafe fn advance_mut(&mut self, cnt: usize) { (**self).advance_mut(cnt) } } impl> Buf for io::Cursor { fn remaining(&self) -> usize { let len = self.get_ref().as_ref().len(); let pos = self.position(); if pos >= len as u64 { return 0; } len - pos as usize } fn bytes(&self) -> &[u8] { let pos = self.position() as usize; &(self.get_ref().as_ref())[pos..] } fn advance(&mut self, cnt: usize) { let pos = self.position() as usize; let pos = cmp::min(self.get_ref().as_ref().len(), pos + cnt); self.set_position(pos as u64); } } impl + AsRef<[u8]>> BufMut for io::Cursor { fn remaining_mut(&self) -> usize { self.remaining() } /// Advance the internal cursor of the BufMut unsafe fn advance_mut(&mut self, cnt: usize) { let pos = self.position() as usize; let pos = cmp::min(self.get_mut().as_mut().len(), pos + cnt); self.set_position(pos as u64); } /// Returns a mutable slice starting at the current BufMut position and of /// length between 0 and `BufMut::remaining()`. /// /// The returned byte slice may represent uninitialized memory. unsafe fn bytes_mut(&mut self) -> &mut [u8] { let pos = self.position() as usize; &mut (self.get_mut().as_mut())[pos..] } } impl BufMut for Vec { fn remaining_mut(&self) -> usize { usize::MAX - self.len() } unsafe fn advance_mut(&mut self, cnt: usize) { let len = self.len() + cnt; if len > self.capacity() { // Reserve additional // TODO: Should this case panic? let cap = self.capacity(); self.reserve(cap - len); } self.set_len(len); } unsafe fn bytes_mut(&mut self) -> &mut [u8] { use std::slice; if self.capacity() == self.len() { self.reserve(64); // Grow the vec } let cap = self.capacity(); let len = self.len(); let ptr = self.as_mut_ptr(); &mut slice::from_raw_parts_mut(ptr, cap)[len..] } }