s2n_codec/encoder/
buffer.rs1use crate::encoder::Encoder;
5
6#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
8pub struct EncoderBuffer<'a> {
9 bytes: &'a mut [u8],
10 position: usize,
11}
12
13impl<'a> EncoderBuffer<'a> {
14 #[inline]
16 pub fn new(bytes: &'a mut [u8]) -> Self {
17 Self { bytes, position: 0 }
18 }
19
20 #[inline]
25 pub fn set_position(&mut self, position: usize) {
26 debug_assert!(
27 position <= self.capacity(),
28 "position {position} exceeded capacity of {}",
29 self.capacity()
30 );
31 self.position = position;
32 }
33
34 #[inline]
39 pub fn advance_position(&mut self, offset: usize) {
40 let position = self.position + offset;
41 self.set_position(position)
42 }
43
44 #[inline]
46 pub fn split_off(self) -> (&'a mut [u8], &'a mut [u8]) {
47 self.bytes.split_at_mut(self.position)
48 }
49
50 #[inline]
52 pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
53 self.bytes.split_at_mut(self.position)
54 }
55
56 #[inline]
58 pub fn as_mut_slice(&mut self) -> &mut [u8] {
59 unsafe { self.bytes.get_unchecked_mut(..self.position) }
60 }
61
62 #[inline]
63 pub(crate) fn assert_capacity(&self, len: usize) {
64 debug_assert!(
65 len <= self.remaining_capacity(),
66 "not enough buffer capacity. wanted: {}, available: {}",
67 len,
68 self.remaining_capacity()
69 );
70 }
71}
72
73impl Encoder for EncoderBuffer<'_> {
74 #[inline]
75 fn write_sized<F: FnOnce(&mut [u8])>(&mut self, len: usize, write: F) {
76 self.assert_capacity(len);
77 let end = self.position + len;
78 let bytes = unsafe {
79 self.bytes.get_unchecked_mut(self.position..end)
81 };
82 write(bytes);
83 self.position = end;
84 }
85
86 #[inline]
87 fn write_slice(&mut self, slice: &[u8]) {
88 self.write_sized(slice.len(), |dest| dest.copy_from_slice(slice));
89 }
90
91 #[inline]
92 fn write_repeated(&mut self, count: usize, value: u8) {
93 self.write_sized(count, |dest| {
94 for byte in dest {
95 *byte = value;
96 }
97 })
98 }
99
100 #[inline]
101 fn write_zerocopy<
102 T: zerocopy::IntoBytes + zerocopy::FromBytes + zerocopy::Unaligned,
103 F: FnOnce(&mut T),
104 >(
105 &mut self,
106 write: F,
107 ) {
108 let len = core::mem::size_of::<T>();
109 self.write_sized(len, |bytes| {
110 let value = unsafe {
111 &mut *(bytes as *mut _ as *mut T)
113 };
114 write(value)
115 })
116 }
117
118 #[inline]
119 fn capacity(&self) -> usize {
120 self.bytes.len()
121 }
122
123 #[inline]
124 fn len(&self) -> usize {
125 self.position
126 }
127}