固定緩沖區的壓縮/解壓縮算法,適用於網絡傳輸數據包的壓縮,具有壓縮速度快、壓縮率適中特點,而且壓縮後數據緩沖區可控。 其中包含固定緩沖區的壓縮類(TKYFixedPack)和解壓縮類(TKYFixedUnpack),源碼如下: [cpp] // ======================================= // 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 [cpp] // ======================================= // 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 < 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) { // 初始化 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; } }