⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kaeziparchiveimplement.cpp

📁 zip解压源码.
💻 CPP
📖 第 1 页 / 共 5 页
字号:

            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 + -