-
-
[转帖]位操作
-
发表于: 2015-8-7 19:06 1733
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
struct bitrdwr_pos {
char *p;
int pos; // 0~7
};
struct bit_buf {
char *buf;
int len;
struct bitrdwr_pos write_pos;
struct bitrdwr_pos read_pos;
};
#define sizeof_bits(type) (sizeof(type)*8)
#define bit_buf_rdable(bitbuf_addr, bits) \
(((((bitbuf_addr)->buf+(bitbuf_addr)->len) \
- ((bitbuf_addr)->read_pos.p+1))*sizeof_bits(char)) \
+ ((bitbuf_addr)->read_pos.pos+1) >= (bits))
#define bit_buf_wrable(bitbuf_addr, bits) \
(((((bitbuf_addr)->buf+(bitbuf_addr)->len) \
- ((bitbuf_addr)->write_pos.p+1))*sizeof_bits(char)) \
+ ((bitbuf_addr)->write_pos.pos+1) >= (bits))
#define set_bitrdwr_position(pos_addr, _p, _pos) do { \
(pos_addr)->p = (_p); \
(pos_addr)->pos = (_pos); \
} while(0)
#define BIT_BUF_SIZE 1024
enum BIT_RDWR_MOD {
MOD_NORMAL,
MOD_STOP,
};
enum BIT_RDWR_RET {
RET_NORMAL,
RET_FINISH,
RET_ERR,
};
/*
* 7 0
* char: xxxxxxxx
* ↑ ↑ [from_bit,to_bit]
* +---+
* ↖num
* example:
* 5 -> [bit1, bit3]: xxxx[101]x
* 10-> [bit1, bit3]: xxxx[010]x, overflow
*/
static int bitwr_in_char(char *ch, int from_bit, int to_bit, unsigned char num)
{
if (from_bit < 0 || from_bit >= sizeof_bits(char)
|| to_bit < 0 || to_bit >= sizeof_bits(char))
return -1;
if (from_bit > to_bit) {
from_bit ^= to_bit;
to_bit ^= from_bit;
from_bit ^= to_bit;
}
if ((1<<(to_bit-from_bit+1)) - 1 < num)
printf("%s(), %d: overflow\n", __FUNCTION__, __LINE__);
*ch &= ((((1<<sizeof_bits(char))-1)<<(to_bit+1)) | ((1<<from_bit)-1));
*ch |= (num<<from_bit);
return 0;
}
/*
* 7 0
* char: xXXXXXxx
* ↑ ↑ [from_bit,to_bit]
* +---+
* ↘num
*/
static int bitrd_in_char(char *ch, int from_bit, int to_bit)
{
if (from_bit < 0 || from_bit >= sizeof_bits(char)
|| to_bit < 0 || to_bit >= sizeof_bits(char))
return -1;
if (from_bit > to_bit) {
from_bit ^= to_bit;
to_bit ^= from_bit;
from_bit ^= to_bit;
}
// ←1bit →3bits
// char: XXXXXxx0 000XXXXX
// ↑ ↑ ↑ ↑
return (int)((*(unsigned char *)ch << (sizeof_bits(char)-(to_bit+1)))
>> (sizeof_bits(char)-(to_bit-from_bit+1)));
}
/*
* 位读写缓冲区销毁
*/
static void bit_buf_destroy(struct bit_buf *bitbuf)
{
if (bitbuf != NULL)
{
if (bitbuf->buf != NULL)
free(bitbuf->buf);
free(bitbuf);
}
}
/*
* 位读写缓冲区创建
*/
static struct bit_buf *bit_buf_create(int size)
{
struct bit_buf *bitbuf = NULL;
bitbuf = malloc(sizeof(struct bit_buf));
if (bitbuf == NULL) {
printf("%s(), %d: malloc failed\n", __FUNCTION__, __LINE__);
goto err;
}
bitbuf->len = size;
bitbuf->buf = malloc(size);
if (bitbuf->buf == NULL) {
printf("%s(), %d: malloc failed\n", __FUNCTION__, __LINE__);
goto err;
}
set_bitrdwr_position(&bitbuf->write_pos, bitbuf->buf, sizeof_bits(char)-1);
set_bitrdwr_position(&bitbuf->read_pos, bitbuf->buf, sizeof_bits(char)-1);
return bitbuf;
err:
bit_buf_destroy(bitbuf);
return NULL;
}
/*
* buf->read_pos.p:pos开始处,读取bits位对应的值
* bits>sizeof_bits(int),取低sizeof(int)位
*/
static int bit_buf_read(struct bit_buf *bitbuf, int bits)
{
int num = 0;
while (bits > 0)
{
int _bits;
if (bits > sizeof_bits(int))
{
// 忽略int范围以外的高位
_bits = (bitbuf->read_pos.pos+1) < bits-sizeof_bits(int) ?
(bitbuf->read_pos.pos+1) : bits-sizeof_bits(int);
}
else
{
// int范围内的值
int _num;
_bits = (bitbuf->read_pos.pos+1) < bits ? (bitbuf->read_pos.pos+1) : bits;
_num = bitrd_in_char(bitbuf->read_pos.p, bitbuf->read_pos.pos, (bitbuf->read_pos.pos+1)-_bits);
num |= ((_num <<(bits-_bits)) & ~(((unsigned int)((1LL<<sizeof_bits(int))-1) << bits) | ((1<<(bits-_bits))-1)));
}
if (_bits < bitbuf->read_pos.pos+1)
bitbuf->read_pos.pos -= _bits;
else {
bitbuf->read_pos.p ++;
bitbuf->read_pos.pos = sizeof_bits(char)-1;
}
bits -= _bits;
}
return num;
}
/*
* buf->write_pos.p:pos开始处的bits位,填充为num值
* bits>sizeof(int),高位填充0.
*/
static int bit_buf_write(struct bit_buf *bitbuf, int num, int bits)
{
while (bits > 0)
{
// 根据buf->write_pos->pos,和剩余bits,确定当前要写的区间
// (high, low] →buf->write_pos.pos
int _bits = (bitbuf->write_pos.pos+1) < bits ? (bitbuf->write_pos.pos+1) : bits;
int low = bits-_bits;
unsigned char fill_num = 0;
if (low < sizeof_bits(int)) {
int high = bits > sizeof_bits(int) ? sizeof_bits(int) : bits;
fill_num = (num & ~((unsigned int)((1LL<<sizeof_bits(int))-1)<<high)) >> low;
}
if (bitbuf->write_pos.p >= bitbuf->buf+bitbuf->len) {
printf("%s(), %d: no enough buf\n", __FUNCTION__, __LINE__);
return -1;
}
bitwr_in_char(bitbuf->write_pos.p, bitbuf->write_pos.pos, (bitbuf->write_pos.pos+1)-_bits, fill_num);
// never: _bits > bitbuf->write_pos.pos+1
if (_bits < bitbuf->write_pos.pos+1)
bitbuf->write_pos.pos -= _bits;
else {
bitbuf->write_pos.p ++;
bitbuf->write_pos.pos = sizeof_bits(char)-1;
}
bits -= _bits;
}
return 0;
}
/*
* 读文件内容,以指定位数为一个值
*/
static int bits_read(char *file, enum BIT_RDWR_MOD mod, int bits, int *num)
{
static int fd = 0;
static struct bit_buf *bitbuf = NULL;
#define close_buf_fd() do { \
if (bitbuf != NULL) { \
bit_buf_destroy(bitbuf); \
bitbuf = NULL; \
} \
if (fd > 0) { \
close(fd); \
fd = 0; \
} \
} while(0)
if (mod == MOD_STOP) {
close_buf_fd();
return RET_NORMAL;
}
if (fd <= 0)
{
if ((fd = open(file, O_RDONLY)) < 0) {
printf("%s(), %d: open file \"%s\" failed\n", __FUNCTION__, __LINE__, file);
goto err;
}
if ((bitbuf = bit_buf_create(BIT_BUF_SIZE)) == NULL)
goto err;
set_bitrdwr_position(&bitbuf->read_pos, bitbuf->buf+bitbuf->len, sizeof_bits(char)-1);
}
if (!bit_buf_rdable(bitbuf, bits))
{
int i = 0, len;
while (bitbuf->read_pos.p+i < bitbuf->buf+bitbuf->len)
{
bitbuf->buf[i] = bitbuf->read_pos.p[i];
i ++;
}
len = read(fd, bitbuf->buf+i, bitbuf->len-i);
if (len < 0)
goto err;
bitbuf->read_pos.p = bitbuf->buf;
bitbuf->len = len+i;
#ifdef LZW_DEBUG
{
int j = 0;
for (; j < bitbuf->len; j ++)
printf("%02x ", (unsigned char)bitbuf->buf[j]);
printf("\n");
printf("pos: %d\n", bitbuf->read_pos.pos);
}
#endif
if (!bit_buf_rdable(bitbuf, bits)) {
close_buf_fd();
return RET_FINISH;
}
}
#ifdef LZW_DEBUG
printf("%s(), %d: %p, %d -----\n", __FUNCTION__, __LINE__, bitbuf->read_pos.p, bitbuf->read_pos.pos);
#endif
*num = bit_buf_read(bitbuf, bits);
return RET_NORMAL;
err:
close_buf_fd();
return RET_ERR;
}
/*
* 将num值以指定位数写进文件
*/
static int bits_write(char *file, enum BIT_RDWR_MOD mod, int bits, int num)
{
static int fd = 0;
static struct bit_buf *bitbuf = NULL;
#define close_buf_fd() do { \
if (bitbuf != NULL) { \
bit_buf_destroy(bitbuf); \
bitbuf = NULL; \
} \
if (fd > 0) { \
close(fd); \
fd = 0; \
} \
} while(0)
if (mod == MOD_STOP)
{
if (fd >0 && (bitbuf->write_pos.p > bitbuf->buf
|| bitbuf->write_pos.pos != sizeof_bits(char)-1)) {
write(fd, bitbuf->buf, (bitbuf->write_pos.p+1)-bitbuf->buf);
#ifdef LZW_DEBUG
{
int i = 0;
for (; i < (bitbuf->write_pos.p+1)-bitbuf->buf; i ++)
printf("%02x ", (unsigned char)bitbuf->buf[i]);
printf("\n");
printf("%s(), %d: flush !!!!!\n", __FUNCTION__, __LINE__);
printf("pos: %d\n", bitbuf->write_pos.pos);
}
#endif
}
close_buf_fd();
return RET_NORMAL;
}
if (fd <= 0)
{
if ((fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0644)) < 0) {
printf("%s(), %d: open file \"%s\" failed\n", __FUNCTION__, __LINE__, file);
goto err;
}
if ((bitbuf = bit_buf_create(BIT_BUF_SIZE)) == NULL)
goto err;
}
if (!bit_buf_wrable(bitbuf, bits))
{
int len = bitbuf->write_pos.p - bitbuf->buf;
write(fd, bitbuf->buf, len);
#ifdef LZW_DEBUG
{
int i = 0;
for (; i < len; i ++)
printf("%02x ", (unsigned char)bitbuf->buf[i]);
printf("\n");
printf("%s(), %d: flush, %d, len: %d, *p: %x !!!!!\n",
__FUNCTION__, __LINE__, num, len, *(unsigned char*)bitbuf->write_pos.p);
}
#endif
bitbuf->buf[0] = *bitbuf->write_pos.p;
bitbuf->write_pos.p = bitbuf->buf;
}
bit_buf_write(bitbuf, num, bits);
return RET_NORMAL;
err:
close_buf_fd();
return RET_ERR;
}
int main()
{
#define BITS 11
int i, ret;
for (i = 0; i < 1024; i ++)
bits_write("./test.txt", MOD_NORMAL, BITS, i);
bits_write("./test.txt", MOD_STOP, 0, 0);
while(1)
{
ret = bits_read("./test.txt", MOD_NORMAL, BITS, &i);
switch (ret)
{
case RET_NORMAL:
printf("%d +++++\n", i);
break;
case RET_FINISH:
goto finish;
case RET_ERR:
default:
goto err;
}
}
finish:
return 0;
err:
return -1;
}
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
struct bitrdwr_pos {
char *p;
int pos; // 0~7
};
struct bit_buf {
char *buf;
int len;
struct bitrdwr_pos write_pos;
struct bitrdwr_pos read_pos;
};
#define sizeof_bits(type) (sizeof(type)*8)
#define bit_buf_rdable(bitbuf_addr, bits) \
(((((bitbuf_addr)->buf+(bitbuf_addr)->len) \
- ((bitbuf_addr)->read_pos.p+1))*sizeof_bits(char)) \
+ ((bitbuf_addr)->read_pos.pos+1) >= (bits))
#define bit_buf_wrable(bitbuf_addr, bits) \
(((((bitbuf_addr)->buf+(bitbuf_addr)->len) \
- ((bitbuf_addr)->write_pos.p+1))*sizeof_bits(char)) \
+ ((bitbuf_addr)->write_pos.pos+1) >= (bits))
#define set_bitrdwr_position(pos_addr, _p, _pos) do { \
(pos_addr)->p = (_p); \
(pos_addr)->pos = (_pos); \
} while(0)
#define BIT_BUF_SIZE 1024
enum BIT_RDWR_MOD {
MOD_NORMAL,
MOD_STOP,
};
enum BIT_RDWR_RET {
RET_NORMAL,
RET_FINISH,
RET_ERR,
};
/*
* 7 0
* char: xxxxxxxx
* ↑ ↑ [from_bit,to_bit]
* +---+
* ↖num
* example:
* 5 -> [bit1, bit3]: xxxx[101]x
* 10-> [bit1, bit3]: xxxx[010]x, overflow
*/
static int bitwr_in_char(char *ch, int from_bit, int to_bit, unsigned char num)
{
if (from_bit < 0 || from_bit >= sizeof_bits(char)
|| to_bit < 0 || to_bit >= sizeof_bits(char))
return -1;
if (from_bit > to_bit) {
from_bit ^= to_bit;
to_bit ^= from_bit;
from_bit ^= to_bit;
}
if ((1<<(to_bit-from_bit+1)) - 1 < num)
printf("%s(), %d: overflow\n", __FUNCTION__, __LINE__);
*ch &= ((((1<<sizeof_bits(char))-1)<<(to_bit+1)) | ((1<<from_bit)-1));
*ch |= (num<<from_bit);
return 0;
}
/*
* 7 0
* char: xXXXXXxx
* ↑ ↑ [from_bit,to_bit]
* +---+
* ↘num
*/
static int bitrd_in_char(char *ch, int from_bit, int to_bit)
{
if (from_bit < 0 || from_bit >= sizeof_bits(char)
|| to_bit < 0 || to_bit >= sizeof_bits(char))
return -1;
if (from_bit > to_bit) {
from_bit ^= to_bit;
to_bit ^= from_bit;
from_bit ^= to_bit;
}
// ←1bit →3bits
// char: XXXXXxx0 000XXXXX
// ↑ ↑ ↑ ↑
return (int)((*(unsigned char *)ch << (sizeof_bits(char)-(to_bit+1)))
>> (sizeof_bits(char)-(to_bit-from_bit+1)));
}
/*
* 位读写缓冲区销毁
*/
static void bit_buf_destroy(struct bit_buf *bitbuf)
{
if (bitbuf != NULL)
{
if (bitbuf->buf != NULL)
free(bitbuf->buf);
free(bitbuf);
}
}
/*
* 位读写缓冲区创建
*/
static struct bit_buf *bit_buf_create(int size)
{
struct bit_buf *bitbuf = NULL;
bitbuf = malloc(sizeof(struct bit_buf));
if (bitbuf == NULL) {
printf("%s(), %d: malloc failed\n", __FUNCTION__, __LINE__);
goto err;
}
bitbuf->len = size;
bitbuf->buf = malloc(size);
if (bitbuf->buf == NULL) {
printf("%s(), %d: malloc failed\n", __FUNCTION__, __LINE__);
goto err;
}
set_bitrdwr_position(&bitbuf->write_pos, bitbuf->buf, sizeof_bits(char)-1);
set_bitrdwr_position(&bitbuf->read_pos, bitbuf->buf, sizeof_bits(char)-1);
return bitbuf;
err:
bit_buf_destroy(bitbuf);
return NULL;
}
/*
* buf->read_pos.p:pos开始处,读取bits位对应的值
* bits>sizeof_bits(int),取低sizeof(int)位
*/
static int bit_buf_read(struct bit_buf *bitbuf, int bits)
{
int num = 0;
while (bits > 0)
{
int _bits;
if (bits > sizeof_bits(int))
{
// 忽略int范围以外的高位
_bits = (bitbuf->read_pos.pos+1) < bits-sizeof_bits(int) ?
(bitbuf->read_pos.pos+1) : bits-sizeof_bits(int);
}
else
{
// int范围内的值
int _num;
_bits = (bitbuf->read_pos.pos+1) < bits ? (bitbuf->read_pos.pos+1) : bits;
_num = bitrd_in_char(bitbuf->read_pos.p, bitbuf->read_pos.pos, (bitbuf->read_pos.pos+1)-_bits);
num |= ((_num <<(bits-_bits)) & ~(((unsigned int)((1LL<<sizeof_bits(int))-1) << bits) | ((1<<(bits-_bits))-1)));
}
if (_bits < bitbuf->read_pos.pos+1)
bitbuf->read_pos.pos -= _bits;
else {
bitbuf->read_pos.p ++;
bitbuf->read_pos.pos = sizeof_bits(char)-1;
}
bits -= _bits;
}
return num;
}
/*
* buf->write_pos.p:pos开始处的bits位,填充为num值
* bits>sizeof(int),高位填充0.
*/
static int bit_buf_write(struct bit_buf *bitbuf, int num, int bits)
{
while (bits > 0)
{
// 根据buf->write_pos->pos,和剩余bits,确定当前要写的区间
// (high, low] →buf->write_pos.pos
int _bits = (bitbuf->write_pos.pos+1) < bits ? (bitbuf->write_pos.pos+1) : bits;
int low = bits-_bits;
unsigned char fill_num = 0;
if (low < sizeof_bits(int)) {
int high = bits > sizeof_bits(int) ? sizeof_bits(int) : bits;
fill_num = (num & ~((unsigned int)((1LL<<sizeof_bits(int))-1)<<high)) >> low;
}
if (bitbuf->write_pos.p >= bitbuf->buf+bitbuf->len) {
printf("%s(), %d: no enough buf\n", __FUNCTION__, __LINE__);
return -1;
}
bitwr_in_char(bitbuf->write_pos.p, bitbuf->write_pos.pos, (bitbuf->write_pos.pos+1)-_bits, fill_num);
// never: _bits > bitbuf->write_pos.pos+1
if (_bits < bitbuf->write_pos.pos+1)
bitbuf->write_pos.pos -= _bits;
else {
bitbuf->write_pos.p ++;
bitbuf->write_pos.pos = sizeof_bits(char)-1;
}
bits -= _bits;
}
return 0;
}
/*
* 读文件内容,以指定位数为一个值
*/
static int bits_read(char *file, enum BIT_RDWR_MOD mod, int bits, int *num)
{
static int fd = 0;
static struct bit_buf *bitbuf = NULL;
#define close_buf_fd() do { \
if (bitbuf != NULL) { \
bit_buf_destroy(bitbuf); \
bitbuf = NULL; \
} \
if (fd > 0) { \
close(fd); \
fd = 0; \
} \
} while(0)
if (mod == MOD_STOP) {
close_buf_fd();
return RET_NORMAL;
}
if (fd <= 0)
{
if ((fd = open(file, O_RDONLY)) < 0) {
printf("%s(), %d: open file \"%s\" failed\n", __FUNCTION__, __LINE__, file);
goto err;
}
if ((bitbuf = bit_buf_create(BIT_BUF_SIZE)) == NULL)
goto err;
set_bitrdwr_position(&bitbuf->read_pos, bitbuf->buf+bitbuf->len, sizeof_bits(char)-1);
}
if (!bit_buf_rdable(bitbuf, bits))
{
int i = 0, len;
while (bitbuf->read_pos.p+i < bitbuf->buf+bitbuf->len)
{
bitbuf->buf[i] = bitbuf->read_pos.p[i];
i ++;
}
len = read(fd, bitbuf->buf+i, bitbuf->len-i);
if (len < 0)
goto err;
bitbuf->read_pos.p = bitbuf->buf;
bitbuf->len = len+i;
#ifdef LZW_DEBUG
{
int j = 0;
for (; j < bitbuf->len; j ++)
printf("%02x ", (unsigned char)bitbuf->buf[j]);
printf("\n");
printf("pos: %d\n", bitbuf->read_pos.pos);
}
#endif
if (!bit_buf_rdable(bitbuf, bits)) {
close_buf_fd();
return RET_FINISH;
}
}
#ifdef LZW_DEBUG
printf("%s(), %d: %p, %d -----\n", __FUNCTION__, __LINE__, bitbuf->read_pos.p, bitbuf->read_pos.pos);
#endif
*num = bit_buf_read(bitbuf, bits);
return RET_NORMAL;
err:
close_buf_fd();
return RET_ERR;
}
/*
* 将num值以指定位数写进文件
*/
static int bits_write(char *file, enum BIT_RDWR_MOD mod, int bits, int num)
{
static int fd = 0;
static struct bit_buf *bitbuf = NULL;
#define close_buf_fd() do { \
if (bitbuf != NULL) { \
bit_buf_destroy(bitbuf); \
bitbuf = NULL; \
} \
if (fd > 0) { \
close(fd); \
fd = 0; \
} \
} while(0)
if (mod == MOD_STOP)
{
if (fd >0 && (bitbuf->write_pos.p > bitbuf->buf
|| bitbuf->write_pos.pos != sizeof_bits(char)-1)) {
write(fd, bitbuf->buf, (bitbuf->write_pos.p+1)-bitbuf->buf);
#ifdef LZW_DEBUG
{
int i = 0;
for (; i < (bitbuf->write_pos.p+1)-bitbuf->buf; i ++)
printf("%02x ", (unsigned char)bitbuf->buf[i]);
printf("\n");
printf("%s(), %d: flush !!!!!\n", __FUNCTION__, __LINE__);
printf("pos: %d\n", bitbuf->write_pos.pos);
}
#endif
}
close_buf_fd();
return RET_NORMAL;
}
if (fd <= 0)
{
if ((fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0644)) < 0) {
printf("%s(), %d: open file \"%s\" failed\n", __FUNCTION__, __LINE__, file);
goto err;
}
if ((bitbuf = bit_buf_create(BIT_BUF_SIZE)) == NULL)
goto err;
}
if (!bit_buf_wrable(bitbuf, bits))
{
int len = bitbuf->write_pos.p - bitbuf->buf;
write(fd, bitbuf->buf, len);
#ifdef LZW_DEBUG
{
int i = 0;
for (; i < len; i ++)
printf("%02x ", (unsigned char)bitbuf->buf[i]);
printf("\n");
printf("%s(), %d: flush, %d, len: %d, *p: %x !!!!!\n",
__FUNCTION__, __LINE__, num, len, *(unsigned char*)bitbuf->write_pos.p);
}
#endif
bitbuf->buf[0] = *bitbuf->write_pos.p;
bitbuf->write_pos.p = bitbuf->buf;
}
bit_buf_write(bitbuf, num, bits);
return RET_NORMAL;
err:
close_buf_fd();
return RET_ERR;
}
int main()
{
#define BITS 11
int i, ret;
for (i = 0; i < 1024; i ++)
bits_write("./test.txt", MOD_NORMAL, BITS, i);
bits_write("./test.txt", MOD_STOP, 0, 0);
while(1)
{
ret = bits_read("./test.txt", MOD_NORMAL, BITS, &i);
switch (ret)
{
case RET_NORMAL:
printf("%d +++++\n", i);
break;
case RET_FINISH:
goto finish;
case RET_ERR:
default:
goto err;
}
}
finish:
return 0;
err:
return -1;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [求助]CVE编号对应代码 5741
- [求助]汇编语句“xx = .”是什么意思? 2896
- [求助]shellcode 丶丶 2953
- [分享]网址记录 7912
看原图
赞赏
雪币:
留言: