hexo_io/
byte_buffer.rs

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    /// Moves the byte buffer to the left by the specified [size]
37    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    /// Moves the byte buffer to the right by the specified [size]
49    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    /// Returns the length of the byte buffer
61    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    /// Clones inner representation of the byte buffer and returns Vec<u8> of it
75    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}