darkfi_sdk/monotree/
bits.rs1use std::ops::Range;
21
22use super::{
23 utils::{bit, bytes_to_int, len_lcp, nbytes_across},
24 BitsLen,
25};
26use crate::GenericResult;
27
28#[derive(Debug, Clone, PartialEq)]
29pub struct Bits<'a> {
31 pub path: &'a [u8],
32 pub range: Range<BitsLen>,
33}
34
35impl<'a> Bits<'a> {
36 pub fn new(bytes: &'a [u8]) -> Self {
37 Bits { path: bytes, range: 0..(bytes.len() as BitsLen * 8) }
38 }
39
40 pub fn from_bytes(bytes: &'a [u8]) -> Self {
42 let u = std::mem::size_of::<BitsLen>();
43 let start: BitsLen = bytes_to_int(&bytes[..u]);
44 let end: BitsLen = bytes_to_int(&bytes[u..2 * u]);
45 Self { path: &bytes[2 * u..], range: start..end }
46 }
47
48 pub fn to_bytes(&self) -> GenericResult<Vec<u8>> {
50 let start = (self.range.start / 8) as usize;
51 let end = self.range.end.div_ceil(8) as usize;
52 let mut path = self.path[start..end].to_owned();
53 let r = (self.range.start % 8) as u8;
54 if r != 0 {
55 let mask = 0xffu8 >> r;
56 path[0] &= mask;
57 }
58 let r = (self.range.end % 8) as u8;
59 if r != 0 {
60 let mask = 0xffu8 << (8 - r);
61 let last = path.len() - 1;
62 path[last] &= mask;
63 }
64 Ok([&self.range.start.to_be_bytes(), &self.range.end.to_be_bytes(), &path[..]].concat())
65 }
66
67 pub fn first(&self) -> bool {
69 bit(self.path, self.range.start)
70 }
71
72 pub fn len(&self) -> BitsLen {
73 self.range.end - self.range.start
74 }
75
76 pub fn is_empty(&self) -> bool {
77 self.len() == 0 || self.path.len() == 0
78 }
79
80 pub fn take(&self, n: BitsLen) -> Self {
82 let x = self.range.start + n;
83 let q = nbytes_across(self.range.start, x);
84 let range = self.range.start..x;
85 Self { path: &self.path[..q as usize], range }
86 }
87
88 pub fn drop(&self, n: BitsLen) -> Self {
90 let x = self.range.start + n;
91 let q = x / 8;
92 let range = x % 8..self.range.end - 8 * (x / 8);
93 Self { path: &self.path[q as usize..], range }
94 }
95
96 pub fn len_common_bits(a: &Self, b: &Self) -> BitsLen {
98 len_lcp(a.path, &a.range, b.path, &b.range)
99 }
100}