2018-10-24 10:21:51 +00:00
extern crate bit_vec ;
2018-09-22 04:07:14 +00:00
extern crate ssz ;
2018-10-24 10:21:51 +00:00
use bit_vec ::BitVec ;
2018-07-12 04:59:50 +00:00
2018-11-15 17:19:59 +00:00
use std ::default ;
2018-10-24 10:21:51 +00:00
/// A BooleanBitfield represents a set of booleans compactly stored as a vector of bits.
2018-11-15 17:19:59 +00:00
/// The BooleanBitfield is given a fixed size during construction. Reads outside of the current size return an out-of-bounds error. Writes outside of the current size expand the size of the set.
2018-10-24 10:21:51 +00:00
#[ derive(Debug, Clone, PartialEq) ]
pub struct BooleanBitfield ( BitVec ) ;
/// Error represents some reason a request against a bitfield was not satisfied
#[ derive(Debug) ]
pub enum Error {
/// OutOfBounds refers to indexing into a bitfield where no bits exist; returns the illegal index and the current size of the bitfield, respectively
OutOfBounds ( usize , usize ) ,
2018-07-12 04:59:50 +00:00
}
impl BooleanBitfield {
2018-11-15 17:19:59 +00:00
/// Create a new bitfield.
2018-07-12 04:59:50 +00:00
pub fn new ( ) -> Self {
2018-11-15 17:19:59 +00:00
Default ::default ( )
}
/// Create a new bitfield with the given length `initial_len` and all values set to `bit`.
pub fn from_elem ( inital_len : usize , bit : bool ) -> Self {
Self {
0 : BitVec ::from_elem ( inital_len , bit ) ,
}
2018-07-12 04:59:50 +00:00
}
2018-09-10 05:50:35 +00:00
2018-10-24 10:21:51 +00:00
/// Create a new bitfield using the supplied `bytes` as input
2018-11-15 17:19:59 +00:00
pub fn from_bytes ( bytes : & [ u8 ] ) -> Self {
2018-10-24 10:21:51 +00:00
Self {
0 : BitVec ::from_bytes ( bytes ) ,
}
2018-07-12 04:59:50 +00:00
}
2018-09-10 05:50:35 +00:00
/// Read the value of a bit.
///
2018-10-24 10:21:51 +00:00
/// If the index is in bounds, then result is Ok(value) where value is `true` if the bit is 1 and `false` if the bit is 0.
/// If the index is out of bounds, we return an error to that extent.
pub fn get ( & self , i : usize ) -> Result < bool , Error > {
match self . 0. get ( i ) {
Some ( value ) = > Ok ( value ) ,
None = > Err ( Error ::OutOfBounds ( i , self . 0. len ( ) ) ) ,
2018-07-12 04:59:50 +00:00
}
}
2018-09-10 05:50:35 +00:00
/// Set the value of a bit.
///
2018-11-15 17:19:59 +00:00
/// If the index is out of bounds, we expand the size of the underlying set to include the new index.
/// Returns the previous value if there was one.
pub fn set ( & mut self , i : usize , value : bool ) -> Option < bool > {
let previous = match self . get ( i ) {
Ok ( previous ) = > Some ( previous ) ,
Err ( Error ::OutOfBounds ( _ , len ) ) = > {
let new_len = i - len + 1 ;
self . 0. grow ( new_len , false ) ;
None
}
} ;
2018-10-24 10:21:51 +00:00
self . 0. set ( i , value ) ;
2018-11-15 17:19:59 +00:00
previous
2018-07-12 08:19:20 +00:00
}
2018-09-10 05:50:35 +00:00
2018-10-24 10:21:51 +00:00
/// Returns the index of the highest set bit. Some(n) if some bit is set, None otherwise.
pub fn highest_set_bit ( & self ) -> Option < usize > {
self . 0. iter ( ) . rposition ( | bit | bit )
2018-09-24 08:06:47 +00:00
}
2018-10-24 10:21:51 +00:00
/// Returns the number of bits in this bitfield.
pub fn len ( & self ) -> usize {
self . 0. len ( )
2018-09-22 04:07:14 +00:00
}
2018-11-20 18:12:49 +00:00
/// Returns the number of bytes required to represent this bitfield.
pub fn num_bytes ( & self ) -> usize {
self . to_bytes ( ) . len ( )
}
2018-10-24 10:21:51 +00:00
/// Returns the number of `1` bits in the bitfield
pub fn num_set_bits ( & self ) -> usize {
self . 0. iter ( ) . filter ( | & bit | bit ) . count ( )
2018-07-17 03:21:28 +00:00
}
2018-10-24 10:21:51 +00:00
/// Returns a vector of bytes representing the bitfield
pub fn to_bytes ( & self ) -> Vec < u8 > {
self . 0. to_bytes ( )
2018-09-22 04:07:14 +00:00
}
}
2018-11-15 17:19:59 +00:00
impl default ::Default for BooleanBitfield {
/// default provides the "empty" bitfield
/// Note: the empty bitfield is set to the `0` byte.
fn default ( ) -> Self {
Self ::from_elem ( 8 , false )
}
}
2018-09-22 04:07:14 +00:00
impl ssz ::Decodable for BooleanBitfield {
2018-11-04 14:35:00 +00:00
fn ssz_decode ( bytes : & [ u8 ] , index : usize ) -> Result < ( Self , usize ) , ssz ::DecodeError > {
let len = ssz ::decode ::decode_length ( bytes , index , ssz ::LENGTH_BYTES ) ? ;
2018-09-22 04:07:14 +00:00
if ( ssz ::LENGTH_BYTES + len ) > bytes . len ( ) {
return Err ( ssz ::DecodeError ::TooShort ) ;
}
2018-10-24 10:21:51 +00:00
2018-09-22 04:07:14 +00:00
if len = = 0 {
2018-11-04 14:35:00 +00:00
Ok ( ( BooleanBitfield ::new ( ) , index + ssz ::LENGTH_BYTES ) )
2018-09-22 04:07:14 +00:00
} else {
2018-11-15 17:19:59 +00:00
let field = BooleanBitfield ::from_bytes ( & bytes [ ( index + 4 ) .. ( index + len + 4 ) ] ) ;
2018-09-22 04:07:14 +00:00
let index = index + ssz ::LENGTH_BYTES + len ;
2018-10-24 10:21:51 +00:00
Ok ( ( field , index ) )
2018-09-22 04:07:14 +00:00
}
}
}
2018-07-12 04:59:50 +00:00
#[ cfg(test) ]
mod tests {
use super ::* ;
2018-09-22 04:07:14 +00:00
2018-09-30 04:54:03 +00:00
#[ test ]
2018-10-24 10:21:51 +00:00
fn test_empty_bitfield ( ) {
let mut field = BooleanBitfield ::new ( ) ;
2018-11-15 17:19:59 +00:00
let original_len = field . len ( ) ;
for i in 0 .. 100 {
if i < original_len {
assert! ( ! field . get ( i ) . unwrap ( ) ) ;
} else {
assert! ( field . get ( i ) . is_err ( ) ) ;
}
let previous = field . set ( i , true ) ;
if i < original_len {
assert! ( ! previous . unwrap ( ) ) ;
} else {
assert! ( previous . is_none ( ) ) ;
}
2018-10-24 10:21:51 +00:00
}
}
2018-09-30 04:54:03 +00:00
2018-10-24 10:21:51 +00:00
const INPUT : & [ u8 ] = & [ 0b0000_0010 , 0b0000_0010 ] ;
2018-09-30 04:54:03 +00:00
2018-10-24 10:21:51 +00:00
#[ test ]
fn test_get_from_bitfield ( ) {
2018-11-15 17:19:59 +00:00
let field = BooleanBitfield ::from_bytes ( INPUT ) ;
2018-10-24 10:21:51 +00:00
let unset = field . get ( 0 ) . unwrap ( ) ;
assert! ( ! unset ) ;
let set = field . get ( 6 ) . unwrap ( ) ;
assert! ( set ) ;
let set = field . get ( 14 ) . unwrap ( ) ;
assert! ( set ) ;
2018-09-30 04:54:03 +00:00
}
2018-09-22 04:07:14 +00:00
#[ test ]
2018-10-24 10:21:51 +00:00
fn test_set_for_bitfield ( ) {
2018-11-15 17:19:59 +00:00
let mut field = BooleanBitfield ::from_bytes ( INPUT ) ;
2018-10-24 10:21:51 +00:00
let previous = field . set ( 10 , true ) . unwrap ( ) ;
assert! ( ! previous ) ;
let previous = field . get ( 10 ) . unwrap ( ) ;
assert! ( previous ) ;
let previous = field . set ( 6 , false ) . unwrap ( ) ;
assert! ( previous ) ;
let previous = field . get ( 6 ) . unwrap ( ) ;
assert! ( ! previous ) ;
2018-09-22 04:07:14 +00:00
}
#[ test ]
2018-10-24 10:21:51 +00:00
fn test_highest_set_bit ( ) {
2018-11-15 17:19:59 +00:00
let field = BooleanBitfield ::from_bytes ( INPUT ) ;
2018-10-24 10:21:51 +00:00
assert_eq! ( field . highest_set_bit ( ) . unwrap ( ) , 14 ) ;
2018-09-22 04:07:14 +00:00
2018-10-24 10:21:51 +00:00
let field = BooleanBitfield ::new ( ) ;
assert_eq! ( field . highest_set_bit ( ) , None ) ;
2018-09-22 04:07:14 +00:00
}
#[ test ]
2018-10-24 10:21:51 +00:00
fn test_len ( ) {
2018-11-15 17:19:59 +00:00
let field = BooleanBitfield ::from_bytes ( INPUT ) ;
2018-10-24 10:21:51 +00:00
assert_eq! ( field . len ( ) , 16 ) ;
2018-09-22 04:07:14 +00:00
2018-10-24 10:21:51 +00:00
let field = BooleanBitfield ::new ( ) ;
2018-11-15 17:19:59 +00:00
assert_eq! ( field . len ( ) , 8 ) ;
2018-09-22 04:07:14 +00:00
}
2018-07-12 04:59:50 +00:00
#[ test ]
2018-10-24 10:21:51 +00:00
fn test_num_set_bits ( ) {
2018-11-15 17:19:59 +00:00
let field = BooleanBitfield ::from_bytes ( INPUT ) ;
2018-10-24 10:21:51 +00:00
assert_eq! ( field . num_set_bits ( ) , 2 ) ;
2018-09-10 05:50:35 +00:00
2018-10-24 10:21:51 +00:00
let field = BooleanBitfield ::new ( ) ;
assert_eq! ( field . num_set_bits ( ) , 0 ) ;
2018-07-12 04:59:50 +00:00
}
#[ test ]
2018-10-24 10:21:51 +00:00
fn test_to_bytes ( ) {
2018-11-15 17:19:59 +00:00
let field = BooleanBitfield ::from_bytes ( INPUT ) ;
2018-10-24 10:21:51 +00:00
assert_eq! ( field . to_bytes ( ) , INPUT ) ;
2018-09-10 05:50:35 +00:00
2018-10-24 10:21:51 +00:00
let field = BooleanBitfield ::new ( ) ;
2018-11-15 17:19:59 +00:00
assert_eq! ( field . to_bytes ( ) , vec! [ 0 ] ) ;
}
#[ test ]
fn test_out_of_bounds ( ) {
let mut field = BooleanBitfield ::from_bytes ( INPUT ) ;
let out_of_bounds_index = field . len ( ) ;
assert! ( field . set ( out_of_bounds_index , true ) . is_none ( ) ) ;
2018-11-20 18:12:49 +00:00
assert! ( field . len ( ) = = out_of_bounds_index + 1 ) ;
2018-11-15 17:19:59 +00:00
assert! ( field . get ( out_of_bounds_index ) . unwrap ( ) ) ;
for i in 0 .. 100 {
if i < = out_of_bounds_index {
assert! ( field . set ( i , true ) . is_some ( ) ) ;
} else {
assert! ( field . set ( i , true ) . is_none ( ) ) ;
}
}
2018-07-12 08:19:20 +00:00
}
2018-11-20 18:12:49 +00:00
#[ test ]
fn test_num_bytes ( ) {
let field = BooleanBitfield ::from_bytes ( INPUT ) ;
assert_eq! ( field . num_bytes ( ) , 2 ) ;
let field = BooleanBitfield ::from_elem ( 2 , true ) ;
assert_eq! ( field . num_bytes ( ) , 1 ) ;
let field = BooleanBitfield ::from_elem ( 13 , true ) ;
assert_eq! ( field . num_bytes ( ) , 2 ) ;
}
2018-07-12 04:59:50 +00:00
}