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

📄 jar.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 3 页
字号:
/*0233*/    /* Set currentOffset to be the offset of buffer[0] */
/*0234*/    currentOffset = minOffset; 
/*0235*/    /* Set bp to be the location at which to start looking */
/*0236*/    bp = jarFile + length - ENDHDRSIZ;  /* Where to start looking */
/*0237*/#endif /* JAR_FILES_USE_STDIO */
/*0238*/
/*0239*/    for (;;) {
/*0240*/        /* "buffer" contains a block of data from the file, starting at
/*0241./         * currentOffset "position" in the file.
/*0242./         * We investigate whether   currentOffset + (bp - buffer)  is the start
/*0243./         * of the end header in the zip file.  
/*0244./         *
/*0245./         * We use a simplified version of Knuth-Morris-Pratt search algorithm.
/*0246./         * The header we're looking for is 'P' 'K' 5  6
/*0247./         */
/*0248*/        switch(bp[0]) {
/*0249*/            case '\006':   /* The header must start at least 3 bytes back */
/*0250*/                bp -= 3; break;
/*0251*/            case '\005':   /* The header must start at least 2 bytes back  */
/*0252*/                bp -= 2; break;
/*0253*/            case 'K':      /* The header must start at least 1 byte back  */
/*0254*/                bp -= 1; break;
/*0255*/            case 'P':      /* Either this is the header, or the header must
/*0256./                            * start at least 4  back */
/*0257*/                if (bp[1] == 'K' && bp[2] == 5 && bp[3] == 6) {
/*0258*/                    /* We have what may be a header.  Let's make sure the
/*0259./                     * implied length of the jar file matches the actual
/*0260./                     * length.
/*0261./                     */
/*0262*/                    int endpos = currentOffset + (bp - buffer);
/*0263*/                    if (endpos + ENDHDRSIZ + ENDCOM(bp) == length) {
/*0264*/                        unsigned long cenOffset = endpos - ENDSIZ(bp);
/*0265*/                        unsigned long locOffset = cenOffset - ENDOFF(bp);
/*0266*/#if JAR_FILES_USE_STDIO
/*0267*/                        if (   fseek(file, locOffset, SEEK_SET) >= 0
/*0268*/                            && getc(file) == 'P' && getc(file) == 'K'
/*0269*/                            && getc(file) == 3   && getc(file) == 4) {
/*0270*/                            entry->u.jar.file = file;
/*0271*/                            entry->u.jar.cenOffset = cenOffset;
/*0272*/                            entry->u.jar.locOffset = locOffset;
/*0273*/                            return TRUE;
/*0274*/                        }
/*0275*/#else
/*0276*/                        const unsigned char *cenPtr = jarFile + cenOffset;
/*0277*/                        const unsigned char *locPtr = jarFile + locOffset;
/*0278*/                        if (GETSIG(locPtr) == LOCSIG) { 
/*0279*/                            entry->u.mjar.base   = jarFile;
/*0280*/                            entry->u.mjar.cenPtr = cenPtr;
/*0281*/                            entry->u.mjar.locPtr = locPtr;
/*0282*/                            return TRUE;
/*0283*/                        }
/*0284*/#endif /* JAR_FILES_USE_STDIO */
/*0285*/
/*0286*/                        goto failureReturn;
/*0287*/                    }
/*0288*/                }
/*0289*/                /* FALL THROUGH */
/*0290*/            default:    
/*0291*/                /* The header must start at least four characters back, since
/*0292./                 * the current character isn't in the header */
/*0293*/                bp -= 4;
/*0294*/        }
/*0295*/        if (bp < buffer) {
/*0296*/#if JAR_FILES_USE_STDIO
/*0297*/            /* We've moved outside our window into the file.  We must
/*0298./             * move the window backwards */
/*0299*/            int count = currentOffset - minOffset; /* Bytes left in file */
/*0300*/            if (count == 0) {
/*0301*/                /* Nothing left to read.  Time to give up */
/*0302*/                goto failureReturn;
/*0303*/            } else {
/*0304*/                /* up to ((bp - buffer) + ENDHDRSIZ) bytes in the buffer might
/*0305./                 * still be part of the end header, so the most bytes we can
/*0306./                 * actually read are
/*0307./                 *      bufferSize - ((bp - buffer) + ENDHDRSIZE).
/*0308./                 */
/*0309*/                int available = (bufferSize - ENDHDRSIZ) + (buffer - bp);
/*0310*/                if (count > available) {
/*0311*/                    count = available;
/*0312*/                }
/*0313*/            }
/*0314*/            /* Back up, while keeping our virtual currentOffset the same */
/*0315*/            currentOffset -= count;
/*0316*/            bp += count;
/*0317*/            memmove(buffer + count, buffer, bufferSize - count);
/*0318*/            if (   (fseek(file, currentOffset, SEEK_SET) < 0)
/*0319*/                   || (fread(buffer, sizeof(char), count, file) 
/*0320*/                                 != (unsigned)count)) {
/*0321*/                goto failureReturn;
/*0322*/            }
/*0323*/#else
/*0324*/            /* There's nothing left to do. */
/*0325*/            goto failureReturn;
/*0326*/#endif /* JAR_FILE_USE_STDIO */
/*0327*/        }
/*0328*/    } /* end of for loop */
/*0329*/
/*0330*/failureReturn:    
/*0331*/#if JAR_FILES_USE_STDIO
/*0332*/    if (file != NULL) { 
/*0333*/        fclose(file);
/*0334*/    }
/*0335*/#endif /* JAR_FILES_USE_STDIO */
/*0336*/
/*0337*/    return FALSE;
/*0338*/}
/*0339*/
/*0340*//*=========================================================================
/*0341./ * FUNCTION:      closeJARFile
/*0342./ * OVERVIEW:      Close a jar file that had previous been opened by 
/*0343./ *                openJARFile
/*0344./ *   parameters:  
/*0345./ *      JAR_INFO:  structure previously filled in by openJARFile
/*0346./ *
/*0347./ *   returns:
/*0348./ *      nothing
/*0349./ *=======================================================================*/
/*0350*/
/*0351*/void
/*0352*/closeJARFile(JAR_INFO entry)
/*0353*/{
/*0354*/#if JAR_FILES_USE_STDIO
/*0355*/    fclose((FILE *)entry->u.jar.file);
/*0356*/#endif
/*0357*/}
/*0358*/
/*0359*//*=========================================================================
/*0360./ * FUNCTION:      loadJARFileEntry()
/*0361./ * OVERVIEW:      Reads an entry in a jar file
/*0362./ *
/*0363./ * INTERFACE:
/*0364./ *   parameters:  JAR_INFO: structure returned by openJARFile
/*0365./ *                filename: name of entry to read
/*0366./ *                lengthP:  on return, contains length of entry in jar file
/*0367./ *                          (does >>NOT<< include extraBytes)
/*0368./ *                extraBytes:  value has this many extra bytes padded at the
/*0369./ *                          beginning.
/*0370./ *
/*0371./ * NOTE: The result is malloc'ed on the heap.  It is up to the caller to protect
/*0372./ *        this result from garbage collectino
/*0373./ *=======================================================================*/
/*0374*/
/*0375*/void *
/*0376*/loadJARFileEntry(JAR_INFO entry, const char *filename,
/*0377*/                 long *lengthP, int extraBytes)
/*0378*/{
/*0379*/    unsigned int filenameLength = strlen(filename);
/*0380*/    unsigned int nameLength;
/*0381*/
/*0382*/#if JAR_FILES_USE_STDIO
/*0383*/    unsigned char *p = (unsigned char *)str_buffer; /* temporary storage */
/*0384*/    int offset = entry->u.jar.cenOffset; /* offset of first header */
/*0385*/    FILE *file = entry->u.jar.file;
/*0386*/#else 
/*0387*/    unsigned const char *p = entry->u.mjar.cenPtr; /* pointer to first header */
/*0388*/#endif
/*0389*/
/*0390*/    while(TRUE) { 
/*0391*/#if JAR_FILES_USE_STDIO        
/*0392*/        /* Offset contains the offset of the next central header. Read the
/*0393./         * header into the temporary buffer */
/*0394*/        if (/* Go to the header */
/*0395*/               (fseek(file, offset, SEEK_SET) < 0) 
/*0396*/            /* Read the bytes */
/*0397*/            || (fread(p, sizeof(char), CENHDRSIZ, file) != CENHDRSIZ)) { 
/*0398*/            return NULL;
/*0399*/        }
/*0400*/#endif
/*0401*/        /* p contains the current central header */
/*0402*/        if (GETSIG(p) != CENSIG) { 
/*0403*/            /* We've reached the end of the headers */
/*0404*/            return NULL;
/*0405*/        } 
/*0406*/        nameLength = CENNAM(p);
/*0407*/        if (nameLength == filenameLength) { 
/*0408*/#if JAR_FILES_USE_STDIO
/*0409*/            if (fread(p + CENHDRSIZ, sizeof(char), nameLength, file)
/*0410*/                      != nameLength) {
/*0411*/                return NULL;
/*0412*/            }
/*0413*/#endif
/*0414*/            if (memcmp(p + CENHDRSIZ, filename, nameLength) == 0) { 
/*0415*/                break;
/*0416*/            } 
/*0417*/        }
/*0418*/
/*0419*/#if JAR_FILES_USE_STDIO
/*0420*/        /* Set offset to the next central header */
/*0421*/        offset += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);
/*0422*/#else 
/*0423*/        /* Have p point to the next central header */
/*0424*/        p += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);
/*0425*/#endif
/*0426*/    }
/*0427*/    return loadJARFileEntryInternal(entry, p, lengthP, extraBytes);
/*0428*/}
/*0429*/
/*0430*//*=========================================================================
/*0431./ * FUNCTION:      loadJARFileEntries()
/*0432./ * OVERVIEW:      Reads multiple jar entries from a jar file
/*0433./ *
/*0434./ * INTERFACE:
/*0435./ *   parameters:  JAR_INFO: structure returned by openJARFile
/*0436./ *                testFunction: callback to determine whether to read
/*0437./ *                      the specified file
/*0438./ *                runFunction:  callback called after each jar file is read.
/*0439./ *                info:  Info passed to testFunction and runFunction.
/*0440./ *
/*0441./ * NOTE: The jar files are malloc'ed on the heap.  It is up to the caller
/*0442./ * to ensure that they are handled correctly.
/*0443./ *
/*0444./ * The testFuction is called as:
/*0445./ *     bool_t testFunction(const char *name, int nameLength, 
/*0446./ *                         int *extraBytes, void *info)
/*0447./ * It should return TRUE or FALSE, indicating whether to read the specified
/*0448./ * jar file or not.  
/*0449./ *      name:        name of entry (not NULL terminated)
/*0450./ *      nameLength:  length of name
/*0451./ *      extraBytes:  *extraBytes contains 0, but the test function can
/*0452./ *                   change this to indicate that padding is needed at the
/*0453./ *                   beginning of the entry.
/*0454./ *      info:        Arg passed to loadJARFileEntries
/*0455./ * 
/*0456./ * The runFunction is called for any entry for which the testFunction
/*0457./ * returned TRUE
/*0458./ *     void runFunction(const char *name, int nameLength, 
/*0459./ *                      void *value, long length, void*info);
/*0460./ * The arguments are as follows:
/*0461./ *     name:          name of entry (not NULL terminated)
/*0462./ *     nameLength:    length of name
/*0463./ *     value:         Decoded jar entry, or NULL if a problem.
/*0464./ *     length:        Length of jar file entry (not included extra bytes)

⌨️ 快捷键说明

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