#![cfg_attr(feature = "nightly", deny(missing_docs))]
#![cfg_attr(feature = "nightly", feature(external_doc))]
#![cfg_attr(feature = "nightly", doc(include = "../README.md"))]
#![cfg_attr(test, deny(warnings))]
#[inline]
pub fn length(value: u64) -> usize {
let zero_len = 64 - value.leading_zeros();
let offset = if zero_len == 0 { 7 } else { 6 };
((offset + zero_len) / 7) as usize
}
#[inline]
pub fn encode(value: u64, buf: &mut [u8]) -> usize {
encode_with_offset(value, buf, 0)
}
#[inline]
pub fn encode_with_offset(value: u64, buf: &mut [u8], offset: usize) -> usize {
let mut off = offset;
let mut val = value;
while val > 127 {
buf[off] = (val as u8) | 128;
off += 1;
val >>= 7;
}
buf[off] = val as u8;
off + 1 - offset
}
#[inline]
pub fn decode(buf: &[u8], value: &mut u64) -> usize {
decode_with_offset(buf, 0, value)
}
#[inline]
pub fn decode_with_offset(buf: &[u8], offset: usize, value: &mut u64) -> usize {
let mut val = 0 as u64;
let mut fac = 1 as u64;
let mut off = offset;
loop {
let byte = buf[off];
off += 1;
val += fac * ((byte & 127) as u64);
fac <<= 7;
if byte & 128 == 0 {
break;
}
}
*value = val;
off - offset
}
#[inline]
pub fn signed_length(value: i64) -> usize {
length(unsign(value))
}
#[inline]
pub fn signed_encode(value: i64, buf: &mut [u8]) -> usize {
encode_with_offset(unsign(value), buf, 0)
}
#[inline]
pub fn signed_encode_with_offset(
value: i64,
buf: &mut [u8],
offset: usize,
) -> usize {
encode_with_offset(unsign(value), buf, offset)
}
#[inline]
pub fn signed_decode(buf: &[u8], value: &mut i64) -> usize {
signed_decode_with_offset(buf, 0, value)
}
#[inline]
pub fn signed_decode_with_offset(
buf: &[u8],
offset: usize,
value: &mut i64,
) -> usize {
let mut val = 0;
let off = decode_with_offset(buf, offset, &mut val);
*value = sign(val);
off
}
#[inline]
fn unsign(value: i64) -> u64 {
if value >= 0 {
(value * 2) as u64
} else {
(value * -2 - 1) as u64
}
}
#[inline]
fn sign(value: u64) -> i64 {
if value & 1 != 0 {
-(((value + 1) / 2) as i64)
} else {
(value / 2) as i64
}
}