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
31 * Trivial typedef to ensure that ZipEntry is not treated as a simple
32 * integer. We use NULL to indicate an invalid value.
34 typedef void* ZipEntry;
37 * One entry in the hash table.
39 typedef struct ZipHashEntry {
41 unsigned short nameLen;
46 * Read-only Zip archive.
48 * We want "open" and "find entry by name" to be fast operations, and
49 * we want to use as little memory as possible. We memory-map the zip
50 * central directory, and load a hash table with pointers to the filenames
51 * (which aren't null-terminated). The other fields are at a fixed offset
52 * from the filename, so we don't need to extract those (but we do need
53 * to byte-read and endian-swap them every time we want them).
55 * It's possible that somebody has handed us a massive (~1GB) zip archive,
56 * so we can't expect to mmap the entire file.
58 * To speed comparisons when doing a lookup by name, we could make the mapping
59 * "private" (copy-on-write) and null-terminate the filenames after verifying
60 * the record structure. However, this requires a private mapping of
61 * every page that the Central Directory touches. Easier to tuck a copy
62 * of the string length into the hash table entry.
64 typedef struct ZipArchive {
65 /* open Zip archive */
68 /* mapped central directory area */
69 off_t mDirectoryOffset;
70 MemMapping mDirectoryMap;
72 /* number of entries in the Zip archive */
76 * We know how many entries are in the Zip archive, so we can have a
77 * fixed-size hash table. We probe on collisions.
80 ZipHashEntry* mHashTable;
83 /* Zip compression methods we support */
85 kCompressStored = 0, // no compression
86 kCompressDeflated = 8, // standard deflate
93 * On success, returns 0 and populates "pArchive". Returns nonzero errno
96 int dexZipOpenArchive(const char* fileName, ZipArchive* pArchive);
99 * Like dexZipOpenArchive, but takes a file descriptor open for reading
100 * at the start of the file. The descriptor must be mappable (this does
101 * not allow access to a stream).
103 * "debugFileName" will appear in error messages, but is not otherwise used.
105 int dexZipPrepArchive(int fd, const char* debugFileName, ZipArchive* pArchive);
108 * Close archive, releasing resources associated with it.
110 * Depending on the implementation this could unmap pages used by classes
111 * stored in a Jar. This should only be done after unloading classes.
113 void dexZipCloseArchive(ZipArchive* pArchive);
116 * Return the archive's file descriptor.
118 DEX_INLINE int dexZipGetArchiveFd(const ZipArchive* pArchive) {
119 return pArchive->mFd;
123 * Find an entry in the Zip archive, by name. Returns NULL if the entry
126 ZipEntry dexZipFindEntry(const ZipArchive* pArchive,
127 const char* entryName);
130 * Retrieve one or more of the "interesting" fields. Non-NULL pointers
133 * Returns 0 on success.
135 int dexZipGetEntryInfo(const ZipArchive* pArchive, ZipEntry entry,
136 int* pMethod, size_t* pUncompLen, size_t* pCompLen, off_t* pOffset,
137 long* pModWhen, long* pCrc32);
142 DEX_INLINE long dexGetZipEntryOffset(const ZipArchive* pArchive,
143 const ZipEntry entry)
146 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, &val, NULL, NULL);
149 DEX_INLINE size_t dexGetZipEntryUncompLen(const ZipArchive* pArchive,
150 const ZipEntry entry)
153 dexZipGetEntryInfo(pArchive, entry, NULL, &val, NULL, NULL, NULL, NULL);
156 DEX_INLINE long dexGetZipEntryModTime(const ZipArchive* pArchive,
157 const ZipEntry entry)
160 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, &val, NULL);
163 DEX_INLINE long dexGetZipEntryCrc32(const ZipArchive* pArchive,
164 const ZipEntry entry)
167 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, NULL, &val);
172 * Uncompress and write an entry to a file descriptor.
174 * Returns 0 on success.
176 int dexZipExtractEntryToFile(const ZipArchive* pArchive,
177 const ZipEntry entry, int fd);
180 * Utility function to compute a CRC-32.
182 u4 dexInitCrc32(void);
183 u4 dexComputeCrc32(u4 crc, const void* buf, size_t len);
189 #endif /*_LIBDEX_ZIPARCHIVE*/