关于C++类库KYLib: 固定缓冲区的压缩/解压缩类源码(二)
// Version: 3.0.0.0 (build 2012.04.19)
// Author : Kyee Ye
// Email : kyee_ye(at)126.com
// Copyright (C) Kyee workroom
// =======================================
#include "KYFixedPack.h"
namespace KYLib
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* 深度和偏移量编码操作的相关静态函数 */
// 常量
#define Max_Depth 258 // 最大匹配深度
#define Max_Offset 1024 // 最大偏移量
#define Mask_Index 0x7FFF // 索引的掩码
#define Mask_Hash 0x0FFF // 哈希的掩码
#define Hash_RandomGene 45673 // 哈希的随机因子必须是素数,
// 且除以 4096 的商和余数也是素数
// 深度的编码
#define High_Depth 8 // 后缀的最高项数
// 偏移量的编码
#define Prefix_Offset 4 // 偏移量的前缀位数
#define High_Offset 15 // = 2^Prefix_Offset - 1
// 前缀码的位值
static const Byte Bits_Prefix[8] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01};
// 高位与模值
static const Byte Bits_HiAnd[8] = {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE};
// 布尔位值
static const Byte Bits_Bool[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
// 深度前缀编码的基数
static const Byte _D_Base[9] = {0, 2, 4, 8, 12, 20, 36, 68,
132};
// 深度前缀编码的后缀位数
static const Byte _D_Bits[9] = {1, 1, 2, 2, 3, 4, 5, 6,
7};
// 偏移量前缀编码的基数
static const Word _O_Base[16] = {0, 1, 2, 3, 4, 6, 8, 12,
16, 24, 32, 48, 64, 128, 256, 512};
// 偏移量前缀编码的后缀位数
static const Byte _O_Bits[16] = {0, 0, 0, 0, 1, 1, 2, 2,
3, 3, 4, 4, 6, 7, 8, 9};
// Prefix前缀码 -> 缓冲区
// 注: APos 非空, ABitBegin 取值 [0..7], ACount + ABitBegin < 256
static void PrefixToBuffer(char* &APos, Byte& ABitBegin, Byte ACount)
{
// 初始化
Byte byteRest;
Byte* pPos = (Byte*)APos;
// 检查前缀是否非空
if (ACount != 0)
{
// 检查非空
if (ABitBegin != 0)
{
Byte byteCount = ACount + ABitBegin;
if (byteCount < 8)
{
*pPos |= Bits_Prefix[ABitBegin] & Bits_HiAnd[byteCount];
ACount = 0;
ABitBegin = (Byte)byteCount;
}
else
{
*pPos |= Bits_Prefix[ABitBegin];
ACount -= 8 - ABitBegin;
ABitBegin = 0;
pPos++;
}
}
// 判断是否剩余前缀码
if (ACount != 0)
{
byteRest = ACount & 0x07;
ACount = ACount >> 3;
// 按字节添加
for (; ACount > 0; ACount--, pPos++)
*pPos = 0xFF;
// 剩下位数
if (byteRest != 0)
{
*pPos = Bits_HiAnd[byteRest];
ABitBegin = byteRest;
}
}
}
// 处理前缀码结束符 0
if (ABitBegin == 7)
pPos++;
else if (ABitBegin == 0)
*pPos = 0;
// 修改起始位
ABitBegin = (ABitBegin + 1) & 0x07;
APos = (char*)pPos;
}
// 缓冲区 -> Prefix前缀码
// 注: APos 和 AEnd 非空, ABitBegin 取值 [0..7], ACount + ABitBegin < 256
static bool BufferToPrefix(char* &APos, char* AEnd, Byte& ABitBegin,
Byte& ACount, Byte AMax)
{
// 初始化
bool result = false;
// 范围检查
if (APos < AEnd)
{
// 初始化