📄 kaeziparchiveimplement.cpp
字号:
if (c == 1) // q. 256,1 sequence?
{
cs++; // a. yes .. increase code size
continue; // ..and get next character
}
else
if (c == 2) // q. clear tree (256,2)?
{ // a. yes .. partially clear nodes
for (d = &dict[257];d < fd; d++) // loop thru dictionary starting past literals
d->parent_c |= 0x8000; // ..and mark as unused
for (d = &dict[257];d < fd; d++) // loop again thru dictionary checking each used node
{
c = d->parent_c & 0x7fff; // get node's next pointer
if (c >= 257) // q. uses another node?
dict[c].parent_c &= 0x7fff; // a. yes .. clear target
}
for (d = &dict[257];d < fd; d++) // loop once more, this time release unneeded entries
if (d->parent_c & 0x8000) // q. need to be cleared?
d->parent_c = FREE; // a. yes .. set it to free
for (d = &dict[257];d < ld; d++) // loop thru dictionary to find the first free node
if (d->parent_c == FREE) // q. find a free entry?
break; // a. yes .. exit loop
fd = d; // save next free dict node
continue; // ..continue with inner loop
}//if (c == 2)
}//if (c == 256)
if (c < 256) // q. literal code?
store_char(b_c = c); // a. yes .. put out literal
else // else .. must be .gt. 256
{
if(dict[c].parent_c == FREE) // q. using new code?
{
decode_stack[cnt++] = b_c; // a. yes .. store old character
c = p_c; // set up search criteria
}
while (c > 255) // loop finding entries to use
{
d = &dict[c]; // point to current entry
decode_stack[cnt++] = d->c; // put character into stack
c = d->parent_c; // get parent's code
}
store_char(b_c = c); // put out first character
while (cnt) // loop outputing from ..
store_char(decode_stack[--cnt]);// ..decode stack
}
fd->parent_c = p_c; // store parent's code
fd->c = b_c; // ..and its character
p_c = s_c; // set up new parent code
while (++fd < ld) // loop thru dictionary
if (fd->parent_c == FREE) // q. entry free?
break; // a. yes .. done looping
}//for (;;) // inner loop
/*
farfree(decode_stack);
farfree(dict);
*/
//seawind added
free(decode_stack); // free decode stack
free(dict); // ..and dictionary
}
/* ******************************************************************** *
*
* extract_expand() -- extract a reduced file
*
* ******************************************************************** */
void KAEZipArchive::extract_expand(LF *lfp)
{
UINT i, j, k, // loop variables
c, // current character
save_reduce, // reduction character
reduce_m, // mask
reduce_s, // shift value
exp_len; // expand length
BYTE last_c = 0, // last character
state = 0, // state machine indicator
*p; // work pointer
FS *fsp, // follower sets pointer
*fse; // ..and entry
static BYTE reduce[4][2] = // reduction mask and lengths
{
{ 0x7f, 7 },
{ 0x3f, 6 },
{ 0x1f, 5 },
{ 0x0f, 4 }
},
len_codes[33] = // bit lengths for numbers
{
1, 1, 1, 2, 2, 3, 3, 3, 3, 4, // this table maps the minimum
4, 4, 4, 4, 4, 4, 4, 5, 5, 5, // ..number of bits to represent
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // ..a value
5, 5, 5
};
fsp = (FS *) malloc_chk(256 * sizeof(FS)); // allocate memory for sets
i = lfp->lf_cm - LF_CM_REDUCED1; // get index into array
reduce_m = reduce[i][0]; // ..copy over mask
reduce_s = reduce[i][1]; // ..and shift amount
for (i = 256, fse = &fsp[255]; i--; fse--) // build follower sets
{
if ((j = get_code(6)) == -1) // q. get a length code ok?
break; // a. no .. exit loop
fse->set_len = j; // save length of set data
for (p = fse->set; j--; p++) // set up length in set
{
if ((k = get_code(8)) == -1) // q. get a data code ok?
break; // a. no .. exit loop
*p = (char) k; // save set data
}
}
for (;;) // loop till file processed
{
//seawind added for stop
if(m_nActionCancel || m_nZipFileCracked)
break;
fse = &fsp[last_c]; // current follower set
if (! fse->set_len) // q. empty set?
{ // a. yes .. get more input
if ((c = get_code(8)) == -1) // q. get a code ok?
break; // a. no .. exit loop
}
else
{
if ((c = get_code(1)) == -1) // q. get a code ok?
break; // a. no .. exit loop
if (c) // q. need to get another byte?
{ // a. yes .. get another
if ((c = get_code(8)) == -1) // q. get a code ok?
break; // a. no .. exit loop
}
else
{
i = len_codes[fse->set_len]; // get next read bit length
if ((c = get_code(i)) == -1) // q. get next code ok?
break; // a. no .. exit loop
c = fse->set[c]; // get encoded character
}
}
last_c = c; // set up new last character
switch (state) // based on current state
{
case 0: // 0: output character
if (c == EXPLODE_DLE) // q. DLE character?
state = 1; // a. yes .. change states
else
store_char(c); // else .. output character
break; // ..then process next character
case 1: // 1: store length
if (! c) // q. null character?
{
//seawind modified
store_char((char)(EXPLODE_DLE)); // a. yes .. output a DLE char
state = 0; // ..and change states
}
else
{
save_reduce = c; // save character being reduced
c &= reduce_m; // clear unused bits
exp_len = c; // save length to expand
state = (c == reduce_m) ? 2 : 3; // select next state
}
break; // ..then process next character
case 2: // 2: store length
exp_len += c; // save length to expand
state = 3; // select next state
break; // ..then get next character
case 3: // 3: expand string
c = ((save_reduce >> reduce_s) << 8) + c + 1; // compute offset backwards
exp_len += 3; // set up expansion length
//seawind modified
if ((UINT)(sbp - sb) >= c) // q. backward wrap?
p = sbp - c; // a. no .. just back up a bit
else
p = sb_size - c + sbp; // else .. find at end of buffer
while (exp_len--) // copy previously outputed
{ // ..strings from sliding buffer
store_char(*p); // put out each character
if (++p >= sbe) // q. hit the end of the buffer?
p = sb; // a. yes .. back to beginning
}
state = 0; // change state back
break; // ..and process next character
}//switch (state)
}//for (;;)
free(fsp); // free follower sets
}
/* ******************************************************************** *
*
* extract_explode() -- extract an imploded file
*
* ******************************************************************** */
void KAEZipArchive::extract_explode(LF *lfp)
{
UINT c, // current read character
ltf, // literal S-F tree available
db, // dictionary read bits
d, // distance
len, // ..and length to go back
mml; // minimum match length 3
BYTE *p; // work dictionary pointer
SFT *sft, *sft2, *sft3; // S-F trees pointers
sft = (SFT *) malloc_chk((256 + 64 + 64) * sizeof(SFT)); // get memory for S-F trees
sft2 = &sft[256]; // ..and set up ..
sft3 = &sft[320]; // ..the base pointers
db = (lfp->lf_flag & LF_FLAG_8K) ? 7 : 6; // ..and dictionary read in bits
mml = ((ltf = lfp->lf_flag & LF_FLAG_3SF)!= 0) ? 3 : 2; // set literal S-F tree available
// ..and minimum match lengths
if (ltf) // q. literal tree available?
exp_load_tree(sft, 256); // a. yes .. load literal tree
exp_load_tree(sft2, 64); // ..then load length trees
exp_load_tree(sft3, 64); // ..and finally, distance trees
for (;;) // loop processing compressed data
{
//seawind added for stop
if(m_nActionCancel || m_nZipFileCracked)
break;
if ((c = get_code(1)) == -1) // q. get a bit ok?
break; // a. no .. exit loop
if (c) // q. encoded literal data?
{ // a. yes .. continue processing
if (ltf) // q. literal S-F tree available?
{ // a. yes .. get char from tree
if ((c = exp_read(sft)) == -1) // q. get char from tree ok?
break; // a. no .. exit loop
}
else
if ((c = get_code(8)) == -1) // q. get next character ok?
break; // a. no .. exit loop
store_char(c); // ..and put char to output stream
}
else // else .. use sliding dictionary
{
if ((d = get_code(db)) == -1) // q. get distance code ok?
break; // a. no .. exit loop
if ((c = exp_read(sft3)) == -1) // q. get distance S-F code ok?
break; // a. no .. exit loop
d = (d | (c << db)) + 1; // update distance
if ((len = exp_read(sft2)) == -1) // q. get length S-F code ok?
break; // a. no .. exit loop
if (len == 63) // q. get max amount?
{ // a. yes .. get another byte
if ((c = get_code(8)) == -1) // q. get additional len ok?
break; // a. no .. exit loop
len += c; // ..then add to overall length
}
len += mml; // add in minimum match length
//seawind modified
if ((UINT)(sbp - sb) >= d) // q. backward wrap?
p = sbp - d; // a. no .. just back up a bit
else
p = sb_size - d + sbp; // else .. find at end of buffer
while (len--) // copy previously outputed
{ // ..strings from sliding buffer
store_char(*p); // put out each character
if (++p >= sbe) // q. hit the end of the buffer?
p = sb; // a. yes .. back to beginning
}
}//else
}//for (;;)
free(sft); // free S-F trees
}
/* ******************************************************************** *
*
* exp_load_tree() -- load a single S-F t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -