1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use core::convert::From;
use core::ops::{Deref, DerefMut};

#[cfg(feature = "std")]
use std::io::{self, Read, Write};

/// A byte buffer which is versed in both the Greater and Lesser arts
///
/// Convenient for grabbing all the data from a file, and then using `Pread`/`Pwrite`, etc., on it.
///
/// # Example
/// ```rust
/// use scroll::{ctx, Pread, Pwrite, Buffer};
/// let hello_world: &str = "hello world";
/// let mut buffer = Buffer::with(0x0u8, hello_world.len());
/// buffer.pwrite(hello_world, 0).unwrap();
/// let hello = buffer.pread_with::<&str>(0, ctx::SPACE).unwrap();
/// assert_eq!(hello, "hello");
/// ```

#[derive(Default)]
pub struct Buffer {
    inner: Vec<u8>
}

impl Buffer {
    /// Creates a new buffer from `bytes`
    /// # Example
    /// ```rust
    /// use scroll::Buffer;
    /// let bytes: [u8; 2] = [0x48, 0x49];
    /// let buffer = Buffer::new(bytes);
    pub fn new<T: AsRef<[u8]>> (bytes: T) -> Self {
        Buffer { inner: Vec::from(bytes.as_ref()) }
    }
    /// Initializes a new buffer with `seed`, `size` times
    /// # Example
    /// ```rust
    /// use scroll::Buffer;
    /// let buffer = Buffer::with(0x0u8, 10);
    pub fn with (seed: u8, size: usize) -> Self {
        Buffer { inner: vec![seed; size] }
    }
    /// Tries to suck the bytes out from `R` and create a new `Buffer` from it.
    /// **NB** only present if `std` cfg is used
    /// # Example
    /// ```rust
    /// use scroll::Buffer;
    /// use std::io::Cursor;
    /// let bytes: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
    /// // this could be a `File` also
    /// let cursor = Cursor::new(bytes);
    /// let buffer = Buffer::try_from(cursor).unwrap();
    #[cfg(feature = "std")]
    pub fn try_from<R: Read> (mut file: R) -> io::Result<Buffer> {
        let mut inner = Vec::new();
        file.read_to_end(&mut inner)?;
        Ok(Buffer { inner: inner })
    }
    pub fn as_slice (&self) -> &[u8] {
        self.inner.as_slice()
    }
    /// Consumes self and returns the inner byte vector
    pub fn into_inner(self) -> Vec<u8> {
        self.inner
    }
}

// these gets us Pread, Pwrite, Gread, Gwrite, Greadable... abstraction ftw
impl AsRef<[u8]> for Buffer {
    fn as_ref (&self) -> &[u8] {
        self.inner.as_slice()
    }
}

impl AsMut<[u8]> for Buffer {
    fn as_mut (&mut self) -> &mut [u8] {
        self.inner.as_mut_slice()
    }
}

// can't impl because without specialization (i think) because conflicts with above...
// impl<T> From<T> for Buffer where T: AsRef<[u8]> {
//     fn from(bytes: T) -> Buffer {
//         Buffer { inner: Vec::from(bytes.as_ref()) }
//     }
// }

impl Deref for Buffer {
    type Target = [u8];
    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl DerefMut for Buffer {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.inner
    }
}

// this (will) gets us Lread
#[cfg(feature = "std")]
impl Read for Buffer {
    fn read (&mut self, buf: &mut [u8]) -> io::Result<usize> {
        Read::read(&mut self.inner.as_slice(), buf)
    }
}

// this gets us Lwrite
#[cfg(feature = "std")]
impl Write for Buffer {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        Write::write(&mut self.inner.as_mut_slice(), buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        Write::flush(&mut self.inner.as_mut_slice())
    }
}