Skip to main content

gaia_binary/
lib.rs

1#![warn(missing_docs)]
2//! Binary encoding and decoding for Gaia project.
3
4pub mod reader;
5pub mod traits;
6pub mod writer;
7
8use std::{
9    io::{Read, Write},
10    marker::PhantomData,
11};
12
13pub use reader::BinaryReader;
14pub use traits::BinaryFormat;
15pub use writer::BinaryWriter;
16
17/// A reader wrapper that tracks position.
18#[derive(Debug)]
19pub struct TrackingReader<R: Read> {
20    /// Inner reader.
21    pub inner: R,
22    /// Current position.
23    pub position: u64,
24}
25
26impl<R: Read> Read for TrackingReader<R> {
27    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
28        let n = self.inner.read(buf)?;
29        self.position += n as u64;
30        Ok(n)
31    }
32}
33
34impl<R: Read + std::io::Seek> std::io::Seek for TrackingReader<R> {
35    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
36        self.position = self.inner.seek(pos)?;
37        Ok(self.position)
38    }
39}
40
41/// A writer wrapper that tracks position.
42#[derive(Debug)]
43pub struct TrackingWriter<W: Write> {
44    /// Inner writer.
45    pub inner: W,
46    /// Current position.
47    pub position: u64,
48}
49
50impl<W: Write + std::io::Seek> std::io::Seek for TrackingWriter<W> {
51    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
52        self.position = self.inner.seek(pos)?;
53        Ok(self.position)
54    }
55}
56
57impl<W: Write> Write for TrackingWriter<W> {
58    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
59        let n = self.inner.write(buf)?;
60        self.position += n as u64;
61        Ok(n)
62    }
63
64    fn flush(&mut self) -> std::io::Result<()> {
65        self.inner.flush()
66    }
67}
68
69/// Byte order traits.
70pub trait ByteOrder {
71    /// Read u16.
72    fn read_u16(buf: &[u8]) -> u16;
73    /// Read u32.
74    fn read_u32(buf: &[u8]) -> u32;
75    /// Read u64.
76    fn read_u64(buf: &[u8]) -> u64;
77    /// Write u16.
78    fn write_u16(buf: &mut [u8], n: u16);
79    /// Write u32.
80    fn write_u32(buf: &mut [u8], n: u32);
81    /// Write u64.
82    fn write_u64(buf: &mut [u8], n: u64);
83}
84
85/// Big endian implementation.
86pub struct BigEndian;
87impl ByteOrder for BigEndian {
88    fn read_u16(buf: &[u8]) -> u16 {
89        u16::from_be_bytes(buf.try_into().unwrap())
90    }
91    fn read_u32(buf: &[u8]) -> u32 {
92        u32::from_be_bytes(buf.try_into().unwrap())
93    }
94    fn read_u64(buf: &[u8]) -> u64 {
95        u64::from_be_bytes(buf.try_into().unwrap())
96    }
97    fn write_u16(buf: &mut [u8], n: u16) {
98        buf.copy_from_slice(&n.to_be_bytes())
99    }
100    fn write_u32(buf: &mut [u8], n: u32) {
101        buf.copy_from_slice(&n.to_be_bytes())
102    }
103    fn write_u64(buf: &mut [u8], n: u64) {
104        buf.copy_from_slice(&n.to_be_bytes())
105    }
106}
107
108/// Little endian implementation.
109pub struct LittleEndian;
110impl ByteOrder for LittleEndian {
111    fn read_u16(buf: &[u8]) -> u16 {
112        u16::from_le_bytes(buf.try_into().unwrap())
113    }
114    fn read_u32(buf: &[u8]) -> u32 {
115        u32::from_le_bytes(buf.try_into().unwrap())
116    }
117    fn read_u64(buf: &[u8]) -> u64 {
118        u64::from_le_bytes(buf.try_into().unwrap())
119    }
120    fn write_u16(buf: &mut [u8], n: u16) {
121        buf.copy_from_slice(&n.to_le_bytes())
122    }
123    fn write_u32(buf: &mut [u8], n: u32) {
124        buf.copy_from_slice(&n.to_le_bytes())
125    }
126    fn write_u64(buf: &mut [u8], n: u64) {
127        buf.copy_from_slice(&n.to_le_bytes())
128    }
129}
130
131/// Fixed-size encoding with a specific byte order.
132pub struct Fixed<E: ByteOrder>(PhantomData<E>);
133
134impl<E: ByteOrder> BinaryFormat for Fixed<E> {
135    fn read_u16<R: Read>(reader: &mut R) -> std::io::Result<u16> {
136        let mut buf = [0u8; 2];
137        reader.read_exact(&mut buf)?;
138        Ok(E::read_u16(&buf))
139    }
140    fn write_u16<W: Write>(writer: &mut W, value: u16) -> std::io::Result<()> {
141        let mut buf = [0u8; 2];
142        E::write_u16(&mut buf, value);
143        writer.write_all(&buf)
144    }
145    fn read_u32<R: Read>(reader: &mut R) -> std::io::Result<u32> {
146        let mut buf = [0u8; 4];
147        reader.read_exact(&mut buf)?;
148        Ok(E::read_u32(&buf))
149    }
150    fn write_u32<W: Write>(writer: &mut W, value: u32) -> std::io::Result<()> {
151        let mut buf = [0u8; 4];
152        E::write_u32(&mut buf, value);
153        writer.write_all(&buf)
154    }
155    fn read_u64<R: Read>(reader: &mut R) -> std::io::Result<u64> {
156        let mut buf = [0u8; 8];
157        reader.read_exact(&mut buf)?;
158        Ok(E::read_u64(&buf))
159    }
160    fn write_u64<W: Write>(writer: &mut W, value: u64) -> std::io::Result<()> {
161        let mut buf = [0u8; 8];
162        E::write_u64(&mut buf, value);
163        writer.write_all(&buf)
164    }
165    fn read_i16<R: Read>(reader: &mut R) -> std::io::Result<i16> {
166        Ok(Self::read_u16(reader)? as i16)
167    }
168    fn write_i16<W: Write>(writer: &mut W, value: i16) -> std::io::Result<()> {
169        Self::write_u16(writer, value as u16)
170    }
171    fn read_i32<R: Read>(reader: &mut R) -> std::io::Result<i32> {
172        Ok(Self::read_u32(reader)? as i32)
173    }
174    fn write_i32<W: Write>(writer: &mut W, value: i32) -> std::io::Result<()> {
175        Self::write_u32(writer, value as u32)
176    }
177    fn read_i64<R: Read>(reader: &mut R) -> std::io::Result<i64> {
178        Ok(Self::read_u64(reader)? as i64)
179    }
180    fn write_i64<W: Write>(writer: &mut W, value: i64) -> std::io::Result<()> {
181        Self::write_u64(writer, value as u64)
182    }
183    fn read_f32<R: Read>(reader: &mut R) -> std::io::Result<f32> {
184        Ok(f32::from_bits(Self::read_u32(reader)?))
185    }
186    fn write_f32<W: Write>(writer: &mut W, value: f32) -> std::io::Result<()> {
187        Self::write_u32(writer, value.to_bits())
188    }
189    fn read_f64<R: Read>(reader: &mut R) -> std::io::Result<f64> {
190        Ok(f64::from_bits(Self::read_u64(reader)?))
191    }
192    fn write_f64<W: Write>(writer: &mut W, value: f64) -> std::io::Result<()> {
193        Self::write_u64(writer, value.to_bits())
194    }
195}
196
197/// Extension trait for reading binary data.
198pub trait ReadBytesExt: Read {
199    /// Read a u16 value.
200    fn read_u16<T: ByteOrder>(&mut self) -> std::io::Result<u16> {
201        let mut buf = [0u8; 2];
202        self.read_exact(&mut buf)?;
203        Ok(T::read_u16(&buf))
204    }
205    /// Read a u32 value.
206    fn read_u32<T: ByteOrder>(&mut self) -> std::io::Result<u32> {
207        let mut buf = [0u8; 4];
208        self.read_exact(&mut buf)?;
209        Ok(T::read_u32(&buf))
210    }
211    /// Read a u64 value.
212    fn read_u64<T: ByteOrder>(&mut self) -> std::io::Result<u64> {
213        let mut buf = [0u8; 8];
214        self.read_exact(&mut buf)?;
215        Ok(T::read_u64(&buf))
216    }
217    /// Read an i16 value.
218    fn read_i16<T: ByteOrder>(&mut self) -> std::io::Result<i16> {
219        Ok(self.read_u16::<T>()? as i16)
220    }
221    /// Read an i32 value.
222    fn read_i32<T: ByteOrder>(&mut self) -> std::io::Result<i32> {
223        Ok(self.read_u32::<T>()? as i32)
224    }
225    /// Read an i64 value.
226    fn read_i64<T: ByteOrder>(&mut self) -> std::io::Result<i64> {
227        Ok(self.read_u64::<T>()? as i64)
228    }
229    /// Read an f32 value.
230    fn read_f32<T: ByteOrder>(&mut self) -> std::io::Result<f32> {
231        Ok(f32::from_bits(self.read_u32::<T>()?))
232    }
233    /// Read an f64 value.
234    fn read_f64<T: ByteOrder>(&mut self) -> std::io::Result<f64> {
235        Ok(f64::from_bits(self.read_u64::<T>()?))
236    }
237    /// Read a u8 value.
238    fn read_u8(&mut self) -> std::io::Result<u8> {
239        let mut buf = [0u8; 1];
240        self.read_exact(&mut buf)?;
241        Ok(buf[0])
242    }
243    /// Read an i8 value.
244    fn read_i8(&mut self) -> std::io::Result<i8> {
245        Ok(self.read_u8()? as i8)
246    }
247}
248
249impl<R: Read + ?Sized> ReadBytesExt for R {}
250
251/// Extension trait for writing binary data.
252pub trait WriteBytesExt: Write {
253    /// Write a u16 value.
254    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> std::io::Result<()> {
255        let mut buf = [0u8; 2];
256        T::write_u16(&mut buf, n);
257        self.write_all(&buf)
258    }
259    /// Write a u32 value.
260    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> std::io::Result<()> {
261        let mut buf = [0u8; 4];
262        T::write_u32(&mut buf, n);
263        self.write_all(&buf)
264    }
265    /// Write a u64 value.
266    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> std::io::Result<()> {
267        let mut buf = [0u8; 8];
268        T::write_u64(&mut buf, n);
269        self.write_all(&buf)
270    }
271    /// Write an i16 value.
272    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> std::io::Result<()> {
273        self.write_u16::<T>(n as u16)
274    }
275    /// Write an i32 value.
276    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> std::io::Result<()> {
277        self.write_u32::<T>(n as u32)
278    }
279    /// Write an i64 value.
280    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> std::io::Result<()> {
281        self.write_u64::<T>(n as u64)
282    }
283    /// Write an f32 value.
284    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> std::io::Result<()> {
285        self.write_u32::<T>(n.to_bits())
286    }
287    /// Write an f64 value.
288    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> std::io::Result<()> {
289        self.write_u64::<T>(n.to_bits())
290    }
291    /// Write a u8 value.
292    fn write_u8(&mut self, n: u8) -> std::io::Result<()> {
293        self.write_all(&[n])
294    }
295    /// Write an i8 value.
296    fn write_i8(&mut self, n: i8) -> std::io::Result<()> {
297        self.write_u8(n as u8)
298    }
299}
300
301impl<W: Write + ?Sized> WriteBytesExt for W {}
302
303/// Variable-length encoding (LEB128).
304pub struct Leb128<E: ByteOrder = LittleEndian>(PhantomData<E>);
305
306impl<E: ByteOrder> BinaryFormat for Leb128<E> {
307    fn read_u16<R: Read>(reader: &mut R) -> std::io::Result<u16> {
308        Ok(read_u32_leb128(reader)? as u16)
309    }
310    fn write_u16<W: Write>(writer: &mut W, value: u16) -> std::io::Result<()> {
311        write_u32_leb128(writer, value as u32)
312    }
313    fn read_u32<R: Read>(reader: &mut R) -> std::io::Result<u32> {
314        read_u32_leb128(reader)
315    }
316    fn write_u32<W: Write>(writer: &mut W, value: u32) -> std::io::Result<()> {
317        write_u32_leb128(writer, value)
318    }
319    fn read_u64<R: Read>(reader: &mut R) -> std::io::Result<u64> {
320        read_u64_leb128(reader)
321    }
322    fn write_u64<W: Write>(writer: &mut W, value: u64) -> std::io::Result<()> {
323        write_u64_leb128(writer, value)
324    }
325    fn read_i16<R: Read>(reader: &mut R) -> std::io::Result<i16> {
326        Fixed::<E>::read_i16(reader)
327    }
328    fn write_i16<W: Write>(writer: &mut W, value: i16) -> std::io::Result<()> {
329        Fixed::<E>::write_i16(writer, value)
330    }
331    fn read_i32<R: Read>(reader: &mut R) -> std::io::Result<i32> {
332        read_i32_leb128(reader)
333    }
334    fn write_i32<W: Write>(writer: &mut W, value: i32) -> std::io::Result<()> {
335        write_i32_leb128(writer, value)
336    }
337    fn read_i64<R: Read>(reader: &mut R) -> std::io::Result<i64> {
338        read_i64_leb128(reader)
339    }
340    fn write_i64<W: Write>(writer: &mut W, value: i64) -> std::io::Result<()> {
341        write_i64_leb128(writer, value)
342    }
343    fn read_f32<R: Read>(reader: &mut R) -> std::io::Result<f32> {
344        Fixed::<E>::read_f32(reader)
345    }
346    fn write_f32<W: Write>(writer: &mut W, value: f32) -> std::io::Result<()> {
347        Fixed::<E>::write_f32(writer, value)
348    }
349    fn read_f64<R: Read>(reader: &mut R) -> std::io::Result<f64> {
350        Fixed::<E>::read_f64(reader)
351    }
352    fn write_f64<W: Write>(writer: &mut W, value: f64) -> std::io::Result<()> {
353        Fixed::<E>::write_f64(writer, value)
354    }
355}
356
357/// ZigZag transformation wrapper for signed integers.
358pub struct ZigZag<F: BinaryFormat>(PhantomData<F>);
359
360impl<F: BinaryFormat> BinaryFormat for ZigZag<F> {
361    fn read_u16<R: Read>(reader: &mut R) -> std::io::Result<u16> {
362        F::read_u16(reader)
363    }
364    fn write_u16<W: Write>(writer: &mut W, value: u16) -> std::io::Result<()> {
365        F::write_u16(writer, value)
366    }
367    fn read_u32<R: Read>(reader: &mut R) -> std::io::Result<u32> {
368        F::read_u32(reader)
369    }
370    fn write_u32<W: Write>(writer: &mut W, value: u32) -> std::io::Result<()> {
371        F::write_u32(writer, value)
372    }
373    fn read_u64<R: Read>(reader: &mut R) -> std::io::Result<u64> {
374        F::read_u64(reader)
375    }
376    fn write_u64<W: Write>(writer: &mut W, value: u64) -> std::io::Result<()> {
377        F::write_u64(writer, value)
378    }
379
380    fn read_i16<R: Read>(reader: &mut R) -> std::io::Result<i16> {
381        let val = F::read_u16(reader)?;
382        Ok(((val >> 1) as i16) ^ -((val & 1) as i16))
383    }
384    fn write_i16<W: Write>(writer: &mut W, value: i16) -> std::io::Result<()> {
385        let val = ((value << 1) ^ (value >> 15)) as u16;
386        F::write_u16(writer, val)
387    }
388
389    fn read_i32<R: Read>(reader: &mut R) -> std::io::Result<i32> {
390        let val = F::read_u32(reader)?;
391        Ok(((val >> 1) as i32) ^ -((val & 1) as i32))
392    }
393    fn write_i32<W: Write>(writer: &mut W, value: i32) -> std::io::Result<()> {
394        let val = ((value << 1) ^ (value >> 31)) as u32;
395        F::write_u32(writer, val)
396    }
397
398    fn read_i64<R: Read>(reader: &mut R) -> std::io::Result<i64> {
399        let val = F::read_u64(reader)?;
400        Ok(((val >> 1) as i64) ^ -((val & 1) as i64))
401    }
402    fn write_i64<W: Write>(writer: &mut W, value: i64) -> std::io::Result<()> {
403        let val = ((value << 1) ^ (value >> 63)) as u64;
404        F::write_u64(writer, val)
405    }
406
407    fn read_f32<R: Read>(reader: &mut R) -> std::io::Result<f32> {
408        F::read_f32(reader)
409    }
410    fn write_f32<W: Write>(writer: &mut W, value: f32) -> std::io::Result<()> {
411        F::write_f32(writer, value)
412    }
413    fn read_f64<R: Read>(reader: &mut R) -> std::io::Result<f64> {
414        F::read_f64(reader)
415    }
416    fn write_f64<W: Write>(writer: &mut W, value: f64) -> std::io::Result<()> {
417        F::write_f64(writer, value)
418    }
419}
420
421/// Read an i64 from LEB128 encoding.
422pub fn read_i64_leb128<R: Read>(reader: &mut R) -> std::io::Result<i64> {
423    let val = read_u64_leb128(reader)?;
424    Ok(((val >> 1) as i64) ^ -((val & 1) as i64))
425}
426
427/// Write an i64 to LEB128 encoding.
428pub fn write_i64_leb128<W: Write>(writer: &mut W, value: i64) -> std::io::Result<()> {
429    let val = ((value << 1) ^ (value >> 63)) as u64;
430    write_u64_leb128(writer, val)
431}
432
433/// Read a u32 from LEB128 encoding.
434pub fn read_u32_leb128<R: Read>(reader: &mut R) -> std::io::Result<u32> {
435    let mut result = 0;
436    let mut shift = 0;
437    loop {
438        let mut buf = [0u8; 1];
439        reader.read_exact(&mut buf)?;
440        let byte = buf[0];
441        result |= ((byte & 0x7F) as u32) << shift;
442        if byte & 0x80 == 0 {
443            break;
444        }
445        shift += 7;
446    }
447    Ok(result)
448}
449
450/// Write a u32 to LEB128 encoding.
451pub fn write_u32_leb128<W: Write>(writer: &mut W, mut value: u32) -> std::io::Result<()> {
452    loop {
453        let mut byte = (value & 0x7F) as u8;
454        value >>= 7;
455        if value != 0 {
456            byte |= 0x80;
457        }
458        writer.write_all(&[byte])?;
459        if value == 0 {
460            break;
461        }
462    }
463    Ok(())
464}
465
466/// Read a u64 from LEB128 encoding.
467pub fn read_u64_leb128<R: Read>(reader: &mut R) -> std::io::Result<u64> {
468    let mut result = 0;
469    let mut shift = 0;
470    loop {
471        let mut buf = [0u8; 1];
472        reader.read_exact(&mut buf)?;
473        let byte = buf[0];
474        result |= ((byte & 0x7F) as u64) << shift;
475        if byte & 0x80 == 0 {
476            break;
477        }
478        shift += 7;
479    }
480    Ok(result)
481}
482
483/// Write a u64 to LEB128 encoding.
484pub fn write_u64_leb128<W: Write>(writer: &mut W, mut value: u64) -> std::io::Result<()> {
485    loop {
486        let mut byte = (value & 0x7F) as u8;
487        value >>= 7;
488        if value != 0 {
489            byte |= 0x80;
490        }
491        writer.write_all(&[byte])?;
492        if value == 0 {
493            break;
494        }
495    }
496    Ok(())
497}
498
499/// Read an i32 from LEB128 encoding.
500pub fn read_i32_leb128<R: Read>(reader: &mut R) -> std::io::Result<i32> {
501    let val = read_u32_leb128(reader)?;
502    Ok(((val >> 1) as i32) ^ -((val & 1) as i32))
503}
504
505/// Write an i32 to LEB128 encoding.
506pub fn write_i32_leb128<W: Write>(writer: &mut W, value: i32) -> std::io::Result<()> {
507    let val = ((value << 1) ^ (value >> 31)) as u32;
508    write_u32_leb128(writer, val)
509}