qubit_io/stream/
leb128_writer.rs1use std::io::{
12 Result,
13 Seek,
14 SeekFrom,
15 Write,
16};
17
18use crate::WriteExt;
19use crate::codec::{
20 Leb128Codec,
21 NonStrict,
22};
23
24pub struct Leb128Writer<W> {
32 inner: W,
33 buffer: [u8; 19],
34}
35
36impl<W> Leb128Writer<W> {
37 #[must_use]
39 #[inline]
40 pub const fn new(inner: W) -> Self {
41 Self { inner, buffer: [0; 19] }
42 }
43
44 #[must_use]
46 #[inline]
47 pub const fn get_ref(&self) -> &W {
48 &self.inner
49 }
50
51 #[must_use]
53 #[inline]
54 pub fn get_mut(&mut self) -> &mut W {
55 &mut self.inner
56 }
57
58 #[must_use]
60 #[inline]
61 pub fn into_inner(self) -> W {
62 self.inner
63 }
64}
65
66macro_rules! impl_write_value {
67 ($method:ident, $ty:ty, $doc:literal) => {
68 #[doc = $doc]
69 #[inline]
70 pub fn $method(&mut self, value: $ty) -> Result<()> {
71 type Codec = Leb128Codec<$ty, NonStrict>;
72
73 self.write_leb128::<$ty, { Codec::REQUIRED_MIN_BUFFER_LEN }, _>(value, |bytes, value| unsafe {
74 Codec::write_unchecked(bytes, 0, value)
75 })
76 }
77 };
78}
79
80impl<W> Leb128Writer<W>
81where
82 W: Write,
83{
84 #[inline]
85 fn write_leb128<T, const N: usize, F>(&mut self, value: T, encode: F) -> Result<()>
86 where
87 F: FnOnce(&mut [u8; 19], T) -> usize,
88 {
89 let len = encode(&mut self.buffer, value);
90 unsafe { self.inner.write_all_unchecked(&self.buffer, 0, len) }
92 }
93
94 impl_write_value!(write_u8, u8, "Writes an unsigned LEB128 `u8`.");
95 impl_write_value!(write_u16, u16, "Writes an unsigned LEB128 `u16`.");
96 impl_write_value!(write_u32, u32, "Writes an unsigned LEB128 `u32`.");
97 impl_write_value!(write_u64, u64, "Writes an unsigned LEB128 `u64`.");
98 impl_write_value!(write_u128, u128, "Writes an unsigned LEB128 `u128`.");
99 impl_write_value!(write_usize, usize, "Writes an unsigned LEB128 `usize`.");
100 impl_write_value!(write_i8, i8, "Writes a signed LEB128 `i8`.");
101 impl_write_value!(write_i16, i16, "Writes a signed LEB128 `i16`.");
102 impl_write_value!(write_i32, i32, "Writes a signed LEB128 `i32`.");
103 impl_write_value!(write_i64, i64, "Writes a signed LEB128 `i64`.");
104 impl_write_value!(write_i128, i128, "Writes a signed LEB128 `i128`.");
105 impl_write_value!(write_isize, isize, "Writes a signed LEB128 `isize`.");
106
107 #[inline]
121 pub fn write_utf8_string(&mut self, value: &str) -> Result<()> {
122 self.write_usize(value.len())?;
123 let bytes = value.as_bytes();
124 unsafe { self.inner.write_all_unchecked(bytes, 0, bytes.len()) }
126 }
127}
128
129impl<W> Write for Leb128Writer<W>
130where
131 W: Write,
132{
133 #[inline]
147 fn write(&mut self, buffer: &[u8]) -> Result<usize> {
148 self.inner.write(buffer)
149 }
150
151 #[inline]
157 fn flush(&mut self) -> Result<()> {
158 self.inner.flush()
159 }
160}
161
162impl<W> Seek for Leb128Writer<W>
163where
164 W: Seek,
165{
166 #[inline]
180 fn seek(&mut self, position: SeekFrom) -> Result<u64> {
181 self.inner.seek(position)
182 }
183}