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

📄 inflate.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information").  You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * * Use is subject to license terms. *//*========================================================================= * SYSTEM:    KVM * SUBSYSTEM: JAR file reader / inflater. * FILE:      inflate.c * OVERVIEW:  Routines for inflating (decompressing) the contents  *            of a JAR file. The routines are optimized to reduce *            code size and run-time memory requirement so that  *            they can run happily on small devices. * AUTHOR:    Ioi Lam, Consumer & Embedded, Sun Microsystems, Inc. *            Refined by Tasneem Sayeed, Consumer & Embedded *            Frank Yellin *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#ifdef INFLATE_DEBUG_FILE#include "sys/stat.h"#endif#include "global.h"#include "assert.h"#include "jar.h"/* Assume that we're being compiled as part of the KVM, unless told * otherwise */#ifndef COMPILING_FOR_KVM#  define COMPILING_FOR_KVM 1#endif#include "inflate.h"#include "inflateint.h"#include "inflatetables.h"static bool_t decodeDynamicHuffmanTables(inflaterState *state,                                         HuffmanCodeTable **lcodesPtr,                                         HuffmanCodeTable **dcodesPtr);static HuffmanCodeTable *makeCodeTable(inflaterState *state,                                       unsigned char *codelen,                                       unsigned numElems,                                       unsigned maxQuickBits);static bool_t inflateHuffman(inflaterState *state, bool_t fixedHuffman);static bool_t inflateStored(inflaterState *state);/*========================================================================= * Decompression functions *=======================================================================*//*=========================================================================== * FUNCTION:  inflateData * TYPE:      jar file decoding * INTERFACE: *   parameters: method, compressed data, compressed length, *               decompressed data, decompressed size *   returns:    TRUE if the data was encoded in a supported <method> and the *                  size of the decoded data is exactly the same as <decompLen> *               FALSE if an error occurs * NOTE: *    The caller of this method must insure that this function can safely *    up to INFLATER_EXTRA_BYTES beyond compData + compLen without causing *    any problems. *    The inflater algorithm occasionally reads one more byte than it needs *    to.  But it double checks that it doesn't actually care what's in that *    extra byte. *===========================================================================*//* Change some definitions so that this compiles niceless, even if it * compiled as part of something that requires real malloc() and free() */#if !COMPILING_FOR_KVM#  undef START_TEMPORARY_ROOTS#  undef END_TEMPORARY_ROOTS#  undef ASSERTING_NO_ALLOCATION #  undef END_ASSERTING_NO_ALLOCATION #  undef INDICATE_DYNAMICALLY_INSIDE_TEMPORARY_ROOTS#  undef IS_TEMPORARY_ROOT#  define START_TEMPORARY_ROOTS#  define END_TEMPORARY_ROOTS#  define ASSERTING_NO_ALLOCATION #  define END_ASSERTING_NO_ALLOCATION #  define INDICATE_DYNAMICALLY_INSIDE_TEMPORARY_ROOTS#  define IS_TEMPORARY_ROOT(var, value) var = value#  define mallocBytes(x) malloc(x)#  define freeBytes(x)   if (x == NULL) {} else free(x)#else#  define freeBytes(x)#endif/* These three macros are provided because some ports may want to  * put the output bytes into something other than the provided outFile * buffer.  */#ifndef  INFLATER_PUT_BYTE#    define INFLATER_PUT_BYTE(offset, value)  outFile[offset] = value;#endif#ifndef INFLATER_GET_BYTE#    define INFLATER_GET_BYTE(offset)         outFile[offset]#endif#ifndef INFLATER_FLUSH_OUTPUT#    define INFLATER_FLUSH_OUTPUT()#endifbool_tinflateData(void *compData, /* compressed data source */        JarGetByteFunctionType getBytes,        int compLen,        /* length of compressed data */        UNSIGNED_CHAR_HANDLE decompData,        int decompLen)      /* length of decompression buffer */{    inflaterState stateStruct;    bool_t result;    inflateBufferIndex = inflateBufferCount = 0;/* Temporarily define state, so that LOAD_IN, LOAD_OUT, etc. macros work */#define state (&stateStruct)    stateStruct.outFileH = decompData;    stateStruct.outOffset = 0;    stateStruct.outLength = decompLen;    stateStruct.inFile = compData;    stateStruct.inData = 0;    stateStruct.inDataSize = 0;    stateStruct.inRemaining = compLen + INFLATER_EXTRA_BYTES;    stateStruct.getBytes = getBytes;#ifdef INFLATE_DEBUG_FILE    {        static int length = 0;        if (length == 0) {            struct stat stat_buffer;            stat(INFLATE_DEBUG_FILE, &stat_buffer);            length = stat_buffer.st_size;;        }        if (length == decompLen) {            FILE *f = fopen(INFLATE_DEBUG_FILE, "rb");            state->jarDebugBytes = malloc(length);            fseek(f, 0, SEEK_SET);            fread(state->jarDebugBytes, sizeof(char), length, f);            fclose(f);        } else {            state->jarDebugBytes = NULL;        }    }#endif    for(;;) {        int type;        DECLARE_IN_VARIABLES        LOAD_IN;        NEEDBITS(3);        type = NEXTBITS(3);        DUMPBITS(3);        STORE_IN;        switch (type >> 1) {            default:            case BTYPE_INVALID:                ziperr(KVM_MSG_JAR_INVALID_BTYPE);                result = FALSE;                break;            case BTYPE_NO_COMPRESSION:                result = inflateStored(state);                break;            case BTYPE_FIXED_HUFFMAN:                result = inflateHuffman(state, TRUE);                break;            case BTYPE_DYNA_HUFFMAN:                START_TEMPORARY_ROOTS                    result = inflateHuffman(state, FALSE);                END_TEMPORARY_ROOTS                break;        }        if (!result) {             break;        } else if (type & 1) {             INFLATER_FLUSH_OUTPUT();            if (state->inRemaining + (state->inDataSize >> 3) !=                              INFLATER_EXTRA_BYTES) {                ziperr(KVM_MSG_JAR_INPUT_BIT_ERROR);                result = FALSE;            } else if (state->outOffset != state->outLength) {                ziperr(KVM_MSG_JAR_OUTPUT_BIT_ERROR);                result = FALSE;            }            break;        }    }#ifdef INFLATE_DEBUG_FILE    if (state->jarDebugBytes != NULL) {        free(state->jarDebugBytes);    }#endif    /* Remove temporary definition of state defined above */#undef state    return result;}static bool_tinflateStored(inflaterState *state){    DECLARE_IN_VARIABLES    DECLARE_OUT_VARIABLES    unsigned len, nlen;    LOAD_IN; LOAD_OUT;    DUMPBITS(inDataSize & 7);   /* move to byte boundary */    NEEDBITS(32)    len = NEXTBITS(16);    DUMPBITS(16);    nlen = NEXTBITS(16);    DUMPBITS(16);    ASSERT(inDataSize == 0);    if (len + nlen != 0xFFFF) {        ziperr(KVM_MSG_JAR_BAD_LENGTH_FIELD);        return FALSE;    } else if (inRemaining < len) {        ziperr(KVM_MSG_JAR_INPUT_OVERFLOW);        return FALSE;    } else if (outOffset + len > outLength) {        ziperr(KVM_MSG_JAR_OUTPUT_OVERFLOW);        return FALSE;    } else {        int count;        while (len > 0) {          if (inflateBufferCount > 0) {            /* we have data buffered, copy it first */            memcpy(&outFile[outOffset], &inflateBuffer[inflateBufferIndex],                    (count = (inflateBufferCount <= len ? inflateBufferCount : len)));            len -= count;            inflateBufferCount -= count;            inflateBufferIndex += count;            outOffset += count;            inRemaining -= count;          }          if (len > 0) {            /* need more, refill the buffer */            outFile[outOffset++] = NEXTBYTE;            len--;            inRemaining--;          }        }    }    STORE_IN;    STORE_OUT;    return TRUE;}static bool_tinflateHuffman(inflaterState *state, bool_t fixedHuffman){    bool_t noerror = FALSE;    DECLARE_IN_VARIABLES    DECLARE_OUT_VARIABLES    unsigned int quickDataSize = 0, quickDistanceSize = 0;    unsigned int code, litxlen;    HuffmanCodeTable *lcodes, *dcodes;    if (!fixedHuffman) {        INDICATE_DYNAMICALLY_INSIDE_TEMPORARY_ROOTS;        IS_TEMPORARY_ROOT(lcodes, NULL);        IS_TEMPORARY_ROOT(dcodes, NULL);        if (!decodeDynamicHuffmanTables(state, &lcodes, &dcodes)) {            noerror = TRUE;            goto done;        }        quickDataSize = lcodes->h.quickBits;        quickDistanceSize = dcodes->h.quickBits;        UPDATE_IN_OUT_AFTER_POSSIBLE_GC;    }    LOAD_IN;    LOAD_OUT;    for (;;) {        if (inRemaining < 0) {            goto done_loop;        }        NEEDBITS(MAX_BITS + MAX_ZIP_EXTRA_LENGTH_BITS);        if (fixedHuffman) {            /*   literal (hex)             * 0x100 - 0x117   7   0.0000.00   -  0.0101.11             *     0 -    8f   8   0.0110.000  -  1.0111.111             *   118 -   11f   8   1.1000.000  -  1.1000.111             *    90 -    ff   9   1.1001.0000 -  1.1111.1111             */            /* Get 9 bits, and reverse them. */            code = NEXTBITS(9);            code = REVERSE_9BITS(code);            if (code <  0x060) {                /* A 7-bit code  */                DUMPBITS(7);                litxlen = 0x100 + (code >> 2);            } else if (code < 0x190) {                DUMPBITS(8);                litxlen = (code >> 1) + ((code < 0x180) ? (0x000 - 0x030)                          : (0x118 - 0x0c0));            } else {                DUMPBITS(9);                litxlen = 0x90 + code - 0x190;            }        } else {            GET_HUFFMAN_ENTRY(lcodes, quickDataSize, litxlen, done_loop);        }        if (litxlen <= 255) {            if (outOffset < outLength) {#ifdef INFLATE_DEBUG_FILE                if (state->jarDebugBytes                    && state->jarDebugBytes[outOffset] != litxlen) {                    ziperr(KVM_MSG_JAR_DRAGON_SINGLE_BYTE);                }#endif                INFLATER_PUT_BYTE(outOffset, litxlen);                outOffset++;            } else {                goto done_loop;            }        } else if (litxlen == 256) {               /* end of block */            noerror = TRUE;            goto done_loop;        } else if (litxlen > 285) {            ziperr(KVM_MSG_JAR_INVALID_LITERAL_OR_LENGTH);            goto done_loop;        } else {            unsigned int n = litxlen - LITXLEN_BASE;            unsigned int length = ll_length_base[n];            unsigned int moreBits = ll_extra_bits[n];            unsigned int d0, distance;            /* The NEEDBITS(..) above took care of this */            length += NEXTBITS(moreBits);            DUMPBITS(moreBits);            NEEDBITS(MAX_BITS);            if (fixedHuffman) {                d0 = REVERSE_5BITS(NEXTBITS(5));                DUMPBITS(5);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -