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
use crate::{
config::Endian,
de::read::Reader,
error::{DecodeError, IntegerType},
};
pub fn varint_decode_i16<R: Reader>(read: &mut R, endian: Endian) -> Result<i16, DecodeError> {
let n = super::varint_decode_u16(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
} else {
// negative number
// !m * 2 + 1 = n
// !m * 2 = n - 1
// !m = (n - 1) / 2
// m = !((n - 1) / 2)
// since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2)
!(n / 2) as _
})
}
pub fn varint_decode_i32<R: Reader>(read: &mut R, endian: Endian) -> Result<i32, DecodeError> {
let n = super::varint_decode_u32(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
} else {
// negative number
// !m * 2 + 1 = n
// !m * 2 = n - 1
// !m = (n - 1) / 2
// m = !((n - 1) / 2)
// since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2)
!(n / 2) as _
})
}
pub fn varint_decode_i64<R: Reader>(read: &mut R, endian: Endian) -> Result<i64, DecodeError> {
let n = super::varint_decode_u64(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
} else {
// negative number
// !m * 2 + 1 = n
// !m * 2 = n - 1
// !m = (n - 1) / 2
// m = !((n - 1) / 2)
// since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2)
!(n / 2) as _
})
}
pub fn varint_decode_i128<R: Reader>(read: &mut R, endian: Endian) -> Result<i128, DecodeError> {
let n = super::varint_decode_u128(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
} else {
// negative number
// !m * 2 + 1 = n
// !m * 2 = n - 1
// !m = (n - 1) / 2
// m = !((n - 1) / 2)
// since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2)
!(n / 2) as _
})
}
pub fn varint_decode_isize<R: Reader>(read: &mut R, endian: Endian) -> Result<isize, DecodeError> {
match varint_decode_i64(read, endian) {
Ok(val) => Ok(val as isize),
Err(DecodeError::InvalidIntegerType { found, .. }) => {
Err(DecodeError::InvalidIntegerType {
expected: IntegerType::Isize,
found: found.into_signed(),
})
}
Err(e) => Err(e),
}
}