add additional Bitv constructors (as proposed in issue #2964)
This commit is contained in:
parent
f445497d6b
commit
9297c76598
1 changed files with 99 additions and 0 deletions
|
|
@ -420,6 +420,44 @@ struct Bitv {
|
|||
vec::from_fn(self.nbits, |x| self.init_to_vec(x))
|
||||
}
|
||||
|
||||
/**
|
||||
* Organise the bits into bytes, such that the first bit in the
|
||||
* bitv becomes the high-order bit of the first byte. If the
|
||||
* size of the bitv is not a multiple of 8 then trailing bits
|
||||
* will be filled-in with false/0
|
||||
*/
|
||||
fn to_bytes() -> ~[u8] {
|
||||
|
||||
fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
|
||||
let offset = byte * 8 + bit;
|
||||
if offset >= bitv.nbits {
|
||||
0
|
||||
} else {
|
||||
bitv[offset] as u8 << (7 - bit)
|
||||
}
|
||||
}
|
||||
|
||||
let len = self.nbits/8 +
|
||||
if self.nbits % 8 == 0 { 0 } else { 1 };
|
||||
vec::from_fn(len, |i|
|
||||
bit(&self, i, 0) |
|
||||
bit(&self, i, 1) |
|
||||
bit(&self, i, 2) |
|
||||
bit(&self, i, 3) |
|
||||
bit(&self, i, 4) |
|
||||
bit(&self, i, 5) |
|
||||
bit(&self, i, 6) |
|
||||
bit(&self, i, 7)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform self into a [bool] by turning each bit into a bool
|
||||
*/
|
||||
fn to_bools() -> ~[bool] {
|
||||
vec::from_fn(self.nbits, |i| self[i])
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts `self` to a string.
|
||||
*
|
||||
|
|
@ -461,6 +499,38 @@ struct Bitv {
|
|||
|
||||
} // end of bitv class
|
||||
|
||||
/**
|
||||
* Transform a byte-vector into a bitv. Each byte becomes 8 bits,
|
||||
* with the most significant bits of each byte coming first. Each
|
||||
* bit becomes true if equal to 1 or false if equal to 0.
|
||||
*/
|
||||
fn from_bytes(bytes: &[u8]) -> Bitv {
|
||||
from_fn(bytes.len() * 8, |i| {
|
||||
let b = bytes[i / 8] as uint;
|
||||
let offset = i % 8;
|
||||
b >> (7 - offset) & 1 == 1
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a [bool] into a bitv by converting each bool into a bit.
|
||||
*/
|
||||
fn from_bools(bools: &[bool]) -> Bitv {
|
||||
from_fn(bools.len(), |i| bools[i])
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a bitv of the specified length where the value at each
|
||||
* index is f(index).
|
||||
*/
|
||||
fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv {
|
||||
let bitv = Bitv(len, false);
|
||||
for uint::range(0, len) |i| {
|
||||
bitv.set(i, f(i));
|
||||
}
|
||||
return bitv;
|
||||
}
|
||||
|
||||
const uint_bits: uint = 32u + (1u << 32u >> 27u);
|
||||
|
||||
pure fn lor(w0: uint, w1: uint) -> uint { return w0 | w1; }
|
||||
|
|
@ -815,6 +885,35 @@ mod tests {
|
|||
assert a.equal(b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bytes() {
|
||||
let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
|
||||
let str = ~"10110110" + ~"00000000" + ~"11111111";
|
||||
assert bitv.to_str() == str;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_bytes() {
|
||||
let bv = Bitv(3, true);
|
||||
bv.set(1, false);
|
||||
assert bv.to_bytes() == ~[0b10100000];
|
||||
|
||||
let bv = Bitv(9, false);
|
||||
bv.set(2, true);
|
||||
bv.set(8, true);
|
||||
assert bv.to_bytes() == ~[0b00100000, 0b10000000];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bools() {
|
||||
assert from_bools([true, false, true, true]).to_str() == ~"1011";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_bools() {
|
||||
let bools = ~[false, false, true, false, false, true, true, false];
|
||||
assert from_bytes([0b00100110]).to_bools() == bools;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue