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

📄 jar.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 2 页
字号:
 *=======================================================================*/voidcloseJARFile(JAR_INFO entry){#if JAR_FILES_USE_STDIO    fclose((FILE *)entry->u.jar.file);#endif}/*========================================================================= * FUNCTION:      loadJARFileEntry() * OVERVIEW:      Reads an entry in a jar file * * INTERFACE: *   parameters:  JAR_INFO: structure returned by openJARFile *                filename: name of entry to read *                lengthP:  on return, contains length of entry in jar file *                          (does >>NOT<< include extraBytes) *                extraBytes:  value has this many extra bytes padded at the *                          beginning. * * NOTE: The result is malloc'ed on the heap.  It is up to the caller to protect *        this result from garbage collection *=======================================================================*/void *loadJARFileEntry(JAR_INFO entry, const char *filename,                 long *lengthP, int extraBytes){    unsigned int filenameLength = strlen(filename);    unsigned int nameLength;#if JAR_FILES_USE_STDIO    unsigned char *p = (unsigned char *)str_buffer; /* temporary storage */    int offset = entry->u.jar.cenOffset; /* offset of first header */    FILE *file = entry->u.jar.file;#else     unsigned const char *p = entry->u.mjar.cenPtr; /* pointer to first header */#endif    while(TRUE) { #if JAR_FILES_USE_STDIO                /* Offset contains the offset of the next central header. Read the         * header into the temporary buffer */        if (/* Go to the header */               (fseek(file, offset, SEEK_SET) < 0)             /* Read the bytes */            || (fread(p, sizeof(char), CENHDRSIZ, file) != CENHDRSIZ)) {             return NULL;        }#endif        /* p contains the current central header */        if (GETSIG(p) != CENSIG) {             /* We've reached the end of the headers */            return NULL;        }         nameLength = CENNAM(p);        if (nameLength == filenameLength) { #if JAR_FILES_USE_STDIO            if (fread(p + CENHDRSIZ, sizeof(char), nameLength, file)                      != nameLength) {                return NULL;            }#endif            if (memcmp(p + CENHDRSIZ, filename, nameLength) == 0) {                 break;            }         }#if JAR_FILES_USE_STDIO        /* Set offset to the next central header */        offset += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);#else         /* Have p point to the next central header */        p += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);#endif    }    return loadJARFileEntryInternal(entry, p, lengthP, extraBytes);}/*========================================================================= * FUNCTION:      loadJARFileEntries() * OVERVIEW:      Reads multiple jar entries from a jar file * * INTERFACE: *   parameters:  JAR_INFO: structure returned by openJARFile *                testFunction: callback to determine whether to read *                      the specified file *                runFunction:  callback called after each jar file is read. *                info:  Info passed to testFunction and runFunction. * * NOTE: The jar files are malloc'ed on the heap.  It is up to the caller * to ensure that they are handled correctly. * * The testFuction is called as: *     bool_t testFunction(const char *name, int nameLength,  *                         int *extraBytes, void *info) * It should return TRUE or FALSE, indicating whether to read the specified * jar file or not.   *      name:        name of entry (not NULL terminated) *      nameLength:  length of name *      extraBytes:  *extraBytes contains 0, but the test function can *                   change this to indicate that padding is needed at the *                   beginning of the entry. *      info:        Arg passed to loadJARFileEntries *  * The runFunction is called for any entry for which the testFunction * returned TRUE *     void runFunction(const char *name, int nameLength,  *                      void *value, long length, void*info); * The arguments are as follows: *     name:          name of entry (not NULL terminated) *     nameLength:    length of name *     value:         Decoded jar entry, or NULL if a problem. *     length:        Length of jar file entry (not included extra bytes) *     info:          Arg passed to loadJARFileEntries *=======================================================================*/voidloadJARFileEntries(JAR_INFO entry,                    JARFileTestFunction testFunction,                   JARFileRunFunction runFunction,                    void *info){    const char *name;    unsigned int nameLength;#if JAR_FILES_USE_STDIO    unsigned char *p = (unsigned char *)str_buffer; /* temporary storage */    FILE *file = entry->u.jar.file;    unsigned long offset = entry->u.jar.cenOffset;#else    /* Start at the beginning of the central header */    unsigned const char *p = entry->u.mjar.cenPtr; #endif    for (;;) { #if JAR_FILES_USE_STDIO        if (/* Go to the next central header */               (fseek(file, offset, SEEK_SET) < 0)             /* Read the bytes */            || (fread(p, sizeof(char), CENHDRSIZ, file) != CENHDRSIZ)            ) {               break;        }        /* Set offset to the next central header */#endif        if (GETSIG(p) != CENSIG) {             /* We've reached the end of the headers */            break;        }        name = (const char *)p + CENHDRSIZ;        nameLength = CENNAM(p);        #if JAR_FILES_USE_STDIO        if (fread(p+CENHDRSIZ, sizeof(char), nameLength, file) != nameLength) {            break;        }        /* We need to update the offset now, rather than later, since         * the temporary buffer might get overwritten.         */        offset += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);#endif        if (name[nameLength - 1] != '/') {             START_TEMPORARY_ROOTS                DECLARE_TEMPORARY_ROOT(JAR_INFO, entryX, entry);                int extraBytes = 0;                if (testFunction(name, nameLength, &extraBytes, info)) {                     long length;                    unsigned char *value =                         loadJARFileEntryInternal(entryX, p, &length, extraBytes);                    runFunction(name, nameLength, value, length, info);                }                entry = entryX;            END_TEMPORARY_ROOTS        }#if !JAR_FILES_USE_STDIO        p += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);#endif      }}/*========================================================================= * FUNCTION:      loadJARFileEntryInternal() * OVERVIEW:      Internal function for reading a jar file * * parameters:   *     JAR_INFO: structure returned by openJARFile. *     centralInfo:  pointer to info in central directory for this entry *     lengthP:  On return, contains length of the entry (not including *             padding caused by extraBytes) *     extraBytes:  Pad the entry with this many extra bytes at the front. * returns: *     result of decompressing the Jar entry. * * NOTE:  If JAR_FILES_USE_STDIO, then centralInfo points at str_buffer, *        which contains the central header.  If !JAR_FILES_USE_STDIO, then *        centralInfo points at the actual bytes. */    static void *loadJARFileEntryInternal(JAR_INFO entry, const unsigned char *centralInfo,                          long *lengthP, int extraBytes) {    unsigned long decompLen = CENLEN(centralInfo); /* the decompressed length */    unsigned long compLen   = CENSIZ(centralInfo); /* the compressed length */    unsigned long method    = CENHOW(centralInfo); /* how it is stored */    unsigned long expectedCRC = CENCRC(centralInfo); /* expected CRC */    unsigned long actualCRC;    unsigned char *result = NULL;#if JAR_FILES_USE_STDIO    FILE *file = entry->u.jar.file;    unsigned long locOffset = entry->u.jar.locOffset;    unsigned char *p = (unsigned char *)str_buffer;#else     unsigned const char *locPtr = entry->u.mjar.locPtr;     const unsigned char *p;#endif    /* Make sure file is not encrypted */    if ((CENFLG(centralInfo) & 1) == 1) {        goto errorReturn;    }    /* This may cause a GC, so we have to extract out of "entry" all the     * info we need, before calling this.     */    result = (unsigned char *)mallocBytes(extraBytes + decompLen);#if !COMPILING_FOR_KVM    if (result == NULL) {        goto errorReturn;    }#endif#if JAR_FILES_USE_STDIO    if (/* Go to the beginning of the LOC header */        (fseek(file, locOffset + CENOFF(centralInfo), SEEK_SET) < 0)         /* Read it */        || (fread(p, sizeof(char), LOCHDRSIZ, file) != LOCHDRSIZ)         /* Skip over name and extension, if any */        || (fseek(file, LOCNAM(p) + LOCEXT(p), SEEK_CUR) < 0)) {        goto errorReturn;    }#else     /* Go to the beginning of the LOC header */    p = locPtr + CENOFF(centralInfo);    /* Skip over the actual bits of the header */    p += LOCHDRSIZ + LOCNAM(p) + LOCEXT(p);#endif    switch (method) {         case STORED:            /* The actual bits are right there in the file */            if (compLen != decompLen) {                goto errorReturn;            }#if JAR_FILES_USE_STDIO                     fread(result + extraBytes, sizeof(char), decompLen, file);#else            memcpy(result + extraBytes, p, decompLen);#endif            break;        case DEFLATED: {            bool_t inflateOK;            START_TEMPORARY_ROOTS                DECLARE_TEMPORARY_ROOT_FROM_BASE(unsigned char*,                                                  decompData,                                                  result + extraBytes, result);#if JAR_FILES_USE_STDIO                void *arg = file;#else                void *arg = &p;#endif                inflateOK = inflateData(arg,                                (JarGetByteFunctionType)jar_getBytes, compLen,                                 &decompData, decompLen);                /* The inflater can allocate memory, so we need to regenerate                 * value from decompData. */                result = decompData - extraBytes;            END_TEMPORARY_ROOTS            if (!inflateOK) {                 goto errorReturn;            }             break;        }                        default:            /* Unknown method */            goto errorReturn;            break;    }    if (result != NULL) {         actualCRC = jarCRC32(result + extraBytes, decompLen);        if (actualCRC != expectedCRC) {             goto errorReturn;        }    }    *lengthP = decompLen;    return (void *)result;errorReturn:        freeBytes(result);    *lengthP = 0;    return NULL;}/*========================================================================= * FUNCTION:      jarCRC32 * OVERVIEW:      Returns the CRC of an array of bytes, using the same *                algorithm as used by the JAR reader. * INTERFACE: *   parameters:  data:     pointer to the array of bytes *                length:   length of data, in bytes *   returns:     CRC *=======================================================================*/static unsigned longjarCRC32(unsigned char *data, unsigned long length) {    unsigned long crc = 0xFFFFFFFF;    unsigned int j;    for ( ; length > 0; length--, data++) {        crc ^= *data;        for (j = 8; j > 0; --j) {            crc = (crc & 1) ? ((crc >> 1) ^ 0xedb88320) : (crc >> 1);        }    }    return ~crc;}/* * Callback passed to inflate, to read the next byte of data. */static intjar_getBytes(char *buff, int length, void* p) {#if JAR_FILES_USE_STDIO    return fread(buff, sizeof(char), length, (FILE *)p);#else    return *(*(unsigned char **)p)++;#endif}

⌨️ 快捷键说明

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