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}