00001
00002
00003
00004
00005
00006
00007
00008
00009
00014
00015 #ifndef BITWRITER_HPP_INCLUDED
00016 #define BITWRITER_HPP_INCLUDED
00017
00018 #include <string>
00019 #include <cstddef>
00020 #include <climits>
00021
00040 class bitwriter {
00041
00042 public:
00044 bitwriter() : num(0), current(0), mask(0x80) { ; }
00045
00048 virtual ~bitwriter() { ; }
00049
00050 public:
00053 virtual bool error() const { return false; }
00054
00056 void align_byte()
00057 {
00058 if (mask != 0x80)
00059 {
00060 ++num; write_next_byte(current);
00061 current = 0;
00062 mask = 0x80;
00063 }
00064 }
00065
00066 public:
00069
00072 size_t bits_done() const { return 8*num + 8 - log2_tab[mask]; }
00075 size_t bytes_done() const { return num; }
00076
00079 size_t tell_bit() const { return bits_done(); }
00080
00083 size_t tell_byte() const { return bytes_done(); }
00084
00086
00087 public:
00090
00093 void put_bit(bool v)
00094 {
00095 if (v) current |= mask;
00096 if (!(mask >>= 1))
00097 {
00098 ++num; write_next_byte(current);
00099 current = 0;
00100 mask = 0x80;
00101 }
00102 }
00103
00106 void put_byte(unsigned char v)
00107 {
00108 ++num;
00109
00110 if (mask == 0x80) { write_next_byte(v); return; }
00111
00112 unsigned char ml = log2_tab[mask];
00113 current |= v >> (8 - ml);
00114 write_next_byte(current);
00115 current = v << ml;
00116 }
00117
00120 void put_word(unsigned short v)
00121 {
00122 put_byte((v >> 8) & 0x00ff);
00123 put_byte((v ) & 0x00ff);
00124 }
00125
00128 void put_dword(unsigned long v)
00129 {
00130 put_byte((unsigned char) ((v >> 24) & 0x00ff));
00131 put_byte((unsigned char) ((v >> 16) & 0x00ff));
00132 put_byte((unsigned char) ((v >> 8 ) & 0x00ff));
00133 put_byte((unsigned char) ((v ) & 0x00ff));
00134 }
00135
00140 void put_float(float v) { write((char*)&v, sizeof(float)); }
00141
00146 void put_double(double v) { write((char*)&v, sizeof(double)); }
00147
00150 void put_string(std::string &s)
00151 {
00152 size_t len = s.length();
00153
00154 if ((len > 0x0000ffff) || (len == 0))
00155 {
00156 put_word(0);
00157 put_dword(len);
00158 } else {
00159 put_word(len);
00160 }
00161
00162 write(s.c_str(), len);
00163 }
00164
00168 void write(const char *buffer, size_t length)
00169 {
00170 for ( ; length; --length) put_byte(*buffer++);
00171 }
00172
00174
00175 public:
00178
00179 void put(bool v) { put_bit(v); }
00180 void put(char v) { put_byte(v); }
00181 void put(unsigned char v) { put_byte(v); }
00182 void put(short v) { put_word(v); }
00183 void put(unsigned short v) { put_word(v); }
00184 #if UINT_MAX == 0xffff
00185 void put(int v) { put_word(v); }
00186 void put(unsigned int v) { put_word(v); }
00187 #else
00188 void put(int v) { put_dword(v); }
00189 void put(unsigned int v) { put_dword(v); }
00190 #endif
00191 void put(long v) { put_dword(v); }
00192 void put(unsigned long v) { put_dword(v); }
00193
00194 void put(float v) { put_float(v); }
00195 void put(double v) { put_double(v); }
00196 void put(std::string &s) { put_string(s); }
00197
00199
00200 protected:
00203 void finalize() { align_byte(); }
00204
00208 virtual void write_next_byte(char c) = 0;
00209
00210 size_t num;
00211
00212 private:
00213 unsigned char current;
00214 unsigned char mask;
00215
00217 static const unsigned char log2_tab[256];
00218 };
00219
00220 #endif // BITWRITER_HPP_INCLUDED