bytebuffer/lib.rs
1use byteorder::{BigEndian, ByteOrder, LittleEndian};
2use std::{
3 fmt::Debug,
4 io::{Error, ErrorKind, Read, Result, Write},
5};
6
7/// An enum to represent the byte order of the ByteBuffer object
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub enum Endian {
10 BigEndian,
11 LittleEndian,
12}
13
14/// A byte buffer object specifically turned to easily read and write binary values
15#[derive(Clone, PartialEq, Eq, Hash)]
16pub struct ByteBuffer {
17 data: Vec<u8>,
18 wpos: usize,
19 rpos: usize,
20 rbit: usize,
21 wbit: usize,
22 endian: Endian,
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_bytes()
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: {:?}, endian: {:?} }}",
85 remaining_data, self.data, 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 quaddruple 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 a 32 bits floating point number 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_f32(0.1)
329 /// ```
330 pub fn write_f32(&mut self, val: f32) {
331 let mut buf = [0; 4];
332
333 match self.endian {
334 Endian::BigEndian => BigEndian::write_f32(&mut buf, val),
335 Endian::LittleEndian => LittleEndian::write_f32(&mut buf, val),
336 };
337
338 self.write_bytes(&buf);
339 }
340
341 /// Append a 64 bits floating point number to the buffer.
342 /// _Note_: This method resets the read and write cursor for bitwise reading.
343 ///
344 /// #Example
345 ///
346 /// ```
347 /// # use bytebuffer::*;
348 /// let mut buffer = ByteBuffer::new();
349 /// buffer.write_f64(0.1)
350 /// ```
351 pub fn write_f64(&mut self, val: f64) {
352 let mut buf = [0; 8];
353
354 match self.endian {
355 Endian::BigEndian => BigEndian::write_f64(&mut buf, val),
356 Endian::LittleEndian => LittleEndian::write_f64(&mut buf, val),
357 };
358 self.write_bytes(&buf);
359 }
360
361 /// Append a string to the buffer.
362 /// _Note_: This method resets the read and write cursor for bitwise reading.
363 ///
364 /// *Format* The format is `(u32)size + size * (u8)characters`
365 ///
366 /// #Example
367 ///
368 /// ```
369 /// # use bytebuffer::*;
370 /// let mut buffer = ByteBuffer::new();
371 /// buffer.write_string("Hello")
372 /// ```
373 pub fn write_string(&mut self, val: &str) {
374 self.write_u32(val.len() as u32);
375 self.write_bytes(val.as_bytes());
376 }
377
378 // Read operations
379
380 /// Read a defined amount of raw bytes, or return an IO error if not enough bytes are
381 /// available.
382 /// _Note_: This method resets the read and write cursor for bitwise reading.
383 pub fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
384 self.flush_bits();
385 if self.rpos + size > self.data.len() {
386 return Err(Error::new(
387 ErrorKind::UnexpectedEof,
388 "could not read enough bytes from buffer",
389 ));
390 }
391 let range = self.rpos..self.rpos + size;
392 let mut res = Vec::<u8>::new();
393 res.write_all(&self.data[range])?;
394 self.rpos += size;
395 Ok(res)
396 }
397
398 /// Read one byte, or return an IO error if not enough bytes are available.
399 /// _Note_: This method resets the read and write cursor for bitwise reading.
400 ///
401 /// #Example
402 ///
403 /// ```
404 /// # use bytebuffer::*;
405 /// let mut buffer = ByteBuffer::from_bytes(&vec![0x1]);
406 /// let value = buffer.read_u8().unwrap(); //Value contains 1
407 /// ```
408 pub fn read_u8(&mut self) -> Result<u8> {
409 self.flush_bits();
410 if self.rpos >= self.data.len() {
411 return Err(Error::new(
412 ErrorKind::UnexpectedEof,
413 "could not read enough bits from buffer",
414 ));
415 }
416 let pos = self.rpos;
417 self.rpos += 1;
418 Ok(self.data[pos])
419 }
420
421 /// Same as `read_u8()` but for signed values
422 pub fn read_i8(&mut self) -> Result<i8> {
423 Ok(self.read_u8()? as i8)
424 }
425
426 /// Read a 2-bytes long value, or return an IO error if not enough bytes are available.
427 /// _Note_: This method resets the read and write cursor for bitwise reading.
428 ///
429 /// #Example
430 ///
431 /// ```
432 /// # use bytebuffer::*;
433 /// let mut buffer = ByteBuffer::from_bytes(&vec![0x0, 0x1]);
434 /// let value = buffer.read_u16().unwrap(); //Value contains 1
435 /// ```
436 pub fn read_u16(&mut self) -> Result<u16> {
437 read_number!(self, read_u16, 2)
438 }
439
440 /// Same as `read_u16()` but for signed values
441 /// _Note_: This method resets the read and write cursor for bitwise reading.
442 pub fn read_i16(&mut self) -> Result<i16> {
443 Ok(self.read_u16()? as i16)
444 }
445
446 /// Read a four-bytes long value, or return an IO error if not enough bytes are available.
447 /// _Note_: This method resets the read and write cursor for bitwise reading.
448 ///
449 /// #Example
450 ///
451 /// ```
452 /// # use bytebuffer::*;
453 /// let mut buffer = ByteBuffer::from_bytes(&vec![0x0, 0x0, 0x0, 0x1]);
454 /// let value = buffer.read_u32().unwrap(); // Value contains 1
455 /// ```
456 pub fn read_u32(&mut self) -> Result<u32> {
457 read_number!(self, read_u32, 4)
458 }
459
460 /// Same as `read_u32()` but for signed values
461 /// _Note_: This method resets the read and write cursor for bitwise reading.
462 pub fn read_i32(&mut self) -> Result<i32> {
463 Ok(self.read_u32()? as i32)
464 }
465
466 /// Read an eight bytes long value, or return an IO error if not enough bytes are available.
467 /// _Note_: This method resets the read and write cursor for bitwise reading.
468 ///
469 /// #Example
470 ///
471 /// ```
472 /// # use bytebuffer::*;
473 /// let mut buffer = ByteBuffer::from_bytes(&vec![0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1]);
474 /// let value = buffer.read_u64().unwrap(); //Value contains 1
475 /// ```
476 pub fn read_u64(&mut self) -> Result<u64> {
477 read_number!(self, read_u64, 8)
478 }
479
480 /// Same as `read_u64()` but for signed values
481 /// _Note_: This method resets the read and write cursor for bitwise reading.
482 pub fn read_i64(&mut self) -> Result<i64> {
483 Ok(self.read_u64()? as i64)
484 }
485
486 /// Read a 32 bits floating point value, or return an IO error if not enough bytes are available.
487 /// _Note_: This method resets the read and write cursor for bitwise reading.
488 pub fn read_f32(&mut self) -> Result<f32> {
489 read_number!(self, read_f32, 4)
490 }
491
492 /// Read a 64 bits floating point 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 pub fn read_f64(&mut self) -> Result<f64> {
495 read_number!(self, read_f64, 8)
496 }
497
498 /// Read a string.
499 ///
500 /// _Note_: First it reads a 32 bits value representing the size, then 'size' raw bytes
501 /// that must be encoded as UTF8.
502 /// _Note_: This method resets the read and write cursor for bitwise reading.
503 pub fn read_string(&mut self) -> Result<String> {
504 let size = self.read_u32()?;
505 match String::from_utf8(self.read_bytes(size as usize)?) {
506 Ok(string_result) => Ok(string_result),
507 Err(e) => Err(Error::new(ErrorKind::InvalidData, e)),
508 }
509 }
510
511 // Other
512
513 /// Dump the byte buffer to a string.
514 pub fn to_hex_dump(&self) -> String {
515 let mut str = String::new();
516 for b in &self.data {
517 str = str + &format!("0x{:01$x} ", b, 2);
518 }
519 str.pop();
520 str
521 }
522
523 /// Return the position of the reading cursor
524 pub fn get_rpos(&self) -> usize {
525 self.rpos
526 }
527
528 /// Set the reading cursor position.
529 /// _Note_: Sets the reading cursor to `min(newPosition, self.len())` to prevent overflow
530 pub fn set_rpos(&mut self, rpos: usize) {
531 self.rpos = std::cmp::min(rpos, self.data.len());
532 }
533
534 /// Return the writing cursor position
535 pub fn get_wpos(&self) -> usize {
536 self.wpos
537 }
538
539 /// Set the writing cursor position.
540 /// _Note_: Sets the writing cursor to `min(newPosition, self.len())` to prevent overflow
541 pub fn set_wpos(&mut self, wpos: usize) {
542 self.wpos = std::cmp::min(wpos, self.data.len());
543 }
544
545 /// Return the raw byte buffer bytes.
546 pub fn as_bytes(&self) -> &[u8] {
547 &self.data
548 }
549
550 /// Return the raw byte buffer as a Vec<u8>.
551 pub fn into_bytes(&self) -> Vec<u8> {
552 self.data.to_vec()
553 }
554
555 //Bit manipulation functions
556
557 /// Read 1 bit. Return true if the bit is set to 1, otherwhise, return false.
558 ///
559 /// _Note_: Bits are read from left to right
560 ///
561 /// #Example
562 ///
563 /// ```
564 /// # use bytebuffer::*;
565 /// let mut buffer = ByteBuffer::from_bytes(&vec![128]); // 10000000b
566 /// let value1 = buffer.read_bit().unwrap(); //value1 contains true (eg: bit is 1)
567 /// let value2 = buffer.read_bit().unwrap(); //value2 contains false (eg: bit is 0)
568 /// ```
569 pub fn read_bit(&mut self) -> Result<bool> {
570 if self.rpos >= self.data.len() {
571 return Err(Error::new(
572 ErrorKind::UnexpectedEof,
573 "could not read enough bits from buffer",
574 ));
575 }
576 let bit = self.data[self.rpos] & (1 << (7 - self.rbit)) != 0;
577 self.rbit += 1;
578 if self.rbit > 7 {
579 self.flush_rbits();
580 }
581 Ok(bit)
582 }
583
584 /// Read n bits. an return the corresponding value an u64.
585 ///
586 /// _Note_: We cannot read more than 64 bits
587 ///
588 /// _Note_: Bits are read from left to right
589 ///
590 /// #Example
591 ///
592 /// ```
593 /// # use bytebuffer::*;
594 /// let mut buffer = ByteBuffer::from_bytes(&vec![128]); // 10000000b
595 /// let value = buffer.read_bits(3).unwrap(); // value contains 4 (eg: 100b)
596 /// ```
597 pub fn read_bits(&mut self, n: u8) -> Result<u64> {
598 if n > 64 {
599 return Err(Error::new(
600 ErrorKind::InvalidInput,
601 "cannot read more than 64 bits",
602 ));
603 }
604
605 if n == 0 {
606 Ok(0)
607 } else {
608 Ok((u64::from(self.read_bit()?) << (n - 1)) | self.read_bits(n - 1)?)
609 }
610 }
611
612 /// Discard all the pending bits available for reading or writing and place the corresponding cursor to the next byte.
613 ///
614 /// _Note_: If no bits are currently read or written, this function does nothing.
615 ///
616 /// #Example
617 ///
618 /// ```text
619 /// 10010010 | 00000001
620 /// ^
621 /// 10010010 | 00000001 // read_bit called
622 /// ^
623 /// 10010010 | 00000001 // flush_bit() called
624 /// ^
625 /// ```
626 pub fn flush_bits(&mut self) {
627 if self.rbit > 0 {
628 self.flush_rbits();
629 }
630 if self.wbit > 0 {
631 self.flush_wbits();
632 }
633 }
634
635 fn flush_rbits(&mut self) {
636 self.rpos += 1;
637 self.rbit = 0
638 }
639
640 fn flush_wbits(&mut self) {
641 self.wpos += 1;
642 self.wbit = 0
643 }
644
645 /// Append 1 bit value to the buffer.
646 /// The bit is appended like this :
647 ///
648 /// ```text
649 /// ...| XXXXXXXX | 10000000 |....
650 /// ```
651 pub fn write_bit(&mut self, bit: bool) {
652 let size = self.wpos + 1;
653 if size > self.data.len() {
654 self.resize(size);
655 }
656
657 if bit {
658 self.data[self.wpos] |= 1 << (7 - self.wbit);
659 }
660
661 self.wbit += 1;
662
663 if self.wbit > 7 {
664 self.wbit = 0;
665 self.wpos += 1;
666 }
667 }
668
669 /// Write the given value as a sequence of n bits
670 ///
671 /// #Example
672 ///
673 /// ```
674 /// # use bytebuffer::*;
675 /// let mut buffer = ByteBuffer::new();
676 /// buffer.write_bits(4, 3); // append 100b
677 /// ```
678 pub fn write_bits(&mut self, value: u64, n: u8) {
679 if n > 0 {
680 self.write_bit((value >> (n - 1)) & 1 != 0);
681 self.write_bits(value, n - 1);
682 } else {
683 self.write_bit((value & 1) != 0);
684 }
685 }
686}