blob: 0cd98b221523b6dbbdf5c8f68bd6740cdc2937c5 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16/*
17 * Read-only access to Zip archives, with minimal heap allocation.
18 */
19#ifndef _LIBDEX_ZIPARCHIVE
20#define _LIBDEX_ZIPARCHIVE
21
22#include "SysUtil.h"
23#include "DexFile.h" // need DEX_INLINE
24
25
26/*
27 * Trivial typedef to ensure that ZipEntry is not treated as a simple
28 * integer. We use NULL to indicate an invalid value.
29 */
30typedef void* ZipEntry;
31
32/*
33 * One entry in the hash table.
34 */
35typedef struct ZipHashEntry {
36 const char* name;
37 unsigned short nameLen;
38 //unsigned int hash;
39} ZipHashEntry;
40
41/*
42 * Read-only Zip archive.
43 *
44 * We want "open" and "find entry by name" to be fast operations, and we
45 * want to use as little memory as possible. We memory-map the file,
46 * and load a hash table with pointers to the filenames (which aren't
47 * null-terminated). The other fields are at a fixed offset from the
48 * filename, so we don't need to extract those (but we do need to byte-read
49 * and endian-swap them every time we want them).
50 *
51 * To speed comparisons when doing a lookup by name, we could make the mapping
52 * "private" (copy-on-write) and null-terminate the filenames after verifying
53 * the record structure. However, this requires a private mapping of
54 * every page that the Central Directory touches. Easier to tuck a copy
55 * of the string length into the hash table entry.
56 */
57typedef struct ZipArchive {
58 /* open Zip archive */
59 int mFd;
60
61 /* mapped file */
62 MemMapping mMap;
63
64 /* number of entries in the Zip archive */
65 int mNumEntries;
66
67 /*
68 * We know how many entries are in the Zip archive, so we can have a
69 * fixed-size hash table. We probe on collisions.
70 */
71 int mHashTableSize;
72 ZipHashEntry* mHashTable;
73} ZipArchive;
74
75/* Zip compression methods we support */
76enum {
77 kCompressStored = 0, // no compression
78 kCompressDeflated = 8, // standard deflate
79};
80
81
82/*
83 * Open a Zip archive.
84 *
85 * On success, returns 0 and populates "pArchive". Returns nonzero errno
86 * value on failure.
87 */
88int dexZipOpenArchive(const char* fileName, ZipArchive* pArchive);
89
90/*
91 * Like dexZipOpenArchive, but takes a file descriptor open for reading
92 * at the start of the file. The descriptor must be mappable (this does
93 * not allow access to a stream).
94 *
95 * "debugFileName" will appear in error messages, but is not otherwise used.
96 */
97int dexZipPrepArchive(int fd, const char* debugFileName, ZipArchive* pArchive);
98
99/*
100 * Close archive, releasing resources associated with it.
101 *
102 * Depending on the implementation this could unmap pages used by classes
103 * stored in a Jar. This should only be done after unloading classes.
104 */
105void dexZipCloseArchive(ZipArchive* pArchive);
106
107/*
108 * Return the archive's file descriptor.
109 */
110DEX_INLINE int dexZipGetArchiveFd(const ZipArchive* pArchive) {
111 return pArchive->mFd;
112}
113
114/*
115 * Find an entry in the Zip archive, by name. Returns NULL if the entry
116 * was not found.
117 */
118ZipEntry dexZipFindEntry(const ZipArchive* pArchive,
119 const char* entryName);
120
121/*
122 * Retrieve one or more of the "interesting" fields. Non-NULL pointers
123 * are filled in.
124 */
125bool dexZipGetEntryInfo(const ZipArchive* pArchive, ZipEntry entry,
126 int* pMethod, long* pUncompLen, long* pCompLen, off_t* pOffset,
127 long* pModWhen, long* pCrc32);
128
129/*
130 * Simple accessors.
131 */
132DEX_INLINE long dexGetZipEntryOffset(const ZipArchive* pArchive,
133 const ZipEntry entry)
134{
135 off_t val = 0;
136 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, &val, NULL, NULL);
137 return (long) val;
138}
139DEX_INLINE long dexGetZipEntryUncompLen(const ZipArchive* pArchive,
140 const ZipEntry entry)
141{
142 long val = 0;
143 dexZipGetEntryInfo(pArchive, entry, NULL, &val, NULL, NULL, NULL, NULL);
144 return val;
145}
146DEX_INLINE long dexGetZipEntryModTime(const ZipArchive* pArchive,
147 const ZipEntry entry)
148{
149 long val = 0;
150 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, &val, NULL);
151 return val;
152}
153DEX_INLINE long dexGetZipEntryCrc32(const ZipArchive* pArchive,
154 const ZipEntry entry)
155{
156 long val = 0;
157 dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, NULL, &val);
158 return val;
159}
160
161/*
162 * Uncompress and write an entry to a file descriptor.
163 */
164bool dexZipExtractEntryToFile(const ZipArchive* pArchive,
165 const ZipEntry entry, int fd);
166
167/*
168 * Utility function to compute a CRC-32.
169 */
170u4 dexInitCrc32(void);
171u4 dexComputeCrc32(u4 crc, const void* buf, size_t len);
172
173#endif /*_LIBDEX_ZIPARCHIVE*/