2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Read-only access to Zip archives, with minimal heap allocation.
20 #ifndef _LIBDEX_ZIPARCHIVE
21 #define _LIBDEX_ZIPARCHIVE
24 #include "DexFile.h" // need DEX_INLINE
28 * Trivial typedef to ensure that ZipEntry is not treated as a simple
29 * integer. We use NULL to indicate an invalid value.
31 typedef void* ZipEntry;
34 * One entry in the hash table.
36 typedef struct ZipHashEntry {
38 unsigned short nameLen;
43 * Read-only Zip archive.
45 * We want "open" and "find entry by name" to be fast operations, and
46 * we want to use as little memory as possible. We memory-map the zip
47 * central directory, and load a hash table with pointers to the filenames
48 * (which aren't null-terminated). The other fields are at a fixed offset
49 * from the filename, so we don't need to extract those (but we do need
50 * to byte-read and endian-swap them every time we want them).
52 * It's possible that somebody has handed us a massive (~1GB) zip archive,
53 * so we can't expect to mmap the entire file.
55 * To speed comparisons when doing a lookup by name, we could make the mapping
56 * "private" (copy-on-write) and null-terminate the filenames after verifying
57 * the record structure. However, this requires a private mapping of
58 * every page that the Central Directory touches. Easier to tuck a copy
59 * of the string length into the hash table entry.
61 typedef struct ZipArchive {
62 /* open Zip archive */
65 /* mapped central directory area */
66 off_t mDirectoryOffset;
67 MemMapping mDirectoryMap;
69 /* number of entries in the Zip archive */
73 * We know how many entries are in the Zip archive, so we can have a
74 * fixed-size hash table. We probe on collisions.
77 ZipHashEntry* mHashTable;
80 /* Zip compression methods we support */
82 kCompressStored = 0, // no compression
83 kCompressDeflated = 8, // standard deflate
90 * On success, returns 0 and populates "pArchive". Returns nonzero errno
93 int dexZipOpenArchive(const char* fileName, ZipArchive* pArchive);
96 * Like dexZipOpenArchive, but takes a file descriptor open for reading
97 * at the start of the file. The descriptor must be mappable (this does
98 * not allow access to a stream).
100 * "debugFileName" will appear in error messages, but is not otherwise used.
102 int dexZipPrepArchive(int fd, const char* debugFileName, ZipArchive* pArchive);
105 * Close archive, releasing resources associated with it.
107 * Depending on the implementation this could unmap pages used by classes
108 * stored in a Jar. This should only be done after unloading classes.
110 void dexZipCloseArchive(ZipArchive* pArchive);
113 * Return the archive's file descriptor.
115 DEX_INLINE int dexZipGetArchiveFd(const ZipArchive* pArchive) {
116 return pArchive->mFd;
120 * Find an entry in the Zip archive, by name. Returns NULL if the entry
123 ZipEntry dexZipFindEntry(const ZipArchive* pArchive,
124 const char* entryName);
127 * Retrieve one or more of the "interesting" fields. Non-NULL pointers
130 * Returns 0 on success.
132 int dexZipGetEntryInfo(const ZipArchive* pArchive, ZipEntry entry,
133 int* pMethod, size_t* pUncompLen, size_t* pCompLen, off_t* pOffset,
134 long* pModWhen, long* pCrc32);
139 DEX_INLINE long dexGetZipEntryOffset(const ZipArchive* pArchive,
140 const ZipEntry entry)
143 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, &val, NULL, NULL);
146 DEX_INLINE size_t dexGetZipEntryUncompLen(const ZipArchive* pArchive,
147 const ZipEntry entry)
150 dexZipGetEntryInfo(pArchive, entry, NULL, &val, NULL, NULL, NULL, NULL);
153 DEX_INLINE long dexGetZipEntryModTime(const ZipArchive* pArchive,
154 const ZipEntry entry)
157 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, &val, NULL);
160 DEX_INLINE long dexGetZipEntryCrc32(const ZipArchive* pArchive,
161 const ZipEntry entry)
164 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, NULL, &val);
169 * Uncompress and write an entry to a file descriptor.
171 * Returns 0 on success.
173 int dexZipExtractEntryToFile(const ZipArchive* pArchive,
174 const ZipEntry entry, int fd);
177 * Utility function to compute a CRC-32.
179 u4 dexInitCrc32(void);
180 u4 dexComputeCrc32(u4 crc, const void* buf, size_t len);
182 #endif /*_LIBDEX_ZIPARCHIVE*/