#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#define DEBUG(fmt, arg...) printf("\033[32m[%s:%d]\033[36m"fmt"\033[0m", __FUNCTION__, __LINE__, ##arg)
unsigned int get_bit_value(unsigned int src, int bit_offset, int bit_size)
{
#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
unsigned int mask = 0;
src >>= bit_offset;
while(bit_size > 0)
mask |= 1 << --bit_size;
return src & mask;
#else
unsigned int mask = 0;
src >>= (sizeof(src) * 8 - bit_offset - bit_size);
while(bit_size > 0)
mask |= 1 << --bit_size;
return src & mask;
#endif
}
int get_bit_buf(unsigned char *buf, int bit_offset, int bit_size)
{
#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
int byte_offset = bit_offset / 8;
unsigned char *p_pos = buf + byte_offset;
int byte_size = 0;
unsigned int value = 0;
int i = 0;
bit_offset = bit_offset % 8;
byte_size = (bit_offset + bit_size + 7) / 8;
for(i = 0; i < byte_size; i++)
{
value |= (p_pos[i] << (i * 8));
}
return get_bit_value(value, bit_offset, bit_size);
#else
int byte_offset = bit_offset / 8;
unsigned char *p_pos = buf + byte_offset;
int byte_size = 0;
unsigned int value = 0;
bit_offset = bit_offset % 8;
byte_size = (bit_offset + bit_size + 7) / 8;
bit_offset += ((sizeof(value) - byte_size) * 8);
while(byte_size > 0)
{
value = (value << 8) | p_pos[0];
p_pos++;
byte_size--;
}
return get_bit_value(value, bit_offset, bit_size);
#endif
}
void set_bit_buf(unsigned char *buf, int bit_offset, int bit_size, int value)
{
#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
int byte_offset = bit_offset / 8;
unsigned char *p_pos = buf + byte_offset;
int byte_size = 0;
int i = 0;
bit_offset = bit_offset % 8;
value = value << bit_offset;
byte_size = (bit_offset + bit_size + 7) / 8;
for(i = 0; i < byte_size; i++)
{
p_pos[i] |= (value >> (i * 8)) & 0xff;
}
#else
int byte_offset = bit_offset / 8;
unsigned char *p_pos = buf + byte_offset;
int byte_size = 0;
bit_offset = bit_offset % 8;
if(((bit_size + bit_offset) % 8) != 0)
value = value << (8 - ((bit_size + bit_offset) % 8));
byte_size = (bit_offset + bit_size + 7) / 8;
while(byte_size > 0)
{
p_pos[0] |= ((value >> ((byte_size - 1) * 8)) & 0xff);
p_pos++;
byte_size--;
}
#endif
}
typedef struct
{
unsigned int a:8;
unsigned int b:1;
unsigned int c:4;
unsigned int d:3;
unsigned int e:9;
unsigned int f:7;
}test_st;
static void hex_dump_data(void *data, int data_size)
{
int i = 0;
unsigned char *p_char = data;
char hex_data[16 * 4];
int len = 0;
for(i = 0; i < data_size; i++)
{
if(i % 16 == 15)
{
len += snprintf(hex_data + len, sizeof(hex_data) - len, "%02x\n", p_char[i]);
DEBUG("%s", hex_data);
memset(hex_data, 0, sizeof(hex_data));
len = 0;
}
else
{
len += snprintf(hex_data + len, sizeof(hex_data) - len, "%02x ", p_char[i]);
}
}
if(len > 0)
{
len += snprintf(hex_data + len, sizeof(hex_data) - len, "\n");
DEBUG("%s", hex_data);
}
}
int main(int argc, char *argv[])
{
test_st v;
v.a = 67;
v.b = 1;
v.c = 4;
v.d = 2;
v.e = 300;
v.f = 4;
#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
DEBUG("LITTLE_ENDIAN\n");
#elif __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
DEBUG("BIG_ENDIAN\n");
#endif
unsigned char buf[4] = {0};
set_bit_buf(buf, 0, 8, v.a);
set_bit_buf(buf, 8, 1, v.b);
set_bit_buf(buf, 9, 4, v.c);
set_bit_buf(buf, 13, 3, v.d);
set_bit_buf(buf, 16, 9, v.e);
set_bit_buf(buf, 25, 7, v.f);
hex_dump_data(buf, sizeof(buf));
DEBUG("a %d\n", get_bit_buf(buf, 0, 8));
DEBUG("b %d\n", get_bit_buf(buf, 8, 1));
DEBUG("c %d\n", get_bit_buf(buf, 9, 4));
DEBUG("d %d\n", get_bit_buf(buf, 13, 3));
DEBUG("e %d\n", get_bit_buf(buf, 16, 9));
DEBUG("f %d\n\n", get_bit_buf(buf, 25, 7));
memcpy(buf, &v, sizeof(v));
hex_dump_data(buf, sizeof(buf));
DEBUG("a %d\n", get_bit_buf(buf, 0, 8));
DEBUG("b %d\n", get_bit_buf(buf, 8, 1));
DEBUG("c %d\n", get_bit_buf(buf, 9, 4));
DEBUG("d %d\n", get_bit_buf(buf, 13, 3));
DEBUG("e %d\n", get_bit_buf(buf, 16, 9));
DEBUG("f %d\n\n", get_bit_buf(buf, 25, 7));
return 0;
}
位域结构存储和读取
最新推荐文章于 2021-08-06 16:35:11 发布