9 #include "../misc/definitions.h"
17 class GenericBitBuffer
20 GenericBitBuffer(usint words);
21 GenericBitBuffer(usint _items, usint item_size);
22 GenericBitBuffer(std::ifstream& file, usint words);
23 GenericBitBuffer(std::ifstream& file, usint _items, usint item_size);
24 GenericBitBuffer(Data* buffer, usint words);
25 GenericBitBuffer(Data* buffer, usint _items, usint item_size);
28 void writeBuffer(std::ofstream& file, bool erase = true);
29 void readBuffer(std::ifstream& file, usint words, bool erase = true);
30 void setBuffer(Data* buffer, usint words);
32 // We assume we are already using a buffer not owned by this.
33 inline void moveBuffer(Data* buffer)
37 this->bits = DATA_BITS;
41 //--------------------------------------------------------------------------
43 inline void reset(bool erase)
46 this->bits = DATA_BITS;
50 memset(this->data, 0, this->size * sizeof(Data));
54 inline void skipBits(usint count)
56 if(count < this->bits)
63 this->pos += 1 + count / DATA_BITS;
64 this->bits = DATA_BITS - count % DATA_BITS;
67 inline void rewind(usint count)
70 if(this->bits > DATA_BITS)
72 usint back = (this->bits - 1) / DATA_BITS;
74 this->bits -= back * DATA_BITS;
78 //--------------------------------------------------------------------------
80 inline usint bitsLeft()
82 return this->bits + DATA_BITS * (this->size - this->pos - 1);
85 inline void writeBits(usint value, usint count)
87 while(count >= this->bits)
90 this->data[this->pos] |= GET(LOWER(value, count), this->bits);
91 this->pos++; this->bits = DATA_BITS;
96 this->data[this->pos] |= HIGHER(GET(value, count), this->bits);
100 // Returns nonzero if bit is 1
101 inline usint readBit()
104 usint bit = this->data[this->pos] & ((usint)1 << this->bits);
106 if(this->bits == 0) { this->pos++; this->bits = DATA_BITS; }
111 inline usint readBits(usint count)
115 while(count >= this->bits)
118 value |= HIGHER(GET(this->data[this->pos], this->bits), count);
119 this->pos++; this->bits = DATA_BITS;
124 value |= GET(LOWER(this->data[this->pos], this->bits), count);
130 //--------------------------------------------------------------------------
133 These operations work on fixed-size items.
136 inline usint getItemSize()
138 return this->item_bits;
142 inline void setItemSize(usint new_size)
144 if(new_size == 0) { return; }
145 this->item_bits = new_size;
149 inline void goToItem(usint item)
151 usint b = item * this->item_bits;
152 this->pos = b / DATA_BITS;
153 this->bits = DATA_BITS - b % DATA_BITS;
154 this->current = item;
157 inline usint readItem()
160 return this->readBits(this->item_bits);
163 inline usint readItem(usint item)
165 this->goToItem(item);
166 return this->readItem();
169 inline usint readFirstItem()
171 return this->readItem(0);
174 inline bool hasNextItem()
176 return (this->current < this->items);
179 inline void writeItem(usint item)
181 this->writeBits(item, this->item_bits);
185 inline void skipItem()
187 this->skipBits(this->item_bits);
191 //--------------------------------------------------------------------------
194 Delta coding for positive integers
197 inline bool canDeltaCode(usint value)
199 return this->deltaCodeLength(value) <= this->bitsLeft();
202 inline usint deltaCodeLength(usint value)
204 usint len = length(value);
205 usint llen = length(len);
206 return (len + llen + llen - 2);
209 // This version returns false if there is no space left for the encoding.
210 inline bool writeDeltaCode(usint value)
212 usint len = length(value);
213 usint llen = length(len);
215 if(len + llen + llen - 2 > this->bitsLeft()) { return false; }
217 // this->writeBits(0, llen - 1); // Now included in the next writeBits()
218 this->writeBits(len, llen + llen - 1);
219 this->writeBits(value, len - 1);
223 // This version assumes the code fits into the buffer.
224 inline void writeDeltaCodeDirect(usint value)
226 usint len = length(value);
227 usint llen = length(len);
229 // this->writeBits(0, llen - 1); // Now included in the next writeBits()
230 this->writeBits(len, llen + llen - 1);
231 this->writeBits(value, len - 1);
234 // We assume the code fits into usint:
235 // 32-bit: value < 2^24
236 // 64-bit: value < 2^54
237 inline void writeDeltaCodeFast(usint value)
239 usint len = length(value);
241 value ^= ((usint)1 << (len - 1));
242 this->writeBits((len << (len - 1)) | value, len + 2 * length(len) - 2);
245 inline usint readDeltaCode()
248 while(this->readBit() == 0) { len++; }
250 usint temp = (((usint)1 << len) | this->readBits(len)) - 1;
251 temp = ((usint)1 << temp) | this->readBits(temp);
255 //--------------------------------------------------------------------------
258 Gamma coding for positive integers
261 inline bool canGammaCode(usint value)
263 return this->gammaCodeLength(value) <= this->bitsLeft();
266 inline usint gammaCodeLength(usint value)
268 return 2 * length(value) - 1;
271 // This version returns false if there is no space left for the encoding.
272 inline bool writeGammaCode(usint value)
274 usint len = length(value);
276 if(len > this->bitsLeft()) { return false; }
278 this->writeBits(0, len - 1);
279 this->writeBits(value, len);
283 // This version assumes the code fits into the buffer.
284 inline void writeGammaCodeDirect(usint value)
286 usint len = length(value);
288 this->writeBits(0, len - 1);
289 this->writeBits(value, len);
292 // We assume the code fits into usint:
293 // 32-bit: value < 2^16
294 // 64-bit: value < 2^32
295 inline void writeGammaCodeFast(usint value)
297 this->writeBits(value, this->gammaCodeLength(value));
300 inline usint readGammaCode()
303 while(this->readBit() == 0) { len++; }
304 return ((usint)1 << len) | this->readBits(len);
307 //--------------------------------------------------------------------------
311 //--------------------------------------------------------------------------
315 usint size, pos, bits;
316 usint item_bits, items, current;
319 const static usint DATA_BITS = sizeof(Data) * CHAR_BIT;
321 inline static usint bitsToData(usint _bits) { return (_bits + DATA_BITS - 1) / DATA_BITS; }
325 typedef GenericBitBuffer<uchar> BitBuffer;
326 typedef GenericBitBuffer<usint> FastBitBuffer;
329 //--------------------------------------------------------------------------
333 GenericBitBuffer<Data>::GenericBitBuffer(usint words) :
342 this->data = new Data[words];
343 memset(this->data, 0, words * sizeof(Data));
347 GenericBitBuffer<Data>::GenericBitBuffer(usint _items, usint item_size) :
350 item_bits(item_size),
355 this->size = bitsToData(items * item_size);
356 this->data = new Data[this->size];
357 memset(this->data, 0, this->size * sizeof(Data));
361 GenericBitBuffer<Data>::GenericBitBuffer(std::ifstream& file, usint words) :
370 this->data = new Data[words];
371 memset(this->data, 0, words * sizeof(Data));
372 file.read((char*)this->data, words * sizeof(Data));
376 GenericBitBuffer<Data>::GenericBitBuffer(std::ifstream& file, usint _items, usint item_size) :
377 size(BITS_TO_WORDS(_items * item_size)),
380 item_bits(item_size),
385 this->data = new Data[this->size];
386 memset(this->data, 0, this->size * sizeof(Data));
387 file.read((char*)this->data, this->size * sizeof(Data));
391 GenericBitBuffer<Data>::GenericBitBuffer(Data* buffer, usint words) :
404 GenericBitBuffer<Data>::GenericBitBuffer(Data* buffer, usint _items, usint item_size) :
405 size(BITS_TO_WORDS(_items * item_size)),
408 item_bits(item_size),
417 GenericBitBuffer<Data>::~GenericBitBuffer()
419 if(this->free_buffer)
425 //--------------------------------------------------------------------------
429 GenericBitBuffer<Data>::writeBuffer(std::ofstream& file, bool erase)
431 file.write((char*)this->data, this->size * sizeof(Data));
437 GenericBitBuffer<Data>::readBuffer(std::ifstream& file, usint words, bool erase)
439 if(words > this->size || !(this->free_buffer))
441 if(this->free_buffer)
446 this->data = new Data[words];
447 this->free_buffer = true;
451 file.read((char*)this->data, words * sizeof(Data));
456 GenericBitBuffer<Data>::setBuffer(Data* buffer, usint words)
458 if(this->free_buffer)
461 this->free_buffer = false;
469 //--------------------------------------------------------------------------
473 GenericBitBuffer<Data>::reportSize()
475 usint bytes = sizeof(*this);
476 if(this->free_buffer) { bytes += this->size * sizeof(Data); }
480 //--------------------------------------------------------------------------
486 #endif // BITBUFFER_H