zip_util.h 10.0 KB
Newer Older
D
duke 已提交
1
/*
X
xdono 已提交
2
 * Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * Prototypes for zip file support
 */

#ifndef _ZIP_H_
#define _ZIP_H_

/*
 * Header signatures
 */
#define LOCSIG 0x04034b50L          /* "PK\003\004" */
#define EXTSIG 0x08074b50L          /* "PK\007\008" */
#define CENSIG 0x02014b50L          /* "PK\001\002" */
#define ENDSIG 0x06054b50L          /* "PK\005\006" */

41 42 43
#define ZIP64_ENDSIG 0x06064b50L    /* "PK\006\006" */
#define ZIP64_LOCSIG 0x07064b50L    /* "PK\006\007" */

D
duke 已提交
44 45 46
/*
 * Header sizes including signatures
 */
47

D
duke 已提交
48 49 50 51 52 53 54 55
#ifdef USE_MMAP
#define SIGSIZ  4
#endif
#define LOCHDR 30
#define EXTHDR 16
#define CENHDR 46
#define ENDHDR 22

56 57 58 59 60 61 62 63 64
#define ZIP64_ENDHDR 56       // ZIP64 end header size
#define ZIP64_LOCHDR 20       // ZIP64 end loc header size
#define ZIP64_EXTHDR 24       // EXT header size
#define ZIP64_EXTID   1       // Extra field Zip64 header ID

#define ZIP64_MAGICVAL 0xffffffffLL
#define ZIP64_MAGICCOUNT 0xffff


D
duke 已提交
65 66 67 68 69
/*
 * Header field access macros
 */
#define CH(b, n) (((unsigned char *)(b))[n])
#define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8))
70 71
#define LG(b, n) ((SH(b, n) | (SH(b, n+2) << 16)) &0xffffffffUL)
#define LL(b, n) (((jlong)LG(b, n)) | (((jlong)LG(b, n+4)) << 32))
D
duke 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
#define GETSIG(b) LG(b, 0)

/*
 * Macros for getting local file (LOC) header fields
 */
#define LOCVER(b) SH(b, 4)          /* version needed to extract */
#define LOCFLG(b) SH(b, 6)          /* general purpose bit flags */
#define LOCHOW(b) SH(b, 8)          /* compression method */
#define LOCTIM(b) LG(b, 10)         /* modification time */
#define LOCCRC(b) LG(b, 14)         /* crc of uncompressed data */
#define LOCSIZ(b) LG(b, 18)         /* compressed data size */
#define LOCLEN(b) LG(b, 22)         /* uncompressed data size */
#define LOCNAM(b) SH(b, 26)         /* filename length */
#define LOCEXT(b) SH(b, 28)         /* extra field length */

/*
 * Macros for getting extra local (EXT) header fields
 */
#define EXTCRC(b) LG(b, 4)          /* crc of uncompressed data */
#define EXTSIZ(b) LG(b, 8)          /* compressed size */
#define EXTLEN(b) LG(b, 12)         /* uncompressed size */

/*
 * Macros for getting central directory header (CEN) fields
 */
#define CENVEM(b) SH(b, 4)          /* version made by */
#define CENVER(b) SH(b, 6)          /* version needed to extract */
#define CENFLG(b) SH(b, 8)          /* general purpose bit flags */
#define CENHOW(b) SH(b, 10)         /* compression method */
#define CENTIM(b) LG(b, 12)         /* modification time */
#define CENCRC(b) LG(b, 16)         /* crc of uncompressed data */
#define CENSIZ(b) LG(b, 20)         /* compressed size */
#define CENLEN(b) LG(b, 24)         /* uncompressed size */
#define CENNAM(b) SH(b, 28)         /* length of filename */
#define CENEXT(b) SH(b, 30)         /* length of extra field */
#define CENCOM(b) SH(b, 32)         /* file comment length */
#define CENDSK(b) SH(b, 34)         /* disk number start */
#define CENATT(b) SH(b, 36)         /* internal file attributes */
#define CENATX(b) LG(b, 38)         /* external file attributes */
#define CENOFF(b) LG(b, 42)         /* offset of local header */

/*
 * Macros for getting end of central directory header (END) fields
 */
#define ENDSUB(b) SH(b, 8)          /* number of entries on this disk */
#define ENDTOT(b) SH(b, 10)         /* total number of entries */
#define ENDSIZ(b) LG(b, 12)         /* central directory size */
#define ENDOFF(b) LG(b, 16)         /* central directory offset */
#define ENDCOM(b) SH(b, 20)         /* size of zip file comment */

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
/*
 * Macros for getting Zip64 end of central directory header fields
 */
