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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
use crate::binary;
use core::panic;
use std::mem::MaybeUninit;

#[derive(Default)]
pub struct Cursor<'a> {
    pub buf: &'a [u8],
    pub next: usize,
}

impl<'a> Cursor<'a> {
    pub fn new(buf: &'a [u8]) -> Cursor<'a> {
        Cursor { buf, next: 0 }
    }

    pub fn has_content(&self) -> bool {
        self.next != self.buf.len()
    }
}

impl<'a, R> From<&'a R> for Cursor<'a>
where
    R: AsRef<[u8]>,
{
    fn from(buf: &'a R) -> Self {
        Self::new(buf.as_ref())
    }
}

impl<'a> Read for Cursor<'a> {
    /// Read a single byte.
    fn read_u8(&mut self) -> u8 {
        let b = self.buf[self.next];
        self.next += 1;
        b
    }

    /// Take a slice of the next `len` bytes and advance the position by `len`.
    fn read(&mut self, len: usize) -> &[u8] {
        let slice = &self.buf[self.next..(self.next + len)];
        self.next += len as usize;
        slice
    }
}

pub trait Read {
    /// Read a single byte.
    fn read_u8(&mut self) -> u8;

    fn read(&mut self, len: usize) -> &[u8];

    /// Read a variable length buffer.
    fn read_buf(&mut self) -> &[u8] {
        let len: u32 = self.read_uvar();
        self.read(len as usize)
    }

    /// Read 2 bytes as unsigned integer
    fn read_u16(&mut self) -> u16 {
        self.read_u8() as u16 | ((self.read_u8() as u16) << 8)
    }

    /// Read 4 bytes as unsigned integer
    fn read_u32(&mut self) -> u32 {
        self.read_u8() as u32
            | (self.read_u8() as u32) << 8
            | (self.read_u8() as u32) << 16
            | (self.read_u8() as u32) << 24
    }

    /// Read 4 bytes as unsigned integer in big endian order.
    /// (most significant byte first)
    fn read_u32_be(&mut self) -> u32 {
        (self.read_u8() as u32) << 24
            | (self.read_u8() as u32) << 16
            | (self.read_u8() as u32) << 8
            | self.read_u8() as u32
    }

    /// Read unsigned integer with variable length.
    /// * numbers < 2^7 are stored in one byte
    /// * numbers < 2^14 are stored in two bytes
    // @todo currently, only 32 bits supported
    fn read_uvar<T: crate::number::Uint>(&mut self) -> T {
        let mut num: T = Default::default();
        let mut len: usize = 0;
        loop {
            let r = self.read_u8();
            num.unshift_add(len, r & binary::BITS7);
            len += 7;
            if r < binary::BIT8 {
                return num;
            }
            if len > 128 {
                panic!("Integer out of range!");
            }
        }
    }

    /// Read signed integer with variable length.
    /// * numbers < 2^7 are stored in one byte
    /// * numbers < 2^14 are stored in two bytes
    // @todo currently, only 32 bits supported
    fn read_ivar(&mut self) -> i64 {
        let mut r = self.read_u8();
        let mut num = (r & binary::BITS6 as u8) as i64;
        let mut len: u32 = 6;
        let is_negative = r & binary::BIT7 as u8 > 0;
        if r & binary::BIT8 as u8 == 0 {
            return if is_negative { -num } else { num };
        }
        loop {
            r = self.read_u8();
            num |= (r as i64 & binary::BITS7 as i64) << len;
            len += 7;
            if r < binary::BIT8 as u8 {
                return if is_negative { -num } else { num };
            }
            if len > 128 {
                panic!("Integer out of range!");
            }
        }
    }

    /// Read string of variable length.
    fn read_string(&mut self) -> &str {
        let buf = self.read_buf();
        unsafe { std::str::from_utf8_unchecked(buf) }
    }

    /// Read float32 in big endian order
    fn read_f32(&mut self) -> f32 {
        let buf = [
            self.read_u8(),
            self.read_u8(),
            self.read_u8(),
            self.read_u8(),
        ];
        f32::from_be_bytes(buf)
    }

    /// Read float64 in big endian order
    // @todo there must be a more elegant way to convert a slice to a fixed-length buffer.
    fn read_f64(&mut self) -> f64 {
        let mut bytes = init_buf();
        bytes.clone_from_slice(self.read(8));
        f64::from_be_bytes(bytes)
    }

    /// Read BigInt64 in big endian order
    fn read_i64(&mut self) -> i64 {
        let mut bytes = init_buf();
        bytes.clone_from_slice(self.read(8));
        i64::from_be_bytes(bytes)
    }

    /// read BigUInt64 in big endian order
    fn read_u64(&mut self) -> u64 {
        let mut bytes = init_buf();
        bytes.clone_from_slice(self.read(8));
        u64::from_be_bytes(bytes)
    }
}

/// Create non-zeroed fixed array of 8-bytes and returns it.
/// Since it's not zeroed it should be filled before use.
#[inline(always)]
fn init_buf() -> [u8; 8] {
    unsafe {
        let b: [MaybeUninit<u8>; 8] = MaybeUninit::uninit().assume_init();
        std::mem::transmute::<_, [u8; 8]>(b)
    }
}