crabmole/encoding/
binary.rs

1/// Provide const encode functions for uvarint
2pub mod encode;
3
4/// Provide decode functions for uvarint
5pub mod decode;
6
7const U8_LEN: usize = 2;
8const U16_LEN: usize = 3;
9const U32_LEN: usize = 5;
10const U64_LEN: usize = 10;
11const U128_LEN: usize = 19;
12
13#[cfg(target_pointer_width = "64")]
14const USIZE_LEN: usize = U64_LEN;
15
16#[cfg(target_pointer_width = "32")]
17const USIZE_LEN: usize = U32_LEN;
18
19/// The possible size of u8 varint
20#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
21#[repr(u8)]
22pub enum U8Size {
23    /// 1
24    One,
25    /// 2
26    Two,
27}
28
29impl U8Size {
30    /// Returns the val in usize
31    #[inline]
32    pub const fn val(self) -> usize {
33        match self {
34            Self::One => 1,
35            Self::Two => 2,
36        }
37    }
38
39    /// Returns the max size of u8 varint
40    #[inline]
41    pub const fn max() -> Self {
42        Self::Two
43    }
44
45    /// Returns the min size of u8 varint
46    #[inline]
47    pub const fn min() -> Self {
48        Self::One
49    }
50
51    #[inline]
52    const fn from(val: usize) -> Self {
53        match val {
54            1 => Self::One,
55            2 => Self::Two,
56            _ => unreachable!(),
57        }
58    }
59}
60
61/// The possible size of u16 varint
62#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
63#[repr(u8)]
64pub enum U16Size {
65    /// 1
66    One,
67    /// 2
68    Two,
69    /// 3
70    Three,
71}
72
73impl U16Size {
74    /// Returns the val in usize
75    #[inline]
76    pub const fn val(self) -> usize {
77        match self {
78            Self::One => 1,
79            Self::Two => 2,
80            Self::Three => 3,
81        }
82    }
83
84    /// Returns the max size of u16 varint
85    #[inline]
86    pub const fn max() -> Self {
87        Self::Three
88    }
89
90    /// Returns the min size of u16 varint
91    #[inline]
92    pub const fn min() -> Self {
93        Self::One
94    }
95
96    #[inline]
97    const fn from(val: usize) -> Self {
98        match val {
99            1 => Self::One,
100            2 => Self::Two,
101            3 => Self::Three,
102            _ => unreachable!(),
103        }
104    }
105}
106
107/// The possible size of u32 varint
108#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
109#[repr(u8)]
110pub enum U32Size {
111    /// 1
112    One,
113    /// 2
114    Two,
115    /// 3
116    Three,
117    /// 4
118    Four,
119    /// 5
120    Five,
121}
122
123impl U32Size {
124    /// Returns the val in usize
125    #[inline]
126    pub const fn val(self) -> usize {
127        match self {
128            Self::One => 1,
129            Self::Two => 2,
130            Self::Three => 3,
131            Self::Four => 4,
132            Self::Five => 5,
133        }
134    }
135
136    /// Returns the max size of u32 varint
137    #[inline]
138    pub const fn max() -> Self {
139        Self::Five
140    }
141
142    /// Returns the min size of u32 varint
143    #[inline]
144    pub const fn min() -> Self {
145        Self::One
146    }
147
148    #[inline]
149    const fn from(val: usize) -> Self {
150        match val {
151            1 => Self::One,
152            2 => Self::Two,
153            3 => Self::Three,
154            4 => Self::Four,
155            5 => Self::Five,
156            _ => unreachable!(),
157        }
158    }
159}
160
161/// The possible size of u64 varint
162#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
163#[repr(u8)]
164pub enum U64Size {
165    /// 1
166    One,
167    /// 2
168    Two,
169    /// 3
170    Three,
171    /// 4
172    Four,
173    /// 5
174    Five,
175    /// 6
176    Six,
177    /// 7
178    Seven,
179    /// 8
180    Eight,
181    /// 9
182    Nine,
183    /// 10
184    Ten,
185}
186
187impl U64Size {
188    /// Returns the val in usize
189    #[inline]
190    pub const fn val(&self) -> usize {
191        match self {
192            Self::One => 1,
193            Self::Two => 2,
194            Self::Three => 3,
195            Self::Four => 4,
196            Self::Five => 5,
197            Self::Six => 6,
198            Self::Seven => 7,
199            Self::Eight => 8,
200            Self::Nine => 9,
201            Self::Ten => 10,
202        }
203    }
204
205    /// Returns the max size of u64 varint
206    #[inline]
207    pub const fn max() -> Self {
208        Self::Ten
209    }
210
211    /// Returns the min size of u64 varint
212    #[inline]
213    pub const fn min() -> Self {
214        Self::One
215    }
216
217    #[inline]
218    const fn from(val: usize) -> Self {
219        match val {
220            1 => Self::One,
221            2 => Self::Two,
222            3 => Self::Three,
223            4 => Self::Four,
224            5 => Self::Five,
225            6 => Self::Six,
226            7 => Self::Seven,
227            8 => Self::Eight,
228            9 => Self::Nine,
229            10 => Self::Ten,
230            _ => unreachable!(),
231        }
232    }
233}
234
235/// The possible size of u128 varint
236#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
237#[repr(u8)]
238pub enum U128Size {
239    /// 1
240    One,
241    /// 2
242    Two,
243    /// 3
244    Three,
245    /// 4
246    Four,
247    /// 5
248    Five,
249    /// 6
250    Six,
251    /// 7
252    Seven,
253    /// 8
254    Eight,
255    /// 9
256    Nine,
257    /// 10
258    Ten,
259    /// 11
260    Eleven,
261    /// 12
262    Twelve,
263    /// 13
264    Thirteen,
265    /// 14
266    Fourteen,
267    /// 15
268    Fifteen,
269    /// 16
270    Sixteen,
271    /// 17
272    Seventeen,
273    /// 18
274    Eighteen,
275    /// 19
276    Nineteen,
277}
278
279impl U128Size {
280    /// Returns the val in usize
281    #[inline]
282    pub const fn val(&self) -> usize {
283        match self {
284            Self::One => 1,
285            Self::Two => 2,
286            Self::Three => 3,
287            Self::Four => 4,
288            Self::Five => 5,
289            Self::Six => 6,
290            Self::Seven => 7,
291            Self::Eight => 8,
292            Self::Nine => 9,
293            Self::Ten => 10,
294            Self::Eleven => 11,
295            Self::Twelve => 12,
296            Self::Thirteen => 13,
297            Self::Fourteen => 14,
298            Self::Fifteen => 15,
299            Self::Sixteen => 16,
300            Self::Seventeen => 17,
301            Self::Eighteen => 18,
302            Self::Nineteen => 19,
303        }
304    }
305
306    /// Returns the max size of u128 varint
307    #[inline]
308    pub const fn max() -> Self {
309        Self::Nineteen
310    }
311
312    /// Returns the min size of u128 varint
313    #[inline]
314    pub const fn min() -> Self {
315        Self::One
316    }
317
318    #[inline]
319    const fn from(val: usize) -> Self {
320        match val {
321            1 => Self::One,
322            2 => Self::Two,
323            3 => Self::Three,
324            4 => Self::Four,
325            5 => Self::Five,
326            6 => Self::Six,
327            7 => Self::Seven,
328            8 => Self::Eight,
329            9 => Self::Nine,
330            10 => Self::Ten,
331            11 => Self::Eleven,
332            12 => Self::Twelve,
333            13 => Self::Thirteen,
334            14 => Self::Fourteen,
335            15 => Self::Fifteen,
336            16 => Self::Sixteen,
337            17 => Self::Seventeen,
338            18 => Self::Eighteen,
339            19 => Self::Nineteen,
340            _ => unreachable!(),
341        }
342    }
343}
344
345/// The possible size of usize varint
346#[cfg(target_pointer_width = "64")]
347pub type Usize = U64Size;
348
349/// The possible size of usize varint
350#[cfg(target_pointer_width = "32")]
351pub type Usize = U32Size;
352
353/// The maximum length of a varint-encoded N-bit integer.
354const MAX_VARINT_LEN64: usize = 10;
355
356/// Appends the uvarint-encoded form of `x` to the given [`Vec`],
357/// as generated by PutUvarint, to buf and returns the extended buffer.
358#[cfg(feature = "alloc")]
359#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
360#[inline]
361pub fn append_uvarint(mut buf: alloc::vec::Vec<u8>, x: impl Unsigned) -> alloc::vec::Vec<u8> {
362    let mut x = x.to_u64();
363    while x >= 0x80 {
364        buf.push((x as u8) | 0x80);
365        x >>= 7;
366    }
367    buf.push(x as u8);
368    buf
369}
370
371/// Writes the varint-encoded form of `x` to the writer.
372#[cfg(feature = "std")]
373#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
374#[inline]
375pub fn write_uvarint<W: std::io::Write>(
376    mut buf: W,
377    x: impl Unsigned,
378) -> Result<usize, std::io::Error> {
379    let mut x = x.to_u64();
380    let mut n = 0;
381    while x >= 0x80 {
382        n += buf.write(&[(x as u8) | 0x80])?;
383        x >>= 7;
384    }
385    buf.write(&[x as u8]).map(|nn| {
386        n += nn;
387        n
388    })
389}
390
391/// Reads an encoded unsigned integer from r and returns the value and number of bytes readed.
392/// The error is EOF only if no bytes were read.
393#[cfg(feature = "std")]
394#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
395#[inline]
396pub fn read_uvarint<R: std::io::Read, I: Unsigned>(mut r: R) -> std::io::Result<(I, usize)> {
397    let mut x = 0;
398    let mut s = 0;
399    for i in 0..MAX_VARINT_LEN64 {
400        let mut b = [0; 1];
401        r.read_exact(&mut b)?;
402
403        if b[0] < 0x80 {
404            if i == MAX_VARINT_LEN64 - 1 && b[0] > 1 {
405                return Err(std::io::Error::new(
406                    std::io::ErrorKind::Other,
407                    Error::Overflow,
408                ));
409            }
410            return Ok((I::from_u64(x | ((b[0] as u64) << s)), i));
411        }
412        x |= ((b[0] & 0x7f) as u64) << s;
413        s += 7;
414    }
415
416    Err(std::io::Error::new(
417        std::io::ErrorKind::Other,
418        Error::Overflow,
419    ))
420}
421
422/// Encodes a uint64 into buf and returns the number of bytes written.
423///
424/// # Panic
425/// The buffer is too small.
426#[inline]
427pub fn put_uvarint(buf: &mut [u8], x: impl Unsigned) -> usize {
428    let mut i = 0;
429    let mut x = x.to_u64();
430    while x >= 0x80 {
431        buf[i] = (x as u8) | 0x80;
432        x >>= 7;
433        i += 1;
434    }
435    buf[i] = x as u8;
436    i + 1
437}
438
439/// Error
440#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
441pub enum Error {
442    /// Buffer is too small
443    SmallBuffer,
444    /// Overflow 64-bit
445    Overflow,
446}
447
448impl core::fmt::Display for Error {
449    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
450        match self {
451            Self::SmallBuffer => write!(f, "binary: the buffer is too small"),
452            Self::Overflow => write!(f, "binary: varint overflows a 64-bit integer"),
453        }
454    }
455}
456
457#[cfg(feature = "std")]
458impl std::error::Error for Error {}
459
460/// Decodes a unsigned integer from buf and returns that value and the
461/// number of bytes read (> 0).
462#[inline]
463pub fn uvarint<R: Unsigned>(buf: &[u8]) -> Result<(R, usize), Error> {
464    let (mut x, mut s) = (0, 0);
465    for (i, b) in buf.iter().enumerate() {
466        if i == MAX_VARINT_LEN64 {
467            return Err(Error::Overflow);
468        }
469
470        let b = *b;
471        if b < 0x80 {
472            if i == MAX_VARINT_LEN64 - 1 && b > 1 {
473                return Err(Error::Overflow);
474            }
475            return Ok((R::from_u64(x | (b as u64) << s), i + 1));
476        }
477        x |= ((b & 0x7f) as u64) << s;
478        s += 7;
479    }
480    Err(Error::SmallBuffer)
481}
482
483/// Appends the varint-encoded form of `x` to the given [`Vec`],
484/// as generated by PutVarint, to buf and returns the extended buffer.
485#[cfg(feature = "alloc")]
486#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
487#[inline]
488pub fn append_varint(buf: alloc::vec::Vec<u8>, x: impl Signed) -> alloc::vec::Vec<u8> {
489    let x = x.to_i64();
490    let mut ux = (x as u64) << 1;
491    if x < 0 {
492        ux = !ux;
493    }
494    append_uvarint(buf, ux)
495}
496
497/// Writes the varint-encoded form of `x` to the writer.
498#[cfg(feature = "std")]
499#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
500#[inline]
501pub fn write_varint<W: std::io::Write>(buf: W, x: impl Signed) -> std::io::Result<usize> {
502    let x = x.to_i64();
503    let mut ux = (x as u64) << 1;
504    if x < 0 {
505        ux = !ux;
506    }
507    write_uvarint(buf, ux)
508}
509
510/// Reads an encoded unsigned integer from r and returns the value and number of bytes readed.
511/// The error is EOF only if no bytes were read.
512#[cfg(feature = "std")]
513#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
514#[inline]
515pub fn read_varint<R: std::io::Read, I: Signed>(r: R) -> std::io::Result<(I, usize)> {
516    let (ux, readed) = read_uvarint::<R, u64>(r)?;
517    let mut x = (ux >> 1) as i64;
518    if ux & 1 != 0 {
519        x = !x;
520    }
521    Ok((I::from_i64(x), readed))
522}
523
524/// Encodes an integer into buf and returns the number of bytes written.
525///
526/// # Panic
527/// The buffer is too small.
528#[inline]
529pub fn put_varint(buf: &mut [u8], x: impl Signed) -> usize {
530    let x = x.to_i64();
531    let mut ux = (x as u64) << 1;
532    if x < 0 {
533        ux = !ux;
534    }
535    put_uvarint(buf, ux)
536}
537
538/// Decodes an integer from buf and returns that value and the
539/// number of bytes read (> 0).
540#[inline]
541pub fn varint<R: Signed>(buf: &[u8]) -> Result<(R, usize), Error> {
542    let (ux, n) = uvarint::<u64>(buf)?;
543    let mut x = (ux >> 1) as i64;
544    if ux & 1 != 0 {
545        x = !x;
546    }
547    Ok((R::from_i64(x), n))
548}
549
550macro_rules! impl_ {
551    ($trait: ident::<$ret:ident>::$fn: ident::$from_fn: ident { $($x:ident),+ $(,)? }) => {
552        $(
553            impl $trait for $x {
554                fn $fn(&self) -> $ret {
555                    *self as $ret
556                }
557
558                fn $from_fn(val: $ret) -> Self {
559                    val as Self
560                }
561            }
562        )*
563    };
564}
565
566/// A marker trait means this value can be trait as an unsigned integer.
567pub trait Unsigned {
568    /// Converts self to u64
569    fn to_u64(&self) -> u64;
570
571    ///
572    fn from_u64(val: u64) -> Self;
573}
574
575impl_! {
576    Unsigned::<u64>::to_u64::from_u64 {
577        u8,
578        u16,
579        u32,
580        usize,
581        u64,
582        u128,
583    }
584}
585
586/// A marker trait means this value can be trait as a signed integer.
587pub trait Signed {
588    /// Converts self to i64
589    fn to_i64(&self) -> i64;
590
591    ///
592    fn from_i64(val: i64) -> Self;
593}
594
595impl_! {
596    Signed::<i64>::to_i64::from_i64 {
597        i8,
598        i16,
599        i32,
600        isize,
601        i64,
602        i128,
603    }
604}
605
606#[cfg(test)]
607mod tests {
608    use super::*;
609
610    const MAX_VARINT_LEN16: usize = 3;
611    const MAX_VARINT_LEN32: usize = 5;
612
613    fn test_constant(w: u64, max: usize) {
614        let mut buf = vec![0; MAX_VARINT_LEN64];
615        let n = put_uvarint(&mut buf, 1u64 << (w - 1));
616        assert_eq!(n, max);
617    }
618
619    #[test]
620    fn test_constants() {
621        test_constant(16, MAX_VARINT_LEN16);
622        test_constant(32, MAX_VARINT_LEN32);
623        test_constant(64, MAX_VARINT_LEN64);
624    }
625}