testnumbat_codec/
num_conv.rs1use crate::nested_ser_output::NestedEncodeOutput;
2
3pub fn using_encoded_number<F: FnOnce(&[u8])>(
8 x: u64,
9 size_in_bits: usize,
10 signed: bool,
11 mut compact: bool,
12 f: F,
13) {
14 let mut result = [0u8; 8];
15 let mut result_size = 0usize;
16 let negative = compact && signed && x >> (size_in_bits - 1) & 1 == 1; let irrelevant_byte = if negative { 0xffu8 } else { 0x00u8 };
21 let mut bit_offset = size_in_bits as isize - 8;
22 while bit_offset >= 0 {
23 let byte = (x >> (bit_offset as usize) & 0xffu64) as u8;
25
26 if compact {
27 if byte != irrelevant_byte {
30 result[result_size] = byte;
31 result_size += 1;
32 compact = false;
33 }
34 } else {
35 result[result_size] = byte;
36 result_size += 1;
37 }
38
39 bit_offset -= 8;
40 }
41
42 f(&result[0..result_size])
43}
44
45pub fn top_encode_number_to_output<O: NestedEncodeOutput>(output: &mut O, x: u64, signed: bool) {
46 let bytes_be: [u8; 8] = x.to_be_bytes();
47 if x == 0 {
48 return;
50 }
51
52 if signed && x == u64::MAX {
53 output.push_byte(0xffu8);
55 return;
56 }
57
58 let negative = signed && bytes_be[0] > 0x7fu8; let irrelevant_byte = if negative { 0xffu8 } else { 0x00u8 };
62
63 let mut offset = 0usize;
64 while bytes_be[offset] == irrelevant_byte {
65 debug_assert!(offset < 7);
66 offset += 1;
67 }
68
69 if signed && bytes_be[offset] >> 7 != negative as u8 {
70 debug_assert!(offset > 0);
71 offset -= 1;
72 }
73
74 output.write(&bytes_be[offset..]);
75}
76
77#[inline(never)]
80pub fn bytes_to_number(bytes: &[u8], signed: bool) -> u64 {
81 if bytes.is_empty() {
82 return 0;
83 }
84 let negative = signed && bytes[0] >> 7 == 1;
85 let mut result = if negative {
86 u64::MAX
90 } else {
91 0u64
92 };
93 for byte in bytes.iter() {
94 result <<= 8;
95 result |= *byte as u64;
96 }
97 result
98}