@@ -420,6 +420,44 @@ struct Bitv {
420
420
vec:: from_fn ( self . nbits , |x| self . init_to_vec ( x) )
421
421
}
422
422
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
+
423
461
/**
424
462
* Converts `self` to a string.
425
463
*
@@ -461,6 +499,38 @@ struct Bitv {
461
499
462
500
} // end of bitv class
463
501
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
+
464
534
const uint_bits: uint = 32 u + ( 1 u << 32 u >> 27 u) ;
465
535
466
536
pure fn lor ( w0 : uint , w1 : uint ) -> uint { return w0 | w1; }
@@ -815,6 +885,35 @@ mod tests {
815
885
assert a. equal ( b) ;
816
886
}
817
887
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
+ }
818
917
}
819
918
820
919
//
0 commit comments