📄 compress.c
字号:
} // while
// get any remaining chars as literals
while (currentptr <= endptr) {
#if 0
#ifdef DEBUG
DbgPrint("\t COMP:Location %d, <No Match>: '%c'\n", (currentptr - context->CompressBuffer),*currentptr) ;
#endif
#endif
// temp=literallookup[context->History[i-1]] ;
literal=*currentptr ;
if (literal & 0x80) {
literal += 0x80;
out_bits_9(literal) ;
} else {
out_bits_8(literal) ;
}
*historyptr++ = *currentptr++ ;
}
bitptr_end() ;
// Check if we expanded the buffer
//
if ((ULONG)(pbyte - CompOutBuffer) > *CurrentLength) { // expanded.
//
// We don't need to do this copy since we can just signal the outside world
// that compression did not take place and the valid data is still in the
// current buffer
//
// RtlMoveMemory(CompOutBuffer, CurrentBuffer, *CurrentLength) ;
memset (context->History, 0, sizeof(context->History)) ;
memset (context->HashTable, 0, sizeof(context->HashTable)) ;
#ifdef COMP_12K
status = 0 ;
#else
status = PACKET_FLUSHED << 8;
#endif
context->CurrentIndex = HISTORY_SIZE+1 ; // this forces a start over next time
} else { // compression successful
*CurrentLength = pbyte - CompOutBuffer;
//
// the compressed data is now in CompOutBuffer - tonybe 01-12-95
//
// *CurrentLength = pbyte - CurrentBuffer ;
status |= PACKET_COMPRESSED << 8;
context->CurrentIndex = historyptr - context->History ;
}
return status;
}
//* getcontextsizes()
//
// Function: Returns size of send and receive context blocks
//
// Parameters: OUT send -> sizeof(SendContext)
// OUT recv -> sizeof(RecvContext)
//
// Returns: Nothing
//
//*
void
getcontextsizes (long *send, long *recv)
{
*send = sizeof(SendContext) ;
*recv = sizeof(RecvContext) ;
}
//* initsendcontext()
//
// Function: Initialize SendContext block
//
// Parameters: IN context -> connection compress context
//
// Returns: Nothing
//
//*
void
initsendcontext (SendContext *context)
{
context->CurrentIndex = 0; // Index into the history
context->ValidHistory = 0 ; // reset valid history
memset (context->HashTable, 0, sizeof(context->HashTable)) ;
memset (context->History, 0, sizeof(context->History)) ;
}
//* initrecvcontext()
//
// Function: Initialize RecvContext block
//
// Parameters: IN context -> connection decompress context
//
// Returns: Nothing
//
//*
void
initrecvcontext (RecvContext *context)
{
context->CurrentPtr = context->History ;
#if DBG
context->DebugFence = DEBUG_FENCE_VALUE;
#endif
memset (context->History, 0, sizeof(context->History)) ;
}
//* decompress()
//
// Function: de-compression function.
//
// Parameters: IN inbuf -> points to data to be uncompressed
// IN inlen -> length of data
// IN start -> flag indicating whether to start with a clean history buffer
// OUT output-> decompressed data
// OUT outlen-> lenght of decompressed data
// IN context -> connection decompress context
//
// Returns: TRUE if decompress was successful
// FALSE if it wasnt
//
// WARNING: CODE IS HIGHLY OPTIMIZED FOR TIME.
//
//*
int
decompress(
UCHAR *inbuf,
int inlen,
int start,
UCHAR **output,
int *outlen,
RecvContext *context)
{
UCHAR *inend; // When we know we're done decompressing
UCHAR *outstart; // Remember where in dbuf we started
UCHAR *current;
int backptr = 0x00; // Back pointer for copy items
int length; // Where to copy from in dbuf
UCHAR *s1, *s2;
int bitset;
int bit;
int byte;
UCHAR *pbyte;
UCHAR *historyend = context->History + HISTORY_SIZE ;
inend = inbuf + inlen ;
//
// Start out looking at the first bit
//
inbit_start(inbuf);
if (start) // start over clean?
context->CurrentPtr = current = context->History ;
else
current = context->CurrentPtr ;
//
// Save our starting position
//
outstart = current;
//
// Decompress until we run out of input
//
while (pbyte < inend) {
//
// Jump on what to do with these three bits.
//
in_bits_3(length);
switch (length) {
case 0:
in_bits_5(length) ;
goto LITERAL ;
case 1:
in_bits_5(length) ;
length += 32 ;
goto LITERAL ;
case 2:
in_bits_5(length) ;
length += 64 ;
goto LITERAL ;
case 3:
in_bits_5(length) ;
length += 96 ;
goto LITERAL ;
case 4:
in_bits_6(length) ;
length +=128 ;
goto LITERAL ;
case 5:
in_bits_6(length) ;
length +=192 ;
goto LITERAL ;
case 6:
in_bits_13 (backptr) ; // 110 - 14 bit offset
backptr+=320 ;
break ;
case 7:
in_bit() ;
if (bitset) {
in_bits_6(backptr) ;
} else {
in_bits_8(backptr) ;
backptr+=64 ;
}
break ;
}
//
// If we reach here, it's a copy item
//
//
// Now get the length
//
in_bit() ; // 1st length bit
if (!bitset) {
length = 3 ;
goto DONE ;
}
in_bit() ; // 2nd length bit
if (!bitset) {
in_bits_2 (length) ;
length += 4 ;
goto DONE ;
}
in_bit() ; // 3rd length bit
if (!bitset) {
in_bits_3 (length) ;
length += 8 ;
goto DONE ;
}
in_bit() ; // 4th length bit
if (!bitset) {
in_bits_4 (length) ;
length += 16 ;
goto DONE ;
}
in_bit() ; // 5th length bit
if (!bitset) {
in_bits_5 (length) ;
length += 32 ;
goto DONE ;
}
in_bit() ; // 6th length bit
if (!bitset) {
in_bits_6 (length) ;
length += 64 ;
goto DONE ;
}
in_bit() ; // 7th length bit
if (!bitset) {
in_bits_7 (length) ;
length += 128 ;
goto DONE ;
}
in_bit() ; // 8th length bit
if (!bitset) {
in_bits_8 (length) ;
length += 256 ;
goto DONE ;
}
in_bit() ; // 9th length bit
if (!bitset) {
in_bits_9 (length) ;
length += 512 ;
goto DONE ;
}
in_bit() ; // 10th length bit
if (!bitset) {
in_bits_10 (length) ;
length += 1024 ;
goto DONE ;
}
//
// length cannot be greater than max packets size which is 1500
//
#if 0
DbgPrint("NDISWAN: RAS Decompressor problem: Possible data corruption\n");
#endif
return FALSE ;
DONE:
//
// Turn the backptr into an index location
//
#ifdef COMP_12K
s2 = current - backptr ;
#else
s2 = context->History + (((current - context->History) - backptr) & (HISTORY_SIZE -1)) ;
#endif
s1 = current;
#if 0
#ifdef DEBUG
DbgPrint("\tdecomp: location: %d, bp %.4d length %.4d\n", (current-context->CurrentPtr), backptr, length);
#endif
#endif
current += length;
// if we are past the end of the history this is a bad sign: abort decompression
//
if (current >= historyend) {
#if 0
DbgPrint("NDISWAN: RAS Decompressor problem: Possible data corruption\n");
#endif
return FALSE ;
}
// loop unrolled to handle lenght>backptr case
//
*s1=*s2;
*(s1+1)=*(s2+1);
s1+=2;
s2+=2;
length-=2;
//
// copy all the bytes
//
while (length) {
*s1++=*s2++;
length--;
}
//
// We have another copy item, and no literals
//
continue;
LITERAL:
#if 0
#ifdef DEBUG
DbgPrint("\tdecomp: Location %d, literal '%c'\n",(current-context->CurrentPtr), length);
#endif
#endif
//
// We have a literal
//
//*current++ = literallookup[length];
*current++ = length;
} // while loop
// End case:
//
if ((bit == 16) && (pbyte == inend)) {
*current++ = *(pbyte -1) ;
}
#if 0
#if DBG
if (context->DebugFence != DEBUG_FENCE_VALUE) {
DbgPrint("Decompression Error!\n");
DbgPrint("context 0x%8.8x, current 0x%8.8x, outstart 0x%8.8x\n", context, current, outstart);
DbgPrint("inbuf 0x%8.8x, inlength %d, start 0x%8.8x\n", inbuf, inlen, start);
DbgBreakPoint();
}
#endif
#endif
*outlen = current - outstart ; // the length of decompressed data
*output = context->CurrentPtr ;
context->CurrentPtr = current ;
return TRUE ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -