OSDN Git Service

Merge change 1055 into donut
[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  * 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  */
30 typedef void* ZipEntry;
31
32 /*
33  * One entry in the hash table.
34  */
35 typedef 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  */
57 typedef 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 */
76 enum {
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  */
88 int 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  */
97 int 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  */
105 void dexZipCloseArchive(ZipArchive* pArchive);
106
107 /*
108  * Return the archive's file descriptor.
109  */
110 DEX_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  */
118 ZipEntry 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  */
125 bool 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  */
132 DEX_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 }
139 DEX_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 }
146 DEX_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 }
153 DEX_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  */
164 bool dexZipExtractEntryToFile(const ZipArchive* pArchive,
165     const ZipEntry entry, int fd);
166
167 /*
168  * Utility function to compute a CRC-32.
169  */
170 u4 dexInitCrc32(void);
171 u4 dexComputeCrc32(u4 crc, const void* buf, size_t len);
172
173 #endif /*_LIBDEX_ZIPARCHIVE*/