首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

基於位操作的緩衝區類 CBitBuffer:高效二進制數據讀寫實作

     編輯:關於C++

為滿足協議解析、壓縮編碼、硬體通訊等場景對位級別數據操作的需求,作者參考 CFile 設計模式實作了 CBitBuffer 類。支援位/字節/十六進制/十進制/二進制字串多種讀寫模式,提供靈活的位指針定位與緩衝區管理功能。

類設計核心結構

class CBitBuffer {
private:
    LONGLONG m_llLength;     // 緩衝區大小(位)
    BYTE* m_pBegin;          // 起始指針
    BYTE* m_pEnd;            // 結束指針(最後一字節下一位置)
    BYTE* m_pCurByte;        // 當前字節指針
    BYTE m_nCurOffset;       // 當前位偏移 (0-7)
    BOOL m_bLocked;          // 鎖定狀態(Create 後鎖定)

    // m_pCurByte + m_nCurOffset 組成「位指針」
public:
    // 狀態查詢
    BOOL IsLocked();
    BOOL IsByteAligned();

    // 位寫入
    void WriteBit0();
    void WriteBit1();
    void WriteBinary(char* pBinStr);  // "0011 1011" 空格忽略,* 略過
    void WriteHex(char* pHexStr);     // "00 01 BA" 大寫無 0X,需位元組對齊
    void WriteDecimal(UINT nData, int nCount); // 指定位寬寫入整數
    void WriteBuffer(BYTE* pSubBuff, int& nCount); // 字節塊寫入

    // 位讀取
    int Read(BYTE nCount); // 讀取 nCount 位轉整數 (nCount ≤ 32)

    // 位置操作
    BYTE* GetBegin();
    BYTE* GetEnd();
    BYTE* GetCurByte();
    BYTE GetCurOffset();
    LONGLONG SetLength(LONGLONG llLen); // 需 8 的倍數
    LONGLONG GetLength();
    LONGLONG SeekToEnd();
    void SeekToBegin();
    LONGLONG Seek(LONGLONG llOff); // 位偏移,正向末尾/負向開頭

    // 生命週期
    CBitBuffer();
    CBitBuffer(BYTE* pBegin, LONGLONG llLen = 0);
    BOOL ShareBuffer(BYTE* pBegin, LONGLONG llLen = 0); // 外部記憶體管理
    BOOL Create(LONGLONG llLen); // 內部分配並鎖定
    void Release(); // 解鎖釋放
    virtual ~CBitBuffer();
};

關鍵演算法實作亮點

位讀取:64 位暫存器一次讀取 8 字節

int CBitBuffer::Read(BYTE nCount) {
    DWORD64 D64 = *((DWORD64*)m_pCurByte);
    // 位元組序轉換(小端序處理)
    D64 = (D64 >> 8*0 << (64-8)) | (D64 >> 8*1 << (64-8) >> (8*1)) | ...;
    int re = (int)(D64 << m_nCurOffset >> (64-nCount));
    m_pCurByte += (m_nCurOffset + nCount) / 8;
    m_nCurOffset = (m_nCurOffset + nCount) % 8;
    return re;
}

位寫入:掩碼操作

void CBitBuffer::WriteBit1() {
    *m_pCurByte |= (0x80 >> m_nCurOffset);
    if (++m_nCurOffset >= 8) { m_pCurByte++; m_nCurOffset = 0; }
}
void CBitBuffer::WriteBit0() {
    *m_pCurByte &= ~(0x80 >> m_nCurOffset);
    if (++m_nCurOffset >= 8) { m_pCurByte++; m_nCurOffset = 0; }
}

十六進制字串寫入:雙字符合併

解析每兩個十六進制字符合併為一字節,處理奇數長度情況(低 4 位暫存)。

十進制寫入:跨字節邊界組合

將數值按指定位寬拆分為頭部(保留原高位)、中間(新數值)、尾部(保留原低位),通過 64 位暫存器組合後一次寫回。

使用場景與注意事項

  • 適用:網路協議封裝/解析、位流編碼/解碼、嵌入式寄存器映射、檔案格式生成
  • 效能提示:作者承認部分操作效率較低(如 Read 的位元組序轉換),可優化為查表法或 SIMD
  • 邊界檢查:Read/Seek 未內建邊界檢查,調用者需自行保證不越界
  • 記憶體所有權:ShareBuffer 管理外部記憶體不負責釋放;Create 內部分配需配對 Release
  • 執行緒安全:非執行緒安全,多執行緒需外部同步

擴展建議

  • 新增 ReadBinary/ReadHex/ReadDecimal 對稱讀取介面
  • 支援大端/小端序配置選項
  • 加入 CRC/校驗和計算輔助方法
  • 提供 std::vector / std::string 互轉便利函數

作者郵箱:mymong@163.net,歡迎改進建議與交流。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved