1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use crate::error::{Error, Result};
use std::io;

// Code copied from https://github.com/gimli-rs/leb128/blob/master/src/lib.rs.
// Changing the type from i64 to i128

const CONTINUATION_BIT: u8 = 1 << 7;
const SIGN_BIT: u8 = 1 << 6;

pub fn encode_nat<W>(w: &mut W, mut val: u128) -> Result<()>
where
    W: io::Write + ?Sized,
{
    loop {
        let mut byte = (val & 0x7fu128) as u8;
        val >>= 7;
        if val != 0 {
            byte |= CONTINUATION_BIT;
        }
        let buf = [byte];
        w.write_all(&buf)?;
        if val == 0 {
            return Ok(());
        }
    }
}
pub fn encode_int<W>(w: &mut W, mut val: i128) -> Result<()>
where
    W: io::Write + ?Sized,
{
    loop {
        let mut byte = val as u8;
        val >>= 6;
        let done = val == 0 || val == -1;
        if done {
            byte &= !CONTINUATION_BIT;
        } else {
            val >>= 1;
            byte |= CONTINUATION_BIT;
        }
        let buf = [byte];
        w.write_all(&buf)?;
        if done {
            return Ok(());
        }
    }
}
pub fn decode_nat<R>(r: &mut R) -> Result<u128>
where
    R: io::Read + ?Sized,
{
    let mut result = 0;
    let mut shift = 0;
    loop {
        let mut buf = [0];
        r.read_exact(&mut buf)?;
        if shift == 127 && buf[0] != 0x00 && buf[0] != 0x01 {
            while buf[0] & CONTINUATION_BIT != 0 {
                r.read_exact(&mut buf)?;
            }
            return Err(Error::msg("nat overflow"));
        }
        let low_bits = (buf[0] & !CONTINUATION_BIT) as u128;
        result |= low_bits << shift;
        if buf[0] & CONTINUATION_BIT == 0 {
            return Ok(result);
        }
        shift += 7;
    }
}
pub fn decode_int<R>(r: &mut R) -> Result<i128>
where
    R: io::Read + ?Sized,
{
    let mut result = 0;
    let mut shift = 0;
    let size = 128;
    let mut byte;
    loop {
        let mut buf = [0];
        r.read_exact(&mut buf)?;
        byte = buf[0];
        if shift == 127 && byte != 0x00 && byte != 0x7f {
            while buf[0] & CONTINUATION_BIT != 0 {
                r.read_exact(&mut buf)?;
            }
            return Err(Error::msg("int overflow"));
        }
        let low_bits = (byte & !CONTINUATION_BIT) as i128;
        result |= low_bits << shift;
        shift += 7;
        if byte & CONTINUATION_BIT == 0 {
            break;
        }
    }
    if shift < size && (byte & SIGN_BIT) == SIGN_BIT {
        result |= !0 << shift;
    }
    Ok(result)
}