data_view/
dataview.rs

1use super::*;
2
3/// This struct represents a data view for reading and writing data in a byte array.
4/// When read/write, This increment current offset by the size of the value.
5#[derive(Debug, Clone, PartialEq, Eq, Default)]
6pub struct DataView<T> {
7    pub data: T,
8    pub offset: usize,
9}
10
11impl<T> DataView<T> {
12    /// # Examples
13    ///
14    /// ```
15    /// use data_view::DataView;
16    ///
17    /// let view = DataView::new([0; 16]);
18    /// ```
19    pub const fn new(data: T) -> Self {
20        Self { data, offset: 0 }
21    }
22}
23
24impl<T: AsRef<[u8]>> DataView<T> {
25    /// Returns remaining slice from the current offset.
26    /// It doesn't change the offset.
27    ///
28    /// # Examples
29    ///
30    /// ```
31    /// use data_view::DataView;
32    ///
33    /// let mut view = DataView::new([1, 2]);
34    ///
35    /// assert_eq!(view.remaining_slice(), &[1, 2]);
36    /// view.offset = 42;
37    /// assert!(view.remaining_slice().is_empty());
38    /// ```
39    #[inline]
40    pub fn remaining_slice(&self) -> &[u8] {
41        let data = self.data.as_ref();
42        unsafe { data.get_unchecked(self.offset.min(data.len())..) }
43    }
44
45    /// Reads a value of type `E: Endian` from the DataView.
46    ///
47    /// # Examples
48    ///
49    /// ```
50    /// use data_view::DataView;
51    ///
52    /// let mut view = DataView::new([0; 4]);
53    ///
54    /// view.write::<u16>(42);
55    /// view.offset = 0;
56    /// assert_eq!(view.read::<u16>(), Some(42));
57    /// assert_eq!(view.read::<u32>(), None);
58    /// ```
59    #[inline]
60    pub fn read<E: Endian>(&mut self) -> Option<E> {
61        let data = self.data.as_ref();
62        let total_len = self.offset + size_of::<E>();
63        if total_len > data.len() {
64            return None;
65        }
66        let num = unsafe { E::__read_at__(data.as_ptr().add(self.offset)) };
67        self.offset = total_len;
68        Some(num)
69    }
70
71    /// Read slice from the current offset.
72    ///
73    /// # Example
74    /// ```
75    /// use data_view::DataView;
76    ///
77    /// let mut view = DataView::new([1, 2, 3]);
78    ///
79    /// assert_eq!(view.read_slice(2), Some([1, 2].as_ref()));
80    /// assert_eq!(view.read_slice(3), None);
81    /// ```
82    #[inline]
83    pub fn read_slice(&mut self, len: usize) -> Option<&[u8]> {
84        let total_len = self.offset + len;
85        let slice = self.data.as_ref().get(self.offset..total_len)?;
86        self.offset = total_len;
87        Some(slice)
88    }
89
90    /// Create a buffer and returns it, from the current offset.
91    ///
92    /// # Examples
93    ///
94    /// ```
95    /// use data_view::DataView;
96    ///
97    /// let mut view = DataView::new([1, 2, 3]);
98    ///
99    /// assert_eq!(view.read_buf(), Some([1, 2]));
100    /// assert_eq!(view.read_buf::<3>(), None);
101    /// ```
102    #[inline]
103    pub fn read_buf<const N: usize>(&mut self) -> Option<[u8; N]> {
104        let data = self.data.as_ref();
105        let total_len = self.offset + N;
106        if total_len > data.len() {
107            return None;
108        }
109        let buf = unsafe { ptr::read(data.as_ptr().add(self.offset) as *const [u8; N]) };
110        self.offset = total_len;
111        Some(buf)
112    }
113}
114
115impl<T: AsMut<[u8]>> DataView<T> {
116    /// # Examples
117    ///
118    /// ```
119    /// use data_view::DataView;
120    ///
121    /// let mut view = DataView::new([0; 3]);
122    ///
123    /// assert_eq!(view.write(42_u16), Ok(()));
124    /// assert_eq!(view.write(123_u32), Err(()));
125    /// ```
126    #[inline]
127    pub fn write<E: Endian>(&mut self, num: E) -> Result<(), ()> {
128        let data = self.data.as_mut();
129        let total_len = self.offset + size_of::<E>();
130        if total_len > data.len() {
131            return Err(());
132        }
133        unsafe { E::__write_at__(num, data.as_mut_ptr().add(self.offset)) };
134        self.offset = total_len;
135        Ok(())
136    }
137
138    /// Writes a slice into the data view.
139    ///
140    /// # Examples
141    ///
142    /// ```
143    /// use data_view::DataView;
144    ///
145    /// let mut view = DataView::new([0; 3]);
146    ///
147    /// assert_eq!(view.write_slice([4, 2]), Ok(()));
148    /// assert_eq!(view.write_slice([1, 2, 3]), Err(()));
149    /// assert_eq!(view.data, [4, 2, 0]);
150    /// ```
151    #[inline]
152    pub fn write_slice(&mut self, slice: impl AsRef<[u8]>) -> Result<(), ()> {
153        let src = slice.as_ref();
154        let data = self.data.as_mut();
155        let count = src.len();
156        let total_len = self.offset + count;
157        if total_len > data.len() {
158            return Err(());
159        }
160        unsafe {
161            ptr::copy_nonoverlapping(src.as_ptr(), data.as_mut_ptr().add(self.offset), count);
162        }
163        self.offset = total_len;
164        Ok(())
165    }
166}
167
168impl<T> From<T> for DataView<T> {
169    #[inline]
170    fn from(data: T) -> Self {
171        Self::new(data)
172    }
173}