📄 bitio.cpp
字号:
#include "StdAfx.h"
#include ".\BitIO.h"
// Add pre in the front of bits
// Input: char * bits
// int & bits_len
// char * pre
// int pre_len
// Output: char * bits
// int & bits_len
void BitOp::AddPrefix(char * bits, int & bits_len, char * pre, int pre_len)
{
if (bits_len + pre_len > 8 * sizeof(long)) // NT_REVISITED, the longest length of code is 8*sizeof(long)
return;
unsigned long * pl_bits = (unsigned long *)bits;
unsigned long * pl_pre = (unsigned long *)pre;
*pl_bits = *pl_bits << pre_len;
unsigned long mask = 0xFFFFFFFF;
mask <<= pre_len;
*pl_bits |= (*pl_pre & (~mask));
bits_len += pre_len;
}
BitIO::BitIO(void)
{
}
BitIO::~BitIO(void)
{
}
bool BitIO::Write(const char * bits, int bits_len)
{
return true;
}
void BitIO::Flush()
{
}
void BitIO::Close()
{
}
int BitIO::ReadABit(char * c, int start)
{
return 0;
}
bool BitIO::ReadAByte(char & c)
{
return(true);
}
int BitIO::GetMode() // return the working mode of current object
{
return this->mode;
}
bool FileBitIO::Init(fstream * p_fs)
{
return (this->Init(p_fs, 1024 * 1024, 2));
}
bool FileBitIO::Init(fstream * p_fs, int bufsize, int work_mode, unsigned long leng)
{
this->max_bits_num = leng * 8;
this->bits_num = 0;
this->mode = work_mode;
this->fs = p_fs;
this->buf_size = bufsize;
buf = new char[bufsize];
memset(buf, 0, bufsize);
this->used = 0;
this->handled = 0;
this->unhandled = 0;
return true;
}
bool FileBitIO::Init(fstream * p_fs, int bufsize, int work_mode)
{
return(this->Init(p_fs, bufsize, work_mode, 0));
}
// write "code_len" bits from "code" to buffer.
bool FileBitIO::Write(const char * code, int code_len)
{
unsigned long byte_idx = used / 8;
int bit_idx = used % 8;
assert(code_len + bit_idx <= 8*sizeof(long)); // now, it's only for less than 32bits each time.
if (byte_idx + sizeof(long) + 1 > this->buf_size) { // NT_REVISITED, sizeof(long)
this->fs->write(this->buf, byte_idx);
memset(this->buf, 0, byte_idx);
if (bit_idx)
this->buf[0] = this->buf[byte_idx];
used = bit_idx;
byte_idx = 0;
}
assert(byte_idx + sizeof(long) + 1 <= this->buf_size);
union u {
unsigned long l;
char code[4]; // NT_REVISISTED
} un;
un.l = 0;
un.code[0] = code[0];
if (code_len > 8)
un.code[1] = code[1];
if (code_len > 16)
un.code[2] = code[2];
if (code_len > 24)
un.code[3] = code[3];
un.l <<= bit_idx;
int j = 0;
while ( 8*j < bit_idx + code_len)
{
buf[byte_idx + j] |= un.code[j];
j++;
}
unsigned char mask = 0xff;
int shift = (8 - (bit_idx + code_len) % 8) %8;
buf[byte_idx + j-1] &= (mask >> shift);
used += code_len;
this->bits_num += code_len;
return true;
}
int FileBitIO::RenewReadBuf()
{
if (this->unhandled == 0) {
int read_num;
int bits_remains = this->max_bits_num - this->bits_num;
if (bits_remains % 8 != 0)
read_num = bits_remains/8 + 1;
else
read_num = bits_remains/8;
if (read_num > this->buf_size)
read_num = this->buf_size;
this->fs->read(this->buf, read_num);
// this->fs->get(this->buf[0]); // can try to read more bits, NT_REVISITED
if (this->fs->eof())
return -1;
this->unhandled = read_num*8;
this->handled = 0;
}
return 1;
}
// read next bit from input file. if file ends, return -1
int FileBitIO::ReadABit()
{
static unsigned char mask[8] = {(unsigned char)1, (unsigned char)2, (unsigned char)4, (unsigned char)8,
(unsigned char)16, (unsigned char)32, (unsigned char)64, (unsigned char)128};
if (this->max_bits_num != 0 && this->bits_num+1 > this->max_bits_num)
return -1;
if (this->RenewReadBuf() == -1)
return -1;
this->bits_num++;
int byte_idx = this->handled >> 3; // this->handled / 8
int bit_idx = this->handled & 0x0007; // this->handled % 8
this->handled++;
this->unhandled--;
if(this->buf[byte_idx] & mask[bit_idx])
return 1;
else
return 0;
}
// read next bit from input file to the start bit of c. if file ends, return -1
int FileBitIO::ReadABit(char * c, int start)
{
static unsigned char mask[8] = {(unsigned char)1, (unsigned char)2, (unsigned char)4, (unsigned char)8,
(unsigned char)16, (unsigned char)32, (unsigned char)64, (unsigned char)128};
/* if (this->used + 1 > this->buf_size) {
this->fs->read(this->buf, this->buf_size/8);
this->used = 0;
}
*/
// assert(this->used + 1 <= this->buf_size);
if (this->max_bits_num != 0 && this->bits_num+1 > this->max_bits_num)
return -1;
if (this->RenewReadBuf() == -1)
return -1;
this->bits_num++;
int byte_idx = this->handled / 8; // this->handled / 8
int bit_idx = this->handled % 8; // this->handled % 8
int start_byte_idx = start / 8;
int start_bit_idx = start % 8;
int ret_val;
char tmp = this->buf[byte_idx] & mask[bit_idx];
if (tmp) {
c[start_byte_idx] |= mask[start_bit_idx];
ret_val = 1;
} else {
c[start_byte_idx] &= (~mask[start_bit_idx]);
ret_val = 0;
}
this->handled++;
this->unhandled--;
return ret_val;
}
// read next char from input file to c
// now, the function doesn't use buffer and thread. NT_REVISITED
bool FileBitIO::ReadAByte(char & c)
{
if (!(this->handled & 0x0007)) { // % 8
if (this->bits_num >= this->max_bits_num)
return false;
if (this->RenewReadBuf() == -1)
return false;
int byte_idx = this->handled >> 3; // this->handled/8
c = this->buf[byte_idx];
this->bits_num+=8;
this->handled += 8;
this->unhandled -= 8;
} else {
for (int i=0; i <= 7; i++) {
if (this->ReadABit(&c, i) == -1)
return false;
}
}
return true;
}
void FileBitIO::Flush()
{
this->fs->write(this->buf, this->used/8);
memset(this->buf, 0, this->used/8);
if (used%8 != 0) {
this->buf[0] = this->buf[this->used/8];
}
used %= 8;
this->fs->flush();
}
void FileBitIO::FlushEnd()
{
if (this->used == 0)
return;
this->fs->write(this->buf, (this->used -1)/8 + 1);
memset(this->buf, 0, (this->used -1)/8 + 1);
used = 0;
this->fs->flush();
}
void FileBitIO::Close()
{
this->FlushEnd();
this->fs->close();
}
FileBitIO::FileBitIO(void)
{
}
FileBitIO::~FileBitIO(void)
{
if (this->buf != NULL)
delete this->buf;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -