数据缓冲的任意多位的读写操作

如果要移植到其它平台,修改类型的宏定义即可。

头文件 (utiloph.h)

#ifndef UTILOPH_H__
#define  UTILOPH_H__

#ifdef __cplusplus
extern   " C "   {
#endif


//* mask bit - [0x0001, 0x0002, 0x0004, ... 0x8000]
#define MASK_BIT(pos_in_bit) 
        ((UINT16)(
1 << (pos_in_bit)))
//* len_in_bit<32
#define LENGTH_TO_BITS(len_in_bit) 
        (
~(0xffffffff << (len_in_bit)))
#define MASK_BITS(lowest_pos, len_in_bit) 
        ((LENGTH_TO_BITS(len_in_bit) 
& 0xffffffff<< (lowest_pos))
#define CLR_BITS(addr_data, lowest_pos, len_in_bit) 
        ((addr_data) 
& (~MASK_BITS((lowest_pos), (len_in_bit))))

///
//* 得到缓冲数据从pos_in_bit开始的bit数据
/**
 * /param pbuf [IN]缓冲数据
 * /param pos_in_bit [IN]位置(从0开始)(in bit)
 * /return 得到的值
 
*/

extern UINT8
oph_get_bit(
const UINT8* pbuf, UINT32 pos_in_bit);

//* 设置缓冲数据从pos_in_bit开始的bit数据
/**
 * /param pbuf [IN,OUT]缓冲数据
 * /param pos_in_bit [IN]位置(从0开始)(in bit)
 * /param new_val [IN]新值
 
*/

extern void
oph_set_bit(UINT8
* pbuf, UINT32 pos_in_bit, UINT8 new_val);

//* 得到缓冲数据从pos_in_bit开始的多位数据
/**
 * /param pbuf [IN]缓冲数据
 * /param pos_in_bit [IN]起始位置(从0开始)(in bit)
 * /param len_in_bit [IN]长度(<=32) (in bit)
 * /return 得到的多位的值(0~31)
 
*/

extern UINT32
oph_get_bits(
const UINT8* pbuf, UINT32 pos_in_bit, UINT8 len_in_bit);

//* 设置缓冲数据从pos_in_bit开始的多位数据
/**
 * /param pbuf [IN,OUT]缓冲数据
 * /param pos_in_bit [IN]起始位置(从0开始)(in bit)
 * /param len_in_bit [IN]长度(<=32)(in bit)
 * /param new_val [IN]新值
 
*/

extern void
oph_set_bits(UINT8
* pbuf, UINT32 pos_in_bit, UINT8 len_in_bit, UINT32 new_val);

//* 复制源缓冲长度为bit_src_pos之后的多bit数据到目的缓冲长度为bit_dst_pos之后的多bit之后
/**
 * /param pdst_buf [IN,OUT]目的缓冲数据
 * /param dst_pos_in_bit [IN]目的缓冲起始位置(从0开始)(in bit)
 * /param psrc_buf [IN]源缓冲数据
 * /param src_pos_in_bit [IN]源缓冲起始位置(从0开始)(in bit)
 * /param len_in_bit [IN]待复制的源缓冲数据的长度(in bit)
 
*/

extern void
oph_copy_bits(UINT8 
*pdst_buf, UINT32 dst_pos_in_bit,
                
const UINT8* psrc_buf, UINT32 src_pos_in_bit, UINT32 len_in_bit);


#ifdef __cplusplus
}

#endif

#endif  /* UTILOPH_H__ */

实现文件 (utiloph.c)

#include  " utiloph.h "


UINT8
oph_get_bit(
const  UINT8 *  pbuf, UINT32 pos_in_bit)
{
    UINT32 index
=0;                /* 缓冲索引 */
    UINT8 co_pos_in_bit
=0;        /* 相对(comparatively)位置(0~7)(in bit) */
    UINT8 result
=0;                /* 返回结果 */
    UINT8 temp
=0;

    assert(pbuf 
!= NULL);
    index
=pos_in_bit/8;
    co_pos_in_bit
=(UINT8)(pos_in_bit%8);

    
/* 得到当前位所在的字节 */
    temp
=pbuf[index];
    
/* 得到当前位 */
    temp 
<<= co_pos_in_bit;
    temp 
>>= (8-1);
    result
=(UINT8)(temp & 0x01);

    
return result;
}


void
oph_set_bit(UINT8
*  pbuf, UINT32 pos_in_bit, UINT8 new_val)
{
    UINT32 index
=0;                /* 缓冲索引 */
    UINT8 co_pos_in_bit
=0;        /* 相对(comparatively)位置(0~7)(in bit) */
    UINT8 temp
=0;

    assert(pbuf 
!= NULL);
    index
=pos_in_bit/8;
    co_pos_in_bit
=(UINT8)(pos_in_bit%8);

    temp
=pbuf[index];
    
/* 清零 */
    temp 
&= (UINT8)(~(1 << (8-co_pos_in_bit-1)));

    
if((new_val & 0x01!= 0x0)
    
{
        
/* 赋新值 */
        temp 
|= (UINT8)(1 << (8-co_pos_in_bit-1));
    }

    pbuf[index]
=temp;
}


UINT32
oph_get_bits(
const  UINT8 *  pbuf, UINT32 pos_in_bit, UINT8 len_in_bit)
{
    UINT32 result
=0;            /* 返回结果 */
    UINT32 index
=0;                /* 缓冲索引 */
    UINT8 co_pos_in_bit
=0;        /* 相对(comparatively)位置(0~7)(in bit) */
    UINT8 temp_buf[
5]={0};        /* 临时缓冲 */
    UINT8 i
=0;

    assert(pbuf 
!= NULL);
    assert(len_in_bit 
<= 32);
    memset(temp_buf, 
0sizeof(temp_buf));
    
if (len_in_bit == 0)
        
return 0;
    index
=pos_in_bit/8;
    co_pos_in_bit
=(UINT8)(pos_in_bit%8);
    
/* 复制缓冲 */
    
for (i=0; i<5; i++)
        temp_buf[i]
=pbuf[index+i];
    
/* 取32-bit */
    result 
= MAKELONG(
        MAKEWORD((temp_buf[
3<< co_pos_in_bit) | (temp_buf[4>> (8-co_pos_in_bit))
        , (temp_buf[
2<< co_pos_in_bit) | (temp_buf[3>> (8-co_pos_in_bit))), 
        MAKEWORD((temp_buf[
1<< co_pos_in_bit) | (temp_buf[2>> (8-co_pos_in_bit))
        , (temp_buf[
0<< co_pos_in_bit) | (temp_buf[1>> (8-co_pos_in_bit)))
        );
    
/* 取有用部分 */
    result 
>>= (32-len_in_bit);

    
return result;
}


void
oph_set_bits(UINT8
*  pbuf, UINT32 pos_in_bit, UINT8 len_in_bit, UINT32 new_val)
{
    UINT8 len_count
=0;            /* 当前剩余位长度计数(in bit) */
    UINT32 index
=0;                /* 缓冲索引 */
    UINT8 co_pos_in_bit
=0;        /* 相对(comparatively)位置(0~7)(in bit) */
    UINT8 new_buf[
4]={0};        /* new_val缓冲 */
    UINT8 temp_buf[
5]={0};        /* 临时缓冲 */
    UINT8 i
=0;
    UINT8 k
=0;
    UINT8 nCount
=0;

    assert(pbuf 
!= NULL);
    assert(len_in_bit 
<= 32);
    memset(temp_buf, 
0sizeof(temp_buf));
    
if (len_in_bit == 0)
        
return;
    index
=pos_in_bit/8;
    co_pos_in_bit
=(UINT8)(pos_in_bit%8);

    
if (len_in_bit<32)
        new_val 
&= (UINT32)MASK_BITS(0, len_in_bit);
    new_val 
<<= (32-len_in_bit);
    new_buf[
0]=HIBYTE(HIWORD(new_val));
    new_buf[
1]=LOBYTE(HIWORD(new_val));
    new_buf[
2]=HIBYTE(LOWORD(new_val));
    new_buf[
3]=LOBYTE(LOWORD(new_val));

    temp_buf[
0]=(UINT8)((UINT16)(new_buf[0>> co_pos_in_bit) & 0x00ff);
    temp_buf[
1]=(UINT8)(((UINT16)(new_buf[0<< (8-co_pos_in_bit)) 
        
| (UINT16)(new_buf[1>> co_pos_in_bit)) & 0x00ff);
    temp_buf[
2]=(UINT8)(((UINT16)(new_buf[1<< (8-co_pos_in_bit)) 
        
| (UINT16)(new_buf[2>> co_pos_in_bit)) & 0x00ff);
    temp_buf[
3]=(UINT8)(((UINT16)(new_buf[2<< (8-co_pos_in_bit)) 
        
| (UINT16)(new_buf[3>> co_pos_in_bit)) & 0x00ff);
    temp_buf[
4]=(UINT8)((UINT16)(new_buf[3<< (8-co_pos_in_bit)) & 0x00ff);

    
if (co_pos_in_bit+len_in_bit<=8)
    
/* 在同一段8-bit内 */
    
{
        pbuf[index]
=(UINT8)CLR_BITS(pbuf[index], (8-co_pos_in_bit-len_in_bit), len_in_bit);
        pbuf[index] 
|= temp_buf[0];
    }

    
else
    
/* 跨8-bit段 */
    
{
        len_count
=len_in_bit;
        
/* 首部 */
        pbuf[index]
=(UINT8)CLR_BITS(pbuf[index], 0, (8-co_pos_in_bit));
        pbuf[index
++|= temp_buf[k++];
        len_count 
= (UINT8)(len_count-(8-co_pos_in_bit));
        
/* 中部 */
        nCount 
= (UINT8)(len_count/8);
        
for (i=0; i<nCount; i++)
        
{
            pbuf[index
++]=temp_buf[k++];
            len_count 
-= 8;
        }

        
/* 尾部 */
        
if (len_count>0)
        
{
            pbuf[index]
=(UINT8)CLR_BITS(pbuf[index], (8-len_count), len_count);
            pbuf[index] 
|= temp_buf[k];
        }

    }

}


void
oph_copy_bits(UINT8 
* pdst_buf, UINT32 dst_pos_in_bit,
                
const  UINT8 *  psrc_buf, UINT32 src_pos_in_bit, UINT32 len_in_bit)
{
    UINT32 len_count
=0;            /* 当前剩余位长度计数(in bit) */
    UINT32 dst_cur_pos;            
/* 目的缓冲的当前位置(in bit) */
    UINT32 src_cur_pos;            
/* 源缓冲的当前位置(in bit) */
    UINT32 temp
=0;                /* 当前要复制的数据 */

    assert(pdst_buf 
!= NULL);
    assert(psrc_buf 
!= NULL);
    
if (len_in_bit == 0)
        
return;

    len_count
=len_in_bit;
    dst_cur_pos
=dst_pos_in_bit;
    src_cur_pos
=src_pos_in_bit;

    
/* 剩余位长度 > 32-bit 时 */
    
for(len_count=len_in_bit; len_count>32; len_count -= 32)
    
{
        temp
=oph_get_bits(psrc_buf, src_cur_pos, 32);
        oph_set_bits(pdst_buf, dst_cur_pos, 
32, temp);
        dst_cur_pos 
+= 32;
        src_cur_pos 
+= 32;
    }

    
/* 剩余位长度 <= 32-bit 时 */
    temp
=oph_get_bits(psrc_buf, src_cur_pos, (UINT8)len_count);
    oph_set_bits(pdst_buf, dst_cur_pos, (UINT8)len_count, temp);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值