blob: 739dbf5f256bea5a29ab2622595d30bde1bde4f7 [file] [log] [blame]
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -08001/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Simple Zip archive support.
5 */
6#ifndef _MINZIP_ZIP
7#define _MINZIP_ZIP
8
9#include "inline_magic.h"
10
11#include <stdlib.h>
12#include <utime.h>
13
14#include "Hash.h"
15#include "SysUtil.h"
16
Doug Zongker28ce47c2011-10-28 10:33:05 -070017#ifdef __cplusplus
18extern "C" {
19#endif
20
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080021/*
22 * One entry in the Zip archive. Treat this as opaque -- use accessors below.
23 *
24 * TODO: we're now keeping the pages mapped so we don't have to copy the
25 * filename. We can change the accessors to retrieve the various pieces
26 * directly from the source file instead of copying them out, for a very
27 * slight speed hit and a modest reduction in memory usage.
28 */
29typedef struct ZipEntry {
30 unsigned int fileNameLen;
31 const char* fileName; // not null-terminated
32 long offset;
33 long compLen;
34 long uncompLen;
35 int compression;
36 long modTime;
37 long crc32;
38 int versionMadeBy;
39 long externalFileAttributes;
40} ZipEntry;
41
42/*
43 * One Zip archive. Treat as opaque.
44 */
45typedef struct ZipArchive {
46 int fd;
47 unsigned int numEntries;
48 ZipEntry* pEntries;
49 HashTable* pHash; // maps file name to ZipEntry
50 MemMapping map;
51} ZipArchive;
52
53/*
54 * Represents a non-NUL-terminated string,
55 * which is how entry names are stored.
56 */
57typedef struct {
58 const char *str;
59 size_t len;
60} UnterminatedString;
61
62/*
63 * Open a Zip archive.
64 *
65 * On success, returns 0 and populates "pArchive". Returns nonzero errno
66 * value on failure.
67 */
68int mzOpenZipArchive(const char* fileName, ZipArchive* pArchive);
69
70/*
71 * Close archive, releasing resources associated with it.
72 *
73 * Depending on the implementation this could unmap pages used by classes
74 * stored in a Jar. This should only be done after unloading classes.
75 */
76void mzCloseZipArchive(ZipArchive* pArchive);
77
78
79/*
80 * Find an entry in the Zip archive, by name.
81 */
82const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
83 const char* entryName);
84
85/*
86 * Get the number of entries in the Zip archive.
87 */
88INLINE unsigned int mzZipEntryCount(const ZipArchive* pArchive) {
89 return pArchive->numEntries;
90}
91
92/*
93 * Get an entry by index. Returns NULL if the index is out-of-bounds.
94 */
95INLINE const ZipEntry*
96mzGetZipEntryAt(const ZipArchive* pArchive, unsigned int index)
97{
98 if (index < pArchive->numEntries) {
99 return pArchive->pEntries + index;
100 }
101 return NULL;
102}
103
104/*
105 * Get the index number of an entry in the archive.
106 */
107INLINE unsigned int
108mzGetZipEntryIndex(const ZipArchive *pArchive, const ZipEntry *pEntry) {
109 return pEntry - pArchive->pEntries;
110}
111
112/*
113 * Simple accessors.
114 */
115INLINE UnterminatedString mzGetZipEntryFileName(const ZipEntry* pEntry) {
116 UnterminatedString ret;
117 ret.str = pEntry->fileName;
118 ret.len = pEntry->fileNameLen;
119 return ret;
120}
121INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
122 return pEntry->offset;
123}
124INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
125 return pEntry->uncompLen;
126}
127INLINE long mzGetZipEntryModTime(const ZipEntry* pEntry) {
128 return pEntry->modTime;
129}
130INLINE long mzGetZipEntryCrc32(const ZipEntry* pEntry) {
131 return pEntry->crc32;
132}
133bool mzIsZipEntrySymlink(const ZipEntry* pEntry);
134
135
136/*
137 * Type definition for the callback function used by
138 * mzProcessZipEntryContents().
139 */
140typedef bool (*ProcessZipEntryContentsFunction)(const unsigned char *data,
141 int dataLen, void *cookie);
142
143/*
144 * Stream the uncompressed data through the supplied function,
145 * passing cookie to it each time it gets called. processFunction
146 * may be called more than once.
147 *
148 * If processFunction returns false, the operation is abandoned and
149 * mzProcessZipEntryContents() immediately returns false.
150 *
151 * This is useful for calculating the hash of an entry's uncompressed contents.
152 */
153bool mzProcessZipEntryContents(const ZipArchive *pArchive,
154 const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
155 void *cookie);
156
157/*
158 * Read an entry into a buffer allocated by the caller.
159 */
160bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
161 char* buf, int bufLen);
162
163/*
164 * Check the CRC on this entry; return true if it is correct.
165 * May do other internal checks as well.
166 */
167bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
168
169/*
170 * Inflate and write an entry to a file.
171 */
172bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
Doug Zongker1c4ceae2009-05-08 09:43:28 -0700173 const ZipEntry *pEntry, int fd);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800174
175/*
Doug Zongker6aece332010-02-01 14:40:12 -0800176 * Inflate and write an entry to a memory buffer, which must be long
177 * enough to hold mzGetZipEntryUncomplen(pEntry) bytes.
178 */
179bool mzExtractZipEntryToBuffer(const ZipArchive *pArchive,
180 const ZipEntry *pEntry, unsigned char* buffer);
181
182/*
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800183 * Inflate all entries under zipDir to the directory specified by
184 * targetDir, which must exist and be a writable directory.
185 *
186 * The immediate children of zipDir will become the immediate
187 * children of targetDir; e.g., if the archive contains the entries
188 *
189 * a/b/c/one
190 * a/b/c/two
191 * a/b/c/d/three
192 *
193 * and mzExtractRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting
194 * files will be
195 *
196 * /tmp/one
197 * /tmp/two
198 * /tmp/d/three
199 *
200 * flags is zero or more of the following:
201 *
202 * MZ_EXTRACT_FILES_ONLY - only unpack files, not directories or symlinks
203 * MZ_EXTRACT_DRY_RUN - don't do anything, but do invoke the callback
204 *
205 * If timestamp is non-NULL, file timestamps will be set accordingly.
206 *
207 * If callback is non-NULL, it will be invoked with each unpacked file.
208 *
209 * Returns true on success, false on failure.
210 */
211enum { MZ_EXTRACT_FILES_ONLY = 1, MZ_EXTRACT_DRY_RUN = 2 };
212bool mzExtractRecursive(const ZipArchive *pArchive,
213 const char *zipDir, const char *targetDir,
214 int flags, const struct utimbuf *timestamp,
215 void (*callback)(const char *fn, void*), void *cookie);
216
Doug Zongker28ce47c2011-10-28 10:33:05 -0700217#ifdef __cplusplus
218}
219#endif
220
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800221#endif /*_MINZIP_ZIP*/