azalea_buf/impls/
primitives.rs

1use std::io::{self, Cursor, Read, Write};
2
3use byteorder::{BE, ReadBytesExt, WriteBytesExt};
4use tracing::warn;
5
6use crate::{AzBuf, AzBufVar, BufReadError};
7
8impl AzBuf for () {
9    fn azalea_read(_buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
10        Ok(())
11    }
12    fn azalea_write(&self, _buf: &mut impl Write) -> io::Result<()> {
13        Ok(())
14    }
15}
16
17impl AzBuf for i32 {
18    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
19        Ok(buf.read_i32::<BE>()?)
20    }
21    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
22        buf.write_i32::<BE>(*self)
23    }
24}
25
26impl AzBufVar for i32 {
27    /// Read a single varint from the reader and return the value
28    fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
29        // fast varint impl based on https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67
30        let mut buffer = [0];
31        let mut ans = 0;
32        for i in 0..5 {
33            buf.read_exact(&mut buffer)?;
34            ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i);
35            if buffer[0] & 0b1000_0000 == 0 {
36                break;
37            }
38        }
39        Ok(ans)
40    }
41
42    fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
43        let mut buffer = [0];
44        let mut value = *self;
45        if value == 0 {
46            buf.write_all(&buffer)?;
47        }
48        while value != 0 {
49            buffer[0] = (value & 0b0111_1111) as u8;
50            value = (value >> 7) & (i32::MAX >> 6);
51            if value != 0 {
52                buffer[0] |= 0b1000_0000;
53            }
54            buf.write_all(&buffer)?;
55        }
56        Ok(())
57    }
58}
59
60impl AzBufVar for i64 {
61    fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
62        let mut buffer = [0];
63        let mut ans = 0;
64        for i in 0..10 {
65            buf.read_exact(&mut buffer)
66                .map_err(|_| BufReadError::InvalidVarLong)?;
67            ans |= ((buffer[0] & 0b0111_1111) as i64) << (7 * i);
68            if buffer[0] & 0b1000_0000 == 0 {
69                break;
70            }
71        }
72        Ok(ans)
73    }
74
75    fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
76        let mut buffer = [0];
77        let mut value = *self;
78        if value == 0 {
79            buf.write_all(&buffer).unwrap();
80        }
81        while value != 0 {
82            buffer[0] = (value & 0b0111_1111) as u8;
83            value = (value >> 7) & (i64::MAX >> 6);
84            if value != 0 {
85                buffer[0] |= 0b1000_0000;
86            }
87            buf.write_all(&buffer)?;
88        }
89        Ok(())
90    }
91}
92
93impl AzBufVar for u64 {
94    fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
95        i64::azalea_read_var(buf).map(|i| i as u64)
96    }
97    fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
98        i64::azalea_write_var(&(*self as i64), buf)
99    }
100}
101
102impl AzBuf for u32 {
103    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
104        Ok(i32::azalea_read(buf)? as u32)
105    }
106    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
107        i32::azalea_write(&(*self as i32), buf)
108    }
109}
110
111impl AzBufVar for u32 {
112    fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
113        Ok(i32::azalea_read_var(buf)? as u32)
114    }
115    fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
116        i32::azalea_write_var(&(*self as i32), buf)
117    }
118}
119
120impl AzBuf for u16 {
121    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
122        i16::azalea_read(buf).map(|i| i as u16)
123    }
124    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
125        i16::azalea_write(&(*self as i16), buf)
126    }
127}
128
129impl AzBuf for i16 {
130    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
131        Ok(buf.read_i16::<BE>()?)
132    }
133    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
134        buf.write_i16::<BE>(*self)
135    }
136}
137
138impl AzBufVar for u16 {
139    fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
140        Ok(i32::azalea_read_var(buf)? as u16)
141    }
142    fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
143        i32::azalea_write_var(&(*self as i32), buf)
144    }
145}
146
147impl AzBuf for i64 {
148    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
149        Ok(buf.read_i64::<BE>()?)
150    }
151    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
152        buf.write_i64::<BE>(*self)
153    }
154}
155
156impl AzBuf for u64 {
157    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
158        i64::azalea_read(buf).map(|i| i as u64)
159    }
160    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
161        buf.write_u64::<BE>(*self)
162    }
163}
164
165impl AzBuf for bool {
166    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
167        let byte = u8::azalea_read(buf)?;
168        if byte > 1 {
169            warn!("Boolean value was not 0 or 1, but {byte}");
170        }
171        Ok(byte != 0)
172    }
173    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
174        let byte = u8::from(*self);
175        byte.azalea_write(buf)
176    }
177}
178
179impl AzBuf for u8 {
180    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
181        Ok(buf.read_u8()?)
182    }
183    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
184        buf.write_u8(*self)
185    }
186}
187
188impl AzBuf for i8 {
189    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
190        u8::azalea_read(buf).map(|i| i as i8)
191    }
192    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
193        (*self as u8).azalea_write(buf)
194    }
195}
196
197impl AzBuf for f32 {
198    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
199        Ok(buf.read_f32::<BE>()?)
200    }
201    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
202        buf.write_f32::<BE>(*self)
203    }
204}
205
206impl AzBuf for f64 {
207    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
208        Ok(buf.read_f64::<BE>()?)
209    }
210    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
211        buf.write_f64::<BE>(*self)
212    }
213}