关于C++类库KYLib: 固定缓冲区的压缩/解压缩类源码
来源:互联网 发布:c语言库函数,命令大全 编辑:程序博客网 时间:2024/05/21 17:19
固定缓冲区的压缩/解压缩类源码及测试例子: http://download.csdn.net/detail/kyee/5052133
固定缓冲区的压缩/解压缩算法,适用于网络传输数据包的压缩,具有压缩速度快、压缩率适中特点,而且压缩后数据缓冲区可控。
其中包含固定缓冲区的压缩类(TKYFixedPack)和解压缩类(TKYFixedUnpack),源码如下:
// =======================================// Unit : 固定缓冲区的压缩/解压缩单元// Version: 3.0.0.0 (build 2012.04.19)// Author : Kyee Ye// Email : kyee_ye(at)126.com// Copyright (C) Kyee workroom// =======================================#ifndef _KYFixedPack_H_#define _KYFixedPack_H_#include "KYPackObj.h"namespace KYLib{// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* TKYFixedPack - 固定缓冲区的压缩类(基于LZ压缩算法) */class TKYFixedPack{public: TKYFixedPack(); virtual ~TKYFixedPack(); // 属性 char* Dest() const { return FDest; } // default: NULL Word Size() const { return FSize; } // default: 0 Word MaxSize() const { return FMaxSize; } // default: 0 Longword DataSize() const { return FDataSize; } // default: 0 bool IsPacking() const { return FIsPacking; } // default: false // 设置压缩结果缓冲区的最大尺寸 bool SetMaxSize(Word ASize); // 重置 void Reset(); // 压缩缓冲区 bool Pack(const char* ABuffer, long ASize, Word AMax = 0xFFFF);private: void DoCopy(const char* ABuffer, long ASize); bool DoMatch(Byte* APos, Byte* AEnd, Word& AOffset, Byte& ADepth);private: char FContext[1024]; // 压缩数据的上下文 Word FHash[4096]; // 哈希表 char* FDest; // 压缩后的缓冲区 Word FSize; // 压缩后数据尺寸 Word FMaxSize; // 缓冲区最大尺寸 Longword FDataSize; // 总压缩数据尺寸 Longword FLastSize; // 上一次 pack 结束后的尺寸 Byte FBitBegin; // 第一个字节数据开始位 bool FIsPacking; // 判断是否正在压缩private: // 编码项 typedef struct { Byte Length; // 编码位数 char Bits[3]; // 编码 } TCode, *PCode;private: // 初始化深度和偏移量的静态编码表 static void _Init_Depth_Codes(TCode* ACodes, const Byte* ABase, const Byte* ASuffix, Byte AHigh); static void _Init_Offset_Codes();private: // 深度和偏移量的静态编码表 static TCode _Codes_Depth[256]; static TCode _Codes_Offset[1024]; // TKYFixedPack 的静态成员初始化类 static class TInitialization { public: TInitialization(); ~TInitialization(); } _Initialization; friend class TInitialization;};// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* TKYFixedUnpack - 固定缓冲区的解压缩类(基于LZ压缩算法) */class TKYFixedUnpack{public: // 解压缩缓冲区 // 1. ABuffer 存放 ASize 字节的已压缩数据 // 2. ADest 存放解压缩后的数据, ADestSize >= ASize // 3. 若返回值 > 0 表示解压缩后数据的尺寸 // 4. 若返回值为 0 表示解压缩失败, 可能 ADestSize 太小或数据未压缩 // 5. 若返回值为 -1 表示参数不合法 // 6. 若返回值为 -2 表示解压缩失败, 原因是数据已损坏 static long Unpack(const char* ABuffer, long ASize, char* ADest, long ADestSize);};}#endif
// =======================================// Unit : 固定缓冲区的压缩/解压缩单元// 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 < 256static 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 < 256static bool BufferToPrefix(char* &APos, char* AEnd, Byte& ABitBegin, Byte& ACount, Byte AMax){ // 初始化 bool result = false; // 范围检查 if (APos < AEnd) { // 初始化 Byte* pPos = (Byte*)APos; Byte* pEnd = (Byte*)AEnd; Byte byteAnd = Bits_Prefix[ABitBegin]; Byte byteCount = 0; // 扫描完整前缀码 if ((*pPos & byteAnd) == byteAnd) { byteCount = 8 - ABitBegin; ABitBegin = 0; pPos++; // 整个字符 for (; pPos < pEnd; pPos++, byteCount += 8) if (*pPos != 0xFF) break; } // 范围检查 if (pPos < pEnd) { // 扫描剩余前缀码 for (; ABitBegin < 8; ABitBegin++, byteCount++) if ((*pPos & Bits_Bool[ABitBegin]) == 0) break; // 判断是否成功 if (byteCount <= AMax) { // 处理前缀码结束符 0 ABitBegin++; if (ABitBegin == 8) { ABitBegin = 0; pPos++; } // 结果 ACount = byteCount; result = true; } } // 更新位置 APos = (char*)pPos; } // 返回结果 return result;}// 缓冲区 -> Depth// 注: APos 和 AEnd 非空, ABitBegin 取值 [0..7]static bool BufferToDepth(char* &APos, char* AEnd, Byte& ABitBegin, Word& ADepth){ // 初始化 Byte byteIndex; bool result = false; // 取索引 if (BufferToPrefix(APos, AEnd, ABitBegin, byteIndex, High_Depth)) { // 初始化 Byte byteValue = 0; Byte byteBits = _D_Bits[byteIndex]; // 取后缀 if (BufferToByte(APos, AEnd, ABitBegin, byteValue, byteBits)) { ADepth = _D_Base[byteIndex] + byteValue; result = true; } } // 返回结果 return result;}// 缓冲区 -> Offset(含编/解码)// 注: APos 和 AEnd 非空, ABitBegin 取值 [0..7]static bool BufferToOffset(char* &APos, char* AEnd, Byte& ABitBegin, Word& AOffset){ // 初始化 Byte byteIndex; bool result = false; // 取索引 if (BufferToByte(APos, AEnd, ABitBegin, byteIndex, Prefix_Offset)) { // 初始化 Word wordValue = 0; Byte byteBits = _O_Bits[byteIndex]; // 取后缀 if ((byteBits == 0) || BufferToWord(APos, AEnd, ABitBegin, wordValue, byteBits)) { AOffset = _O_Base[byteIndex] + wordValue; result = true; } } // 返回结果 return result;}// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* TKYFixedPack - 固定缓冲区的压缩类(基于LZ压缩算法) */// ---------------- 静态成员 ----------------// 深度和偏移量的静态编码表TKYFixedPack::TCode TKYFixedPack::_Codes_Depth[256];TKYFixedPack::TCode TKYFixedPack::_Codes_Offset[1024];// TKYFixedPack 的静态成员初始化对象TKYFixedPack::TInitialization TKYFixedPack::_Initialization;// TKYFixedPack 的静态成员初始化类的构造函数TKYFixedPack::TInitialization::TInitialization(){ // 初始化深度和偏移量的静态编码表 _Init_Depth_Codes(_Codes_Depth, _D_Base, _D_Bits, High_Depth); _Init_Offset_Codes();}// TKYFixedPack 的静态成员初始化类的析构函数TKYFixedPack::TInitialization::~TInitialization(){}// ---------------- 静态函数 ----------------// 初始化深度的静态编码表void TKYFixedPack::_Init_Depth_Codes(TCode* ACodes, const Byte* ABase, const Byte* ASuffix, Byte AHigh){ // 初始化 char* pBits; PCode pCodes, pEnd; Byte byteNo, byteBits, byteLength, byteBegin, byteValue; // 循环添加静态编码表 for (byteNo = 0, pCodes = ACodes; byteNo <= AHigh; byteNo++) { pEnd = ACodes + ((byteNo != AHigh) ? ABase[byteNo+1] : 256); byteBits = ASuffix[byteNo]; byteLength = byteNo + 1 + byteBits; // 判断后缀码位数是否非 0 if (byteBits != 0) for (byteValue = 0; pCodes < pEnd; pCodes++, byteValue++) { pCodes->Length = byteLength; pBits = pCodes->Bits; byteBegin = 0; PrefixToBuffer(pBits, byteBegin, byteNo); ByteToBuffer(pBits, byteBegin, byteValue, byteBits); } else for (; pCodes < pEnd; pCodes++) { pCodes->Length = byteLength; pBits = pCodes->Bits; byteBegin = 0; PrefixToBuffer(pBits, byteBegin, byteNo); } }}// 初始化偏移量的静态编码表void TKYFixedPack::_Init_Offset_Codes(){ // 初始化 char* pBits; PCode pCodes, pEnd; Word wValue; Byte byteNo, byteBits, byteLength, byteBegin; // 循环添加静态编码表 for (byteNo = 0, pCodes = _Codes_Offset; byteNo <= High_Offset; byteNo++) { pEnd = _Codes_Offset + ((byteNo < High_Offset) ? _O_Base[byteNo+1] : Max_Offset); byteBits = _O_Bits[byteNo]; byteLength = Prefix_Offset + byteBits; // 判断后缀码位数是否非 0 if (byteBits != 0) for (wValue = 0; pCodes < pEnd; pCodes++, wValue++) { pCodes->Length = byteLength; pBits = pCodes->Bits; byteBegin = 0; ByteToBuffer(pBits, byteBegin, byteNo, Prefix_Offset); WordToBuffer(pBits, byteBegin, wValue, byteBits); } else for (; pCodes < pEnd; pCodes++) { pCodes->Length = byteLength; pBits = pCodes->Bits; byteBegin = 0; ByteToBuffer(pBits, byteBegin, byteNo, Prefix_Offset); } }}// ---------------- 构造函数和析构函数 ----------------// 构造函数TKYFixedPack::TKYFixedPack(){ // 初始化 FDest = NULL; FMaxSize = 0; FIsPacking = false; // 清空 Reset();}// 析构函数TKYFixedPack::~TKYFixedPack(){ if (FDest != NULL) { free(FDest); FDest = NULL; }}// ---------------- 私有函数 ----------------// 拷贝上下文void TKYFixedPack::DoCopy(const char* ABuffer, long ASize){ // 初始化 long intSize; char* pDest = (char*)FContext; char* pPos = (char*)ABuffer; char* pEnd = pPos + ASize; // 检查尺寸 if (ASize >= Max_Offset) memcpy(pDest, pEnd - Max_Offset, Max_Offset); else if (FLastSize >= Max_Offset) { intSize = Max_Offset - ASize; memmove(pDest, pDest + ASize, intSize); memcpy(pDest + intSize, pPos, ASize); } else if (FLastSize + ASize > Max_Offset) { intSize = Max_Offset - ASize; memmove(pDest, pDest + (FLastSize - intSize), intSize); memcpy(pDest + intSize, pPos, ASize); } else memcpy(pDest + FLastSize, pPos, ASize); // 修改最后尺寸 FDataSize = FLastSize + ASize; FLastSize = FDataSize;}// 索引项匹配bool TKYFixedPack::DoMatch(Byte* APos, Byte* AEnd, Word& AOffset, Byte& ADepth){ // 初始化 bool result = false; Word wIndex, wHash, wValue; // 计算 Hash 值 wHash = ((Word)APos[0] << 8) ^ ((Word)APos[1] << 4) ^ (Word)APos[2]; wHash = ((wHash * Hash_RandomGene) >> 4) & Mask_Hash; wValue = FHash[wHash]; wIndex = (Word)FDataSize & Mask_Index; AOffset = (wIndex - wValue) & Mask_Index; FHash[wHash]= wIndex; // 判断偏移量是否有效 if ((wValue <= Mask_Index) && (AOffset < Max_Offset) && (AOffset != 0)) { // 初始化 Word wDepth = (Word)Min(AEnd - APos, Max_Depth); Byte* pPos = APos; Byte* pEnd = APos + wDepth; Byte* pDest; // 检查是否超出上下文 if (FDataSize - FLastSize >= AOffset) { pDest = APos - AOffset; while ((pPos < pEnd) && (*pPos == *pDest)) { pPos++; pDest++; } } else { // 初始化 Word wSize = (Word)(FDataSize - FLastSize); // (FDataSize - FLastSize < AOffset) Word wFront = AOffset - wSize; // 计算起始位置 pDest = (Byte*)FContext; if (FLastSize >= Max_Offset) pDest += Max_Offset - wFront; else pDest += FLastSize - wFront; // 判断是否分二部分比较 if (wFront < wDepth) { // 初始化 Byte* pDestEnd = pDest + wFront; // 前半部分比较 while ((pDest < pDestEnd) && (*pPos == *pDest)) { pPos++; pDest++; } // 判断是否需要继续匹配 if (pDest == pDestEnd) { pDest = APos - wSize; while ((pPos < pEnd) && (*pPos == *pDest)) { pPos++; pDest++; } } } else while ((pPos < pEnd) && (*pPos == *pDest)) { pPos++; pDest++; } } // 检查匹配长度 wDepth = (Word)(pPos - APos); if (wDepth >= 3) { ADepth = (Byte)(wDepth - 3); result = true; } } // 返回结果 return result;}// ---------------- 保护函数 ----------------// ---------------- 公有函数 ----------------// 设置压缩结果缓冲区的最大尺寸bool TKYFixedPack::SetMaxSize(Word ASize){ // 初始化 bool result = true; // 判断状态 if (FIsPacking) result = false; else if (FMaxSize != ASize) { // 初始化 char* pData = NULL; // 判断是否需要分配 if (ASize != 0) { pData = (char*)malloc(ASize + 8); // 冗余长度, 防止编码超出 result = (pData != NULL); } // 判断是否继续 if (result) { // 先释放 if (FDest != NULL) free(FDest); // 交换 FDest = pData; FMaxSize = ASize; } } // 返回结果 return result;}// 重置void TKYFixedPack::Reset(){ if (!FIsPacking) { // 置空 FSize = 0; FBitBegin = 0; FDataSize = 0; FLastSize = 0; // 初始化哈希表 memset(FHash, -1, sizeof(FHash)); }}// 压缩缓冲区bool TKYFixedPack::Pack(const char* ABuffer, long ASize, Word AMax){ // 检查是否正在压缩及检查参数 if (FIsPacking || (FDest == NULL) || (ASize <= 0) || (ABuffer == NULL)) return false; // 初始化 bool result = false; // 置压缩状态 FIsPacking = true; // 操作 try { // 初始化 Word wSize, wOffset; PCode pCode; Byte* pSame; Byte* pLast; Byte* pPos = (Byte*)ABuffer; Byte* pEnd = pPos + ASize - 2; Byte* pBuffEnd = pPos + ASize; char* pDest = FDest + FSize - (Byte)(FBitBegin != 0); char* pDestEnd = FDest + Min(FMaxSize, AMax); Byte byteDepth= 0; Byte byteBegin= FBitBegin; bool boolOver = false; bool boolSame, boolNext; Byte byteLen1, byteLen2; // 循环匹配 while (pPos < pEnd) { // 检查是否相同数据 pLast = Min(pBuffEnd, pPos + Max_Offset + 10); pSame = pPos + 1; while ((pSame < pLast) && (*pSame == *pPos)) pSame++; // 检查相同数据尺寸是否大于等于 3 wSize = pSame - pPos; boolSame = (wSize >= 3); if (wSize <= 32) { boolNext = DoMatch(pPos, pBuffEnd, wOffset, byteDepth); if (boolNext && boolSame && (byteDepth + 3 >= wSize) && (wOffset != 1)) { if (byteDepth + 3 != wSize) boolSame = false; else { byteLen1 = (wSize < 11) ? _Codes_Offset[0].Length + 11 : _Codes_Offset[0].Length + _Codes_Offset[wSize - 11].Length + 8; byteLen2 = _Codes_Offset[wOffset].Length + _Codes_Depth[byteDepth].Length; boolSame = (byteLen1 <= byteLen2); } } } // 判断压缩为相同数据 if (boolSame) { // 压缩标志 BoolToBuffer(pDest, byteBegin, true); // 偏移量编码 pCode = &_Codes_Offset[wSize >= 11]; if (pCode->Length != 0) BitsToBuffer(pDest, byteBegin, pCode->Bits, pCode->Length); // 深度编码 if (wSize < 11) ByteToBuffer(pDest, byteBegin, (Byte)(wSize - 3), 3); else { pCode = &_Codes_Offset[wSize - 11]; if (pCode->Length != 0) BitsToBuffer(pDest, byteBegin, pCode->Bits, pCode->Length); } // 相同的字符 CharToBuffer(pDest, byteBegin, *pPos); FDataSize += wSize; pPos = pSame; } else if (boolNext) { // 压缩标志 BoolToBuffer(pDest, byteBegin, true); // 偏移量编码 pCode = &_Codes_Offset[wOffset]; if (pCode->Length != 0) BitsToBuffer(pDest, byteBegin, pCode->Bits, pCode->Length); // 深度编码 pCode = &_Codes_Depth[byteDepth]; if (pCode->Length != 0) BitsToBuffer(pDest, byteBegin, pCode->Bits, pCode->Length); // 更新位置 wSize = byteDepth + 3; FDataSize += wSize; pPos += wSize; } else { // 未压缩标志并存放字节 BoolToBuffer(pDest, byteBegin, false); CharToBuffer(pDest, byteBegin, *pPos); // 更新位置 FDataSize++; pPos++; } // 检查是否溢出 if (pDest >= pDestEnd) { boolOver = true; break; } } // 判断是否未溢出 if (!boolOver) { // 末尾 2 个字节 while (pPos < pBuffEnd) { // 未压缩标志并存放字节 BoolToBuffer(pDest, byteBegin, false); CharToBuffer(pDest, byteBegin, *pPos); // 更新位置 FDataSize++; pPos++; } // 检查是否溢出 if (pDest < pDestEnd) { FSize = (Word)(pDest - FDest) + (Byte)(byteBegin != 0); FBitBegin = byteBegin; result = true; // 拷贝上下文 DoCopy(ABuffer, ASize); } } } catch (...) {} // 恢复数据尺寸 if (!result) { FDataSize = FLastSize; if (FBitBegin != 0) FDest[FSize - 1] &= Bits_HiAnd[FBitBegin]; } // 返回结果 FIsPacking = false; return result;}// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* TKYFixedUnpack - 固定缓冲区的解压缩类(基于LZ压缩算法) */// ---------------- 静态函数 ----------------// 解压缩缓冲区// 1. ABuffer 存放 ASize 字节的已压缩数据// 2. ADest 存放解压缩后的数据, ADestSize >= ASize// 3. 若返回值 > 0 表示解压缩后数据的尺寸// 4. 若返回值为 0 表示解压缩失败, 可能 ADestSize 太小或数据未压缩// 5. 若返回值为 -1 表示参数不合法// 6. 若返回值为 -2 表示解压缩失败, 原因是数据已损坏long TKYFixedUnpack::Unpack(const char* ABuffer, long ASize, char* ADest, long ADestSize){ // 检查参数 if ((ABuffer == NULL) || (ASize <= 0) || (ADest == NULL) || (ADestSize < ASize)) return -1; // 初始化 long result = -2; // 操作 try { // 初始化 char* pLast; char* pMatch; char* pDest = ADest; char* pDestEnd = ADest + ADestSize; char* pPos = (char*)ABuffer; char* pEnd = pPos + ASize - 1; char* pBuffEnd = pPos + ASize; Byte byteBegin = 0; bool boolOver = false; bool boolError = false; bool boolMatched; char charValue; Byte byteSame; Word wDepth, wOffset; // 循环匹配 while (pPos < pEnd) { // 取匹配标志 BufferToBool(pPos, byteBegin, boolMatched); // 判断是否匹配 if (boolMatched) { // 取偏移量和深度 if (!BufferToOffset(pPos, pBuffEnd, byteBegin, wOffset)) { boolError = true; break; } else if (wOffset == 0) // 相同数据 (same < 11) { // 取深度及字符 if (!BufferToByte(pPos, pBuffEnd, byteBegin, byteSame, 3) || !BufferToChar(pPos, pBuffEnd, byteBegin, charValue)) { boolError = true; break; } else if (pDest + byteSame + 3 > pDestEnd) { boolOver = true; break; } else { pLast = pDest + byteSame + 3; for (; pDest < pLast; pDest++) *pDest = charValue; } } else if (wOffset == 1) // 相同数据 { // 取深度及字符 if (!BufferToOffset(pPos, pBuffEnd, byteBegin, wDepth) || !BufferToChar(pPos, pBuffEnd, byteBegin, charValue)) { boolError = true; break; } else if (pDest + wDepth + 11 > pDestEnd) { boolOver = true; break; } else { pLast = pDest + wDepth + 11; for (; pDest < pLast; pDest++) *pDest = charValue; } } else if ((wOffset > pDest - ADest) || !BufferToDepth(pPos, pBuffEnd, byteBegin, wDepth) || (wDepth > 0xFF)) { boolError = true; break; } else if (pDest + wDepth + 3 > pDestEnd) { boolOver = true; break; } else { pLast = pDest + wDepth + 3; pMatch = pDest - wOffset; for (; pDest < pLast; pDest++, pMatch++) *pDest = *pMatch; } } else if (pDest < pDestEnd) { BufferToChar(pPos, byteBegin, charValue); *(pDest++) = charValue; } else { boolOver = true; break; } } // 检查最后一个字节 if (!boolOver && !boolError && (pPos < pBuffEnd) && (byteBegin <= 1)) { // 取匹配标志 BufferToBool(pPos, byteBegin, boolMatched); // 必须是匹配项 if (boolMatched && BufferToOffset(pPos, pBuffEnd, byteBegin, wOffset) && (wOffset != 0) && (wOffset <= pDest - ADest) && BufferToDepth(pPos, pBuffEnd, byteBegin, wDepth)) { if (pDest + wDepth + 3 > pDestEnd) boolOver = true; else { pLast = pDest + wDepth + 3; pMatch = pDest - wOffset; for (; pDest < pLast; pDest++, pMatch++) *pDest = *pMatch; } } } // 判断是否溢出 if (boolOver) result = 0; else if (!boolError) result = pDest - ADest; } catch (...) {} // 返回结果 return result;}}
- 关于C++类库KYLib: 固定缓冲区的压缩/解压缩类源码
- 关于C++类库KYLib: 快速压缩/解压缩类源码
- 关于C++类库KYLib: 压缩/解压缩类
- 关于C++类库KYLib:源码?
- 关于C++类库KYLib: 用C语言实现平衡二叉树(AVL tree)的源码
- 关于C++类库KYLib: 使用AVLtree实现 map 类模板源码
- 关于C++类库KYLib: String 替换函数源码
- 关于C++类库KYLib:与MFC类库差别?
- 关于C++类库KYLib: 平衡二叉树类(AVL tree)
- 关于C的缓冲区
- 移动设备可用的压缩解压缩源码
- 移动设备可用的压缩解压缩源码
- C#压缩解压缩源码
- 关于LZW算法的压缩与解压缩
- 关于tar命令的压缩与解压缩
- 关于C++类库KYLib: 扩展平衡二叉树类(AVL extended tree)
- 如何把一个文件压缩成几个固定大小的文件及解压缩
- java压缩解压缩rar、zip 、tar文件 工具类源码
- Git和Repo扫盲
- win7家庭版(home)下administrator用户如何开启?
- 使用sys无法通过sqlplus或者sqldeveloper连接数据库
- 快速学习js 笔记五 dom对象 document
- 一年足迹记录
- 关于C++类库KYLib: 固定缓冲区的压缩/解压缩类源码
- Linux学习路径
- 通过Session 登入/登出
- 常用的网格布局算法
- Oracle学习计划
- SQL语句、PL/SQL语句、SQL*PLUS语句结束符号
- 数据库崩溃后对redo log的使用
- Scanf连续调用多次并且存在%c的问题
- Errors running builder 'JavaScript Validator' on project