musli/writer/
slice_mut_writer.rs1use core::marker::PhantomData;
2use core::ptr::NonNull;
3
4use crate::Context;
5use crate::alloc::Vec;
6
7use super::{SliceOverflow, Writer};
8
9pub struct SliceMutWriter<'a> {
34 start: NonNull<u8>,
35 end: NonNull<u8>,
36 _marker: PhantomData<&'a mut [u8]>,
37}
38
39impl<'a> SliceMutWriter<'a> {
40 pub(super) fn new(slice: &'a mut [u8]) -> Self {
41 unsafe {
43 let range = slice.as_mut_ptr_range();
44 let start = NonNull::new_unchecked(range.start);
45 let end = NonNull::new_unchecked(range.end);
46 Self {
47 start,
48 end,
49 _marker: PhantomData,
50 }
51 }
52 }
53
54 #[inline]
55 pub(crate) fn remaining(&self) -> usize {
56 self.end.as_ptr() as usize - self.start.as_ptr() as usize
57 }
58}
59
60impl<'a> Writer for SliceMutWriter<'a> {
61 type Ok = usize;
62
63 type Mut<'this>
64 = &'this mut SliceMutWriter<'a>
65 where
66 Self: 'this;
67
68 #[inline]
69 fn finish<C>(&mut self, _: C) -> Result<Self::Ok, C::Error>
70 where
71 C: Context,
72 {
73 Ok(self.remaining())
74 }
75
76 #[inline]
77 fn borrow_mut(&mut self) -> Self::Mut<'_> {
78 self
79 }
80
81 #[inline]
82 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
83 where
84 C: Context,
85 {
86 self.write_bytes(cx, buffer.as_slice())
88 }
89
90 #[inline]
91 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
92 where
93 C: Context,
94 {
95 let end = self.start.as_ptr().wrapping_add(bytes.len());
96
97 if end > self.end.as_ptr() || end < self.start.as_ptr() {
98 return Err(cx.message(SliceOverflow {
99 n: bytes.len(),
100 capacity: self.remaining(),
101 }));
102 }
103
104 unsafe {
106 self.start
107 .as_ptr()
108 .copy_from_nonoverlapping(bytes.as_ptr(), bytes.len());
109 self.start = NonNull::new_unchecked(end);
110 }
111
112 Ok(())
113 }
114
115 #[inline]
116 fn write_byte<C>(&mut self, cx: C, b: u8) -> Result<(), C::Error>
117 where
118 C: Context,
119 {
120 if self.start == self.end {
121 return Err(cx.message(format_args!(
122 "Buffer overflow, remaining is 0 while tried to write 1"
123 )));
124 }
125
126 unsafe {
128 self.start.write(b);
129 self.start = self.start.add(1);
130 }
131
132 Ok(())
133 }
134}