aboutsummaryrefslogtreecommitdiffstats
path: root/src/bitfield.rs
diff options
context:
space:
mode:
authorBryan Newbold <bnewbold@robocracy.org>2017-12-11 21:33:59 -0800
committerBryan Newbold <bnewbold@robocracy.org>2017-12-11 21:33:59 -0800
commitb82f57d1ef9bc1cf8f55753df94f75e83d16a75b (patch)
treed73935b5ef32fdeeb2009363ed5560b541a61696 /src/bitfield.rs
parentf3b9046a9599354eac634eefaba79eb1b106e9a5 (diff)
downloadgeniza-b82f57d1ef9bc1cf8f55753df94f75e83d16a75b.tar.gz
geniza-b82f57d1ef9bc1cf8f55753df94f75e83d16a75b.zip
refactor higher level peer APIs (WIP)
Diffstat (limited to 'src/bitfield.rs')
-rw-r--r--src/bitfield.rs55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/bitfield.rs b/src/bitfield.rs
new file mode 100644
index 0000000..11640ea
--- /dev/null
+++ b/src/bitfield.rs
@@ -0,0 +1,55 @@
+
+use errors::*;
+use integer_encoding::VarInt;
+use bit_field::BitArray;
+
+
+// WrappedBitfield
+//
+// uses vec of u64 internally?
+//
+// fn from_message()
+// fn get(u64)
+
+pub fn decode_bitfield(raw_bf: &[u8]) -> Result<Vec<u8>> {
+ let mut offset = 0; // byte offset that we have read up to
+ if raw_bf.len() < 1 {
+ bail!("Expected (varint-encoded) bitfield to have len>=1");
+ }
+ let mut bit_array: Vec<u8> = vec![];
+ while offset < raw_bf.len() {
+ let (header, inc): (u64, usize) = VarInt::decode_var(&raw_bf[offset..]);
+ offset += inc;
+
+ if (header & 0x01) == 0x01 {
+ // compressed
+ let bit = (header & 0x02) == 0x02;
+ let run_len = header >> 2;
+ if bit {
+ bit_array.append(&mut vec![0xFF; run_len as usize]);
+ } else {
+ bit_array.append(&mut vec![0x00; run_len as usize]);
+ }
+ } else {
+ // uncompressed
+ let byte_count = header >> 1;
+ let mut data = raw_bf[offset..(offset + byte_count as usize)].to_vec();
+ bit_array.append(&mut data);
+ offset += byte_count as usize;
+ }
+ }
+ // XXX: HACK
+ bit_array.reverse();
+ return Ok(bit_array);
+}
+
+/// Finds the index of the lowest bit
+pub fn max_high_bit(bf: &[u8]) -> u64 {
+ // XXX: HACK, going backwards
+ for i in 0..bf.bit_length() {
+ if bf.get_bit(i) {
+ return (bf.bit_length() - i - 1) as u64;
+ }
+ }
+ return 0;
+}