关于C++类库KYLib: 固定缓冲区的压缩/解压缩类源码(七)

2014-11-24 08:13:32 · 作者: · 浏览: 5
eBegin;
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;