00001
00002
00003
00004
00005
00006
00007
00008
00009
00014
00015 #ifndef BITREADER_HPP_INCLUDED
00016 #define BITREADER_HPP_INCLUDED
00017
00018 #include <iostream>
00019 #include <string>
00020 #include <cstddef>
00021 #include <climits>
00022
00023
00024 #ifdef _MSC_VER
00025 #pragma warning(disable:4800)
00026 #endif
00027
00047 class bitreader {
00048
00049 public:
00052 bitreader(size_t size_in_bits=0)
00053 : offs(0), length(size_in_bits), current(0), mask(0) { ; }
00054
00057 virtual ~bitreader() { ; }
00058
00059 public:
00062 virtual bool error() const { return false; }
00063
00065 void align_byte() { offs = (offs + 7) & ~0x0007; mask = 0; }
00066
00067 public:
00070
00073 bool empty() const { return offs >= length; }
00076 size_t bits_left() const { return length - offs; }
00079 size_t bytes_left() const { return bits_left() / 8; }
00080
00083 size_t get_bit_length() const { return length; }
00084
00087 size_t get_byte_length() const { return get_bit_length() / 8; }
00088
00091 size_t tell_bit() const { return offs; }
00092
00095 size_t tell_byte() const { return tell_bit() / 8; }
00096
00098
00099 public:
00102
00105 virtual bool supports_seek() const = 0;
00106
00110 size_t seek_bit(size_t pos) { offs = pos; reposition(); return offs; }
00111
00115 size_t seek_byte(size_t pos) { return seek_bit(8 * pos); }
00116
00124 size_t seek_bit(int pos, std::ios::seekdir rpos)
00125 {
00126 switch (rpos)
00127 {
00128 case std::ios::beg:
00129 return seek_bit(pos);
00130 break;
00131 case std::ios::cur:
00132 return seek_bit(offs + pos);
00133 break;
00134 case std::ios::end:
00135 return seek_bit(length - pos);
00136 break;
00137 }
00138 return 0;
00139 }
00140
00148 size_t seek_byte(int pos, std::ios::seekdir rpos)
00149 {
00150 return seek_bit(8 * pos, rpos);
00151 }
00152
00154
00155 public:
00158
00161 bool get_bit()
00162 {
00163 ++offs;
00164
00165 if (!mask)
00166 {
00167 current = read_next_byte();
00168 mask = 0x80;
00169 }
00170
00171 const bool bit = (bool)(current & mask);
00172 mask >>= 1;
00173
00174 return bit;
00175 }
00176
00179 unsigned char get_byte()
00180 {
00181 offs += 8;
00182
00183 if (!mask) return read_next_byte();
00184
00185 size_t bit_offs = offs & 0x0007;
00186 unsigned char tmp = current << (unsigned char)bit_offs;
00187 current = read_next_byte();
00188
00189 return tmp | (current >> (8 - (unsigned char)bit_offs));
00190 }
00191
00194 unsigned short get_word()
00195 {
00196 unsigned short v = get_byte();
00197 v = (v << 8) | get_byte();
00198
00199 return v;
00200 }
00201
00204 unsigned long get_dword()
00205 {
00206 unsigned long v = get_byte();
00207 v = (v << 8) | get_byte();
00208 v = (v << 8) | get_byte();
00209 v = (v << 8) | get_byte();
00210
00211 return v;
00212 }
00213
00218 float get_float()
00219 {
00220 float v;
00221 read((char*)&v, sizeof(float));
00222 return v;
00223 }
00224
00229 double get_double()
00230 {
00231 double v;
00232 read((char*)&v, sizeof(double));
00233 return v;
00234 }
00235
00238 std::string get_string()
00239 {
00240 size_t len = get_word();
00241
00242 if (len == 0) len = get_dword();
00243
00244 std::string s;
00245
00246 s.reserve(len);
00247 for ( ; len; --len) s += get_byte();
00248
00249 return s;
00250 }
00251
00255 void read(char *buffer, size_t len)
00256 {
00257 for ( ; len; --len) *buffer++ = get_byte();
00258 }
00259
00261
00262 public:
00265
00266 void get(bool &v) { v = get_bit(); }
00267 void get(char &v) { v = get_byte(); }
00268 void get(unsigned char &v) { v = get_byte(); }
00269 void get(short &v) { v = get_word(); }
00270 void get(unsigned short &v) { v = get_word(); }
00271 #if UINT_MAX == 0xffff
00272 void get(int &v) { v = get_word(); }
00273 void get(unsigned int &v) { v = get_word(); }
00274 #else
00275 void get(int &v) { v = get_dword(); }
00276 void get(unsigned int &v) { v = get_dword(); }
00277 #endif
00278 void get(long &v) { v = get_dword(); }
00279 void get(unsigned long &v) { v = get_dword(); }
00280
00281 void get(float &v) { read((char*)&v, sizeof(float)); }
00282 void get(double &v) { read((char*)&v, sizeof(double)); }
00283 void get(std::string &s) { s = get_string(); }
00284
00286
00287 protected:
00290 void finalize() { align_byte(); }
00291
00295 virtual char read_next_byte() = 0;
00296
00300 virtual void set_position(size_t pos) { ; }
00301
00304 void reposition()
00305 {
00306 size_t byte_offs = offs / 8;
00307 size_t bit_offs = offs & 0x0007;
00308
00309 set_position(byte_offs);
00310
00311 mask = 0;
00312
00313 if (bit_offs)
00314 {
00315 mask = 1 << (7 - (unsigned int)bit_offs);
00316
00317 current = read_next_byte();
00318 }
00319 }
00320
00321 size_t offs;
00322 size_t length;
00323
00324 private:
00325 unsigned char current;
00326 unsigned char mask;
00327 };
00328
00329 #endif // __BITREADER_HPP_INCLUDED