bytebuffer/
buffer.rs

1use crate::Endian;
2use byteorder::{BigEndian, ByteOrder, LittleEndian};
3use std::{
4    fmt::Debug,
5    io::{Error, ErrorKind, Read, Result, Write},
6};
7
8/// A byte buffer object specifically turned to easily read and write binary values
9#[derive(Clone, PartialEq, Eq, Hash)]
10pub struct ByteBuffer {
11    data: Vec<u8>,
12    wpos: usize,
13    rpos: usize,
14    wbit: usize,
15    rbit: usize,
16    endian: Endian,
17}
18
19impl From<&[u8]> for ByteBuffer {
20    fn from(val: &[u8]) -> Self {
21        ByteBuffer::from_bytes(val)
22    }
23}
24
25impl From<Vec<u8>> for ByteBuffer {
26    fn from(val: Vec<u8>) -> Self {
27        ByteBuffer::from_vec(val)
28    }
29}
30
31impl From<ByteBuffer> for Vec<u8> {
32    fn from(val: ByteBuffer) -> Self {
33        val.into_vec()
34    }
35}
36
37impl Default for ByteBuffer {
38    fn default() -> Self {
39        Self::new()
40    }
41}
42
43impl Read for ByteBuffer {
44    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
45        self.flush_bits();
46        let read_len = std::cmp::min(self.data.len() - self.rpos, buf.len());
47        let range = self.rpos..self.rpos + read_len;
48        for (i, val) in self.data[range].iter().enumerate() {
49            buf[i] = *val;
50        }
51        self.rpos += read_len;
52        Ok(read_len)
53    }
54}
55
56impl Write for ByteBuffer {
57    fn write(&mut self, buf: &[u8]) -> Result<usize> {
58        self.write_bytes(buf);
59        Ok(buf.len())
60    }
61
62    fn flush(&mut self) -> Result<()> {
63        Ok(())
64    }
65}
66
67impl Debug for ByteBuffer {
68    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
69        let rpos = if self.rbit > 0 {
70            self.rpos + 1
71        } else {
72            self.rpos
73        };
74
75        let read_len = self.data.len() - rpos;
76        let mut remaining_data = vec![0; read_len];
77        let range = rpos..rpos + read_len;
78        for (i, val) in self.data[range].iter().enumerate() {
79            remaining_data[i] = *val;
80        }
81
82        write!(
83            f,
84            "ByteBuffer {{ remaining_data: {:?}, total_data: {:?}, wpos: {:?}, rpos: {:?}, endian: {:?} }}",
85            remaining_data, self.data, self.wpos, self.rpos, self.endian
86        )
87    }
88}
89
90macro_rules! read_number {
91    ($self:ident, $name:ident, $offset:expr) => {{
92        $self.flush_bits();
93        if $self.rpos + $offset > $self.data.len() {
94            return Err(Error::new(
95                ErrorKind::UnexpectedEof,
96                "could not read enough bits from buffer",
97            ));
98        }
99        let range = $self.rpos..$self.rpos + $offset;
100        $self.rpos += $offset;
101
102        Ok(match $self.endian {
103            Endian::BigEndian => BigEndian::$name(&$self.data[range]),
104            Endian::LittleEndian => LittleEndian::$name(&$self.data[range]),
105        })
106    }};
107}
108
109impl ByteBuffer {
110    /// Construct a new, empty, ByteBuffer
111    pub fn new() -> ByteBuffer {
112        ByteBuffer {
113            data: vec![],
114            wpos: 0,
115            rpos: 0,
116            rbit: 0,
117            wbit: 0,
118            endian: Endian::BigEndian,
119        }
120    }
121
122    /// Construct a new ByteBuffer filled with the data array.
123    pub fn from_bytes(bytes: &[u8]) -> ByteBuffer {
124        let mut buffer = ByteBuffer::new();
125        buffer.write_bytes(bytes);
126        buffer
127    }
128
129    /// Constructs a new ByteBuffer from an existing vector. This
130    /// function takes ownership of the vector
131    pub fn from_vec(vec: Vec<u8>) -> ByteBuffer {
132        let len = vec.len();
133        ByteBuffer {
134            data: vec,
135            wpos: len,
136            rpos: 0,
137            rbit: 0,
138            wbit: 0,
139            endian: Endian::BigEndian,
140        }
141    }
142
143    /// Return the buffer size
144    pub fn len(&self) -> usize {
145        self.data.len()
146    }
147
148    pub fn is_empty(&self) -> bool {
149        self.data.is_empty()
150    }
151
152    /// Clear the buffer and reinitialize the reading and writing cursors
153    pub fn clear(&mut self) {
154        self.data.clear();
155        self.reset_cursors();
156        self.reset_bits_cursors();
157    }
158
159    /// Reinitialize the reading and writing cursor
160    pub fn reset_cursors(&mut self) {
161        self.wpos = 0;
162        self.rpos = 0;
163    }
164
165    /// Reinitialize the bit reading and bit writing cursor
166    pub fn reset_bits_cursors(&mut self) {
167        self.rbit = 0;
168        self.wbit = 0;
169    }
170
171    /// Change the buffer size to size.
172    ///
173    /// _Note_: You cannot shrink a buffer with this method
174    pub fn resize(&mut self, size: usize) {
175        let diff = size - self.data.len();
176        if diff > 0 {
177            self.data.extend(std::iter::repeat(0).take(diff))
178        }
179    }
180
181    /// Set the byte order of the buffer
182    ///
183    /// _Note_: By default the buffer uses big endian order
184    pub fn set_endian(&mut self, endian: Endian) {
185        self.endian = endian;
186    }
187
188    /// Returns the current byte order of the buffer
189    pub fn endian(&self) -> Endian {
190        self.endian
191    }
192
193    // Write operations
194
195    /// Append a byte array to the buffer. The buffer is automatically extended if needed
196    /// _Note_: This method resets the read and write cursor for bitwise reading.
197    ///
198    /// #Example
199    ///
200    /// ```
201    /// # use bytebuffer::*;
202    /// let mut buffer = ByteBuffer::new();
203    /// buffer.write_bytes(&vec![0x1, 0xFF, 0x45]); // buffer contains [0x1, 0xFF, 0x45]
204    /// ```
205    pub fn write_bytes(&mut self, bytes: &[u8]) {
206        self.flush_bits();
207
208        let size = bytes.len() + self.wpos;
209
210        if size > self.data.len() {
211            self.resize(size);
212        }
213
214        for v in bytes {
215            self.data[self.wpos] = *v;
216            self.wpos += 1;
217        }
218    }
219
220    /// Append a byte (8 bits value) to the buffer
221    /// _Note_: This method resets the read and write cursor for bitwise reading.
222    ///
223    /// #Example
224    ///
225    /// ```
226    /// #  use bytebuffer::*;
227    /// let mut buffer = ByteBuffer::new();
228    /// buffer.write_u8(1) // buffer contains [0x1]
229    /// ```
230    pub fn write_u8(&mut self, val: u8) {
231        self.write_bytes(&[val]);
232    }
233
234    /// Same as `write_u8()` but for signed values
235    /// _Note_: This method resets the read and write cursor for bitwise reading.
236    pub fn write_i8(&mut self, val: i8) {
237        self.write_u8(val as u8);
238    }
239
240    /// Append a word (16 bits value) to the buffer
241    /// _Note_: This method resets the read and write cursor for bitwise reading.
242    ///
243    /// #Example
244    ///
245    /// ```
246    /// #  use bytebuffer::*;
247    /// let mut buffer = ByteBuffer::new();
248    /// buffer.write_u16(1) // buffer contains [0x00, 0x1] if little endian
249    /// ```
250    pub fn write_u16(&mut self, val: u16) {
251        let mut buf = [0; 2];
252
253        match self.endian {
254            Endian::BigEndian => BigEndian::write_u16(&mut buf, val),
255            Endian::LittleEndian => LittleEndian::write_u16(&mut buf, val),
256        };
257
258        self.write_bytes(&buf);
259    }
260
261    /// Same as `write_u16()` but for signed values
262    /// _Note_: This method resets the read and write cursor for bitwise reading.
263    pub fn write_i16(&mut self, val: i16) {
264        self.write_u16(val as u16);
265    }
266
267    /// Append a double word (32 bits value) to the buffer
268    /// _Note_: This method resets the read and write cursor for bitwise reading.
269    ///
270    /// #Example
271    ///
272    /// ```
273    /// #  use bytebuffer::*;
274    /// let mut buffer = ByteBuffer::new();
275    /// buffer.write_u32(1) // buffer contains [0x00, 0x00, 0x00, 0x1] if little endian
276    /// ```
277    pub fn write_u32(&mut self, val: u32) {
278        let mut buf = [0; 4];
279
280        match self.endian {
281            Endian::BigEndian => BigEndian::write_u32(&mut buf, val),
282            Endian::LittleEndian => LittleEndian::write_u32(&mut buf, val),
283        };
284
285        self.write_bytes(&buf);
286    }
287
288    /// Same as `write_u32()` but for signed values
289    /// _Note_: This method resets the read and write cursor for bitwise reading.
290    pub fn write_i32(&mut self, val: i32) {
291        self.write_u32(val as u32);
292    }
293
294    /// Append a quad word (64 bits value) to the buffer
295    /// _Note_: This method resets the read and write cursor for bitwise reading.
296    ///
297    /// #Example
298    ///
299    /// ```
300    /// #  use bytebuffer::*;
301    /// let mut buffer = ByteBuffer::new();
302    /// buffer.write_u64(1) // buffer contains [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1] if little endian
303    /// ```
304    pub fn write_u64(&mut self, val: u64) {
305        let mut buf = [0; 8];
306        match self.endian {
307            Endian::BigEndian => BigEndian::write_u64(&mut buf, val),
308            Endian::LittleEndian => LittleEndian::write_u64(&mut buf, val),
309        };
310
311        self.write_bytes(&buf);
312    }
313
314    /// Same as `write_u64()` but for signed values
315    /// _Note_: This method resets the read and write cursor for bitwise reading.
316    pub fn write_i64(&mut self, val: i64) {
317        self.write_u64(val as u64);
318    }
319
320    /// Append an octo word (128 bits value) to the buffer
321    /// _Note_: This method resets the read and write cursor for bitwise reading.
322    ///
323    /// #Example
324    ///
325    /// ```
326    /// #  use bytebuffer::*;
327    /// let mut buffer = ByteBuffer::new();
328    /// buffer.write_u128(1) // buffer contains [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1] if little endian
329    /// ```
330    pub fn write_u128(&mut self, val: u128) {
331        let mut buf = [0; 16];
332        match self.endian {
333            Endian::BigEndian => BigEndian::write_u128(&mut buf, val),
334            Endian::LittleEndian => LittleEndian::write_u128(&mut buf, val),
335        };
336
337        self.write_bytes(&buf);
338    }
339
340    /// Same as `write_u128()` but for signed values
341    /// _Note_: This method resets the read and write cursor for bitwise reading.
342    pub fn write_i128(&mut self, val: i128) {
343        self.write_u128(val as u128);
344    }
345
346    /// Append a 32 bits floating point number to the buffer.
347    /// _Note_: This method resets the read and write cursor for bitwise reading.
348    ///
349    /// #Example
350    ///
351    /// ```
352    /// #  use bytebuffer::*;
353    /// let mut buffer = ByteBuffer::new();
354    /// buffer.write_f32(0.1)
355    /// ```
356    pub fn write_f32(&mut self, val: f32) {
357        let mut buf = [0; 4];
358
359        match self.endian {
360            Endian::BigEndian => BigEndian::write_f32(&mut buf, val),
361            Endian::LittleEndian => LittleEndian::write_f32(&mut buf, val),
362        };
363
364        self.write_bytes(&buf);
365    }
366
367    /// Append a 64 bits floating point number to the buffer.
368    /// _Note_: This method resets the read and write cursor for bitwise reading.
369    ///
370    /// #Example
371    ///
372    /// ```
373    /// #  use bytebuffer::*;
374    /// let mut buffer = ByteBuffer::new();
375    /// buffer.write_f64(0.1)
376    /// ```
377    pub fn write_f64(&mut self, val: f64) {
378        let mut buf = [0; 8];
379
380        match self.endian {
381            Endian::BigEndian => BigEndian::write_f64(&mut buf, val),
382            Endian::LittleEndian => LittleEndian::write_f64(&mut buf, val),
383        };
384        self.write_bytes(&buf);
385    }
386
387    /// Append a string to the buffer.
388    /// _Note_: This method resets the read and write cursor for bitwise reading.
389    ///
390    /// *Format* The format is `(u32)size + size * (u8)characters`
391    ///
392    /// #Example
393    ///
394    /// ```
395    /// #  use bytebuffer::*;
396    /// let mut buffer = ByteBuffer::new();
397    /// buffer.write_string("Hello")
398    /// ```
399    pub fn write_string(&mut self, val: &str) {
400        self.write_u32(val.len() as u32);
401        self.write_bytes(val.as_bytes());
402    }
403
404    // Read operations
405
406    /// Read a defined amount of raw bytes, or return an IO error if not enough bytes are
407    /// available.
408    /// _Note_: This method resets the read and write cursor for bitwise reading.
409    pub fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
410        self.flush_bits();
411        if self.rpos + size > self.data.len() {
412            return Err(Error::new(
413                ErrorKind::UnexpectedEof,
414                "could not read enough bytes from buffer",
415            ));
416        }
417        let range = self.rpos..self.rpos + size;
418        let mut res = Vec::<u8>::new();
419        res.write_all(&self.data[range])?;
420        self.rpos += size;
421        Ok(res)
422    }
423
424    /// Read one byte, or return an IO error if not enough bytes are available.
425    /// _Note_: This method resets the read and write cursor for bitwise reading.
426    ///
427    /// #Example
428    ///
429    /// ```
430    /// #  use bytebuffer::*;
431    /// let mut buffer = ByteBuffer::from_bytes(&vec![0x1]);
432    /// let value = buffer.read_u8().unwrap(); //Value contains 1
433    /// ```
434    pub fn read_u8(&mut self) -> Result<u8> {
435        self.flush_bits();
436        if self.rpos >= self.data.len() {
437            return Err(Error::new(
438                ErrorKind::UnexpectedEof,
439                "could not read enough bits from buffer",
440            ));
441        }
442        let pos = self.rpos;
443        self.rpos += 1;
444        Ok(self.data[pos])
445    }
446
447    /// Same as `read_u8()` but for signed values
448    pub fn read_i8(&mut self) -> Result<i8> {
449        Ok(self.read_u8()? as i8)
450    }
451
452    /// Read a 2-bytes long value, or return an IO error if not enough bytes are available.
453    /// _Note_: This method resets the read and write cursor for bitwise reading.
454    ///
455    /// #Example
456    ///
457    /// ```
458    /// #  use bytebuffer::*;
459    /// let mut buffer = ByteBuffer::from_bytes(&vec![0x0, 0x1]);
460    /// let value = buffer.read_u16().unwrap(); //Value contains 1
461    /// ```
462    pub fn read_u16(&mut self) -> Result<u16> {
463        read_number!(self, read_u16, 2)
464    }
465
466    /// Same as `read_u16()` but for signed values
467    /// _Note_: This method resets the read and write cursor for bitwise reading.
468    pub fn read_i16(&mut self) -> Result<i16> {
469        Ok(self.read_u16()? as i16)
470    }
471
472    /// Read a four-bytes long value, or return an IO error if not enough bytes are available.
473    /// _Note_: This method resets the read and write cursor for bitwise reading.
474    ///
475    /// #Example
476    ///
477    /// ```
478    /// #  use bytebuffer::*;
479    /// let mut buffer = ByteBuffer::from_bytes(&vec![0x0, 0x0, 0x0, 0x1]);
480    /// let value = buffer.read_u32().unwrap(); // Value contains 1
481    /// ```
482    pub fn read_u32(&mut self) -> Result<u32> {
483        read_number!(self, read_u32, 4)
484    }
485
486    /// Same as `read_u32()` but for signed values
487    /// _Note_: This method resets the read and write cursor for bitwise reading.
488    pub fn read_i32(&mut self) -> Result<i32> {
489        Ok(self.read_u32()? as i32)
490    }
491
492    /// Read an eight bytes long value, or return an IO error if not enough bytes are available.
493    /// _Note_: This method resets the read and write cursor for bitwise reading.
494    ///
495    /// #Example
496    ///
497    /// ```
498    /// #  use bytebuffer::*;
499    /// let mut buffer = ByteBuffer::from_bytes(&vec![0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1]);
500    /// let value = buffer.read_u64().unwrap(); //Value contains 1
501    /// ```
502    pub fn read_u64(&mut self) -> Result<u64> {
503        read_number!(self, read_u64, 8)
504    }
505
506    /// Same as `read_u64()` but for signed values
507    /// _Note_: This method resets the read and write cursor for bitwise reading.
508    pub fn read_i64(&mut self) -> Result<i64> {
509        Ok(self.read_u64()? as i64)
510    }
511
512    /// Read a sixteen bytes long value, or return an IO error if not enough bytes are available.
513    /// _Note_: This method resets the read and write cursor for bitwise reading.
514    ///
515    /// #Example
516    ///
517    /// ```
518    /// #  use bytebuffer::*;
519    /// let mut buffer = ByteBuffer::from_bytes(&vec![0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1]);
520    /// let value = buffer.read_u128().unwrap(); //Value contains 1
521    /// ```
522    pub fn read_u128(&mut self) -> Result<u128> {
523        read_number!(self, read_u128, 16)
524    }
525
526    /// Same as `read_u128()` but for signed values
527    /// _Note_: This method resets the read and write cursor for bitwise reading.
528    pub fn read_i128(&mut self) -> Result<i128> {
529        Ok(self.read_u128()? as i128)
530    }
531
532    /// Read a 32 bits floating point value, or return an IO error if not enough bytes are available.
533    /// _Note_: This method resets the read and write cursor for bitwise reading.
534    pub fn read_f32(&mut self) -> Result<f32> {
535        read_number!(self, read_f32, 4)
536    }
537
538    /// Read a 64 bits floating point value, or return an IO error if not enough bytes are available.
539    /// _Note_: This method resets the read and write cursor for bitwise reading.
540    pub fn read_f64(&mut self) -> Result<f64> {
541        read_number!(self, read_f64, 8)
542    }
543
544    /// Read a string.
545    ///
546    /// _Note_: First it reads a 32 bits value representing the size, then 'size' raw bytes
547    ///         that  must be encoded as UTF8.
548    /// _Note_: This method resets the read and write cursor for bitwise reading.
549    pub fn read_string(&mut self) -> Result<String> {
550        let size = self.read_u32()?;
551        match String::from_utf8(self.read_bytes(size as usize)?) {
552            Ok(string_result) => Ok(string_result),
553            Err(e) => Err(Error::new(ErrorKind::InvalidData, e)),
554        }
555    }
556
557    // Other
558
559    /// Dump the byte buffer to a string.
560    pub fn to_hex_dump(&self) -> String {
561        let mut str = String::new();
562        for b in &self.data {
563            str = str + &format!("0x{:01$x} ", b, 2);
564        }
565        str.pop();
566        str
567    }
568
569    /// Return the position of the reading cursor
570    pub fn get_rpos(&self) -> usize {
571        self.rpos
572    }
573
574    /// Set the reading cursor position.
575    /// _Note_: Sets the reading cursor to `min(newPosition, self.len())` to prevent overflow
576    pub fn set_rpos(&mut self, rpos: usize) {
577        self.rpos = std::cmp::min(rpos, self.data.len());
578    }
579
580    /// Return the writing cursor position
581    pub fn get_wpos(&self) -> usize {
582        self.wpos
583    }
584
585    /// Set the writing cursor position.
586    /// _Note_: Sets the writing cursor to `min(newPosition, self.len())` to prevent overflow
587    pub fn set_wpos(&mut self, wpos: usize) {
588        self.wpos = std::cmp::min(wpos, self.data.len());
589    }
590
591    /// Return the raw byte buffer bytes.
592    pub fn as_bytes(&self) -> &[u8] {
593        &self.data
594    }
595
596    /// Return the raw byte buffer as a Vec<u8>.
597    #[deprecated(
598        since = "2.1.0",
599        note = "use `as_bytes().to_vec()` or `into_vec()` instead"
600    )]
601    pub fn into_bytes(&self) -> Vec<u8> {
602        self.data.to_vec()
603    }
604
605    /// Return the raw byte buffer as a Vec<u8>.
606    pub fn into_vec(self) -> Vec<u8> {
607        self.data
608    }
609
610    //Bit manipulation functions
611
612    /// Read 1 bit. Return true if the bit is set to 1, otherwhise, return false.
613    ///
614    /// _Note_: Bits are read from left to right
615    ///
616    /// #Example
617    ///
618    /// ```
619    /// #  use bytebuffer::*;
620    /// let mut buffer = ByteBuffer::from_bytes(&vec![128]); // 10000000b
621    /// let value1 = buffer.read_bit().unwrap(); //value1 contains true (eg: bit is 1)
622    /// let value2 = buffer.read_bit().unwrap(); //value2 contains false (eg: bit is 0)
623    /// ```
624    pub fn read_bit(&mut self) -> Result<bool> {
625        if self.rpos >= self.data.len() {
626            return Err(Error::new(
627                ErrorKind::UnexpectedEof,
628                "could not read enough bits from buffer",
629            ));
630        }
631        let bit = self.data[self.rpos] & (1 << (7 - self.rbit)) != 0;
632        self.rbit += 1;
633        if self.rbit > 7 {
634            self.flush_rbits();
635        }
636        Ok(bit)
637    }
638
639    /// Read n bits. an return the corresponding value an u64.
640    ///
641    /// _Note_: We cannot read more than 64 bits
642    ///
643    /// _Note_: Bits are read from left to right
644    ///
645    /// #Example
646    ///
647    /// ```
648    /// #  use bytebuffer::*;
649    /// let mut buffer = ByteBuffer::from_bytes(&vec![128]); // 10000000b
650    /// let value = buffer.read_bits(3).unwrap(); // value contains 4 (eg: 100b)
651    /// ```
652    pub fn read_bits(&mut self, n: u8) -> Result<u64> {
653        if n > 64 {
654            return Err(Error::new(
655                ErrorKind::InvalidInput,
656                "cannot read more than 64 bits",
657            ));
658        }
659
660        if n == 0 {
661            Ok(0)
662        } else {
663            Ok((u64::from(self.read_bit()?) << (n - 1)) | self.read_bits(n - 1)?)
664        }
665    }
666
667    /// Discard all the pending bits available for reading or writing and place the corresponding cursor to the next byte.
668    ///
669    /// _Note_: If no bits are currently read or written, this function does nothing.
670    ///
671    /// #Example
672    ///
673    /// ```text
674    /// 10010010 | 00000001
675    /// ^
676    /// 10010010 | 00000001 // read_bit called
677    ///  ^
678    /// 10010010 | 00000001 // flush_bit() called
679    ///            ^
680    /// ```
681    pub fn flush_bits(&mut self) {
682        if self.rbit > 0 {
683            self.flush_rbits();
684        }
685        if self.wbit > 0 {
686            self.flush_wbits();
687        }
688    }
689
690    fn flush_rbits(&mut self) {
691        self.rpos += 1;
692        self.rbit = 0
693    }
694
695    fn flush_wbits(&mut self) {
696        self.wpos += 1;
697        self.wbit = 0
698    }
699
700    /// Append 1 bit value to the buffer.
701    /// The bit is appended like this :
702    ///
703    /// ```text
704    /// ...| XXXXXXXX | 10000000 |....
705    /// ```
706    pub fn write_bit(&mut self, bit: bool) {
707        let size = self.wpos + 1;
708        if size > self.data.len() {
709            self.resize(size);
710        }
711
712        if bit {
713            self.data[self.wpos] |= 1 << (7 - self.wbit);
714        }
715
716        self.wbit += 1;
717
718        if self.wbit > 7 {
719            self.wbit = 0;
720            self.wpos += 1;
721        }
722    }
723
724    /// Write the given value as a sequence of n bits
725    ///
726    /// #Example
727    ///
728    /// ```
729    /// #  use bytebuffer::*;
730    /// let mut buffer = ByteBuffer::new();
731    /// buffer.write_bits(4, 3); // append 100b
732    /// ```
733    pub fn write_bits(&mut self, value: u64, n: u8) {
734        if n > 0 {
735            self.write_bit((value >> (n - 1)) & 1 != 0);
736            self.write_bits(value, n - 1);
737        }
738    }
739}
740
741#[cfg(feature = "half")]
742impl ByteBuffer {
743    /// Read a 16 bits floating point value, or return an IO error if not enough bytes are available.
744    /// _Note_: This method resets the read and write cursor for bitwise reading.
745    pub fn read_f16(&mut self) -> Result<half::f16> {
746        let offset = 2;
747
748        self.flush_bits();
749        if self.rpos + offset > self.data.len() {
750            return Err(Error::new(
751                ErrorKind::UnexpectedEof,
752                "could not read enough bits from buffer",
753            ));
754        }
755        let range = self.rpos..self.rpos + offset;
756        self.rpos += offset;
757
758        let bytes: [u8; 2] = self.data[range]
759            .try_into()
760            .expect("range should always be 2");
761
762        Ok(match self.endian {
763            Endian::BigEndian => half::f16::from_be_bytes(bytes),
764            Endian::LittleEndian => half::f16::from_le_bytes(bytes),
765        })
766    }
767
768    /// Append a 16 bits floating point number to the buffer.
769    /// _Note_: This method resets the read and write cursor for bitwise reading.
770    ///
771    /// #Example
772    ///
773    /// ```
774    /// #  use bytebuffer::*;
775    /// let mut buffer = ByteBuffer::new();
776    /// buffer.write_f16(half::f16::from_f32(0.1))
777    /// ```
778    pub fn write_f16(&mut self, val: half::f16) {
779        match self.endian {
780            Endian::BigEndian => self.write_bytes(&val.to_be_bytes()),
781            Endian::LittleEndian => self.write_bytes(&val.to_le_bytes()),
782        };
783    }
784
785    /// Read a truncated 16 bits floating point value, or return an IO error if not enough bytes are available.
786    /// _Note_: This method resets the read and write cursor for bitwise reading.
787    pub fn read_bf16(&mut self) -> Result<half::bf16> {
788        let offset = 2;
789
790        self.flush_bits();
791        if self.rpos + offset > self.data.len() {
792            return Err(Error::new(
793                ErrorKind::UnexpectedEof,
794                "could not read enough bits from buffer",
795            ));
796        }
797        let range = self.rpos..self.rpos + offset;
798        self.rpos += offset;
799
800        let bytes: [u8; 2] = self.data[range]
801            .try_into()
802            .expect("range should always be 2");
803
804        Ok(match self.endian {
805            Endian::BigEndian => half::bf16::from_be_bytes(bytes),
806            Endian::LittleEndian => half::bf16::from_le_bytes(bytes),
807        })
808    }
809
810    /// Append a truncated 16 bits floating point number to the buffer.
811    /// _Note_: This method resets the read and write cursor for bitwise reading.
812    ///
813    /// #Example
814    ///
815    /// ```
816    /// #  use bytebuffer::*;
817    /// let mut buffer = ByteBuffer::new();
818    /// buffer.write_bf16(half::bf16::from_f32(0.1))
819    /// ```
820    pub fn write_bf16(&mut self, val: half::bf16) {
821        match self.endian {
822            Endian::BigEndian => self.write_bytes(&val.to_be_bytes()),
823            Endian::LittleEndian => self.write_bytes(&val.to_le_bytes()),
824        };
825    }
826}