seqbytes/
bytes.rs

1use std::io::{Read, Seek, SeekFrom};
2
3use super::traits::*;
4
5/// Represents a sequential byte reader which can read bytes. Can be used on types that implement [`Read`] + [`Seek`].
6///
7/// # Examples
8///
9/// ```
10/// use seqbytes::prelude::*;
11/// use std::io::Cursor;
12/// use std::str::FromStr;
13///
14/// let a = vec![69, 96, 255, 255, 0x68, 0x65, 0x6C, 0x6C, 0x6F];
15/// let mut cursor = Cursor::new(a);
16///
17/// let num : i32 = cursor.shift().unwrap();
18/// let s = &*cursor.shift_string(5).unwrap();
19///
20/// assert_eq!(num, -40891);
21/// assert_eq!(*s, *"hello");
22/// ```
23pub trait SeqByteReader {
24    /// Peaks the next `U` from the current position, reading the size of `U`'s amount of bytes, and converting to the `U`. Returns [`None`]
25    /// if there are not enough bytes to be read.
26    fn next<U: SizedNumber>(&mut self) -> Option<U>;
27    /// Peaks the next `U` from the current position, shifting and reading the size of `U`'s amount of bytes, and converting to the `U`. Returns [`None`]
28    /// if there are not enough bytes to be read.
29    ///
30    fn shift<U: SizedNumber>(&mut self) -> Option<U>;
31    /// Peaks the next `amount` of bytes. Returns a [`Vec<u8>`] containing the bytes.
32    fn next_slice(&mut self, amount: usize) -> Option<Vec<u8>>;
33    /// Peaks the next `amount` bytes, and shifting the position by `amount` bytes. Returns a [`Vec<u8>`] containing the bytes.
34    fn shift_slice(&mut self, amount: usize) -> Option<Vec<u8>>;
35    /// Peaks the next `amount` bytes. Returns a [`String`] containing the bytes. Returns [`None`] if there are no
36    /// more bytes to be read. If unimplemented, internally calls `next_slice` and converts it to a lossy UTF-8 String.
37    fn next_string(&mut self, amount: usize) -> Option<String> {
38        let slice = self.next_slice(amount)?;
39
40        Some(String::from_utf8_lossy(&slice).to_string())
41    }
42    /// Peaks the next `amount` bytes, and shifting the position by `amount` bytes. Returns a [`String`] containing the bytes. Returns [`None`] if there are no
43    /// more bytes to be read. If unimplemented, internally calls `shift_slice` and converts it to a lossy UTF-8 String.
44    fn shift_string(&mut self, amount: usize) -> Option<String> {
45        let slice = self.shift_slice(amount)?;
46
47        Some(String::from_utf8_lossy(&slice).to_string())
48    }
49
50    /* Not sure if I should keep these methods. Should I ?
51    fn next_u8(&mut self) -> Option<u8> {
52        self.next::<u8>()
53    }
54    fn next_i8(&mut self) -> Option<i8> {
55        self.next::<i8>()
56    }
57    fn next_u16(&mut self) -> Option<u16> {
58        self.next::<u16>()
59    }
60    fn next_i16(&mut self) -> Option<i16> {
61        self.next::<i16>()
62    }
63    fn next_u32(&mut self) -> Option<u32> {
64        self.next::<u32>()
65    }
66    fn next_i32(&mut self) -> Option<i32> {
67        self.next::<i32>()
68    }
69    fn next_f32(&mut self) -> Option<f32> {
70        self.next::<f32>()
71    }
72    fn next_u64(&mut self) -> Option<u64> {
73        self.next::<u64>()
74    }
75    fn next_i64(&mut self) -> Option<i64> {
76        self.next::<i64>()
77    }
78    fn next_f64(&mut self) -> Option<f64> {
79        self.next::<f64>()
80    }
81
82    fn shift_u8(&mut self) -> Option<u8> {
83        self.shift::<u8>()
84    }
85    fn shift_i8(&mut self) -> Option<i8> {
86        self.shift::<i8>()
87    }
88    fn shift_u16(&mut self) -> Option<u16> {
89        self.shift::<u16>()
90    }
91    fn shift_i16(&mut self) -> Option<i16> {
92        self.shift::<i16>()
93    }
94    fn shift_u32(&mut self) -> Option<u32> {
95        self.shift::<u32>()
96    }
97    fn shift_i32(&mut self) -> Option<i32> {
98        self.shift::<i32>()
99    }
100    fn shift_f32(&mut self) -> Option<f32> {
101        self.shift::<f32>()
102    }
103    fn shift_u64(&mut self) -> Option<u64> {
104        self.shift::<u64>()
105    }
106    fn shift_i64(&mut self) -> Option<i64> {
107        self.shift::<i64>()
108    }
109    fn shift_f64(&mut self) -> Option<f64> {
110        self.shift::<f64>()
111    }
112    */
113}
114/// Represents a sequential byte reader which can read bytes with a specified endianness. Can be used on types that implement [`Read`] + [`Seek`]
115///
116/// # Examples
117///
118/// ```
119/// use seqbytes::prelude::*;
120/// use std::io::Cursor;
121///
122/// let a = vec![69, 96, 255, 255];
123/// let mut cursor = Cursor::new(a);
124///
125/// let num : i32 = cursor.next_e(false).unwrap();
126/// let num2 : i32 = cursor.shift_e(true).unwrap();
127/// let num3 : Option<i32> = cursor.shift_e(false);
128///
129/// assert_ne!(num, num2);
130/// assert_eq!(num, -40891);
131/// assert_eq!(num2, 1163984895);
132/// assert_eq!(num3, None);
133/// ```
134pub trait ESeqByteReader {
135    /// Peaks the next `U` from the current position, reading the size of `U`'s amount of bytes, and converting to the `U` with the specified endianness. Returns [`None`]
136    /// if there are not enough bytes to be read.
137    ///
138    /// # Examples
139    ///
140    /// ```
141    /// use seqbytes::prelude::*;
142    /// use std::io::Cursor;
143    ///
144    /// let a = vec![69, 96, 255, 255];
145    /// let mut cursor = Cursor::new(a);
146    ///
147    /// let pos1 = cursor.position();
148    /// let num : i32 = cursor.next_e(false).unwrap();
149    /// let pos2 = cursor.position();
150    ///
151    /// assert_eq!(pos1, pos2);
152    /// assert_eq!(num, -40891);
153    /// ```
154    fn next_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U>;
155    /// Peaks the next `U` from the current position, shifting and reading the size of `U`'s amount of bytes, and converting to the `U` with the specified endianness. Returns [`None`]
156    /// if there are not enough bytes to be read.
157    ///
158    /// # Examples
159    ///
160    /// ```
161    /// use seqbytes::prelude::*;
162    /// use std::io::Cursor;
163    ///
164    /// let a = vec![69, 96, 255, 255];
165    /// let mut cursor = Cursor::new(a);
166    ///
167    /// let pos1 = cursor.position();
168    /// let num : i32 = cursor.shift_e(false).unwrap();
169    /// let pos2 = cursor.position();
170    ///
171    /// assert_ne!(pos1, pos2);
172    /// assert_eq!(num, -40891);
173    /// ```
174    fn shift_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U>;
175}
176
177impl<T: Seek + Read> SeqByteReader for T {
178    fn next<U: SizedNumber>(&mut self) -> Option<U> {
179        let size = U::size() as isize;
180
181        let mut a = vec![0u8; size as usize];
182        self.read_exact(&mut a).ok()?;
183
184        self.seek(SeekFrom::Current(-size as i64)).unwrap(); // Should not panic, as it is shifting backwards the same amount of bytes as moving forward.
185
186        return U::from_bytes(&a[..]);
187    }
188
189    fn shift<U: SizedNumber>(&mut self) -> Option<U> {
190        let size = U::size() as isize;
191
192        let mut a = vec![0u8; size as usize];
193        self.read_exact(&mut a).ok()?;
194
195        return U::from_bytes(&a[..]);
196    }
197
198    fn next_slice(&mut self, amount: usize) -> Option<Vec<u8>> {
199        let mut a = vec![0u8; amount];
200        self.read_exact(&mut a).ok()?;
201
202        self.seek(SeekFrom::Current(-(amount as i64))).unwrap();
203
204        return Some(a);
205    }
206
207    fn shift_slice(&mut self, amount: usize) -> Option<Vec<u8>> {
208        let mut a = vec![0u8; amount];
209        self.read_exact(&mut a).ok()?;
210
211        return Some(a);
212    }
213}
214impl<T: Seek + Read> ESeqByteReader for T {
215    fn next_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U> {
216        let size = U::size() as isize;
217
218        let mut a = vec![0u8; size as usize];
219        self.read_exact(&mut a).ok()?;
220
221        self.seek(SeekFrom::Current(-size as i64)).unwrap(); // Should not panic, as it is shifting backwards the same amount of bytes as moving forward.
222
223        return U::from_bytes_e(&a[..], bigendian);
224    }
225
226    fn shift_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U> {
227        let size = U::size() as isize;
228
229        let mut a = vec![0u8; size as usize];
230        self.read_exact(&mut a).ok()?;
231
232        return U::from_bytes_e(&a[..], bigendian);
233    }
234}