m2.enlarge-your-data/src/lib/eyd_bitreader.cpp
2005-10-29 22:51:22 +00:00

112 lines
3.2 KiB
C++

#define DEBUG 0
#include "eyd_bitreader.hh"
namespace EydLib {
/*
* int _group_pos;
int _fd;
*/
BitReader::BitReader(int size, int buffer_size = 1024){
// tous les groupes de bits seront de la taille donnée
this->_bitgroup_size = size;
this->_wanted_buffer_size = buffer_size;
this->_real_buffer_size = 0;
this->_read_buffer = new char[this->_wanted_buffer_size];
this->_file_desc = -1;
this->_current_bit_position = (8 * buffer_size) + 1; // on dépasse volontairement
}
BitReader::~BitReader(){
delete(this->_read_buffer);
}
void BitReader::open(std::string filename){
this->_file_desc = ::open(filename.c_str(), O_RDONLY);
this->_eof = false;
}
/*
BitGroup * BitReader::read(int size){
int i;
BitGroup * result = new BitGroup[size];
for (i=0; i<size; i++){
result[i] = this->read_once();
}
return result;
}
*/
bool BitReader::getBitAt(int position){
// on attrappe la bonne case du tableau
// on shift dans le bon sens
// on retourne la valeur du bit.
int size_of_char = 8 * sizeof(char);
int i;
int index_of_char = position / size_of_char;
int shift_of_char = position % size_of_char;
char reader;
if (position > this->_real_buffer_size * size_of_char){
//FIXME: throw exception
} else {
reader = this->_read_buffer[index_of_char];
if (shift_of_char > 0){ reader = reader << shift_of_char; reader = reader >> shift_of_char; }
reader = reader >> (size_of_char - shift_of_char - 1 );
pDEBUG("BitReader::getBitAt","->%c<- shift %d = %d\n",this->_read_buffer[index_of_char], shift_of_char, reader);
}
return reader;
}
ssize_t BitReader::readDirect(void *buf, size_t count){
return ::read(this->_file_desc, buf, count);
}
BitGroup BitReader::read(){
int i;
bool bitValue;
int size_of_char = 8 * sizeof(char);
BitGroup result(this->_bitgroup_size);
if (this->_eof) { throw eBitReaderEndOfFile(); }
if (this->_file_desc < 0){ throw eBitReaderBadFileDescriptor(); }
for (i=0; i < this->_bitgroup_size; i++){
if (this->_current_bit_position >= (this->_wanted_buffer_size * 8)){
// on charge un nouveau bout de fichier
this->_real_buffer_size = ::read(this->_file_desc, this->_read_buffer, this->_wanted_buffer_size);
pDEBUG("BitReader::read","read() -> buffer()\n");
pDEBUG("BitReader::read","READ BUFFER(%d): %s\n",this->_real_buffer_size, this->_read_buffer);
this->_current_bit_position = 0;
}
if (this->_current_bit_position < this->_real_buffer_size * 8){
//printf("TMP result = %s",result.toString().c_str());
bitValue = this->getBitAt(this->_current_bit_position);
result.setBitAt(i, bitValue);
} else {
// dans le cas ou on dépasse la fin du fichier avec un mauvais alignement
this->_eof = true;
if (i==0){ // on est sur le premier caractère
throw eBitReaderEndOfFile();
} else {
BitGroup eof_bg(i);
pDEBUG("BitReader::read","SMALLER BITGROUP ! (%d)\n",i);
for (int j=0; j<i; j++){
eof_bg.setBitAt(j, result.getBitAt(j));
}
result = eof_bg;
break;
}
}
this->_current_bit_position += 1;
}
return result;
}
void BitReader::close(){
::close(this->_file_desc);
}
}