1use std::fmt::{Debug, Formatter};
2use std::string::FromUtf8Error;
3
4#[derive(Clone)]
5pub struct ByteBuffer {
6 inner: Vec<u8>,
7}
8
9impl Debug for ByteBuffer {
10 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
11 f.write_str(&format!("{:?}", self.inner))
12 }
13}
14
15impl ByteBuffer {
16 pub fn new() -> Self {
17 ByteBuffer { inner: Vec::new() }
18 }
19
20 pub fn push_byte(&mut self, byte: u8) {
21 self.inner.push(byte);
22 }
23
24 pub fn push_string(&mut self, string: String) {
25 self.inner.extend_from_slice(string.as_bytes());
26 }
27
28 pub fn push_u32_shrunk(&mut self, num: u32) {
29 self.inner.extend(Self::_to_shrunk_bytes(num));
30 }
31
32 pub fn push_byte_buffer(&mut self, other: &ByteBuffer) {
33 self.inner.extend(other.to_vec());
34 }
35
36 pub fn pad_left(&mut self, size: usize) {
38 let padding = size.checked_sub(self.inner.len());
39 if let Some(padding) = padding {
40 if padding > 0 {
41 let mut padding_vec = vec![0; padding];
42 padding_vec.append(&mut self.inner);
43 self.inner = padding_vec;
44 }
45 }
46 }
47
48 pub fn pad_right(&mut self, size: usize) {
50 let padding = size.checked_sub(self.inner.len());
51
52 if let Some(padding) = padding {
53 if padding > 0 {
54 let mut padding_vec = vec![0; padding];
55 self.inner.append(padding_vec.as_mut());
56 }
57 }
58 }
59
60 pub fn len(&self) -> usize {
62 self.inner.len()
63 }
64
65 pub fn as_usize_unsafe(&self) -> usize {
66 let mut padded = self.clone();
67 padded.pad_left(4);
68 ((padded.inner[0] as usize) << 24)
69 + ((padded.inner[1] as usize) << 16)
70 + ((padded.inner[2] as usize) << 8)
71 + (padded.inner[3] as usize)
72 }
73
74 pub fn to_vec(&self) -> Vec<u8> {
76 self.inner.clone()
77 }
78
79 pub fn to_string(&self) -> Result<String, FromUtf8Error> {
80 String::from_utf8(self.inner.clone())
81 }
82
83 fn _to_shrunk_bytes(value: u32) -> Vec<u8> {
84 let mut bytes = Vec::new();
85 let mut value = value;
86 while value > 0 {
87 bytes.push((value & 0xFF) as u8);
88 value >>= 8;
89 }
90 bytes
91 }
92}
93
94impl From<Vec<u8>> for ByteBuffer {
95 fn from(value: Vec<u8>) -> Self {
96 ByteBuffer { inner: value }
97 }
98}
99
100mod test {
101 use crate::byte_buffer::ByteBuffer;
102
103 #[test]
104 fn byte_push() {
105 let mut buffer = ByteBuffer::new();
106 buffer.push_byte(0x01);
107 buffer.push_byte(0x02);
108
109 assert_eq!(buffer.len(), 2);
110
111 assert_eq!(buffer.to_vec(), vec![0x01, 0x02]);
112 }
113
114 #[test]
115 fn string_push() {
116 let mut buffer = ByteBuffer::new();
117 buffer.push_string("hello world".to_string());
118
119 assert_eq!(buffer.len(), 11);
120
121 assert_eq!(
122 buffer.to_vec(),
123 vec![104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
124 );
125 }
126
127 #[test]
128 fn u32_push() {
129 let mut buffer = ByteBuffer::new();
130 buffer.push_u32_shrunk(13);
131
132 assert_eq!(buffer.len(), 1);
133
134 assert_eq!(buffer.to_vec(), vec![13]);
135 }
136}