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

📄 jar.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 3 页
字号:
/*0465./ *     info:          Arg passed to loadJARFileEntries
/*0466./ *=======================================================================*/
/*0467*/
/*0468*/void
/*0469*/loadJARFileEntries(JAR_INFO entry, 
/*0470*/                   JARFileTestFunction testFunction,
/*0471*/                   JARFileRunFunction runFunction, 
/*0472*/                   void *info)
/*0473*/{
/*0474*/    const char *name;
/*0475*/    unsigned int nameLength;
/*0476*/
/*0477*/#if JAR_FILES_USE_STDIO
/*0478*/    unsigned char *p = (unsigned char *)str_buffer; /* temporary storage */
/*0479*/    FILE *file = entry->u.jar.file;
/*0480*/    unsigned long offset = entry->u.jar.cenOffset;
/*0481*/#else
/*0482*/    /* Start at the beginning of the central header */
/*0483*/    unsigned const char *p = entry->u.mjar.cenPtr; 
/*0484*/#endif
/*0485*/    for (;;) { 
/*0486*/
/*0487*/#if JAR_FILES_USE_STDIO
/*0488*/        if (/* Go to the next central header */
/*0489*/               (fseek(file, offset, SEEK_SET) < 0) 
/*0490*/            /* Read the bytes */
/*0491*/            || (fread(p, sizeof(char), CENHDRSIZ, file) != CENHDRSIZ) 
/*0492*/           ) { 
/*0493*/              break;
/*0494*/        }
/*0495*/        /* Set offset to the next central header */
/*0496*/#endif
/*0497*/        if (GETSIG(p) != CENSIG) { 
/*0498*/            /* We've reached the end of the headers */
/*0499*/            break;
/*0500*/        }
/*0501*/
/*0502*/        name = (const char *)p + CENHDRSIZ;
/*0503*/        nameLength = CENNAM(p);
/*0504*/        
/*0505*/#if JAR_FILES_USE_STDIO
/*0506*/        if (fread(p+CENHDRSIZ, sizeof(char), nameLength, file) != nameLength) {
/*0507*/            break;
/*0508*/        }
/*0509*/        /* We need to update the offset now, rather than later, since
/*0510./         * the temporary buffer might get overwritten.
/*0511./         */
/*0512*/        offset += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);
/*0513*/#endif
/*0514*/        if (name[nameLength - 1] != '/') { 
/*0515*/            START_TEMPORARY_ROOTS
/*0516*/                DECLARE_TEMPORARY_ROOT(JAR_INFO, entryX, entry);
/*0517*/                int extraBytes = 0;
/*0518*/                if (testFunction(name, nameLength, &extraBytes, info)) { 
/*0519*/                    long length;
/*0520*/                    unsigned char *value = 
/*0521*/                        loadJARFileEntryInternal(entryX, p, &length, extraBytes);
/*0522*/                    runFunction(name, nameLength, value, length, info);
/*0523*/                }
/*0524*/                entry = entryX;
/*0525*/            END_TEMPORARY_ROOTS
/*0526*/        }
/*0527*/#if !JAR_FILES_USE_STDIO
/*0528*/        p += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);
/*0529*/#endif  
/*0530*/    }
/*0531*/}
/*0532*/
/*0533*//*=========================================================================
/*0534./ * FUNCTION:      loadJARFileEntryInternal()
/*0535./ * OVERVIEW:      Internal function for reading a jar file
/*0536./ *
/*0537./ * parameters:  
/*0538./ *     JAR_INFO: structure returned by openJARFile.
/*0539./ *     centralInfo:  pointer to info in central directory for this entry
/*0540./ *     lengthP:  On return, contains length of the entry (not including
/*0541./ *             padding caused by extraBytes)
/*0542./ *     extraBytes:  Pad the entry with this many extra bytes at the front.
/*0543./ * returns:
/*0544./ *     result of decompressing the Jar entry.
/*0545./ *
/*0546./ * NOTE:  If JAR_FILES_USE_STDIO, then centralInfo points at str_buffer,
/*0547./ *        which contains the central header.  If !JAR_FILES_USE_STDIO, then
/*0548./ *        centralInfo points at the actual bytes.
/*0549./ */    
/*0550*/
/*0551*/static void *
/*0552*/loadJARFileEntryInternal(JAR_INFO entry, const unsigned char *centralInfo, 
/*0553*/                         long *lengthP, int extraBytes) 
/*0554*/{
/*0555*/    unsigned long decompLen = CENLEN(centralInfo); /* the decompressed length */
/*0556*/    unsigned long compLen   = CENSIZ(centralInfo); /* the compressed length */
/*0557*/    unsigned long method    = CENHOW(centralInfo); /* how it is stored */
/*0558*/    unsigned long expectedCRC = CENCRC(centralInfo); /* expected CRC */
/*0559*/    unsigned long actualCRC;
/*0560*/    unsigned char *result = NULL;
/*0561*/
/*0562*/#if JAR_FILES_USE_STDIO
/*0563*/    FILE *file = entry->u.jar.file;
/*0564*/    unsigned long locOffset = entry->u.jar.locOffset;
/*0565*/    unsigned char *p = (unsigned char *)str_buffer;
/*0566*/#else 
/*0567*/    unsigned const char *locPtr = entry->u.mjar.locPtr; 
/*0568*/    const unsigned char *p;
/*0569*/#endif
/*0570*/
/*0571*/    /* Make sure file is not encrypted */
/*0572*/    if ((CENFLG(centralInfo) & 1) == 1) {
/*0573*/        goto errorReturn;
/*0574*/    }
/*0575*/
/*0576*/    /* This may cause a GC, so we have to extract out of "entry" all the
/*0577./     * info we need, before calling this.
/*0578./     */
/*0579*/    result = (unsigned char *)mallocBytes(extraBytes + decompLen);
/*0580*/#if !COMPILING_FOR_KVM
/*0581*/    if (result == NULL) {
/*0582*/        goto errorReturn;
/*0583*/    }
/*0584*/#endif
/*0585*/
/*0586*/#if JAR_FILES_USE_STDIO
/*0587*/    if (/* Go to the beginning of the LOC header */
/*0588*/        (fseek(file, locOffset + CENOFF(centralInfo), SEEK_SET) < 0) 
/*0589*/        /* Read it */
/*0590*/        || (fread(p, sizeof(char), LOCHDRSIZ, file) != LOCHDRSIZ) 
/*0591*/        /* Skip over name and extension, if any */
/*0592*/        || (fseek(file, LOCNAM(p) + LOCEXT(p), SEEK_CUR) < 0)) {
/*0593*/        goto errorReturn;
/*0594*/    }
/*0595*/#else 
/*0596*/    /* Go to the beginning of the LOC header */
/*0597*/    p = locPtr + CENOFF(centralInfo);
/*0598*/    /* Skip over the actual bits of the header */
/*0599*/    p += LOCHDRSIZ + LOCNAM(p) + LOCEXT(p);
/*0600*/#endif
/*0601*/
/*0602*/    switch (method) { 
/*0603*/        case STORED:
/*0604*/            /* The actual bits are right there in the file */
/*0605*/            if (compLen != decompLen) {
/*0606*/                goto errorReturn;
/*0607*/            }
/*0608*/#if JAR_FILES_USE_STDIO         
/*0609*/            fread(result + extraBytes, sizeof(char), decompLen, file);
/*0610*/#else
/*0611*/            memcpy(result + extraBytes, p, decompLen);
/*0612*/#endif
/*0613*/            break;
/*0614*/
/*0615*/        case DEFLATED: {
/*0616*/            bool_t inflateOK;
/*0617*/            START_TEMPORARY_ROOTS
/*0618*/                DECLARE_TEMPORARY_ROOT_FROM_BASE(unsigned char*, 
/*0619*/                                                 decompData, 
/*0620*/                                                 result + extraBytes, result);
/*0621*/#if JAR_FILES_USE_STDIO
/*0622*/                void *arg = file;
/*0623*/#else
/*0624*/                void *arg = &p;
/*0625*/#endif
/*0626*/                inflateOK = inflate(arg, jar_getByte, compLen, 
/*0627*/                                    &decompData, decompLen);
/*0628*/                /* The inflater can allocate memory, so we need to regenerate
/*0629./                 * value from decompData. */
/*0630*/                result = decompData - extraBytes;
/*0631*/            END_TEMPORARY_ROOTS
/*0632*/            if (!inflateOK) { 
/*0633*/                goto errorReturn;
/*0634*/            } 
/*0635*/            break;
/*0636*/        }
/*0637*/                
/*0638*/        default:
/*0639*/            /* Unknown method */
/*0640*/            goto errorReturn;
/*0641*/            break;
/*0642*/    }
/*0643*/
/*0644*/    if (result != NULL) { 
/*0645*/        actualCRC = jarCRC32(result + extraBytes, decompLen);
/*0646*/        if (actualCRC != expectedCRC) { 
/*0647*/            goto errorReturn;
/*0648*/        }
/*0649*/    }
/*0650*/    *lengthP = decompLen;
/*0651*/    return (void *)result;
/*0652*/
/*0653*/errorReturn:    
/*0654*/    freeBytes(result);
/*0655*/    *lengthP = 0;
/*0656*/    return NULL;
/*0657*/}
/*0658*/
/*0659*//*=========================================================================
/*0660./ * FUNCTION:      jarCRC32
/*0661./ * OVERVIEW:      Returns the CRC of an array of bytes, using the same
/*0662./ *                algorithm as used by the JAR reader.
/*0663./ * INTERFACE:
/*0664./ *   parameters:  data:     pointer to the array of bytes
/*0665./ *                length:   length of data, in bytes
/*0666./ *   returns:     CRC
/*0667./ *=======================================================================*/
/*0668*/
/*0669*/static unsigned long
/*0670*/jarCRC32(unsigned char *data, unsigned long length) {
/*0671*/    unsigned long crc = 0xFFFFFFFF;
/*0672*/    unsigned int j;
/*0673*/    for ( ; length > 0; length--, data++) {
/*0674*/        crc ^= *data;
/*0675*/        for (j = 8; j > 0; --j) {
/*0676*/            crc = (crc & 1) ? ((crc >> 1) ^ 0xedb88320) : (crc >> 1);
/*0677*/        }
/*0678*/    }
/*0679*/    return ~crc;
/*0680*/}
/*0681*/
/*0682*//*
/*0683./ * Callback passed to inflate, to read the next byte of data.
/*0684./ */
/*0685*/static int
/*0686*/jar_getByte(void* p) {
/*0687*/#if JAR_FILES_USE_STDIO
/*0688*/    return getc((FILE*)p);
/*0689*/#else
/*0690*/    return *(*(unsigned char **)p)++;
/*0691*/#endif
/*0692*/}
/*0693*/
/*0694*/

⌨️ 快捷键说明

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