darkfi_sdk/monotree/
bits.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 * Copyright (C) 2021 MONOLOG (Taeho Francis Lim and Jongwhan Lee) MIT License
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20use 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)]
29/// `BitVec` implementation based on bytes slice.
30pub 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    /// Construct `Bits` instance by deserializing bytes slice.
41    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    /// Serialize `Bits` into bytes.
49    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    /// Get the very first bit.
68    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    /// Get the first `n` bits.
81    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    /// Skip the first `n` bits.
89    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    /// Get length of the longest common prefix bits for the given two `Bits`.
97    pub fn len_common_bits(a: &Self, b: &Self) -> BitsLen {
98        len_lcp(a.path, &a.range, b.path, &b.range)
99    }
100}