binary_util/
io.rs

1use bytes::{Buf, BufMut, Bytes, BytesMut};
2use std::{
3    collections::VecDeque,
4    io::{Error, IoSlice},
5};
6
7use crate::interfaces::{Reader, Writer};
8
9pub const ERR_EOB: &str = "No more bytes left to be read in buffer";
10pub const ERR_EOM: &str = "Buffer is full, cannot write more bytes";
11pub const ERR_VARINT_TOO_LONG: &str = "Varint is too long to be written to buffer";
12
13macro_rules! can_read {
14    ($self: ident, $size: expr) => {
15        $self.buf.remaining() >= $size
16    };
17}
18
19macro_rules! can_write {
20    ($self: ident, $size: expr) => {
21        $self.buf.remaining_mut() >= $size
22    };
23}
24
25macro_rules! read_fn {
26    ($name: ident, $typ: ident, $fn_name: ident, $byte_size: literal) => {
27        #[inline]
28        pub fn $name(&mut self) -> Result<$typ, std::io::Error> {
29            if can_read!(self, $byte_size) {
30                return Ok(self.buf.$fn_name());
31            } else {
32                return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
33            }
34        }
35    };
36}
37
38macro_rules! write_fn {
39    ($name: ident, $typ: ident, $fn_name: ident, $byte_size: literal) => {
40        #[inline]
41        pub fn $name(&mut self, num: $typ) -> Result<(), std::io::Error> {
42            if can_write!(self, $byte_size) {
43                self.buf.$fn_name(num);
44                return Ok(());
45            } else {
46                return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
47            }
48        }
49    };
50}
51
52/// ByteReader is a panic-free way to read bytes from the `byte::Buf` trait.
53///
54/// ## Example
55/// ```rust
56/// use binary_util::io::ByteReader;
57///
58/// fn main() {
59///    let mut buf = ByteReader::from(&[0, 253, 255, 255, 255, 15][..]);
60///    assert_eq!(buf.read_u8().unwrap(), 0);
61///    assert_eq!(buf.read_var_i32().unwrap(), -2147483647);
62/// }
63/// ```
64///
65/// ## Peek Ahead
66/// `ByteReader` also provides a utility `peek_ahead` function that allows you to
67/// "peek ahead" at the next byte in the stream without advancing the stream.
68///
69/// Do not confuse this with any sort of "peek" function. This function does not
70/// increment the read position of the stream, but rather copies the byte at the
71/// specified position.
72/// ```rust
73/// use binary_util::io::ByteReader;
74///
75/// fn main() {
76///    let mut buf = ByteReader::from(&[253, 255, 14, 255, 255, 15][..]);
77///    if buf.peek_ahead(3).unwrap() != 255 {
78///        // buffer is corrupted!
79///    } else {
80///        // read the varint
81///        let num = buf.read_var_i32().unwrap();
82///    }
83/// }
84/// ```
85///
86/// ## Reading a struct without `BinaryDecoder`
87/// This is useful if you are trying to read a struct or optional type and validate the type before
88/// reading the rest of the struct.
89/// ```rust
90/// use binary_util::io::ByteReader;
91///
92/// struct PingPacket {
93///    pub id: u8,
94///    pub time: u64,
95///    pub ack_id: Option<i32>
96/// }
97///
98/// fn main() {
99///     let mut buf = ByteReader::from(&[0, 253, 255, 255, 255, 255, 255, 255, 255, 0][..]);
100///
101///     // Read the id
102///     let id = buf.read_u8().unwrap();
103///
104///     if id == 0 {
105///         // Read the time
106///        let time = buf.read_u64().unwrap();
107///        // read ack
108///        if buf.read_bool().unwrap() {
109///            let ack_id = buf.read_var_i32().unwrap();
110///            let packet = PingPacket { id, time, ack_id: Some(ack_id) };
111///        } else {
112///            let packet = PingPacket { id, time, ack_id: None };
113///        }
114///    }
115/// }
116/// ```
117#[derive(Debug, Clone)]
118pub struct ByteReader {
119    pub(crate) buf: Bytes,
120}
121
122impl From<ByteWriter> for ByteReader {
123    fn from(writer: ByteWriter) -> Self {
124        Self {
125            buf: writer.buf.freeze(),
126        }
127    }
128}
129
130impl Into<Bytes> for ByteReader {
131    fn into(self) -> Bytes {
132        self.buf
133    }
134}
135
136impl Into<Vec<u8>> for ByteReader {
137    fn into(self) -> Vec<u8> {
138        self.buf.to_vec()
139    }
140}
141
142impl Into<VecDeque<u8>> for ByteReader {
143    fn into(self) -> VecDeque<u8> {
144        self.buf.to_vec().into()
145    }
146}
147
148impl From<Bytes> for ByteReader {
149    fn from(buf: Bytes) -> Self {
150        Self { buf }
151    }
152}
153
154impl From<Vec<u8>> for ByteReader {
155    fn from(buf: Vec<u8>) -> Self {
156        Self { buf: buf.into() }
157    }
158}
159
160impl From<&[u8]> for ByteReader {
161    fn from(buf: &[u8]) -> Self {
162        Self {
163            buf: Bytes::from(buf.to_vec()),
164        }
165    }
166}
167
168impl ByteReader {
169    /// `ByteReader` also provides a utility `peek_ahead` function that allows you to
170    /// "peek ahead" at the next byte in the stream without advancing the stream.
171    ///
172    /// Do not confuse this with any sort of "peek" function. This function does not
173    /// increment the read position of the stream, but rather copies the byte at the
174    /// specified position.
175    /// ```rust
176    /// use binary_util::io::ByteReader;
177    ///
178    /// fn main() {
179    ///    let mut buf = ByteReader::from(&[253, 255, 14, 255, 255, 15][..]);
180    ///    if buf.peek_ahead(3).unwrap() != 255 {
181    ///        // buffer is corrupted, varints can never have a leading byte less than 255 if
182    ///        // Their are bytes remaining!
183    ///    } else {
184    ///        // read the varint
185    ///        let num = buf.read_var_i32().unwrap();
186    ///    }
187    /// }
188    /// ```
189    pub fn peek_ahead(&mut self, pos: usize) -> Result<u8, std::io::Error> {
190        if can_read!(self, pos) {
191            return Ok(self.buf.chunk()[pos]);
192        } else {
193            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
194        }
195    }
196
197    read_fn!(read_u8, u8, get_u8, 1);
198    read_fn!(read_i8, i8, get_i8, 1);
199    read_fn!(read_u16, u16, get_u16, 2);
200    read_fn!(read_u16_le, u16, get_u16_le, 2);
201    read_fn!(read_i16, i16, get_i16, 2);
202    read_fn!(read_i16_le, i16, get_i16_le, 2);
203
204    /// Reads a 3-byte unsigned integer from the stream.
205    pub fn read_u24(&mut self) -> Result<u32, std::io::Error> {
206        if can_read!(self, 3) {
207            if let Ok(num) = self.read_uint(3) {
208                dbg!(num);
209                return Ok(num as u32);
210            } else {
211                return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
212            }
213        } else {
214            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
215        }
216    }
217
218    /// Reads a 3-byte unsigned integer from the stream in little endian.
219    /// This is the same as `read_u24` but in little endian.
220    pub fn read_u24_le(&mut self) -> Result<u32, std::io::Error> {
221        if can_read!(self, 3) {
222            if let Ok(num) = self.read_uint_le(3) {
223                return Ok(num as u32);
224            } else {
225                return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
226            }
227        } else {
228            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
229        }
230    }
231
232    pub fn read_i24(&mut self) -> Result<i32, std::io::Error> {
233        if can_read!(self, 3) {
234            if let Ok(num) = self.read_int(3) {
235                return Ok(num as i32);
236            } else {
237                return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
238            }
239        } else {
240            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
241        }
242    }
243
244    pub fn read_i24_le(&mut self) -> Result<i32, std::io::Error> {
245        if can_read!(self, 3) {
246            if let Ok(num) = self.read_int_le(3) {
247                return Ok(num as i32);
248            } else {
249                return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
250            }
251        } else {
252            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
253        }
254    }
255
256    read_fn!(read_u32, u32, get_u32, 4);
257    read_fn!(read_u32_le, u32, get_u32_le, 4);
258    read_fn!(read_f32, f32, get_f32, 4);
259    read_fn!(read_f32_le, f32, get_f32_le, 4);
260
261    /// Reads a var-int 32-bit unsigned integer from the stream.
262    /// This is a variable length integer that can be 1, 2, 3, or 4 bytes long.
263    ///
264    /// This function is recoverable, meaning that if the stream ends before the
265    /// var-int is fully read, it will return an error, and will not consume the
266    /// bytes that were read.
267    #[inline]
268    pub fn read_var_u32(&mut self) -> Result<u32, std::io::Error> {
269        let mut num = 0u32;
270        let mut interval = 0_usize;
271        for i in (0..35).step_by(7) {
272            let byte = self.peek_ahead(interval)?;
273
274            num |= ((byte & 0x7F) as u32) << i;
275            interval += 1;
276
277            if byte & 0x80 == 0 {
278                self.buf.advance(interval);
279                return Ok(num);
280            }
281        }
282        return Err(Error::new(
283            std::io::ErrorKind::Other,
284            "Varint overflow's 32-bit integer",
285        ));
286    }
287
288    read_fn!(read_i32, i32, get_i32, 4);
289    read_fn!(read_i32_le, i32, get_i32_le, 4);
290
291    /// Reads a var-int 32-bit signed integer from the stream.
292    /// This method is the same as `read_var_u32` but it will return a signed integer.
293    pub fn read_var_i32(&mut self) -> Result<i32, std::io::Error> {
294        let num = self.read_var_u32()?;
295
296        Ok((num >> 1) as i32 ^ -((num & 1) as i32))
297    }
298
299    read_fn!(read_u64, u64, get_u64, 8);
300    read_fn!(read_u64_le, u64, get_u64_le, 8);
301    read_fn!(read_i64, i64, get_i64, 8);
302    read_fn!(read_i64_le, i64, get_i64_le, 8);
303    read_fn!(read_f64, f64, get_f64, 8);
304    read_fn!(read_f64_le, f64, get_f64_le, 8);
305
306    /// Reads a var-int 64-bit unsigned integer from the stream.
307    /// This is a variable length integer that can be 1, 2, 3, 4, 5, 6, 7, or 8 bytes long.
308    #[inline]
309    pub fn read_var_u64(&mut self) -> Result<u64, std::io::Error> {
310        let mut num = 0u64;
311        let mut interval = 0_usize;
312        for i in (0..70).step_by(7) {
313            let byte = self.peek_ahead(interval)?;
314
315            num |= ((byte & 0x7F) as u64) << i;
316            interval += 1;
317
318            if byte & 0x80 == 0 {
319                self.buf.advance(interval);
320                return Ok(num);
321            }
322        }
323        return Err(Error::new(
324            std::io::ErrorKind::Other,
325            "Varint overflow's 64-bit integer",
326        ));
327    }
328
329    /// Reads a var-int 64-bit signed integer from the stream.
330    /// This method is the same as `read_var_u64` but it will return a signed integer.
331    ///
332    /// For more information on how this works, see `read_var_i32`.
333    #[inline]
334    pub fn read_var_i64(&mut self) -> Result<i64, std::io::Error> {
335        let num = self.read_var_u64()?;
336        Ok((num >> 1) as i64 ^ -((num & 1) as i64))
337    }
338
339    read_fn!(read_u128, u128, get_u128, 16);
340    read_fn!(read_u128_le, u128, get_u128_le, 16);
341    read_fn!(read_i128, i128, get_i128, 16);
342    read_fn!(read_i128_le, i128, get_i128_le, 16);
343
344    /// Reads an unsigned integer from the stream with a varying size
345    /// indicated by the `size` parameter.
346    pub fn read_uint(&mut self, size: usize) -> Result<u64, std::io::Error> {
347        if can_read!(self, size) {
348            return Ok(self.buf.get_uint(size));
349        } else {
350            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
351        }
352    }
353
354    /// Reads an unsigned integer from the stream with a varying size in little endian
355    /// indicated by the `size` parameter.
356    pub fn read_uint_le(&mut self, size: usize) -> Result<u64, std::io::Error> {
357        if can_read!(self, size) {
358            return Ok(self.buf.get_uint_le(size));
359        } else {
360            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
361        }
362    }
363
364    pub fn read_int(&mut self, size: usize) -> Result<i64, std::io::Error> {
365        if can_read!(self, size) {
366            return Ok(self.buf.get_int(size));
367        } else {
368            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
369        }
370    }
371
372    pub fn read_int_le(&mut self, size: usize) -> Result<i64, std::io::Error> {
373        if can_read!(self, size) {
374            return Ok(self.buf.get_int_le(size));
375        } else {
376            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
377        }
378    }
379
380    pub fn read_char(&mut self) -> Result<char, std::io::Error> {
381        let c = self.read_u32()?;
382
383        if let Some(c) = char::from_u32(c) {
384            return Ok(c);
385        } else {
386            return Err(Error::new(std::io::ErrorKind::InvalidData, "Invalid char"));
387        }
388    }
389
390    pub fn read_bool(&mut self) -> Result<bool, std::io::Error> {
391        if can_read!(self, 1) {
392            return Ok(self.buf.get_u8() != 0);
393        } else {
394            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
395        }
396    }
397
398    /// Reads a string from the stream.
399    /// This is a reversable operation, meaning if it fails,
400    /// the stream will be in the same state as before.
401    pub fn read_string(&mut self) -> Result<String, std::io::Error> {
402        // todo: Make this reversable
403        let len = self.read_var_u64()?;
404        if can_read!(self, len as usize) {
405            let mut string = String::with_capacity(len as usize);
406            unsafe {
407                let v = string.as_mut_vec();
408                v.set_len(len as usize);
409                self.buf.copy_to_slice(&mut v[..]);
410            }
411            return Ok(string);
412        } else {
413            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
414        }
415    }
416
417    /// Reads an `Option` of `T` from the stream.
418    /// `T` must implement the `Reader` trait and be sized.
419    ///
420    /// This operation is not recoverable and will corrupt the stream if it fails.
421    /// If this behavior is desired, you should use `peek_ahead` when implementing
422    /// the `Reader` trait.
423    ///
424    /// # Example
425    /// ```rust
426    /// use binary_util::io::ByteReader;
427    /// use binary_util::interfaces::Reader;
428    ///
429    /// pub struct HelloWorld {
430    ///     pub magic: u32
431    /// }
432    ///
433    /// impl Reader<HelloWorld> for HelloWorld {
434    ///     fn read(reader: &mut ByteReader) -> Result<HelloWorld, std::io::Error> {
435    ///         Ok(HelloWorld {
436    ///             magic: reader.read_u32()?
437    ///         })
438    ///     }
439    /// }
440    ///
441    /// fn main() {
442    ///     // Nothing is here!
443    ///     let mut reader = ByteReader::from(&[0x00][..]);
444    ///     let hello_world = reader.read_option::<HelloWorld>().unwrap();
445    ///     assert_eq!(hello_world.is_some(), false);
446    /// }
447    /// ```
448    pub fn read_option<T: Reader<T>>(&mut self) -> Result<Option<T>, std::io::Error> {
449        if self.read_bool()? {
450            return Ok(Some(T::read(self)?));
451        } else {
452            return Ok(None);
453        }
454    }
455
456    /// Reads a varu32 sized slice from the stream.
457    /// For reading a slice of raw bytes, use `read` instead.
458    pub fn read_sized_slice(&mut self) -> Result<Bytes, std::io::Error> {
459        let len = self.read_var_u32()?;
460
461        if can_read!(self, len as usize) {
462            let b = self.buf.slice(..len as usize);
463            self.buf.advance(len as usize);
464            return Ok(b);
465        } else {
466            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
467        }
468    }
469
470    /// Reads a slice from the stream into the slice passed by the caller.
471    /// For reading a prefixed sized slice, use `read_sized_slice` instead.
472    pub fn read(&mut self, buffer: &mut [u8]) -> Result<(), std::io::Error> {
473        if can_read!(self, buffer.len()) {
474            self.buf.copy_to_slice(buffer);
475            return Ok(());
476        } else {
477            return Err(Error::new(std::io::ErrorKind::UnexpectedEof, ERR_EOB));
478        }
479    }
480
481    /// Reads `T` from the stream.
482    /// `T` must implement the `Reader` trait and be sized.
483    ///
484    /// # Deprecrated
485    ///
486    /// This function is deprecated and will be removed in `v0.3.4`.
487    #[deprecated(note = "Use `read_type` instead")]
488    pub fn read_struct<T: Reader<T>>(&mut self) -> Result<T, std::io::Error> {
489        return self.read_type::<T>();
490    }
491
492    /// Reads `T` from the stream.
493    /// `T` must implement the `Reader` trait and be sized.
494    pub fn read_type<T: Reader<T>>(&mut self) -> Result<T, std::io::Error> {
495        return T::read(self);
496    }
497
498    /// Returns the remaining bytes in the stream.
499    pub fn as_slice(&self) -> &[u8] {
500        self.buf.chunk()
501    }
502}
503
504/// ByteWriter is a panic-free way to write bytes to a `BufMut` trait.
505///
506/// ## Example
507/// A generic example of how to use the `ByteWriter` struct.
508/// ```rust
509/// use binary_util::io::ByteWriter;
510/// use binary_util::io::ByteReader;
511///
512/// fn main() {
513///    let mut writer = ByteWriter::new();
514///    writer.write_string("Hello World!").unwrap();
515///    writer.write_var_u32(65536).unwrap();
516///    writer.write_u8(0).unwrap();
517///
518///    println!("Bytes: {:?}", writer.as_slice());
519/// }
520/// ```
521///
522/// `ByteWriter` also implements the `Into` trait to convert the `ByteWriter` into a `BytesMut` or `Bytes` structs.
523/// ```rust
524/// use binary_util::io::ByteWriter;
525/// use binary_util::io::ByteReader;
526///
527/// fn main() {
528///     let mut writer = ByteWriter::new();
529///     writer.write_u8(1);
530///     writer.write_u8(2);
531///     writer.write_u8(3);
532///
533///     let mut reader: ByteReader = writer.into();
534///     assert_eq!(reader.read_u8().unwrap(), 1);
535///     assert_eq!(reader.read_u8().unwrap(), 2);
536///     assert_eq!(reader.read_u8().unwrap(), 3);
537/// }
538/// ```
539///
540/// #### ByteWriter Implementation Notice
541/// While most of the methods are reversable, some are not.
542/// Meaning there is a chance that if you call a method in a edge case, it will corrupt the stream.
543///
544/// For example, `write_var_u32` is not reversable because we currently do not
545/// allocate a buffer to store the bytes before writing them to the buffer.
546/// While you should never encounter this issue, it is possible when you run out of memory.
547/// This issue is marked as a todo, but is low priority.
548#[derive(Debug, Clone)]
549pub struct ByteWriter {
550    pub(crate) buf: BytesMut,
551}
552
553impl Into<BytesMut> for ByteWriter {
554    fn into(self) -> BytesMut {
555        self.buf
556    }
557}
558
559impl Into<Bytes> for ByteWriter {
560    fn into(self) -> Bytes {
561        self.buf.freeze()
562    }
563}
564
565impl Into<Vec<u8>> for ByteWriter {
566    fn into(self) -> Vec<u8> {
567        self.buf.to_vec()
568    }
569}
570
571impl Into<VecDeque<u8>> for ByteWriter {
572    fn into(self) -> VecDeque<u8> {
573        self.buf.to_vec().into()
574    }
575}
576
577impl From<IoSlice<'_>> for ByteWriter {
578    fn from(slice: IoSlice) -> Self {
579        let mut buf = BytesMut::with_capacity(slice.len());
580        buf.put_slice(&slice);
581        return Self { buf };
582    }
583}
584
585impl From<&[u8]> for ByteWriter {
586    fn from(slice: &[u8]) -> Self {
587        let mut buf = BytesMut::with_capacity(slice.len());
588        buf.put_slice(slice);
589        return Self { buf };
590    }
591}
592
593impl From<ByteReader> for ByteWriter {
594    fn from(reader: ByteReader) -> Self {
595        Self {
596            buf: reader.buf.chunk().into(),
597        }
598    }
599}
600
601impl ByteWriter {
602    pub fn new() -> Self {
603        return Self {
604            buf: BytesMut::new(),
605        };
606    }
607
608    write_fn!(write_u8, u8, put_u8, 1);
609    write_fn!(write_i8, i8, put_i8, 1);
610    write_fn!(write_u16, u16, put_u16, 2);
611    write_fn!(write_u16_le, u16, put_u16_le, 2);
612    write_fn!(write_i16, i16, put_i16, 2);
613    write_fn!(write_i16_le, i16, put_i16_le, 2);
614
615    pub fn write_u24<I: Into<u32>>(&mut self, num: I) -> Result<(), std::io::Error> {
616        return self.write_uint(num.into().into(), 3);
617    }
618
619    pub fn write_u24_le<I: Into<u32>>(&mut self, num: I) -> Result<(), std::io::Error> {
620        return self.write_uint_le(num.into().into(), 3);
621    }
622
623    pub fn write_i24<I: Into<i32>>(&mut self, num: I) -> Result<(), std::io::Error> {
624        return self.write_int(num.into().into(), 3);
625    }
626
627    pub fn write_i24_le<I: Into<i32>>(&mut self, num: I) -> Result<(), std::io::Error> {
628        return self.write_int_le(num.into().into(), 3);
629    }
630
631    write_fn!(write_u32, u32, put_u32, 4);
632    write_fn!(write_u32_le, u32, put_u32_le, 4);
633    write_fn!(write_i32, i32, put_i32, 4);
634    write_fn!(write_i32_le, i32, put_i32_le, 4);
635    write_fn!(write_f32, f32, put_f32, 4);
636    write_fn!(write_f32_le, f32, put_f32_le, 4);
637
638    // todo: write_var_u32, write_var_i32 should be reversable and should not corrupt the stream on failure
639    pub fn write_var_u32(&mut self, num: u32) -> Result<(), std::io::Error> {
640        let mut x = num;
641        while x >= 0x80 {
642            self.write_u8((x as u8) | 0x80)?;
643            x >>= 7;
644        }
645        self.write_u8(x as u8)?;
646        return Ok(());
647    }
648
649    pub fn write_var_i32(&mut self, num: i32) -> Result<(), std::io::Error> {
650        return if num < 0 {
651            let num = num as u32;
652            self.write_var_u32(!(num << 1))
653        } else {
654            let num = num as u32;
655            self.write_var_u32(num << 1)
656        };
657    }
658
659    write_fn!(write_u64, u64, put_u64, 8);
660    write_fn!(write_u64_le, u64, put_u64_le, 8);
661    write_fn!(write_i64, i64, put_i64, 8);
662    write_fn!(write_i64_le, i64, put_i64_le, 8);
663    write_fn!(write_f64, f64, put_f64, 8);
664    write_fn!(write_f64_le, f64, put_f64_le, 8);
665
666    pub fn write_var_u64(&mut self, num: u64) -> Result<(), std::io::Error> {
667        let mut x = (num as u64) & u64::MAX;
668        for _ in (0..70).step_by(7) {
669            if x >> 7 == 0 {
670                self.write_u8(x as u8)?;
671                return Ok(());
672            } else {
673                self.write_u8(((x & 0x7F) | 0x80) as u8)?;
674                x >>= 7;
675            }
676        }
677
678        return Err(Error::new(
679            std::io::ErrorKind::InvalidData,
680            ERR_VARINT_TOO_LONG,
681        ));
682    }
683
684    pub fn write_var_i64(&mut self, num: i64) -> Result<(), std::io::Error> {
685        return if num < 0 {
686            let num = num as u64;
687            self.write_var_u64(!(num << 1))
688        } else {
689            let num = num as u64;
690            self.write_var_u64(num << 1)
691        };
692    }
693
694    write_fn!(write_u128, u128, put_u128, 16);
695    write_fn!(write_u128_le, u128, put_u128_le, 16);
696    write_fn!(write_i128, i128, put_i128, 16);
697    write_fn!(write_i128_le, i128, put_i128_le, 16);
698
699    pub fn write_uint(&mut self, num: u64, size: usize) -> Result<(), std::io::Error> {
700        if can_write!(self, size) {
701            self.buf.put_uint(num, size);
702            return Ok(());
703        } else {
704            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
705        }
706    }
707
708    pub fn write_uint_le(&mut self, num: u64, size: usize) -> Result<(), std::io::Error> {
709        if can_write!(self, size) {
710            self.buf.put_uint_le(num, size);
711            return Ok(());
712        } else {
713            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
714        }
715    }
716
717    pub fn write_int(&mut self, num: i64, size: usize) -> Result<(), std::io::Error> {
718        if can_write!(self, size) {
719            self.buf.put_int(num, size);
720            return Ok(());
721        } else {
722            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
723        }
724    }
725
726    pub fn write_int_le(&mut self, num: i64, size: usize) -> Result<(), std::io::Error> {
727        if can_write!(self, size) {
728            self.buf.put_int_le(num, size);
729            return Ok(());
730        } else {
731            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
732        }
733    }
734
735    pub fn write_char(&mut self, c: char) -> Result<(), std::io::Error> {
736        self.write_u32(c as u32)
737    }
738
739    pub fn write_bool(&mut self, b: bool) -> Result<(), std::io::Error> {
740        if can_write!(self, 1) {
741            self.buf.put_u8(b as u8);
742            return Ok(());
743        } else {
744            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
745        }
746    }
747
748    /// Write a string to the buffer
749    /// The string is written as a var_u32 length followed by the bytes of the string.
750    /// Uses <https://protobuf.dev/programming-guides/encoding/#length-types> for length encoding
751    pub fn write_string(&mut self, string: &str) -> Result<(), std::io::Error> {
752        // https://protobuf.dev/programming-guides/encoding/#length-types
753        if can_write!(self, string.len()) {
754            self.write_var_u32(string.len() as u32)?;
755            self.buf.put_slice(string.as_bytes());
756            return Ok(());
757        } else {
758            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
759        }
760    }
761
762    /// Writes an `Option` to the buffer. The option must implement the `Writer` trait.
763    ///
764    /// ## Example
765    /// ```rust
766    /// use binary_util::io::ByteWriter;
767    /// use binary_util::interfaces::Writer;
768    ///
769    /// pub struct HelloWorld {
770    ///     pub magic: u32
771    /// }
772    ///
773    /// impl Writer for HelloWorld {
774    ///     fn write(&self, buf: &mut ByteWriter) -> Result<(), std::io::Error> {
775    ///         buf.write_u32(self.magic)?;
776    ///         return Ok(());
777    ///     }
778    /// }
779    ///
780    /// fn main() {
781    ///     let hello = HelloWorld { magic: 0xCAFEBABE };
782    ///     let mut buf = hello.write_to_bytes().unwrap();
783    ///
784    ///     println!("Hello World: {:?}", buf);
785    /// }
786    /// ```
787    pub fn write_option(&mut self, option: &Option<impl Writer>) -> Result<(), std::io::Error> {
788        if let Some(option) = option {
789            self.write_bool(true)?;
790            option.write(self)?;
791        } else {
792            self.write_bool(false)?;
793        }
794        return Ok(());
795    }
796
797    /// Writes a size-prefixed slice of bytes to the buffer. The slice is prefixed with a var_u32 length.
798    pub fn write_slice(&mut self, slice: &[u8]) -> Result<(), std::io::Error> {
799        if can_write!(self, slice.len()) {
800            self.write_var_u32(slice.len() as u32)?;
801            self.buf.put_slice(slice);
802            return Ok(());
803        } else {
804            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
805        }
806    }
807
808    /// Writes a slice of bytes to the buffer
809    /// This is not the same as a size-prefixed slice, this is just a raw slice of bytes.
810    ///
811    /// For automatically size-prefixed slices, use `write_slice`.
812    pub fn write(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
813        if can_write!(self, buf.len()) {
814            self.buf.put_slice(buf);
815            return Ok(());
816        } else {
817            return Err(Error::new(std::io::ErrorKind::OutOfMemory, ERR_EOM));
818        }
819    }
820
821    /// Writes `T` to the buffer. `T` must implement the `Writer` trait.
822    /// This is the same as calling `T.write(self)`.
823    /// ```rust
824    /// use binary_util::interfaces::{Reader, Writer};
825    /// use binary_util::io::{ByteReader, ByteWriter};
826    ///
827    /// pub struct HelloPacket {
828    ///     pub name: String,
829    ///     pub age: u8,
830    ///     pub is_cool: bool,
831    ///     pub friends: Vec<String>,
832    /// }
833    ///
834    /// impl Reader<HelloPacket> for HelloPacket {
835    ///     fn read(buf: &mut ByteReader) -> std::io::Result<Self> {
836    ///         Ok(Self {
837    ///             name: buf.read_string()?,
838    ///             age: buf.read_u8()?,
839    ///             is_cool: buf.read_bool()?,
840    ///             friends: Vec::<String>::read(buf)?
841    ///         })
842    ///     }
843    /// }
844    ///
845    /// impl Writer for HelloPacket {
846    ///     fn write(&self, buf: &mut ByteWriter) -> std::io::Result<()> {
847    ///         buf.write_string(&self.name);
848    ///         buf.write_u8(self.age);
849    ///         buf.write_bool(self.is_cool);
850    ///         self.friends.write(buf)?;
851    ///         Ok(())
852    ///     }
853    /// }
854    ///
855    /// fn main() {
856    ///     let mut buf = ByteWriter::new();
857    ///     let packet = HelloPacket {
858    ///         name: "John".to_string(),
859    ///         age: 18,
860    ///         is_cool: true,
861    ///         friends: vec!["Bob".to_string(), "Joe".to_string()]
862    ///     };
863    ///     buf.write_type(&packet).unwrap();
864    /// }
865    /// ```
866    pub fn write_type<T: Writer>(&mut self, t: &T) -> Result<(), std::io::Error> {
867        t.write(self)
868    }
869
870    pub fn as_slice(&self) -> &[u8] {
871        self.buf.chunk()
872    }
873
874    pub fn clear(&mut self) {
875        self.buf.clear();
876    }
877}