基于位操作的类CBitBuffer

由于工作的需要,我写了一个基于位操作的类,由CFile类模仿而来。写的比较仓促,许多操作效率较低,有待改进。

该代码对我比较有用,如果你对代码有任何改进希望你能告诉我。Email:mymong@163.net

一、类定义class CBitBuffer 
{
private:
LONGLONG m_llLength;   // 缓存的大小,单位(位)。
BYTE *  m_pBegin;    // 缓存的起始指针,字节指针,指向缓存的第一个字节。
BYTE *  m_pEnd;    // 缓存的末尾指针,字节指针,指向缓存的最后一个字节的下一个字节。
BYTE *  m_pCurByte;   // 缓存的当前指针,字节指针,指向当前字节。
BYTE   m_nCurOffset; // 从当前字节起始的位偏移量,值范围0-7。
BOOL   m_bLocked;   // 缓存是否被锁住,当你创建一块缓存时,该缓存在释放前为锁住状态,不能重新赋值头指针及缓存大小。
// 注意:m_pCurByte与m_nCurOffset联合构成位指针,可以指向当前位。
public:
// 【状态相关】:
BOOL IsLocked();     // 当前是否为缓存锁住状态。
BOOL IsByteAligned();  // 当前位指针是否为字节对齐。
// 【输入输出】:
// 将当前位写为‘0’,位指针自动后移一位。
void WriteBit0();
// 将当前位写为‘1’,位指针自动后移一位。
void WriteBit1();
// 从当前位指针开始读取nCount个位,并将其转换为整数输出,位指针自动后移。
// (in/out) nCount: 读取的位的个数。
// 注意:该数值范围是0-32,并且确保使用该函数时保证读取数值不会越界,
//   考虑到效率比较低,函数体内没有加入任何校验,需要使用者小心。
int Read(BYTE nCount);
// 从当前位指针开始写入一串二进制数,该数以字符串形式输入,位指针自动后移。
// 参数例子: "0011 1011 0111 1111" ,空格会被忽略。
//      "*000 1111 1111 *111" ,星号所在的位会被略过而不被写入。
void WriteBinary(char * pBinStr);
// 从当前字节指针开始写入一个16进制数,该数以字符串形式输入,位指针自动后移,位偏移置0。
// 参数例子: "00 01 BA", 空格会被忽略,字符串中不能有“0X”字符,且字母均大写。
// 注意:使用该函数前必须确保已经字节对齐了、没有"0X"、字母均大写等,函数体内没有进行校验!
void WriteHex(char * pHexStr);
// 从当前位指针开始写入nCount个位,这nCount个位对应一个指定的数值,该数值可以以十进制或十六进制输入。
void WriteDecimal(UINT nData, int nCount);
// 复制一段数据到当前的缓存,从当前字节指针开始写入,位指针自动后移,位偏移置0。
// (in) pSubBuff: 源数据的头指针。
// (in/out) nCount: 复制的长度,注意是字节的个数。
// actually writed byte count. The count may be less than nCount if the
// end of buffer was reached.
void WriteBuffer(BYTE * pSubBuff, int &nCount);
// 【位置相关】:
// 取得缓存的起始指针。
BYTE * GetBegin();
// 取得缓存的末尾指针,该指针指向缓存最后一个字节的下一个字节。
BYTE * GetEnd();
// 取得当前指针。
BYTE * GetCurByte();
// 取得当前位指针在当前字节的位偏移量。
BYTE GetCurOffset();
// 设定缓存的大小,单位是“位”,但是必须确保是8的倍数。
// 设定缓存大小前,需要确保缓存起始指针已经设定。
// 返回上次设定的缓存大小,如果是第一次设定,返回0。
// 如果缓存已经被锁定,则不能重设大小,返回-1表示失败。
// (in) llLen: 缓存大小,单位是“位”,且是8的倍数,最好以1024*8的形式输入。
LONGLONG SetLength(LONGLONG llLen);
// 取得缓存的大小,单位是“位”,应该是8的倍数。
LONGLONG GetLength();
// 移动当前位指针到缓存的末尾,实际指向缓存最后一个字节的下一个字节的第一个位。
// 返回缓存的大小,单位是“位”,应该是8的倍数。
LONGLONG SeekToEnd();
// 移动当前位指针到缓存的起始处,实际指向缓存的第一个字节的第一个位。
void SeekToBegin();
// 移动当前位指针一个指定的数值偏移量,偏移量是正数时向末尾移动,偏移量是负数时向起始移动,偏移量单位时“位”。
// 返回当前位指针相对起始地址的偏移量,单位时“位”,返回值如果是负数时表示失败。
//(in) llOff: 偏移量,单位"位"。
LONGLONG Seek(LONGLONG llOff);
// 【构造函数】:
// 缺省构造函数没有设定缓存及其大小等,注意在使用前要设定相关内容。
CBitBuffer();
// 该构造函数设定了缓存及其大小。缓存大小缺省为0。
// 缓存大小缺省为0,你必须在实际使用前设定正确的缓存大小。
// 注意:最好不要使用该构造函数,推荐使用ShareBuffer()函数。
CBitBuffer(BYTE * pBegin, LONGLONG llLen = 0);
// 该函数重设缓存的起始地址以及缓存大小,并计算结束地址。
// 如果你没有设定缓存的大小,缺省会被设为0,在使用前一定要设定正确的数值。
// 如果已经有一块数据区,你希望使用CBitBuffer来管理,推荐使用该函数进行初始化。
// 注意:
// 如果是在其他地方分配的内存,使用CBitBuffer来管理,则该内存的释放不是CBitBuffer的职责。
// 如果该CBitBuffer对象已经使用Create()函数创建了缓存,则在调用Release()函数进行释放前不能使用该函数重新设定缓存。
// 如果该CBitBuffer对象已经有缓存,并且也是用该函数设定的,则可以使用该函数再次设定新的缓存。
// 使用该函数设定的缓存不被锁定,所以可以重设缓存及大小。
// 使用该函数时,如果缓存已被锁定,则会返回FALSE表示失败。
// (in) pBegin :被管理的数据区的首地址,指的是第一个字节的地址。
// (in) llLen :数据区被管理的大小,单位“位”,必须是8的倍数,建议使用1024*8的形式输入。
BOOL ShareBuffer(BYTE * pBegin, LONGLONG llLen = 0);
// 使用输入的大小创建一块缓存,缓存大小单位是“位”,必须是8的倍数,建议使用1024*8的形式输入。
// 缓存创建成功返回TRUE,失败返回FALSE。
// 注意:使用该函数创建缓存成功后,缓存会被锁定;调用该函数时,如果缓存已被锁定,创建会失败。
//   如果你确定已经不再需要该缓存时,记住调用Release()函数解锁定并释放缓存。
BOOL Create(LONGLONG llLen);
// 解除缓存锁定,并释放由Create()函数创建的缓存。
void Release();
virtual ~CBitBuffer();
};

