| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2007 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 | * This is similar to the more-complete ZipFile class, but no attempt | 
|  | 21 | * has been made to make them interchangeable.  This class operates under | 
|  | 22 | * a very different set of assumptions and constraints. | 
|  | 23 | * | 
|  | 24 | * One such assumption is that if you're getting file descriptors for | 
|  | 25 | * use with this class as a child of a fork() operation, you must be on | 
|  | 26 | * a pread() to guarantee correct operation. This is because pread() can | 
|  | 27 | * atomically read at a file offset without worrying about a lock around an | 
|  | 28 | * lseek() + read() pair. | 
|  | 29 | */ | 
|  | 30 | #ifndef __LIBS_ZIPFILERO_H | 
|  | 31 | #define __LIBS_ZIPFILERO_H | 
|  | 32 |  | 
|  | 33 | #include <utils/Compat.h> | 
|  | 34 | #include <utils/Errors.h> | 
|  | 35 | #include <utils/FileMap.h> | 
|  | 36 | #include <utils/threads.h> | 
|  | 37 |  | 
|  | 38 | #include <stdio.h> | 
|  | 39 | #include <stdlib.h> | 
|  | 40 | #include <unistd.h> | 
|  | 41 | #include <time.h> | 
|  | 42 |  | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 43 | typedef void* ZipArchiveHandle; | 
|  | 44 |  | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 45 | namespace android { | 
|  | 46 |  | 
|  | 47 | /* | 
|  | 48 | * Trivial typedef to ensure that ZipEntryRO is not treated as a simple | 
|  | 49 | * integer.  We use NULL to indicate an invalid value. | 
|  | 50 | */ | 
|  | 51 | typedef void* ZipEntryRO; | 
|  | 52 |  | 
|  | 53 | /* | 
|  | 54 | * Open a Zip archive for reading. | 
|  | 55 | * | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 56 | * Implemented as a thin wrapper over system/core/libziparchive. | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 57 | * | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 58 | * "open" and "find entry by name" are fast operations and use as little | 
|  | 59 | * memory as possible. | 
|  | 60 | * | 
|  | 61 | * We also support fast iteration over all entries in the file (with a | 
|  | 62 | * stable, but unspecified iteration order). | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 63 | * | 
|  | 64 | * NOTE: If this is used on file descriptors inherited from a fork() operation, | 
|  | 65 | * you must be on a platform that implements pread() to guarantee correctness | 
|  | 66 | * on the shared file descriptors. | 
|  | 67 | */ | 
|  | 68 | class ZipFileRO { | 
|  | 69 | public: | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 70 | /* Zip compression methods we support */ | 
|  | 71 | enum { | 
|  | 72 | kCompressStored     = 0,        // no compression | 
|  | 73 | kCompressDeflated   = 8,        // standard deflate | 
|  | 74 | }; | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 75 |  | 
|  | 76 | /* | 
|  | 77 | * Open an archive. | 
|  | 78 | */ | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 79 | static ZipFileRO* open(const char* zipFileName); | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 80 |  | 
|  | 81 | /* | 
|  | 82 | * Find an entry, by name.  Returns the entry identifier, or NULL if | 
|  | 83 | * not found. | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 84 | */ | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 85 | ZipEntryRO findEntryByName(const char* entryName) const; | 
|  | 86 |  | 
|  | 87 |  | 
|  | 88 | /* | 
|  | 89 | * Start iterating over the list of entries in the zip file. Requires | 
|  | 90 | * a matching call to endIteration with the same cookie. | 
|  | 91 | */ | 
|  | 92 | bool startIteration(void** cookie); | 
|  | 93 |  | 
|  | 94 | /** | 
|  | 95 | * Return the next entry in iteration order, or NULL if there are no more | 
|  | 96 | * entries in this archive. | 
|  | 97 | */ | 
|  | 98 | ZipEntryRO nextEntry(void* cookie); | 
|  | 99 |  | 
|  | 100 | void endIteration(void* cookie); | 
|  | 101 |  | 
|  | 102 | void releaseEntry(ZipEntryRO entry) const; | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 103 |  | 
|  | 104 | /* | 
|  | 105 | * Return the #of entries in the Zip archive. | 
|  | 106 | */ | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 107 | int getNumEntries(); | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 108 |  | 
|  | 109 | /* | 
|  | 110 | * Copy the filename into the supplied buffer.  Returns 0 on success, | 
|  | 111 | * -1 if "entry" is invalid, or the filename length if it didn't fit.  The | 
|  | 112 | * length, and the returned string, include the null-termination. | 
|  | 113 | */ | 
|  | 114 | int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const; | 
|  | 115 |  | 
|  | 116 | /* | 
|  | 117 | * Get the vital stats for an entry.  Pass in NULL pointers for anything | 
|  | 118 | * you don't need. | 
|  | 119 | * | 
|  | 120 | * "*pOffset" holds the Zip file offset of the entry's data. | 
|  | 121 | * | 
|  | 122 | * Returns "false" if "entry" is bogus or if the data in the Zip file | 
|  | 123 | * appears to be bad. | 
|  | 124 | */ | 
|  | 125 | bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen, | 
|  | 126 | size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const; | 
|  | 127 |  | 
|  | 128 | /* | 
|  | 129 | * Create a new FileMap object that maps a subset of the archive.  For | 
|  | 130 | * an uncompressed entry this effectively provides a pointer to the | 
|  | 131 | * actual data, for a compressed entry this provides the input buffer | 
|  | 132 | * for inflate(). | 
|  | 133 | */ | 
|  | 134 | FileMap* createEntryFileMap(ZipEntryRO entry) const; | 
|  | 135 |  | 
|  | 136 | /* | 
|  | 137 | * Uncompress the data into a buffer.  Depending on the compression | 
|  | 138 | * format, this is either an "inflate" operation or a memcpy. | 
|  | 139 | * | 
|  | 140 | * Use "uncompLen" from getEntryInfo() to determine the required | 
|  | 141 | * buffer size. | 
|  | 142 | * | 
|  | 143 | * Returns "true" on success. | 
|  | 144 | */ | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 145 | bool uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const; | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 146 |  | 
|  | 147 | /* | 
|  | 148 | * Uncompress the data to an open file descriptor. | 
|  | 149 | */ | 
|  | 150 | bool uncompressEntry(ZipEntryRO entry, int fd) const; | 
|  | 151 |  | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 152 | ~ZipFileRO(); | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 153 |  | 
|  | 154 | private: | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 155 | /* these are private and not defined */ | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 156 | ZipFileRO(const ZipFileRO& src); | 
|  | 157 | ZipFileRO& operator=(const ZipFileRO& src); | 
|  | 158 |  | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 159 | ZipFileRO(ZipArchiveHandle handle, char* fileName) : mHandle(handle), | 
|  | 160 | mFileName(fileName) | 
|  | 161 | { | 
|  | 162 | } | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 163 |  | 
| Narayan Kamath | aae73e7 | 2013-12-03 13:16:03 +0000 | [diff] [blame^] | 164 | const ZipArchiveHandle mHandle; | 
|  | 165 | char* mFileName; | 
| Mike Lockwood | f99ad11 | 2013-10-03 10:29:39 -0700 | [diff] [blame] | 166 | }; | 
|  | 167 |  | 
|  | 168 | }; // namespace android | 
|  | 169 |  | 
|  | 170 | #endif /*__LIBS_ZIPFILERO_H*/ |