Skip to content

Commit 9297c76

Browse files
Dretchbrson
authored andcommitted
add additional Bitv constructors (as proposed in issue #2964)
1 parent f445497 commit 9297c76

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

src/libstd/bitv.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,44 @@ struct Bitv {
420420
vec::from_fn(self.nbits, |x| self.init_to_vec(x))
421421
}
422422

423+
/**
424+
* Organise the bits into bytes, such that the first bit in the
425+
* bitv becomes the high-order bit of the first byte. If the
426+
* size of the bitv is not a multiple of 8 then trailing bits
427+
* will be filled-in with false/0
428+
*/
429+
fn to_bytes() -> ~[u8] {
430+
431+
fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
432+
let offset = byte * 8 + bit;
433+
if offset >= bitv.nbits {
434+
0
435+
} else {
436+
bitv[offset] as u8 << (7 - bit)
437+
}
438+
}
439+
440+
let len = self.nbits/8 +
441+
if self.nbits % 8 == 0 { 0 } else { 1 };
442+
vec::from_fn(len, |i|
443+
bit(&self, i, 0) |
444+
bit(&self, i, 1) |
445+
bit(&self, i, 2) |
446+
bit(&self, i, 3) |
447+
bit(&self, i, 4) |
448+
bit(&self, i, 5) |
449+
bit(&self, i, 6) |
450+
bit(&self, i, 7)
451+
)
452+
}
453+
454+
/**
455+
* Transform self into a [bool] by turning each bit into a bool
456+
*/
457+
fn to_bools() -> ~[bool] {
458+
vec::from_fn(self.nbits, |i| self[i])
459+
}
460+
423461
/**
424462
* Converts `self` to a string.
425463
*
@@ -461,6 +499,38 @@ struct Bitv {
461499

462500
} // end of bitv class
463501

502+
/**
503+
* Transform a byte-vector into a bitv. Each byte becomes 8 bits,
504+
* with the most significant bits of each byte coming first. Each
505+
* bit becomes true if equal to 1 or false if equal to 0.
506+
*/
507+
fn from_bytes(bytes: &[u8]) -> Bitv {
508+
from_fn(bytes.len() * 8, |i| {
509+
let b = bytes[i / 8] as uint;
510+
let offset = i % 8;
511+
b >> (7 - offset) & 1 == 1
512+
})
513+
}
514+
515+
/**
516+
* Transform a [bool] into a bitv by converting each bool into a bit.
517+
*/
518+
fn from_bools(bools: &[bool]) -> Bitv {
519+
from_fn(bools.len(), |i| bools[i])
520+
}
521+
522+
/**
523+
* Create a bitv of the specified length where the value at each
524+
* index is f(index).
525+
*/
526+
fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv {
527+
let bitv = Bitv(len, false);
528+
for uint::range(0, len) |i| {
529+
bitv.set(i, f(i));
530+
}
531+
return bitv;
532+
}
533+
464534
const uint_bits: uint = 32u + (1u << 32u >> 27u);
465535

466536
pure fn lor(w0: uint, w1: uint) -> uint { return w0 | w1; }
@@ -815,6 +885,35 @@ mod tests {
815885
assert a.equal(b);
816886
}
817887

888+
#[test]
889+
fn test_from_bytes() {
890+
let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
891+
let str = ~"10110110" + ~"00000000" + ~"11111111";
892+
assert bitv.to_str() == str;
893+
}
894+
895+
#[test]
896+
fn test_to_bytes() {
897+
let bv = Bitv(3, true);
898+
bv.set(1, false);
899+
assert bv.to_bytes() == ~[0b10100000];
900+
901+
let bv = Bitv(9, false);
902+
bv.set(2, true);
903+
bv.set(8, true);
904+
assert bv.to_bytes() == ~[0b00100000, 0b10000000];
905+
}
906+
907+
#[test]
908+
fn test_from_bools() {
909+
assert from_bools([true, false, true, true]).to_str() == ~"1011";
910+
}
911+
912+
#[test]
913+
fn test_to_bools() {
914+
let bools = ~[false, false, true, false, false, true, true, false];
915+
assert from_bytes([0b00100110]).to_bools() == bools;
916+
}
818917
}
819918

820919
//

0 commit comments

Comments
 (0)