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