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 if self.pos < capacity {
31 capacity - self.pos
32 } else {
33 0
34 }
35 }
36
37 #[inline]
38 pub fn capacity(&self) -> usize {
39 self.buf.len()
40 }
41
42 #[inline]
43 pub fn slice(&mut self, size: usize) -> Result<&mut [u8]> {
44 if self.len() >= size {
45 Ok(unsafe { self.buf.get_unchecked_mut(self.pos..self.pos + size) })
46 } else {
47 Err(Error::BufferTooShort(self.pos() + size))
48 }
49 }
50
51 #[inline]
52 pub fn u16_be(&mut self, val: u16) -> Result<()> {
53 w_be!(self, u16, val)
54 }
55
56 #[inline]
57 pub fn u32_be(&mut self, val: u32) -> Result<()> {
58 w_be!(self, u32, val)
59 }
60
61 #[inline]
62 pub unsafe fn u16_be_unchecked(&mut self, val: u16) {
63 wu_be!(self, u16, val)
64 }
65
66 #[inline]
67 pub fn u8(&mut self, val: u8) -> Result<()> {
68 unsafe { *self.slice(1)?.get_unchecked_mut(0) = val };
69 self.pos += 1;
70 Ok(())
71 }
72
73 #[inline]
74 pub unsafe fn u8_unchecked(&mut self, val: u8) {
75 *self.buf.get_unchecked_mut(self.pos) = val;
76 self.pos += 1;
77 }
78
79 #[inline]
80 pub unsafe fn bytes_unchecked(&mut self, buf: &[u8]) {
81 self.buf
82 .get_unchecked_mut(self.pos..self.pos + buf.len())
83 .copy_from_slice(buf);
84 self.pos += buf.len();
85 }
86}