bitbuffer/
writestream.rs

1use num_traits::{Float, PrimInt};
2use std::cmp::min;
3use std::mem::size_of;
4use std::ops::{BitOrAssign, BitXor};
5
6use crate::endianness::Endianness;
7use crate::num_traits::{IsSigned, SplitFitUsize, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
8use crate::writebuffer::WriteBuffer;
9use crate::{BitError, BitReadStream, BitWrite, BitWriteSized, Result};
10use std::fmt::Debug;
11
12const USIZE_SIZE: usize = size_of::<usize>();
13const USIZE_BITS: usize = USIZE_SIZE * 8;
14
15/// Stream that provides an a way to write non bit aligned adata
16///
17/// # Examples
18///
19/// ```
20/// use bitbuffer::{BitWriteStream, LittleEndian};
21/// # use bitbuffer::Result;
22///
23/// # fn main() -> Result<()> {
24/// let mut data = Vec::new();
25/// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
26///
27/// stream.write_bool(false)?;
28/// stream.write_int(123u16, 15)?;
29/// # Ok(())
30/// # }
31/// ```
32///
33/// [`BitBuffer`]: struct.BitBuffer.html
34pub struct BitWriteStream<'a, E>
35where
36    E: Endianness,
37{
38    buffer: WriteBuffer<'a, E>,
39}
40
41impl<'a, E> BitWriteStream<'a, E>
42where
43    E: Endianness,
44{
45    /// Create a new write stream
46    ///
47    /// # Examples
48    ///
49    /// ```
50    /// use bitbuffer::{BitWriteStream, LittleEndian};
51    ///
52    /// let mut data = Vec::new();
53    /// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
54    /// ```
55    pub fn new(data: &'a mut Vec<u8>, endianness: E) -> Self {
56        BitWriteStream {
57            buffer: WriteBuffer::new(data, endianness),
58        }
59    }
60
61    /// Create a new write stream
62    ///
63    /// Note that the resulting stream will panic when trying to write more data then fits
64    /// in the provided slice.
65    pub fn from_slice(data: &'a mut [u8], endianness: E) -> Self {
66        BitWriteStream {
67            buffer: WriteBuffer::for_slice(data, endianness),
68        }
69    }
70}
71
72impl<E> BitWriteStream<'_, E>
73where
74    E: Endianness,
75{
76    /// The number of written bits in the buffer
77    pub fn bit_len(&self) -> usize {
78        self.buffer.bit_len()
79    }
80
81    /// The number of written bytes in the buffer
82    pub fn byte_len(&self) -> usize {
83        self.buffer.bit_len().div_ceil(8)
84    }
85
86    fn push_non_fit_bits<I>(&mut self, bits: I, count: usize)
87    where
88        I: ExactSizeIterator,
89        I: DoubleEndedIterator<Item = (usize, u8)>,
90    {
91        self.buffer.push_non_fit_bits(bits, count)
92    }
93
94    /// Push up to an usize worth of bits
95    fn push_bits(&mut self, bits: usize, count: usize) {
96        if count > 0 {
97            self.buffer.push_bits(bits, count)
98        }
99    }
100
101    /// Align the stream on the next byte by writing zero bits and returns the amount of bits written
102    ///
103    /// # Examples
104    ///
105    /// ```
106    /// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
107    /// #
108    /// # fn main() -> Result<()> {
109    /// # use bitbuffer::{BitWriteStream, LittleEndian};
110    ///
111    /// let mut data = Vec::new();
112    /// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
113    /// stream.write_bool(true)?;
114    /// stream.align();
115    /// assert_eq!(stream.bit_len(), 8);
116    /// assert_eq!(data, [0b0000_0001]);
117    /// #
118    /// #     Ok(())
119    /// # }
120    /// ```
121    ///
122    /// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
123    pub fn align(&mut self) -> usize {
124        match self.bit_len() % 8 {
125            0 => 0,
126            n => {
127                self.push_bits(0, 8 - n);
128                8 - n
129            }
130        }
131    }
132
133    /// Write a boolean into the buffer
134    ///
135    /// # Examples
136    ///
137    /// ```
138    /// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
139    /// #
140    /// # fn main() -> Result<()> {
141    /// # use bitbuffer::{BitWriteStream, LittleEndian};
142    ///
143    /// let mut data = Vec::new();
144    /// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
145    /// stream.write_bool(true)?;
146    /// #
147    /// #     Ok(())
148    /// # }
149    /// ```
150    #[inline]
151    pub fn write_bool(&mut self, value: bool) -> Result<()> {
152        self.buffer.push_bool(value);
153        Ok(())
154    }
155
156    /// Write an integer into the buffer
157    ///
158    /// # Examples
159    ///
160    /// ```
161    /// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
162    /// #
163    /// # fn main() -> Result<()> {
164    /// # use bitbuffer::{BitWriteStream, LittleEndian};
165    ///
166    /// let mut data = Vec::new();
167    /// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
168    /// stream.write_int(123u16, 15)?;
169    /// #
170    /// #     Ok(())
171    /// # }
172    /// ```
173    #[inline]
174    pub fn write_int<T>(&mut self, value: T, count: usize) -> Result<()>
175    where
176        T: PrimInt
177            + BitOrAssign
178            + IsSigned
179            + UncheckedPrimitiveInt
180            + BitXor
181            + Debug
182            + SplitFitUsize,
183    {
184        let type_bit_size = size_of::<T>() * 8;
185
186        if type_bit_size < count {
187            return Err(BitError::TooManyBits {
188                requested: count,
189                max: type_bit_size,
190            });
191        }
192
193        if type_bit_size < USIZE_BITS || count <= (USIZE_BITS - (self.bit_len() % 8)) {
194            self.push_bits(value.into_usize_unchecked(), count);
195        } else {
196            self.push_non_fit_bits(value.split_fit_usize::<E>(count as u8), count)
197        }
198
199        Ok(())
200    }
201
202    /// Write a float into the buffer
203    ///
204    /// # Examples
205    ///
206    /// ```
207    /// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
208    /// #
209    /// # fn main() -> Result<()> {
210    /// # use bitbuffer::{BitWriteStream, LittleEndian};
211    ///
212    /// let mut data = Vec::new();
213    /// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
214    /// stream.write_float(123.15f32)?;
215    /// #
216    /// #     Ok(())
217    /// # }
218    /// ```
219    #[inline]
220    pub fn write_float<T>(&mut self, value: T) -> Result<()>
221    where
222        T: Float + UncheckedPrimitiveFloat,
223    {
224        if self.buffer.bit_len() & 7 == 0 {
225            let bytes = value.to_bytes::<E>();
226            self.buffer.extends_from_slice(bytes.as_ref());
227        } else {
228            self.write_int(value.to_int(), size_of::<T>() * 8)?;
229        }
230
231        Ok(())
232    }
233
234    /// Write a number of bytes into the buffer
235    ///
236    /// # Examples
237    ///
238    /// ```
239    /// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
240    /// #
241    /// # fn main() -> Result<()> {
242    /// # use bitbuffer::{BitWriteStream, LittleEndian};
243    ///
244    /// let mut data = Vec::new();
245    /// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
246    /// stream.write_bytes(&[0, 1, 2 ,3])?;
247    /// #
248    /// #     Ok(())
249    /// # }
250    /// ```
251    #[inline]
252    pub fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> {
253        if self.buffer.bit_len() & 7 == 0 {
254            self.buffer.extends_from_slice(bytes);
255        } else {
256            bytes
257                .iter()
258                .copied()
259                .for_each(|chunk| self.push_bits(chunk as usize, 8));
260        }
261        Ok(())
262    }
263
264    /// Write bits from a read stream into the buffer
265    #[inline]
266    pub fn write_bits(&mut self, bits: &BitReadStream<E>) -> Result<()> {
267        let mut bits = bits.clone();
268        let bit_offset = self.bit_len() % 8;
269        if bit_offset > 0 {
270            let bit_count = min(8 - bit_offset, bits.bits_left());
271            let start = bits.read_int::<u8>(bit_count)?;
272            self.push_bits(start as usize, bit_count);
273        }
274
275        while bits.bits_left() > 32 {
276            let chunk = bits.read::<u32>()?;
277            self.push_bits(chunk as usize, 32);
278        }
279
280        if bits.bits_left() > 0 {
281            let end_bits = bits.bits_left();
282            let end = bits.read_int::<u32>(end_bits)?;
283            self.push_bits(end as usize, end_bits);
284        }
285        Ok(())
286    }
287
288    /// Write a string into the buffer
289    ///
290    /// # Examples
291    ///
292    /// ```
293    /// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
294    /// #
295    /// # fn main() -> Result<()> {
296    /// # use bitbuffer::{BitWriteStream, LittleEndian};
297    ///
298    /// let mut data = Vec::new();
299    /// let mut stream = BitWriteStream::new(&mut data, LittleEndian);
300    /// stream.write_string("zero terminated string", None)?;
301    /// stream.write_string("fixed size string, zero padded", Some(64))?;
302    /// #
303    /// #     Ok(())
304    /// # }
305    /// ```
306    pub fn write_string(&mut self, string: &str, length: Option<usize>) -> Result<()> {
307        match length {
308            Some(length) => {
309                if length < string.len() {
310                    return Err(BitError::StringToLong {
311                        string_length: string.len(),
312                        requested_length: length,
313                    });
314                }
315                self.write_bytes(string.as_bytes())?;
316                for _ in 0..(length - string.len()) {
317                    self.push_bits(0, 8)
318                }
319            }
320            None => {
321                self.write_bytes(string.as_bytes())?;
322                self.push_bits(0, 8)
323            }
324        }
325        Ok(())
326    }
327
328    /// Write the type to stream
329    #[inline]
330    pub fn write<T: BitWrite<E>>(&mut self, value: &T) -> Result<()> {
331        value.write(self)
332    }
333
334    /// Write the type to stream
335    #[inline]
336    pub fn write_sized<T: BitWriteSized<E>>(&mut self, value: &T, length: usize) -> Result<()> {
337        value.write_sized(self, length)
338    }
339
340    /// Write the length of a section before the section
341    pub fn reserve_length<Err: From<BitError>, F: Fn(&mut BitWriteStream<E>) -> Result<(), Err>>(
342        &mut self,
343        length_bit_size: usize,
344        body_fn: F,
345    ) -> Result<(), Err> {
346        self.reserve_int(length_bit_size, |stream| {
347            let start = stream.bit_len();
348            body_fn(stream)?;
349            let end = stream.bit_len();
350            Ok((end - start) as u64)
351        })
352    }
353
354    /// Write the length in bytes of a section before the section, the section will be 0 padded to an even byte length
355    pub fn reserve_byte_length<
356        Err: From<BitError>,
357        F: Fn(&mut BitWriteStream<E>) -> Result<(), Err>,
358    >(
359        &mut self,
360        length_bit_size: usize,
361        body_fn: F,
362    ) -> Result<(), Err> {
363        self.reserve_int(length_bit_size, |stream| {
364            let start = stream.bit_len();
365            body_fn(stream)?;
366            let end = stream.bit_len();
367            let bit_len = end - start;
368
369            let pad_len = (8 - (bit_len & 7)) & 7;
370            stream.push_bits(0, pad_len);
371
372            let byte_len = (bit_len + pad_len) / 8;
373            Ok(byte_len as u64)
374        })
375    }
376
377    /// Reserve the length to write an integer
378    pub fn reserve_int<Err: From<BitError>, F: Fn(&mut BitWriteStream<E>) -> Result<u64, Err>>(
379        &mut self,
380        count: usize,
381        body_fn: F,
382    ) -> Result<(), Err> {
383        let start = self.bit_len();
384        self.write_int(0u64, count)?;
385
386        let head_int = body_fn(self)?;
387        self.buffer.set_at(start, head_int, count);
388
389        Ok(())
390    }
391}