时间: 2025-01-25 07:01:22

基于位操作的类CBitBuffer的相关文章

CSS教程:视觉语义不等于基于表现的类

网页制作Webjx文章简介:HTML和CSS中的视觉语义. 你和用户之间的网站堆栈(简化版) 在TXJS大会的最后一天,一个开发者问我: 面向对象的CSS没有给你留下一大堆基于表现的class名? 网络堆栈中的每一层都有它自己的结构.你不会期望将数据库架构用于构建PHP中间件,人们对于HTML和CSS的期望是一样一样的.HTML需要用一种能代表数据或内容的有意义的东西来书写,也就是我所谓的代码语义.HTML中的代码语义对于可移植性和易用性都是极为重要的.另一方面,CSS在堆栈中确实是一个独立的层

C#基于大整数类的RSA算法实现(公钥加密解密,私钥加密解密)

最近因为项目需要通过RSA加密来保证客户端与服务端的通信安全.但是C#自 带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证 书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实 现是基于网上提供的一个大整数类. 一.密钥管理 取得密钥主要 是通过2种方式 一种是通过RSACryptoServiceProvider取得: /// <summary> /// RSA算法对象,此处主要用于获取密钥对 /// </summary&g

基于java枚举类综合应用的说明_java

如下面代码以交灯为示例: 复制代码 代码如下: public class Test {      public static void main(String[] args) {         Trafficlight light = Trafficlight.RED;          System.out.println(light.time);         System.out.println(light.nextLigth());         // ordinal()方法返回枚

android基于SwipeRefreshLayout实现类QQ的侧滑删除

前言 记得去年做一个聊天项目需要实现类似QQ的下拉刷新并且有侧滑删除的功能,在网上找了很久都没有QQ的完美,多多少少存在各种的问题,最后把下拉刷新的功能去掉后,只保留了侧滑删除的功能才找到个完美的.回去后和一朋友讨论,朋友找了以后说了一句,这种功能没有8K以上的是写不出来的(⊙﹏⊙)b.现在看来当时真的太天真了.而如今自己也没有8K还是尝试去写写,顺便当练练手. 还是效果图优先 效果图当中看不出来事件滑动的解决方案(或者是我不会如何录制手指在屏幕上滑动方向和点击,知道的大神请告诉下,谢谢)具体的

Filter组件开发中的SDK基类分析

DirectShow SDK提供了一套开发Filter的基类源代码.基于这些基类开发Filter将大大简化开发过程. 1.CBaseObject 大部分SDK类都从CBaseObject类(参见combase.h)中继承而来的. [cpp] view plaincopy class CBaseObject   {      private:          // Disable the copy constructor and assignment by default so you will

CSS 类选择器

在 CSS 中,类选择器以一个点号显示: .center {text-align: center} 在上面的例子中,所有拥有 center 类的 HTML 元素均为居中. 在下面的 HTML 代码中,h1 和 p 元素都有 center 类.这意味着两者都将遵守 ".center" 选择器中的规则. This heading will be center-aligned This paragraph will also be center-aligned. 注意:类名的第一个字符不能使

走近VB.Net(一),VB中的族,类,对象(摘录部分MSDN)

对象 走近VB.Net(一),VB中的族,类,对象 VB.Net是面向对象(object-oriented)的,又称为物件(object)导向(oriented).在VB.Net中所有的变量类型都是基于object,而不是VariantDim x As Variant 会被升级为 Dim as object.如果你不理解对象,暂时你可以把他理解为一段数据,他是实际存在于内存的,所以对象以称为实例(instance)而类(class)就是类别,他定义一群对象,是一个对象的群体,并定义方法成员.所以

综合布线技术研究:六类并非铜缆布线的归纳

六类标准推出的意义 2002年6月17日,美国通信工业协会正式通过了六类布线标准,并以ANSI/TIA/EIA-568B的附录形式在6月24日正式印刷出版,该标准正式命名为ANSI/TIA/EIA-568-B.2-1.自1997年8月首次提出六类布线规范以来,历经五年之争,经过多次草案修改,六类布线标准终于正式出台. 六类布线标准的出台,不仅结束了商家在产品性能方面的纷争局面,也为用户选择六类布线产品提供了一个可靠的技术依据.要区分真正的六类布线系统,只要检验系统性能指标是否达到六类标准中所有参

六类线标准推出的意义

六类标准推出的意义 2002年6月17日,美国通信工业协会正式通过了六类布线标准,并以ANSI/TIA/EIA-568B的附录形式在6月24日正式印刷出版,该标准正式命名为ANSI/TIA/EIA-568-B.2-1.自1997年8月首次提出六类布线规范以来,历经五年之争,经过多次草案修改,六类布线标准终于正式出台. 六类布线标准的出台,不仅结束了商家在产品性能方面的纷争局面,也为用户选择六类布线产品提供了一个可靠的技术依据.要区分真正的六类布线系统,只要检验系统性能指标是否达到六类标准中所有参