oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1use crate::encoding::varint::{Signed, SignedVarInt, VarInt};
2use std::any::type_name;
3use std::collections::TryReserveError;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
7pub enum Error {
8 #[error("failed to decode variable length integer")]
9 InvalidVarInt,
10
11 #[error("while trying to read more data (expected: {0} bytes), an unexpected end of buffer was reached")]
12 EndOfBuffer(usize),
13
14 #[error("while reading, an unexpected value was found")]
15 UnexpectedValue,
16
17 #[error("failed to allocate memory: {0}")]
18 NotEnoughMemory(#[from] TryReserveError),
19
20 #[error("JSON parsing error: {0}")]
21 InvalidJSON(#[from] serde_json::Error),
22
23 #[error("couldn't deserialize to target type of {0}")]
24 TypeMismatch(&'static str),
25
26 #[error("{0}")]
27 Custom(String),
28}
29
30impl Error {
31 pub fn type_mismatch<T>() -> Self {
32 Error::TypeMismatch(type_name::<T>())
33 }
34}
35
36#[derive(Default)]
37pub struct Cursor<'a> {
38 pub buf: &'a [u8],
39 pub next: usize,
40}
41
42impl<'a> Cursor<'a> {
43 pub fn new(buf: &'a [u8]) -> Cursor<'a> {
44 Cursor { buf, next: 0 }
45 }
46
47 pub fn has_content(&self) -> bool {
48 self.next != self.buf.len()
49 }
50}
51
52impl<'a, R> From<&'a R> for Cursor<'a>
53where
54 R: AsRef<[u8]>,
55{
56 fn from(buf: &'a R) -> Self {
57 Self::new(buf.as_ref())
58 }
59}
60
61impl<'a> Read for Cursor<'a> {
62 /// Take a slice of the next `len` bytes and advance the position by `len`.
63 fn read_exact(&mut self, len: usize) -> Result<&[u8], Error> {
64 if self.next + len > self.buf.len() {
65 Err(Error::EndOfBuffer(len))
66 } else {
67 let slice = &self.buf[self.next..(self.next + len)];
68 self.next += len as usize;
69 Ok(slice)
70 }
71 }
72
73 /// Read a single byte.
74 fn read_u8(&mut self) -> Result<u8, Error> {
75 if let Some(&b) = self.buf.get(self.next) {
76 self.next += 1;
77 Ok(b)
78 } else {
79 Err(Error::EndOfBuffer(1))
80 }
81 }
82}
83
84pub trait Read: Sized {
85 fn read_exact(&mut self, len: usize) -> Result<&[u8], Error>;
86
87 /// Read a single byte.
88 fn read_u8(&mut self) -> Result<u8, Error> {
89 let buf = self.read_exact(1)?;
90 Ok(buf[0])
91 }
92
93 /// Read a variable length buffer.
94 fn read_buf(&mut self) -> Result<&[u8], Error> {
95 let len: u32 = self.read_var()?;
96 self.read_exact(len as usize)
97 }
98
99 /// Read 2 bytes as unsigned integer
100 fn read_u16(&mut self) -> Result<u16, Error> {
101 let buf = self.read_exact(2)?;
102 Ok(buf[0] as u16 | ((buf[1] as u16) << 8))
103 }
104
105 /// Read 4 bytes as unsigned integer
106 fn read_u32(&mut self) -> Result<u32, Error> {
107 let buf = self.read_exact(4)?;
108 Ok(buf[0] as u32 | (buf[1] as u32) << 8 | (buf[2] as u32) << 16 | (buf[3] as u32) << 24)
109 }
110
111 /// Read 4 bytes as unsigned integer in big endian order.
112 /// (most significant byte first)
113 fn read_u32_be(&mut self) -> Result<u32, Error> {
114 let buf = self.read_exact(4)?;
115 Ok((buf[0] as u32) << 24 | (buf[1] as u32) << 16 | (buf[2] as u32) << 8 | buf[3] as u32)
116 }
117
118 /// Read unsigned integer with variable length.
119 /// * numbers < 2^7 are stored in one byte
120 /// * numbers < 2^14 are stored in two bytes
121 #[inline]
122 fn read_var<T: VarInt>(&mut self) -> Result<T, Error> {
123 T::read(self)
124 }
125
126 /// Read unsigned integer with variable length.
127 /// * numbers < 2^7 are stored in one byte
128 /// * numbers < 2^14 are stored in two bytes
129 #[inline]
130 fn read_var_signed<T: SignedVarInt>(&mut self) -> Result<Signed<T>, Error> {
131 T::read_signed(self)
132 }
133
134 /// Read string of variable length.
135 fn read_string(&mut self) -> Result<&str, Error> {
136 let buf = self.read_buf()?;
137 Ok(unsafe { std::str::from_utf8_unchecked(buf) })
138 }
139
140 /// Read float32 in big endian order
141 fn read_f32(&mut self) -> Result<f32, Error> {
142 let mut buf = [0; 4];
143 let slice = self.read_exact(4)?;
144 buf.copy_from_slice(slice);
145 Ok(f32::from_be_bytes(buf))
146 }
147
148 /// Read float64 in big endian order
149 // @todo there must be a more elegant way to convert a slice to a fixed-length buffer.
150 fn read_f64(&mut self) -> Result<f64, Error> {
151 let mut buf = [0; 8];
152 let slice = self.read_exact(8)?;
153 buf.copy_from_slice(slice);
154 Ok(f64::from_be_bytes(buf))
155 }
156
157 /// Read BigInt64 in big endian order
158 fn read_i64(&mut self) -> Result<i64, Error> {
159 let mut buf = [0; 8];
160 let slice = self.read_exact(8)?;
161 buf.copy_from_slice(slice);
162 Ok(i64::from_be_bytes(buf))
163 }
164
165 /// read BigUInt64 in big endian order
166 fn read_u64(&mut self) -> Result<u64, Error> {
167 let mut buf = [0; 8];
168 let slice = self.read_exact(8)?;
169 buf.copy_from_slice(slice);
170 Ok(u64::from_be_bytes(buf))
171 }
172}
173