1use crate::{Error, Result};
2
3#[derive(Debug)]
4pub struct WCursor<'a> {
5 buf: &'a mut [u8],
6 pos: usize,
7}
8
9impl<'a> WCursor<'a> {
10 #[inline]
11 pub fn new(buf: &'a mut [u8]) -> Self {
12 Self { buf, pos: 0 }
13 }
14
15 #[inline]
16 pub fn pos(&self) -> usize {
17 self.pos
18 }
19
20 #[inline]
21 pub fn reset_pos(&mut self) -> usize {
22 let mut new_pos = 0;
23 std::mem::swap(&mut self.pos, &mut new_pos);
24 new_pos
25 }
26
27 #[inline]
28 pub fn len(&self) -> usize {
29 let capacity = self.capacity();
30 capacity.saturating_sub(self.pos)
31 }
32
33 #[inline]
34 pub fn capacity(&self) -> usize {
35 self.buf.len()
36 }
37
38 #[inline]
39 pub fn slice(&mut self, size: usize) -> Result<&mut [u8]> {
40 if self.len() >= size {
41 Ok(unsafe { self.buf.get_unchecked_mut(self.pos..self.pos + size) })
42 } else {
43 Err(Error::BufferTooShort(self.pos() + size))
44 }
45 }
46
47 #[inline]
48 pub fn u16_be(&mut self, val: u16) -> Result<()> {
49 w_be!(self, u16, val)
50 }
51
52 #[inline]
53 pub fn u32_be(&mut self, val: u32) -> Result<()> {
54 w_be!(self, u32, val)
55 }
56
57 #[inline]
58 pub unsafe fn u16_be_unchecked(&mut self, val: u16) {
59 wu_be!(self, u16, val)
60 }
61
62 #[inline]
63 pub fn u8(&mut self, val: u8) -> Result<()> {
64 unsafe {
65 *self.slice(1)?.get_unchecked_mut(0) = val;
66 }
67 self.pos += 1;
68 Ok(())
69 }
70
71 #[inline]
72 pub unsafe fn u8_unchecked(&mut self, val: u8) {
73 unsafe {
74 *self.buf.get_unchecked_mut(self.pos) = val;
75 }
76 self.pos += 1;
77 }
78
79 #[inline]
80 pub unsafe fn bytes_unchecked(&mut self, buf: &[u8]) {
81 unsafe {
82 self.buf
83 .get_unchecked_mut(self.pos..self.pos + buf.len())
84 .copy_from_slice(buf);
85 }
86 self.pos += buf.len();
87 }
88}