Initial
This commit is contained in:
87
bitstream.cpp
Normal file
87
bitstream.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
#include "bitstream.h"
|
||||
|
||||
#define min(x,y) (((x) > (y)) ? (y) : (x))
|
||||
|
||||
// i.e when stream is 0b12345678 0bABCDEFGH and command is
|
||||
// to read 12 bits:
|
||||
// out = 00000000 00000000 0000EFGH 12345678
|
||||
// to read 2 bits:
|
||||
// out = 00000000 00000000 00000000 00000078
|
||||
int ibitstream::getbits(size_t n) {
|
||||
std::cerr << "To read " << n << " count: " << this->count << " " << this->cache << std::endl;
|
||||
int out = 0, read = 0, to_read;
|
||||
|
||||
if (n > 32 || n < 0) {
|
||||
throw std::runtime_error("When reading bits from bitstream n must be <= 32");
|
||||
}
|
||||
|
||||
// read to cache
|
||||
if (this->count == -1 || this->count >= 8) {
|
||||
if (!(this->is >> cache)) throw std::runtime_error("Stream EOF");
|
||||
this->count = 0;
|
||||
}
|
||||
|
||||
while (n > 0) {
|
||||
to_read = min(n, 8 - this->count);
|
||||
std::cerr << "Iter n: " << n << " count: " << this->count << " "
|
||||
<< this->cache << " to_read: " << to_read << " already read: " << read << std::endl;
|
||||
|
||||
// cache & 0b11111000 if count = 3;
|
||||
// cache & 0b10000000 if count = 7;
|
||||
// cache & 0b11111111 if count = 0, etc;
|
||||
uint8_t mask = (((1 << to_read) - 1) << this->count);
|
||||
out |= ((cache & mask) >> this->count) << read;
|
||||
|
||||
std::cerr << "Read result: " << std::bitset<8>((cache & mask) >> this->count) << " " << std::bitset<32>(((cache & mask) >> this->count) << read) << std::endl;
|
||||
|
||||
this->count += to_read;
|
||||
read += to_read;
|
||||
n -= to_read;
|
||||
|
||||
if (this->count == 8){
|
||||
// read another byte
|
||||
if (!(this->is >> cache)) throw std::runtime_error("Stream EOF");
|
||||
this->count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void obitstream::writebits(short bits, size_t n) {
|
||||
std::cerr << "Write: " << std::bitset<16>(bits) << " n: " << n << " count: " << this->count << " cache: " << std::bitset<8>(this->cache) << std::endl;
|
||||
int written = 0, to_write;
|
||||
while (n > 0) {
|
||||
to_write = min(n, 8 - this->count);
|
||||
|
||||
uint8_t chunk = (bits & (((1 << to_write) - 1) << written)) >> written;
|
||||
this->cache |= (chunk << this->count);
|
||||
|
||||
this->count += to_write;
|
||||
written += to_write;
|
||||
n -= to_write;
|
||||
|
||||
if (this->count == 8){
|
||||
// flush chunk
|
||||
std::cerr << "Flush: " << std::bitset<8>(this->cache) << std::endl;
|
||||
|
||||
os << this->cache;
|
||||
os.flush();
|
||||
|
||||
this->count = 0;
|
||||
this->cache = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void obitstream::flush() {
|
||||
std::cerr << "Flush: " << std::bitset<8>(this->cache) << std::endl;
|
||||
os << this->cache;
|
||||
os.flush();
|
||||
|
||||
this->cache = 0;
|
||||
this->count = 0;
|
||||
}
|
Reference in New Issue
Block a user