forked from M-Labs/artiq-zynq
86 lines
1.7 KiB
Rust
86 lines
1.7 KiB
Rust
#[cfg(feature = "alloc")]
|
|
use alloc::vec::Vec;
|
|
|
|
use core_io::{Error as IoError, Read, Write};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Cursor<T> {
|
|
inner: T,
|
|
pos: usize,
|
|
}
|
|
|
|
impl<T> Cursor<T> {
|
|
#[inline]
|
|
pub fn new(inner: T) -> Cursor<T> {
|
|
Cursor { inner, pos: 0 }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn into_inner(self) -> T {
|
|
self.inner
|
|
}
|
|
|
|
#[inline]
|
|
pub fn get_ref(&self) -> &T {
|
|
&self.inner
|
|
}
|
|
|
|
#[inline]
|
|
pub fn get_mut(&mut self) -> &mut T {
|
|
&mut self.inner
|
|
}
|
|
|
|
#[inline]
|
|
pub fn position(&self) -> usize {
|
|
self.pos
|
|
}
|
|
|
|
#[inline]
|
|
pub fn set_position(&mut self, pos: usize) {
|
|
self.pos = pos
|
|
}
|
|
}
|
|
|
|
impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, IoError> {
|
|
let data = &self.inner.as_ref()[self.pos..];
|
|
let len = buf.len().min(data.len());
|
|
// ``copy_from_slice`` generates AXI bursts, use a regular loop instead
|
|
for i in 0..len {
|
|
buf[i] = data[i];
|
|
}
|
|
self.pos += len;
|
|
Ok(len)
|
|
}
|
|
}
|
|
|
|
impl Write for Cursor<&mut [u8]> {
|
|
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
|
let data = &mut self.inner[self.pos..];
|
|
let len = buf.len().min(data.len());
|
|
for i in 0..len {
|
|
data[i] = buf[i];
|
|
}
|
|
self.pos += len;
|
|
Ok(len)
|
|
}
|
|
|
|
#[inline]
|
|
fn flush(&mut self) -> Result<(), IoError> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "alloc")]
|
|
impl Write for Cursor<Vec<u8>> {
|
|
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
|
self.inner.extend_from_slice(buf);
|
|
Ok(buf.len())
|
|
}
|
|
|
|
#[inline]
|
|
fn flush(&mut self) -> Result<(), IoError> {
|
|
Ok(())
|
|
}
|
|
}
|