use core::fmt;
use serde::{de, ser};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
pub struct BitString {
data: Vec<u8>,
}
impl BitString {
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
fn h_number_of_unused_bits(data_size: usize, num_bits: usize) -> u8 {
(data_size * 8 - num_bits) as u8
}
pub fn with_len(num_bits: usize) -> BitString {
let data_size = num_bits / 8 + if num_bits % 8 == 0 { 0 } else { 1 };
let mut data = vec![0x00u8; data_size + 1];
data[0] = Self::h_number_of_unused_bits(data_size, num_bits);
BitString { data }
}
pub fn with_bytes_and_len<V>(data: V, num_bits: usize) -> BitString
where
V: Into<Vec<u8>>,
{
let mut data = data.into();
let number_of_unused = Self::h_number_of_unused_bits(data.len(), num_bits);
data.insert(0, number_of_unused);
BitString { data }
}
pub fn with_bytes<V>(data: V) -> BitString
where
V: Into<Vec<u8>>,
{
let mut data = data.into();
data.insert(0, 0); BitString { data }
}
pub fn get_num_bits(&self) -> usize {
(self.data.len() - 1) * 8 - self.data[0] as usize
}
pub fn set_num_bits(&mut self, num_bits: usize) {
let new_size = num_bits / 8 + if num_bits % 8 == 0 { 0 } else { 1 };
self.data[0] = Self::h_number_of_unused_bits(new_size, num_bits);
self.data.resize(new_size + 1, 0);
}
pub fn is_set(&self, i: usize) -> bool {
if i > self.get_num_bits() {
return false;
}
let bucket = i / 8;
let pos = i - bucket * 8;
let mask = (1 << (7 - pos)) as u8;
self.data[bucket + 1] & mask != 0
}
pub fn set(&mut self, i: usize, val: bool) {
if i > self.get_num_bits() {
return;
}
let bucket = i / 8;
let pos = i - bucket * 8;
let mask = (1 << (7 - pos)) as u8;
if val {
self.data[bucket + 1] |= mask;
} else {
self.data[bucket + 1] &= !mask;
}
}
pub fn get_num_unused_bits(&self) -> u8 {
self.data[0]
}
pub fn get_num_buckets(&self) -> usize {
self.data.len() - 1
}
pub fn get_bucket(&self, i: usize) -> u8 {
self.data[i + 1]
}
pub fn get_bucket_mut(&mut self, i: usize) -> &mut u8 {
&mut self.data[i + 1]
}
pub fn set_bucket(&mut self, i: usize, value: u8) {
self.data[i + 1] = value
}
pub fn payload_view(&self) -> &[u8] {
&self.data[1..]
}
pub fn payload_view_mut(&mut self) -> &mut [u8] {
&mut self.data[1..]
}
}
impl From<BitString> for Vec<u8> {
fn from(mut bs: BitString) -> Self {
bs.data.drain(1..).collect()
}
}
impl<'de> de::Deserialize<'de> for BitString {
fn deserialize<D>(deserializer: D) -> Result<BitString, D::Error>
where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = BitString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid buffer representing a bit string")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_byte_buf(v.to_vec())
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(BitString { data: v })
}
}
deserializer.deserialize_byte_buf(Visitor)
}
}
impl ser::Serialize for BitString {
fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
where
S: ser::Serializer,
{
serializer.serialize_bytes(&self.data)
}
}
impl Default for BitString {
fn default() -> Self {
BitString::with_len(0)
}
}