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}