#[inline]
pub fn encode_oppv_u64(val: u64, buf: &mut Vec<u8>) {
if val < 0x80 {
buf.push(val as u8);
} else if val < 0x4000 {
buf.push(0x80 | ((val >> 8) as u8));
buf.push((val & 0xFF) as u8);
} else if val < 0x20_0000 {
buf.push(0xC0 | ((val >> 16) as u8));
buf.push(((val >> 8) & 0xFF) as u8);
buf.push((val & 0xFF) as u8);
} else if val < 0x1000_0000 {
buf.push(0xE0 | ((val >> 24) as u8));
buf.push(((val >> 16) & 0xFF) as u8);
buf.push(((val >> 8) & 0xFF) as u8);
buf.push((val & 0xFF) as u8);
} else {
buf.push(0xF8);
buf.extend_from_slice(&val.to_be_bytes());
}
}
#[inline]
pub fn decode_oppv_u64(slice: &[u8]) -> Option<(u64, usize)> {
let first = *slice.first()?;
if first < 0x80 {
Some((first as u64, 1))
} else if first < 0xC0 {
if slice.len() < 2 {
return None;
}
let val = (((first & 0x3F) as u64) << 8) | (slice[1] as u64);
Some((val, 2))
} else if first < 0xE0 {
if slice.len() < 3 {
return None;
}
let val = (((first & 0x1F) as u64) << 16) | ((slice[1] as u64) << 8) | (slice[2] as u64);
Some((val, 3))
} else if first < 0xF0 {
if slice.len() < 4 {
return None;
}
let val = (((first & 0x0F) as u64) << 24)
| ((slice[1] as u64) << 16)
| ((slice[2] as u64) << 8)
| (slice[3] as u64);
Some((val, 4))
} else if first == 0xF8 {
if slice.len() < 9 {
return None;
}
let mut bytes = [0u8; 8];
bytes.copy_from_slice(&slice[1..9]);
Some((u64::from_be_bytes(bytes), 9))
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_oppv_strict_order_preservation() {
let test_values = [
0u64,
1,
2,
127,
128,
129,
1000,
16383,
16384,
100_000,
1_000_000,
268_435_455,
268_435_456,
1_000_000_000,
u64::MAX - 1,
u64::MAX,
];
let mut encoded_list = Vec::new();
for &v in &test_values {
let mut buf = Vec::new();
encode_oppv_u64(v, &mut buf);
let (decoded, consumed) = decode_oppv_u64(&buf).unwrap();
assert_eq!(decoded, v);
assert_eq!(consumed, buf.len());
encoded_list.push((v, buf));
}
for i in 0..encoded_list.len() - 1 {
let (v1, ref b1) = encoded_list[i];
let (v2, ref b2) = encoded_list[i + 1];
assert!(
v1 < v2,
"Value {v1} should be strictly less than value {v2}"
);
assert!(
b1 < b2,
"Encoded bytes {b1:?} should be strictly less than bytes {b2:?}"
);
}
}
}