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-12-11 04:34:35 +00:00
use std ::cmp ;
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-12-11 04:34:35 +00:00
#[ derive(Debug, Clone) ]
2018-10-24 10:21:51 +00:00
pub struct BooleanBitfield ( BitVec ) ;
/// Error represents some reason a request against a bitfield was not satisfied
2018-11-22 21:57:28 +00:00
#[ derive(Debug, PartialEq) ]
2018-10-24 10:21:51 +00:00
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 ( )
}
2018-12-04 04:45:43 +00:00
pub fn with_capacity ( initial_len : usize ) -> Self {
Self ::from_elem ( initial_len , false )
}
2018-11-15 17:19:59 +00:00
/// 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
2018-11-20 20:27:44 +00:00
/// Note that this returns the bit layout of the underlying implementation in the `bit-vec` crate.
2018-10-24 10:21:51 +00:00
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-12-11 04:34:35 +00:00
impl cmp ::PartialEq for BooleanBitfield {
/// Determines equality by comparing the `ssz` encoding of the two candidates.
/// This method ensures that the presence of high-order (empty) bits in the highest byte do not exclude equality when they are in fact representing the same information.
fn eq ( & self , other : & Self ) -> bool {
ssz ::ssz_encode ( self ) = = ssz ::ssz_encode ( other )
}
}
2018-11-20 20:27:44 +00:00
impl ssz ::Encodable for BooleanBitfield {
// ssz_append encodes Self according to the `ssz` spec.
fn ssz_append ( & self , s : & mut ssz ::SszStream ) {
2018-12-04 04:45:43 +00:00
s . append_vec ( & self . to_bytes ( ) )
2018-11-20 20:27:44 +00:00
}
}
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-20 20:27:44 +00:00
let bytes = & bytes [ ( index + 4 ) .. ( index + len + 4 ) ] ;
2018-12-04 04:45:43 +00:00
let count = len * 8 ;
let mut field = BooleanBitfield ::with_capacity ( count ) ;
2018-11-20 20:27:44 +00:00
for ( byte_index , byte ) in bytes . iter ( ) . enumerate ( ) {
for i in 0 .. 8 {
2018-12-04 04:45:43 +00:00
let bit = byte & ( 128 > > i ) ;
2018-11-20 20:27:44 +00:00
if bit ! = 0 {
field . set ( 8 * byte_index + i , true ) ;
}
}
}
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-12-03 06:13:39 +00:00
use ssz ::{ ssz_encode , Decodable , SszStream } ;
2018-09-22 04:07:14 +00:00
2018-09-30 04:54:03 +00:00
#[ test ]
2018-11-22 21:57:28 +00:00
fn test_new_bitfield ( ) {
2018-10-24 10:21:51 +00:00
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-11-22 21:57:28 +00:00
#[ test ]
fn test_empty_bitfield ( ) {
let mut field = BooleanBitfield ::from_elem ( 0 , false ) ;
let original_len = field . len ( ) ;
assert_eq! ( original_len , 0 ) ;
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 ( ) ) ;
}
}
assert_eq! ( field . len ( ) , 100 ) ;
assert_eq! ( field . num_set_bits ( ) , 100 ) ;
}
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-11-22 21:57:28 +00:00
let field = BooleanBitfield ::from_bytes ( & [ 0b0000_0011 ] ) ;
assert_eq! ( field . highest_set_bit ( ) . unwrap ( ) , 7 ) ;
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
2018-11-22 21:57:28 +00:00
#[ test ]
fn test_grows_with_false ( ) {
let input_all_set : & [ u8 ] = & [ 0b1111_1111 , 0b1111_1111 ] ;
let mut field = BooleanBitfield ::from_bytes ( input_all_set ) ;
// Define `a` and `b`, where both are out of bounds and `b` is greater than `a`.
let a = field . len ( ) ;
let b = a + 1 ;
// Ensure `a` is out-of-bounds for test integrity.
assert! ( field . get ( a ) . is_err ( ) ) ;
// Set `b` to `true`. Also, for test integrity, ensure it was previously out-of-bounds.
assert! ( field . set ( b , true ) . is_none ( ) ) ;
// Ensure that `a` wasn't also set to `true` during the grow.
assert_eq! ( field . get ( a ) , Ok ( false ) ) ;
assert_eq! ( field . get ( b ) , Ok ( true ) ) ;
}
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-11-20 20:27:44 +00:00
#[ test ]
fn test_ssz_encode ( ) {
2018-12-04 04:45:43 +00:00
let field = create_test_bitfield ( ) ;
2018-11-20 20:27:44 +00:00
let mut stream = SszStream ::new ( ) ;
stream . append ( & field ) ;
2018-12-04 04:45:43 +00:00
assert_eq! ( stream . drain ( ) , vec! [ 0 , 0 , 0 , 2 , 225 , 192 ] ) ;
2018-11-20 20:27:44 +00:00
let field = BooleanBitfield ::from_elem ( 18 , true ) ;
let mut stream = SszStream ::new ( ) ;
stream . append ( & field ) ;
2018-12-04 04:45:43 +00:00
assert_eq! ( stream . drain ( ) , vec! [ 0 , 0 , 0 , 3 , 255 , 255 , 192 ] ) ;
}
fn create_test_bitfield ( ) -> BooleanBitfield {
let count = 2 * 8 ;
let mut field = BooleanBitfield ::with_capacity ( count ) ;
let indices = & [ 0 , 1 , 2 , 7 , 8 , 9 ] ;
for & i in indices {
field . set ( i , true ) ;
}
field
2018-11-20 20:27:44 +00:00
}
#[ test ]
fn test_ssz_decode ( ) {
2018-12-04 04:45:43 +00:00
let encoded = vec! [ 0 , 0 , 0 , 2 , 225 , 192 ] ;
2018-11-20 20:27:44 +00:00
let ( field , _ ) : ( BooleanBitfield , usize ) = ssz ::decode_ssz ( & encoded , 0 ) . unwrap ( ) ;
2018-12-04 04:45:43 +00:00
let expected = create_test_bitfield ( ) ;
2018-11-20 20:27:44 +00:00
assert_eq! ( field , expected ) ;
let encoded = vec! [ 0 , 0 , 0 , 3 , 255 , 255 , 3 ] ;
let ( field , _ ) : ( BooleanBitfield , usize ) = ssz ::decode_ssz ( & encoded , 0 ) . unwrap ( ) ;
2018-12-04 04:45:43 +00:00
let expected = BooleanBitfield ::from_bytes ( & [ 255 , 255 , 3 ] ) ;
2018-11-20 20:27:44 +00:00
assert_eq! ( field , expected ) ;
}
2018-12-03 06:13:39 +00:00
#[ test ]
fn test_ssz_round_trip ( ) {
let original = BooleanBitfield ::from_bytes ( & vec! [ 18 ; 12 ] [ .. ] ) ;
let ssz = ssz_encode ( & original ) ;
let ( decoded , _ ) = BooleanBitfield ::ssz_decode ( & ssz , 0 ) . unwrap ( ) ;
assert_eq! ( original , decoded ) ;
}
2018-07-12 04:59:50 +00:00
}