Advertisement
Guest User

Untitled

a guest
Aug 28th, 2015
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.11 KB | None | 0 0
  1. use std::cmp::min;
  2. use self::BitBufError::*;
  3.  
  4. pub struct BitBuf {
  5. contents: Vec<u8>,
  6. current_bit: u32,
  7. bit_count: u32
  8. }
  9.  
  10. #[derive(Debug, Copy, Clone, PartialEq)]
  11. pub enum BitBufError {
  12. OutOfRoom,
  13. BadNumberOfBits
  14. }
  15.  
  16. pub type BitBufResult<T> = Result<T, BitBufError>;
  17.  
  18. impl BitBuf {
  19. pub fn new(contents: Vec<u8>, bit_count: u32) -> BitBuf {
  20. assert!((bit_count / 8) as usize <= contents.len());
  21.  
  22. BitBuf {
  23. contents: contents,
  24. current_bit: 0,
  25. bit_count: bit_count
  26. }
  27. }
  28.  
  29. pub fn empty() -> BitBuf {
  30. BitBuf {
  31. contents: Vec::new(),
  32. current_bit: 0,
  33. bit_count: 0
  34. }
  35. }
  36.  
  37. pub fn tell(&self) -> u32 {
  38. self.current_bit
  39. }
  40. pub fn seek(&mut self, pos: u32) {
  41. self.current_bit = pos;
  42. }
  43.  
  44. pub fn read_bits_as_u32(&mut self, bit_count: u32) -> BitBufResult<u32> {
  45. if bit_count > 32 {
  46. return Err(BadNumberOfBits);
  47. }
  48.  
  49. let startbit = self.current_bit;
  50. let endbit = self.current_bit + bit_count;
  51. if endbit > self.bit_count {
  52. return Err(BitBufError::OutOfRoom);
  53. }
  54.  
  55. let startbyte = startbit / 8;
  56. let endbyte = endbit / 8 ;
  57. debug_assert!(endbyte as usize <= self.contents.len());
  58.  
  59. let mut val = 0;
  60. let mut bits_read = 0;
  61. let mut skipbits = startbit % 8;
  62. for i in startbyte..endbyte + 1 {
  63. let byte = self.contents[i as usize] as u32;
  64.  
  65. let numbitsskipped = min(skipbits, 8);
  66. skipbits -= numbitsskipped;
  67. let truncatebit = if i == endbyte {
  68. endbit % 8
  69. } else {
  70. 8
  71. };
  72. let maskedbyte = byte & make_bitmask(numbitsskipped, truncatebit);
  73. let shiftedbyte = maskedbyte >> numbitsskipped;
  74.  
  75. val = val | (shiftedbyte << bits_read);
  76. bits_read += truncatebit - numbitsskipped;
  77. }
  78.  
  79. self.current_bit += bits_read;
  80.  
  81. debug_assert_eq!(bits_read, bit_count);
  82. debug_assert!(self.current_bit <= self.bit_count);
  83.  
  84. Ok(val)
  85. }
  86.  
  87. pub fn write_u32_as_bits(&mut self, val: u32, bit_count: u32) -> BitBufResult<()> {
  88. if bit_count > 32 {
  89. return Err(BitBufError::BadNumberOfBits);
  90. }
  91.  
  92. let startbit = self.current_bit;
  93. let endbit = self.current_bit + bit_count;
  94. let startbyte = startbit / 8;
  95. let endbyte = endbit / 8 ;
  96.  
  97.  
  98. let padbytes = endbyte as usize + 1 - self.contents.len();
  99. self.contents.extend(::std::iter::repeat(0)
  100. .take(padbytes));
  101. self.bit_count += padbytes as u32 * 8;
  102.  
  103.  
  104. let mut bits_written = 0;
  105. let mut skipbits = startbit % 8;
  106. for i in startbyte..endbyte + 1 {
  107. let numbitsskipped = min(skipbits, 8);
  108. skipbits -= numbitsskipped;
  109. let truncatebit = if i == endbyte {
  110. endbit % 8
  111. } else {
  112. 8
  113. };
  114. let maskedbyte = ((val >> bits_written) << numbitsskipped) & make_bitmask(numbitsskipped, truncatebit);
  115.  
  116. self.contents[i as usize] = maskedbyte as u8;
  117.  
  118. bits_written += truncatebit - numbitsskipped;
  119. }
  120.  
  121. self.current_bit += bits_written;
  122.  
  123. debug_assert_eq!(bits_written, bit_count);
  124. debug_assert!(self.current_bit <= self.bit_count);
  125.  
  126. Ok(())
  127. }
  128.  
  129. pub fn read_bits_as_i32(&mut self, bit_count: u32) -> BitBufResult<i32> {
  130. let val = try!(self.read_bits_as_u32(bit_count)) as i32;
  131. let max_neg = 1 << (bit_count - 1);
  132. if val > max_neg {
  133. // it's negative (two's complement); fix sign
  134. Ok(val - (2 * max_neg))
  135. } else {
  136. Ok(val)
  137. }
  138. }
  139.  
  140. pub fn write_i32_as_bits(&mut self, val: i32, bit_count: u32) -> BitBufResult<()> {
  141. // FIXME: there should be a check for val being too big here
  142. self.write_u32_as_bits(val as u32, bit_count)
  143. }
  144.  
  145. pub fn bytes(&self) -> &[u8] {
  146. &self.contents[0..(self.bit_count / 8) as usize]
  147. }
  148. }
  149.  
  150. fn make_bitmask(startbit: u32, endbit: u32) -> u32 {
  151. let mask = 0xFFFFFFFF << startbit; // mask LSBs
  152. mask & !(0xFFFFFFFF << endbit) // mask MSBs
  153. }
  154.  
  155. #[test]
  156. fn smoke_write() {
  157. let mut buf = BitBuf::empty();
  158. buf.write_u32_as_bits(89, 19).unwrap();
  159. buf.write_u32_as_bits(42, 12).unwrap();
  160. assert_eq!(buf.bytes(), [0x59, 0x00, 0x50, 0x01]);
  161. }
  162.  
  163. #[test]
  164. fn smoke_read() {
  165. let contents = vec![0x59, 0x00, 0x50, 0x01];
  166. let mut buf = BitBuf::new(contents, 31);
  167. assert_eq!(buf.read_bits_as_u32(19), Ok(89));
  168. assert_eq!(buf.read_bits_as_u32(12), Ok(42));
  169. }
  170.  
  171. #[test]
  172. fn roundtrip() {
  173. let mut buf = BitBuf::empty();
  174. buf.write_u32_as_bits(532, 23).unwrap();
  175. buf.write_u32_as_bits(1, 1).unwrap();
  176. buf.write_i32_as_bits(-98, 8).unwrap();
  177. buf.write_u32_as_bits(9, 6).unwrap();
  178.  
  179. buf.seek(0);
  180.  
  181. assert_eq!(buf.read_bits_as_u32(23), Ok(532));
  182. assert_eq!(buf.read_bits_as_u32(1), Ok(1));
  183. assert_eq!(buf.read_bits_as_i32(8), Ok(-98));
  184. assert_eq!(buf.read_bits_as_u32(6), Ok(9));
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement