1use crate::decoding::Read;
2use crate::encoding::Write;
3use crate::error::Error;
4use std::convert::TryInto;
5use std::mem::size_of;
6
7pub const F64_MAX_SAFE_INTEGER: f64 = (i64::pow(2, 53) - 1) as f64;
8pub const F64_MIN_SAFE_INTEGER: f64 = -F64_MAX_SAFE_INTEGER;
9
10pub trait VarInt: Sized + Copy {
11 fn write<W: Write>(&self, w: &mut W);
12 fn read<R: Read>(r: &mut R) -> Result<Self, Error>;
13}
14
15impl VarInt for usize {
16 #[inline]
17 fn write<W: Write>(&self, w: &mut W) {
18 write_var_u64(*self as u64, w)
19 }
20
21 #[inline]
22 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
23 Ok(read_var_u64(r)? as Self)
24 }
25}
26
27impl VarInt for u128 {
28 fn write<W: Write>(&self, w: &mut W) {
29 let mut value = *self;
30 while value >= 0b10000000 {
31 let b = ((value & 0b01111111) as u8) | 0b10000000;
32 w.write_u8(b);
33 value = value >> 7;
34 }
35
36 w.write_u8((value & 0b01111111) as u8)
37 }
38
39 #[inline]
40 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
41 let mut num = 0u128;
42 let mut len: usize = 0;
43 loop {
44 let r = r.read_u8()?;
45 num |= u128::wrapping_shl((r & 0b01111111) as u128, len as u32);
46 len += 7;
47 if r < 0b10000000 {
48 return Ok(num);
49 }
50 if len > 180 {
51 return Err(Error::VarIntSizeExceeded(180));
52 }
53 }
54 }
55}
56
57impl VarInt for u64 {
58 #[inline]
59 fn write<W: Write>(&self, w: &mut W) {
60 write_var_u64(*self, w)
61 }
62
63 #[inline]
64 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
65 read_var_u64(r)
66 }
67}
68
69impl VarInt for u32 {
70 #[inline]
71 fn write<W: Write>(&self, w: &mut W) {
72 write_var_u32(*self, w)
73 }
74
75 #[inline]
76 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
77 read_var_u32(r)
78 }
79}
80
81impl VarInt for u16 {
82 #[inline]
83 fn write<W: Write>(&self, w: &mut W) {
84 write_var_u32(*self as u32, w)
85 }
86
87 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
88 let value = read_var_u32(r)?;
89 if let Ok(value) = value.try_into() {
90 Ok(value)
91 } else {
92 Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
93 }
94 }
95}
96
97impl VarInt for u8 {
98 #[inline]
99 fn write<W: Write>(&self, w: &mut W) {
100 write_var_u32(*self as u32, w)
101 }
102
103 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
104 let value = read_var_u32(r)?;
105 if let Ok(value) = value.try_into() {
106 Ok(value)
107 } else {
108 Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
109 }
110 }
111}
112
113impl VarInt for isize {
114 #[inline]
115 fn write<W: Write>(&self, w: &mut W) {
116 write_var_i64(*self as i64, w)
117 }
118
119 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
120 let value = read_var_i64(r)?;
121 if let Ok(value) = value.try_into() {
122 Ok(value)
123 } else {
124 Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
125 }
126 }
127}
128
129impl VarInt for i64 {
130 #[inline]
131 fn write<W: Write>(&self, w: &mut W) {
132 write_var_i64(*self, w)
133 }
134
135 #[inline]
136 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
137 read_var_i64(r)
138 }
139}
140
141impl VarInt for i32 {
142 #[inline]
143 fn write<W: Write>(&self, w: &mut W) {
144 write_var_i64(*self as i64, w)
145 }
146
147 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
148 let value = read_var_i64(r)?;
149 if let Ok(value) = value.try_into() {
150 Ok(value)
151 } else {
152 Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
153 }
154 }
155}
156
157impl VarInt for i16 {
158 #[inline]
159 fn write<W: Write>(&self, w: &mut W) {
160 write_var_i64(*self as i64, w)
161 }
162
163 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
164 let value = read_var_i64(r)?;
165 if let Ok(value) = value.try_into() {
166 Ok(value)
167 } else {
168 Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
169 }
170 }
171}
172
173impl VarInt for i8 {
174 #[inline]
175 fn write<W: Write>(&self, w: &mut W) {
176 write_var_i64(*self as i64, w)
177 }
178
179 fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
180 let value = read_var_i64(r)?;
181 if let Ok(value) = value.try_into() {
182 Ok(value)
183 } else {
184 Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
185 }
186 }
187}
188
189fn write_var_u32<W: Write>(mut value: u32, w: &mut W) {
190 while value >= 0b10000000 {
191 let b = ((value & 0b01111111) as u8) | 0b10000000;
192 w.write_u8(b);
193 value = value >> 7;
194 }
195
196 w.write_u8((value & 0b01111111) as u8)
197}
198
199fn write_var_u64<W: Write>(mut value: u64, w: &mut W) {
200 while value >= 0b10000000 {
201 let b = ((value & 0b01111111) as u8) | 0b10000000;
202 w.write_u8(b);
203 value = value >> 7;
204 }
205
206 w.write_u8((value & 0b01111111) as u8)
207}
208
209fn write_var_i64<W: Write>(mut value: i64, w: &mut W) {
210 let is_negative = value < 0;
211 value = if is_negative { -value } else { value };
212 w.write_u8(
213 (if value > 0b00111111 as i64 { 0b10000000 as u8 } else { 0 })
215 | (if is_negative { 0b01000000 as u8 } else { 0 })
217 | (0b00111111 as i64 & value) as u8,
219 );
220 value >>= 6;
221 while value > 0 {
222 w.write_u8(
223 if value > 0b01111111 as i64 {
224 0b10000000 as u8
225 } else {
226 0
227 } | (0b01111111 as i64 & value) as u8,
228 );
229 value >>= 7;
230 }
231}
232
233fn read_var_u64<R: Read>(r: &mut R) -> Result<u64, Error> {
234 let mut num = 0;
235 let mut len: usize = 0;
236 loop {
237 let r = r.read_u8()?;
238 num |= u64::wrapping_shl((r & 0b01111111) as u64, len as u32);
239 len += 7;
240 if r < 0b10000000 {
241 return Ok(num);
242 }
243 if len > 70 {
244 return Err(Error::VarIntSizeExceeded(70));
245 }
246 }
247}
248
249fn read_var_u32<R: Read>(r: &mut R) -> Result<u32, Error> {
250 let mut num = 0;
251 let mut len: usize = 0;
252 loop {
253 let r = r.read_u8()?;
254 num |= u32::wrapping_shl((r & 0b01111111) as u32, len as u32);
255 len += 7;
256 if r < 0b10000000 {
257 return Ok(num);
258 }
259 if len > 70 {
260 return Err(Error::VarIntSizeExceeded(70));
263 }
264 }
265}
266
267fn read_var_i64<R: Read>(reader: &mut R) -> Result<i64, Error> {
268 let mut r = reader.read_u8()?;
269 let mut num = (r & 0b00111111 as u8) as i64;
270 let mut len: u32 = 6;
271 let is_negative = r & 0b01000000 as u8 > 0;
272 if r & 0b10000000 as u8 == 0 {
273 return Ok(if is_negative { -num } else { num });
274 }
275 loop {
276 r = reader.read_u8()?;
277 num |= (r as i64 & 0b01111111 as i64) << len;
278 len += 7;
279 if r < 0b10000000 as u8 {
280 return Ok(if is_negative { -num } else { num });
281 }
282 if len > 70 {
283 return Err(Error::VarIntSizeExceeded(70));
284 }
285 }
286}
287
288pub trait SignedVarInt: Sized + Copy {
289 fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W);
290 fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error>;
291}
292
293#[derive(Debug, Clone, Eq, PartialEq)]
297pub struct Signed<T: Sized + Copy> {
298 value: T,
299 is_negative: bool,
300}
301
302impl<T: Sized + Copy> Signed<T> {
303 pub fn new(value: T, is_negative: bool) -> Self {
304 Signed { value, is_negative }
305 }
306
307 pub fn is_positive(&self) -> bool {
309 !self.is_negative
310 }
311
312 pub fn is_negative(&self) -> bool {
314 self.is_negative
315 }
316
317 pub fn value(&self) -> T {
319 self.value
320 }
321
322 pub fn map<F, U>(&self, f: F) -> Signed<U>
325 where
326 F: FnOnce(T) -> U,
327 U: Sized + Copy,
328 {
329 let mapped = f(self.value);
330 Signed::new(mapped, self.is_negative)
331 }
332}
333
334impl SignedVarInt for i64 {
335 fn write_signed<W: Write>(s: &Signed<Self>, w: &mut W) {
336 let mut value = s.value;
337 let is_negative = s.is_negative;
338 value = if is_negative { -value } else { value };
339 w.write_u8(
340 (if value > 0b00111111 as i64 { 0b10000000 as u8 } else { 0 })
342 | (if is_negative { 0b01000000 as u8 } else { 0 })
344 | (0b00111111 as i64 & value) as u8,
346 );
347 value >>= 6;
348 while value > 0 {
349 w.write_u8(
350 if value > 0b01111111 as i64 {
351 0b10000000 as u8
352 } else {
353 0
354 } | (0b01111111 as i64 & value) as u8,
355 );
356 value >>= 7;
357 }
358 }
359
360 fn read_signed<R: Read>(reader: &mut R) -> Result<Signed<Self>, Error> {
361 let mut r = reader.read_u8()?;
362 let mut num = (r & 0b00111111 as u8) as i64;
363 let mut len: u32 = 6;
364 let is_negative = r & 0b01000000 as u8 > 0;
365 if r & 0b10000000 as u8 == 0 {
366 let num = if is_negative { -num } else { num };
367 return Ok(Signed::new(num, is_negative));
368 }
369 loop {
370 r = reader.read_u8()?;
371 num |= (r as i64 & 0b01111111 as i64) << len;
372 len += 7;
373 if r < 0b10000000 as u8 {
374 let num = if is_negative { -num } else { num };
375 return Ok(Signed::new(num, is_negative));
376 }
377 if len > 70 {
378 return Err(Error::VarIntSizeExceeded(70));
379 }
380 }
381 }
382}
383
384impl SignedVarInt for isize {
385 fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
386 let value = value.map(|v| v as i64);
387 i64::write_signed(&value, w)
388 }
389
390 fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
391 let result = i64::read_signed(r)?;
392 match result.value.try_into() {
393 Ok(i) => Ok(Signed::new(i, result.is_negative)),
394 Err(_) => Err(Error::VarIntSizeExceeded(70)),
395 }
396 }
397}
398
399impl SignedVarInt for i32 {
400 fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
401 let value = value.map(|v| v as i64);
402 i64::write_signed(&value, w)
403 }
404
405 fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
406 let result = i64::read_signed(r)?;
407 match result.value.try_into() {
408 Ok(i) => Ok(Signed::new(i, result.is_negative)),
409 Err(_) => Err(Error::VarIntSizeExceeded(35)),
410 }
411 }
412}
413
414impl SignedVarInt for i16 {
415 fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
416 let value = value.map(|v| v as i64);
417 i64::write_signed(&value, w)
418 }
419
420 fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
421 let result = i64::read_signed(r)?;
422 match result.value.try_into() {
423 Ok(i) => Ok(Signed::new(i, result.is_negative)),
424 Err(_) => Err(Error::VarIntSizeExceeded(21)),
425 }
426 }
427}
428
429impl SignedVarInt for i8 {
430 fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
431 let value = value.map(|v| v as i64);
432 i64::write_signed(&value, w)
433 }
434
435 fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
436 let result = i64::read_signed(r)?;
437 match result.value.try_into() {
438 Ok(i) => Ok(Signed::new(i, result.is_negative)),
439 Err(_) => Err(Error::VarIntSizeExceeded(14)),
440 }
441 }
442}