1 /* 2 * bitstream.h 3 * 4 * Copyright (c) 2007-2009 Dan Weatherford and Facebook, inc. 5 * All rights reserved. 6 */ 7 8 #pragma once 9 #include "serialized_buffer.h" 10 #include <assert.h> 11 12 class bitstream { 13 public: bitstream(serialized_buffer * _buffer)14 bitstream(serialized_buffer* _buffer) : buffer(_buffer), current_byte(0), last_used_bit(0) {} 15 16 // I'm sure this is really slow, but this isn't really in a critical path... get_bits(uint8_t nbits)17 uint32_t get_bits(uint8_t nbits) { 18 uint32_t result = 0; 19 assert(nbits <= 32); 20 while (nbits) { 21 result = result << 1 | get_bit(); 22 --nbits; 23 } 24 return result; 25 } 26 get_bit()27 uint8_t get_bit() { 28 if (! last_used_bit) refill(); 29 --last_used_bit; 30 return ((current_byte & (1 << last_used_bit)) >> last_used_bit) & 1; 31 } 32 get_golomb_ue()33 uint32_t get_golomb_ue() { 34 uint32_t leading_zeros = 0; 35 while (! get_bit()) ++leading_zeros; 36 return ((1 << leading_zeros) | get_bits(leading_zeros)) - 1; 37 } 38 get_golomb_se()39 int32_t get_golomb_se() { 40 uint32_t ue = get_golomb_ue(); 41 if (! ue) return 0; 42 else if (ue & 1) return (ue >> 1); 43 else return (0 - (ue >> 1)); 44 } 45 46 protected: refill()47 void refill() { 48 assert(last_used_bit == 0); 49 current_byte = buffer->get_u8(); 50 last_used_bit = 8; 51 } 52 53 serialized_buffer* buffer; 54 uint8_t current_byte; 55 uint8_t last_used_bit; 56 57 private: 58 bitstream& operator=(const bitstream&); 59 bitstream(const bitstream&); 60 }; 61 62