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
use crate::error::Error;
use crate::number::{Signed, SignedVarInt, VarInt};

#[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> {
    /// Take a slice of the next `len` bytes and advance the position by `len`.
    fn read_exact(&mut self, len: usize) -> Result<&[u8], Error> {
        if self.next + len > self.buf.len() {
            Err(Error::EndOfBuffer(len))
        } else {
            let slice = &self.buf[self.next..(self.next + len)];
            self.next += len as usize;
            Ok(slice)
        }
    }

    /// Read a single byte.
    fn read_u8(&mut self) -> Result<u8, Error> {
        if let Some(&b) = self.buf.get(self.next) {
            self.next += 1;
            Ok(b)
        } else {
            Err(Error::EndOfBuffer(1))
        }
    }
}

pub trait Read: Sized {
    fn read_exact(&mut self, len: usize) -> Result<&[u8], Error>;

    /// Read a single byte.
    fn read_u8(&mut self) -> Result<u8, Error> {
        let buf = self.read_exact(1)?;
        Ok(buf[0])
    }

    /// Read a variable length buffer.
    fn read_buf(&mut self) -> Result<&[u8], Error> {
        let len: u32 = self.read_var()?;
        self.read_exact(len as usize)
    }

    /// Read 2 bytes as unsigned integer
    fn read_u16(&mut self) -> Result<u16, Error> {
        let buf = self.read_exact(2)?;
        Ok(buf[0] as u16 | ((buf[1] as u16) << 8))
    }

    /// Read 4 bytes as unsigned integer
    fn read_u32(&mut self) -> Result<u32, Error> {
        let buf = self.read_exact(4)?;
        Ok(buf[0] as u32 | (buf[1] as u32) << 8 | (buf[2] as u32) << 16 | (buf[3] as u32) << 24)
    }

    /// Read 4 bytes as unsigned integer in big endian order.
    /// (most significant byte first)
    fn read_u32_be(&mut self) -> Result<u32, Error> {
        let buf = self.read_exact(4)?;
        Ok((buf[0] as u32) << 24 | (buf[1] as u32) << 16 | (buf[2] as u32) << 8 | buf[3] as u32)
    }

    /// Read unsigned integer with variable length.
    /// * numbers < 2^7 are stored in one byte
    /// * numbers < 2^14 are stored in two bytes
    #[inline]
    fn read_var<T: VarInt>(&mut self) -> Result<T, Error> {
        T::read(self)
    }

    /// Read unsigned integer with variable length.
    /// * numbers < 2^7 are stored in one byte
    /// * numbers < 2^14 are stored in two bytes
    #[inline]
    fn read_var_signed<T: SignedVarInt>(&mut self) -> Result<Signed<T>, Error> {
        T::read_signed(self)
    }

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

    /// Read float32 in big endian order
    fn read_f32(&mut self) -> Result<f32, Error> {
        let mut buf = [0; 4];
        let slice = self.read_exact(4)?;
        buf.copy_from_slice(slice);
        Ok(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) -> Result<f64, Error> {
        let mut buf = [0; 8];
        let slice = self.read_exact(8)?;
        buf.copy_from_slice(slice);
        Ok(f64::from_be_bytes(buf))
    }

    /// Read BigInt64 in big endian order
    fn read_i64(&mut self) -> Result<i64, Error> {
        let mut buf = [0; 8];
        let slice = self.read_exact(8)?;
        buf.copy_from_slice(slice);
        Ok(i64::from_be_bytes(buf))
    }

    /// read BigUInt64 in big endian order
    fn read_u64(&mut self) -> Result<u64, Error> {
        let mut buf = [0; 8];
        let slice = self.read_exact(8)?;
        buf.copy_from_slice(slice);
        Ok(u64::from_be_bytes(buf))
    }
}