OSDN Git Service

am d336a946: am 024b7b9d: am a0739ea3: am af242824: Revert "Fix a type error in the...
[android-x86/dalvik.git] / libdex / ZipArchive.h
1 /*
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 /*
18  * Read-only access to Zip archives, with minimal heap allocation.
19  */
20 #ifndef _LIBDEX_ZIPARCHIVE
21 #define _LIBDEX_ZIPARCHIVE
22
23 #include "SysUtil.h"
24 #include "DexFile.h"            // need DEX_INLINE
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 /*
31  * Trivial typedef to ensure that ZipEntry is not treated as a simple
32  * integer.  We use NULL to indicate an invalid value.
33  */
34 typedef void* ZipEntry;
35
36 /*
37  * One entry in the hash table.
38  */
39 typedef struct ZipHashEntry {
40     const char*     name;
41     unsigned short  nameLen;
42     //unsigned int    hash;
43 } ZipHashEntry;
44
45 /*
46  * Read-only Zip archive.
47  *
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).
54  *
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.
57  *
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.
63  */
64 typedef struct ZipArchive {
65     /* open Zip archive */
66     int         mFd;
67
68     /* mapped central directory area */
69     off_t       mDirectoryOffset;
70     MemMapping  mDirectoryMap;
71
72     /* number of entries in the Zip archive */
73     int         mNumEntries;
74
75     /*
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.
78      */
79     int         mHashTableSize;
80     ZipHashEntry* mHashTable;
81 } ZipArchive;
82
83 /* Zip compression methods we support */
84 enum {
85     kCompressStored     = 0,        // no compression
86     kCompressDeflated   = 8,        // standard deflate
87 };
88
89
90 /*
91  * Open a Zip archive.
92  *
93  * On success, returns 0 and populates "pArchive".  Returns nonzero errno
94  * value on failure.
95  */
96 int dexZipOpenArchive(const char* fileName, ZipArchive* pArchive);
97
98 /*
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).
102  *
103  * "debugFileName" will appear in error messages, but is not otherwise used.
104  */
105 int dexZipPrepArchive(int fd, const char* debugFileName, ZipArchive* pArchive);
106
107 /*
108  * Close archive, releasing resources associated with it.
109  *
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.
112  */
113 void dexZipCloseArchive(ZipArchive* pArchive);
114
115 /*
116  * Return the archive's file descriptor.
117  */
118 DEX_INLINE int dexZipGetArchiveFd(const ZipArchive* pArchive) {
119     return pArchive->mFd;
120 }
121
122 /*
123  * Find an entry in the Zip archive, by name.  Returns NULL if the entry
124  * was not found.
125  */
126 ZipEntry dexZipFindEntry(const ZipArchive* pArchive,
127     const char* entryName);
128
129 /*
130  * Retrieve one or more of the "interesting" fields.  Non-NULL pointers
131  * are filled in.
132  *
133  * Returns 0 on success.
134  */
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);
138
139 /*
140  * Simple accessors.
141  */
142 DEX_INLINE long dexGetZipEntryOffset(const ZipArchive* pArchive,
143     const ZipEntry entry)
144 {
145     off_t val = 0;
146     dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, &val, NULL, NULL);
147     return (long) val;
148 }
149 DEX_INLINE size_t dexGetZipEntryUncompLen(const ZipArchive* pArchive,
150     const ZipEntry entry)
151 {
152     size_t val = 0;
153     dexZipGetEntryInfo(pArchive, entry, NULL, &val, NULL, NULL, NULL, NULL);
154     return val;
155 }
156 DEX_INLINE long dexGetZipEntryModTime(const ZipArchive* pArchive,
157     const ZipEntry entry)
158 {
159     long val = 0;
160     dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, &val, NULL);
161     return val;
162 }
163 DEX_INLINE long dexGetZipEntryCrc32(const ZipArchive* pArchive,
164     const ZipEntry entry)
165 {
166     long val = 0;
167     dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, NULL, &val);
168     return val;
169 }
170
171 /*
172  * Uncompress and write an entry to a file descriptor.
173  *
174  * Returns 0 on success.
175  */
176 int dexZipExtractEntryToFile(const ZipArchive* pArchive,
177     const ZipEntry entry, int fd);
178
179 /*
180  * Utility function to compute a CRC-32.
181  */
182 u4 dexInitCrc32(void);
183 u4 dexComputeCrc32(u4 crc, const void* buf, size_t len);
184
185 #ifdef __cplusplus
186 }
187 #endif
188
189 #endif /*_LIBDEX_ZIPARCHIVE*/