OSDN Git Service

am 6854a7fc: am faaab7ba: am f6cd559a: am c2c14690: am 4751c150: Fixing bulk reads...
[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
27 /*
28  * Trivial typedef to ensure that ZipEntry is not treated as a simple
29  * integer.  We use NULL to indicate an invalid value.
30  */
31 typedef void* ZipEntry;
32
33 /*
34  * One entry in the hash table.
35  */
36 typedef struct ZipHashEntry {
37     const char*     name;
38     unsigned short  nameLen;
39     //unsigned int    hash;
40 } ZipHashEntry;
41
42 /*
43  * Read-only Zip archive.
44  *
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).
51  *
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.
54  *
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.
60  */
61 typedef struct ZipArchive {
62     /* open Zip archive */
63     int         mFd;
64
65     /* mapped central directory area */
66     off_t       mDirectoryOffset;
67     MemMapping  mDirectoryMap;
68
69     /* number of entries in the Zip archive */
70     int         mNumEntries;
71
72     /*
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.
75      */
76     int         mHashTableSize;
77     ZipHashEntry* mHashTable;
78 } ZipArchive;
79
80 /* Zip compression methods we support */
81 enum {
82     kCompressStored     = 0,        // no compression
83     kCompressDeflated   = 8,        // standard deflate
84 };
85
86
87 /*
88  * Open a Zip archive.
89  *
90  * On success, returns 0 and populates "pArchive".  Returns nonzero errno
91  * value on failure.
92  */
93 int dexZipOpenArchive(const char* fileName, ZipArchive* pArchive);
94
95 /*
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).
99  *
100  * "debugFileName" will appear in error messages, but is not otherwise used.
101  */
102 int dexZipPrepArchive(int fd, const char* debugFileName, ZipArchive* pArchive);
103
104 /*
105  * Close archive, releasing resources associated with it.
106  *
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.
109  */
110 void dexZipCloseArchive(ZipArchive* pArchive);
111
112 /*
113  * Return the archive's file descriptor.
114  */
115 DEX_INLINE int dexZipGetArchiveFd(const ZipArchive* pArchive) {
116     return pArchive->mFd;
117 }
118
119 /*
120  * Find an entry in the Zip archive, by name.  Returns NULL if the entry
121  * was not found.
122  */
123 ZipEntry dexZipFindEntry(const ZipArchive* pArchive,
124     const char* entryName);
125
126 /*
127  * Retrieve one or more of the "interesting" fields.  Non-NULL pointers
128  * are filled in.
129  *
130  * Returns 0 on success.
131  */
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);
135
136 /*
137  * Simple accessors.
138  */
139 DEX_INLINE long dexGetZipEntryOffset(const ZipArchive* pArchive,
140     const ZipEntry entry)
141 {
142     off_t val = 0;
143     dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, &val, NULL, NULL);
144     return (long) val;
145 }
146 DEX_INLINE size_t dexGetZipEntryUncompLen(const ZipArchive* pArchive,
147     const ZipEntry entry)
148 {
149     size_t val = 0;
150     dexZipGetEntryInfo(pArchive, entry, NULL, &val, NULL, NULL, NULL, NULL);
151     return val;
152 }
153 DEX_INLINE long dexGetZipEntryModTime(const ZipArchive* pArchive,
154     const ZipEntry entry)
155 {
156     long val = 0;
157     dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, &val, NULL);
158     return val;
159 }
160 DEX_INLINE long dexGetZipEntryCrc32(const ZipArchive* pArchive,
161     const ZipEntry entry)
162 {
163     long val = 0;
164     dexZipGetEntryInfo(pArchive, entry, NULL, NULL, NULL, NULL, NULL, &val);
165     return val;
166 }
167
168 /*
169  * Uncompress and write an entry to a file descriptor.
170  *
171  * Returns 0 on success.
172  */
173 int dexZipExtractEntryToFile(const ZipArchive* pArchive,
174     const ZipEntry entry, int fd);
175
176 /*
177  * Utility function to compute a CRC-32.
178  */
179 u4 dexInitCrc32(void);
180 u4 dexComputeCrc32(u4 crc, const void* buf, size_t len);
181
182 #endif /*_LIBDEX_ZIPARCHIVE*/