Octane v1.01.20 - The Open Compression Toolkit for C++ http://octane.sourceforge.net/
Homepage | Main | Modules | Class Hierarchy | Compound List | File List | Compound Members | Related Pages

bitio/bitreader.hpp

Go to the documentation of this file.
00001 //
00002 // bitreader  --  wrapper class for bit input
00003 //
00004 // Copyright (c) 2003 by Jørgen Ibsen / Jibz
00005 // All Rights Reserved
00006 //
00007 // http://www.ibsensoftware.com/
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 // ms vc (.net2003) warning about performance loss when casting int to bool
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
 
Generated on 20 May 2004 by doxygen 1.3.3