#define ZIP64_ENDLEN(b) LL(b, 4)      /* size of zip64 end of central dir */
#define ZIP64_ENDVEM(b) SH(b, 12)     /* version made by */
#define ZIP64_ENDVER(b) SH(b, 14)     /* version needed to extract */
#define ZIP64_ENDNMD(b) LG(b, 16)     /* number of this disk */
#define ZIP64_ENDDSK(b) LG(b, 20)     /* disk number of start */
#define ZIP64_ENDTOD(b) LL(b, 24)     /* total number of entries on this disk */
#define ZIP64_ENDTOT(b) LL(b, 32)     /* total number of entries */
#define ZIP64_ENDSIZ(b) LL(b, 40)     /* central directory size in bytes */
#define ZIP64_ENDOFF(b) LL(b, 48)     /* offset of first CEN header */

/*
 * Macros for getting Zip64 end of central directory locator fields
 */
#define ZIP64_LOCDSK(b) LG(b, 4)      /* disk number start */
#define ZIP64_LOCOFF(b) LL(b, 8)      /* offset of zip64 end */
#define ZIP64_LOCTOT(b) LG(b, 16)     /* total number of disks */

D
duke 已提交
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
/*
 * Supported compression methods
 */
#define STORED      0
#define DEFLATED    8

/*
 * Support for reading ZIP/JAR files. Some things worth noting:
 *
 * - Zip file entries larger than 2**32 bytes are not supported.
 * - jzentry time and crc fields are signed even though they really
 *   represent unsigned quantities.
 * - If csize is zero then the entry is uncompressed.
 * - If extra != 0 then the first two bytes are the length of the extra
 *   data in intel byte order.
 * - If pos <= 0 then it is the position of entry LOC header.
 *   If pos > 0 then it is the position of entry data.
 *   pos should not be accessed directly, but only by ZIP_GetEntryDataOffset.
 */

typedef struct jzentry {  /* Zip file entry */
    char *name;           /* entry name */
    jlong time;           /* modification time */
    jlong size;           /* size of uncompressed data */
    jlong csize;          /* size of compressed data (zero if uncompressed) */
    jint crc;             /* crc of uncompressed data */
    char *comment;        /* optional zip file comment */
    jbyte *extra;         /* optional extra data */
    jlong pos;            /* position of LOC header or entry data */
} jzentry;

/*
 * In-memory hash table cell.
 * In a typical system we have a *lot* of these, as we have one for
 * every entry in every active JAR.
 * Note that in order to save space we don't keep the name in memory,
 * but merely remember a 32 bit hash.
 */
typedef struct jzcell {
    unsigned int hash;    /* 32 bit hashcode on name */
182
    jlong cenpos;         /* Offset of central directory file header */
D
duke 已提交
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
    unsigned int next;    /* hash chain: index into jzfile->entries */
} jzcell;

typedef struct cencache {
    char *data;           /* A cached page of CEN headers */
    jlong pos;            /* file offset of data */
} cencache;

/*
 * Use ZFILE to represent access to a file in a platform-indepenent
 * fashion.
 */
#ifdef WIN32
#define ZFILE jlong
#else
#define ZFILE int
#endif

/*
 * Descriptor for a ZIP file.
 */
typedef struct jzfile {   /* Zip file */
    char *name;           /* zip file name */
    jint refs;            /* number of active references */
    jlong len;            /* length (in bytes) of zip file */
#ifdef USE_MMAP
    unsigned char *maddr; /* beginning address of the CEN & ENDHDR */
    jlong mlen;           /* length (in bytes) mmaped */
211
    jlong offset;         /* offset of the mmapped region from the
D
duke 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
                             start of the file. */
#else
    cencache cencache;    /* CEN header cache */
#endif
    ZFILE zfd;            /* open file descriptor */
    void *lock;           /* read lock */
    char *comment;        /* zip file comment */
    char *msg;            /* zip error message */
    jzcell *entries;      /* array of hash cells */
    jint total;           /* total number of entries */
    jint *table;          /* Hash chain heads: indexes into entries */
    jint tablelen;        /* number of hash heads */
    struct jzfile *next;  /* next zip file in search list */
    jzentry *cache;       /* we cache the most recently freed jzentry */
    /* Information on metadata names in META-INF directory */
    char **metanames;     /* array of meta names (may have null names) */
    jint metacurrent;     /* the next empty slot in metanames array */
    jint metacount;       /* number of slots in metanames array */
    jlong lastModified;   /* last modified time */
    jlong locpos;         /* position of first LOC header (usually 0) */
} jzfile;

/*
 * Index representing end of hash chain
 */
#define ZIP_ENDCHAIN ((jint)-1)

jzentry * JNICALL
ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP);

jboolean JNICALL
ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entrynm);

jzentry * JNICALL
ZIP_GetNextEntry(jzfile *zip, jint n);

jzfile * JNICALL
ZIP_Open(const char *name, char **pmsg);

jzfile *
ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified);

jzfile *
ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified);

jzfile *
ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified);

void JNICALL
ZIP_Close(jzfile *zip);

jzentry * ZIP_GetEntry(jzfile *zip, char *name, jint ulen);
void ZIP_Lock(jzfile *zip);
void ZIP_Unlock(jzfile *zip);
jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);

#endif /* !_ZIP_H_ */