buf_view/
buf_view.rs

1use crate::macros::{buf_get_do, buf_read_do};
2
3/// Wrap a &\[u8\] buffer as read only.
4///
5/// BufView support many methods to read primitive types from a byte buffer easily,
6/// it support to read primitive types as big endian or little endian. BufView wrap
7/// the original buffer with reader_index and writer_index as fllowing structure.
8/// When read data from it, the reader_index will advance the data length, and the
9/// read must between the reader_index and writer_index.
10///
11/// Any more, it support get method, too. It make you random get data from the BufView.
12///
13/// BufView structure
14/// ```text
15/// -----------------------------------------------------
16/// |       |                         |                 |
17/// -----------------------------------------------------
18///         ^                         ^                 ^
19///         |                         |                 |
20///   reader_index              writer_index        buf.len()
21/// ```
22/// Example
23/// ```
24/// use buf_view::BufView;
25///
26/// let buf = [0, 1, 2, 3, 4, 5, 6, 7];
27/// let mut buf_view = BufView::wrap(&buf);
28///
29/// assert_eq!(buf_view.read_u8(), 0);
30/// assert_eq!(buf_view.read_u16(), 0x0102);
31/// assert_eq!(buf_view.read_u32(), 0x03040506);
32/// assert_eq!(buf_view.get_u16(1), 0x0102);
33///
34/// // wrap from vector
35/// let v = vec![0, 1, 2, 3, 4, 5, 6, 7];
36/// let mut buf_view = BufView::wrap(v.as_slice());
37/// assert_eq!(buf_view.read_u8(), 0);
38/// assert_eq!(buf_view.read_u32(), 0x01020304);
39///
40/// // wrap from &str
41/// let s = "01234567";
42/// let mut buf_view = BufView::wrap(s.as_bytes());
43/// assert_eq!(buf_view.read_u8(), 0x30);
44/// assert_eq!(buf_view.read_u32(), 0x31323334);
45/// ```
46///
47#[derive(Debug)]
48pub struct BufView<'a> {
49    buf: &'a [u8],
50    reader_index: usize,
51    writer_index: usize,
52}
53
54impl<'a> BufView<'a> {
55    /// Wrap the `buf` as BufView, set the reader_index=0 and writer_index=buf.len(),
56    /// this make the whole `buf` can read and get by default.
57    pub fn wrap(buf: &'a [u8]) -> Self {
58        let len = buf.len();
59        BufView::wrap_with(buf, 0, len)
60    }
61
62    /// Wrap the `buf` as BufView, and specify the reader_index and writer_index.
63    /// ```
64    /// use buf_view::BufView;
65    ///
66    /// let buf = [0, 1, 2, 3, 4, 5, 6];
67    /// let mut buf = BufView::wrap_with(&buf, 1, 5);
68    /// assert_eq!(buf.read_u32(), 0x01020304);
69    /// ```
70    pub fn wrap_with(buf: &'a [u8], reader_index: usize, writer_index: usize) -> Self {
71        assert!(reader_index <= writer_index && buf.len() >= writer_index);
72        BufView {
73            buf,
74            reader_index,
75            writer_index,
76        }
77    }
78
79    pub fn read_u8(&mut self) -> u8 {
80        assert!(self.remaining() >= 1);
81        let val = self.buf[self.reader_index];
82        self.reader_index += 1;
83        val
84    }
85
86    pub fn read_i8(&mut self) -> i8 {
87        self.read_u8() as i8
88    }
89
90    pub fn read_u16(&mut self) -> u16 {
91        buf_read_do!(self, u16, be);
92    }
93
94    pub fn read_u16_le(&mut self) -> u16 {
95        buf_read_do!(self, u16, le);
96    }
97
98    pub fn read_i16(&mut self) -> i16 {
99        buf_read_do!(self, i16, be);
100    }
101
102    pub fn read_i16_le(&mut self) -> i16 {
103        buf_read_do!(self, i16, le);
104    }
105
106    pub fn read_u32(&mut self) -> u32 {
107        buf_read_do!(self, u32, be);
108    }
109
110    pub fn read_u32_le(&mut self) -> u32 {
111        buf_read_do!(self, u32, le);
112    }
113
114    pub fn read_i32(&mut self) -> i32 {
115        buf_read_do!(self, i32, be);
116    }
117
118    pub fn read_i32_le(&mut self) -> i32 {
119        buf_read_do!(self, i32, le);
120    }
121
122    pub fn read_u64(&mut self) -> u64 {
123        buf_read_do!(self, u64, be);
124    }
125
126    pub fn read_u64_le(&mut self) -> u64 {
127        buf_read_do!(self, u64, le);
128    }
129
130    pub fn read_i64(&mut self) -> i64 {
131        buf_read_do!(self, i64, be);
132    }
133
134    pub fn read_i64_le(&mut self) -> i64 {
135        buf_read_do!(self, i64, le);
136    }
137
138    pub fn read_u128(&mut self) -> u128 {
139        buf_read_do!(self, u128, be);
140    }
141
142    pub fn read_u128_le(&mut self) -> u128 {
143        buf_read_do!(self, u128, le);
144    }
145
146    pub fn read_i128(&mut self) -> i128 {
147        buf_read_do!(self, i128, be);
148    }
149
150    pub fn read_i128_le(&mut self) -> i128 {
151        buf_read_do!(self, i128, le);
152    }
153
154    pub fn read_f32(&mut self) -> f32 {
155        buf_read_do!(self, f32, be);
156    }
157
158    pub fn read_f32_le(&mut self) -> f32 {
159        buf_read_do!(self, f32, le);
160    }
161
162    pub fn read_f64(&mut self) -> f64 {
163        buf_read_do!(self, f64, be);
164    }
165
166    pub fn read_f64_le(&mut self) -> f64 {
167        buf_read_do!(self, f64, le);
168    }
169
170    pub fn read_bytes(&mut self, dest: &mut [u8]) -> usize {
171        let left = self.remaining();
172        assert!(left >= dest.len());
173        let copy_len = if dest.len() < left { dest.len() } else { left };
174        let end = self.reader_index + copy_len;
175        dest[..copy_len].copy_from_slice(&self.buf[self.reader_index..end]);
176        self.reader_index = end;
177        copy_len
178    }
179
180    pub fn get_u8(&mut self, index: usize) -> u8 {
181        assert!(self.buf.len() > index);
182        self.buf[index]
183    }
184
185    pub fn get_i8(&mut self, index: usize) -> i8 {
186        self.get_u8(index) as i8
187    }
188
189    pub fn get_u16(&mut self, index: usize) -> u16 {
190        buf_get_do!(self, index, u16, be);
191    }
192
193    pub fn get_u16_le(&mut self, index: usize) -> u16 {
194        buf_get_do!(self, index, u16, le);
195    }
196
197    pub fn get_i16(&mut self, index: usize) -> i16 {
198        buf_get_do!(self, index, i16, be);
199    }
200
201    pub fn get_i16_le(&mut self, index: usize) -> i16 {
202        buf_get_do!(self, index, i16, le);
203    }
204
205    pub fn get_u32(&mut self, index: usize) -> u32 {
206        buf_get_do!(self, index, u32, be);
207    }
208
209    pub fn get_u32_le(&mut self, index: usize) -> u32 {
210        buf_get_do!(self, index, u32, le);
211    }
212
213    pub fn get_i32(&mut self, index: usize) -> i32 {
214        buf_get_do!(self, index, i32, be);
215    }
216
217    pub fn get_i32_le(&mut self, index: usize) -> i32 {
218        buf_get_do!(self, index, i32, le);
219    }
220
221    pub fn get_u64(&mut self, index: usize) -> u64 {
222        buf_get_do!(self, index, u64, be);
223    }
224
225    pub fn get_u64_le(&mut self, index: usize) -> u64 {
226        buf_get_do!(self, index, u64, le);
227    }
228
229    pub fn get_i64(&mut self, index: usize) -> i64 {
230        buf_get_do!(self, index, i64, be);
231    }
232
233    pub fn get_i64_le(&mut self, index: usize) -> i64 {
234        buf_get_do!(self, index, i64, le);
235    }
236
237    pub fn get_u128(&mut self, index: usize) -> u128 {
238        buf_get_do!(self, index, u128, be);
239    }
240
241    pub fn get_u128_le(&mut self, index: usize) -> u128 {
242        buf_get_do!(self, index, u128, le);
243    }
244
245    pub fn get_i128(&mut self, index: usize) -> i128 {
246        buf_get_do!(self, index, i128, be);
247    }
248
249    pub fn get_i128_le(&mut self, index: usize) -> i128 {
250        buf_get_do!(self, index, i128, le);
251    }
252
253    pub fn get_f32(&mut self, index: usize) -> f32 {
254        buf_get_do!(self, index, f32, be);
255    }
256
257    pub fn get_f32_le(&mut self, index: usize) -> f32 {
258        buf_get_do!(self, index, f32, le);
259    }
260
261    pub fn get_f64(&mut self, index: usize) -> f64 {
262        buf_get_do!(self, index, f64, be);
263    }
264
265    pub fn get_f64_le(&mut self, index: usize) -> f64 {
266        buf_get_do!(self, index, f64, le);
267    }
268
269    pub fn get_bytes(&mut self, index: usize, dest: &mut [u8]) -> usize {
270        assert!(self.buf.len() > index);
271        let copy_len = if (index + dest.len()) <= self.buf.len() {
272            dest.len()
273        } else {
274            self.buf.len() - index
275        };
276        dest[..copy_len].copy_from_slice(&self.buf[index..(index + copy_len)]);
277        copy_len
278    }
279
280    pub fn set_reader_index(&mut self, index: usize) {
281        assert!(self.buf.len() >= index && index <= self.writer_index);
282        self.reader_index = index;
283    }
284
285    pub fn reader_index(&self) -> usize {
286        self.reader_index
287    }
288
289    pub fn set_writer_index(&mut self, index: usize) {
290        assert!(self.buf.len() >= index && index >= self.reader_index);
291        self.writer_index = index;
292    }
293
294    pub fn writer_index(&self) -> usize {
295        self.writer_index
296    }
297
298    pub fn set_index(&mut self, reader_index: usize, writer_index: usize) {
299        assert!(reader_index <= writer_index && self.buf.len() >= writer_index);
300        self.reader_index = reader_index;
301        self.writer_index = writer_index;
302    }
303
304    pub fn clear(&mut self) {
305        self.reader_index = 0;
306        self.writer_index = 0;
307    }
308
309    pub fn remaining(&self) -> usize {
310        self.writer_index - self.reader_index
311    }
312
313    pub fn capacity(&self) -> usize {
314        self.buf.len()
315    }
316
317    pub fn as_slice(&mut self) -> &[u8] {
318        &self.buf[self.reader_index..self.writer_index]
319    }
320
321    pub fn as_raw_slice(&mut self) -> &[u8] {
322        self.buf
323    }
324}
325
326impl std::fmt::Display for BufView<'_> {
327    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
328        write!(
329            f,
330            "reader_index: {}, writer_index: {}, capacity: {}",
331            self.reader_index(),
332            self.writer_index(),
333            self.capacity()
334        )
335    }
336}