2 * Copyright (C) 2006 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 // Zip archive entries.
20 // The ZipEntry class is tightly meshed with the ZipFile class.
22 #ifndef __LIBS_ZIPENTRY_H
23 #define __LIBS_ZIPENTRY_H
25 #include <utils/Errors.h>
35 * ZipEntry objects represent a single entry in a Zip archive.
37 * You can use one of these to get or set information about an entry, but
38 * there are no functions here for accessing the data itself. (We could
39 * tuck a pointer to the ZipFile in here for convenience, but that raises
40 * the likelihood of using ZipEntry objects after discarding the ZipFile.)
42 * File information is stored in two places: next to the file data (the Local
43 * File Header, and possibly a Data Descriptor), and at the end of the file
44 * (the Central Directory Entry). The two must be kept in sync.
51 : mDeleted(false), mMarked(false)
56 * Returns "true" if the data is compressed.
58 bool isCompressed(void) const {
59 return mCDE.mCompressionMethod != kCompressStored;
61 int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }
64 * Return the uncompressed length.
66 off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }
69 * Return the compressed length. For uncompressed data, this returns
70 * the same thing as getUncompresesdLen().
72 off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }
75 * Return the offset of the local file header.
77 off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
80 * Return the absolute file offset of the start of the compressed or
83 off_t getFileOffset(void) const {
84 return mCDE.mLocalHeaderRelOffset +
85 LocalFileHeader::kLFHLen +
86 mLFH.mFileNameLength +
87 mLFH.mExtraFieldLength;
91 * Return the data CRC.
93 unsigned long getCRC32(void) const { return mCDE.mCRC32; }
96 * Return file modification time in UNIX seconds-since-epoch.
98 time_t getModWhen(void) const;
101 * Return the archived file name.
103 const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
106 * Application-defined "mark". Can be useful when synchronizing the
107 * contents of an archive with contents on disk.
109 bool getMarked(void) const { return mMarked; }
110 void setMarked(bool val) { mMarked = val; }
113 * Some basic functions for raw data manipulation. "LE" means
116 static inline unsigned short getShortLE(const unsigned char* buf) {
117 return buf[0] | (buf[1] << 8);
119 static inline unsigned long getLongLE(const unsigned char* buf) {
120 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
122 static inline void putShortLE(unsigned char* buf, short val) {
123 buf[0] = (unsigned char) val;
124 buf[1] = (unsigned char) (val >> 8);
126 static inline void putLongLE(unsigned char* buf, long val) {
127 buf[0] = (unsigned char) val;
128 buf[1] = (unsigned char) (val >> 8);
129 buf[2] = (unsigned char) (val >> 16);
130 buf[3] = (unsigned char) (val >> 24);
133 /* defined for Zip archives */
135 kCompressStored = 0, // no compression
143 kCompressDeflated = 8, // standard deflate
145 // lib imploded = 10,
151 * Deletion flag. If set, the entry will be removed on the next
154 bool getDeleted(void) const { return mDeleted; }
158 * Initialize the structure from the file, which is pointing at
159 * our Central Directory entry.
161 status_t initFromCDE(FILE* fp);
164 * Initialize the structure for a new file. We need the filename
165 * and comment so that we can properly size the LFH area. The
166 * filename is mandatory, the comment is optional.
168 void initNew(const char* fileName, const char* comment);
171 * Initialize the structure with the contents of a ZipEntry from
174 status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);
177 * Add some pad bytes to the LFH. We do this by adding or resizing
180 status_t addPadding(int padding);
183 * Set information about the data for this entry.
185 void setDataInfo(long uncompLen, long compLen, unsigned long crc32,
186 int compressionMethod);
189 * Set the modification date.
191 void setModWhen(time_t when);
194 * Set the offset of the local file header, relative to the start of
197 void setLFHOffset(off_t offset) {
198 mCDE.mLocalHeaderRelOffset = (long) offset;
201 /* mark for deletion; used by ZipFile::remove() */
202 void setDeleted(void) { mDeleted = true; }
205 /* these are private and not defined */
206 ZipEntry(const ZipEntry& src);
207 ZipEntry& operator=(const ZipEntry& src);
209 /* returns "true" if the CDE and the LFH agree */
210 bool compareHeaders(void) const;
211 void copyCDEtoLFH(void);
213 bool mDeleted; // set if entry is pending deletion
214 bool mMarked; // app-defined marker
217 * Every entry in the Zip archive starts off with one of these.
219 class LocalFileHeader {
221 LocalFileHeader(void) :
222 mVersionToExtract(0),
224 mCompressionMethod(0),
229 mUncompressedSize(0),
231 mExtraFieldLength(0),
235 virtual ~LocalFileHeader(void) {
237 delete[] mExtraField;
240 status_t read(FILE* fp);
241 status_t write(FILE* fp);
243 // unsigned long mSignature;
244 unsigned short mVersionToExtract;
245 unsigned short mGPBitFlag;
246 unsigned short mCompressionMethod;
247 unsigned short mLastModFileTime;
248 unsigned short mLastModFileDate;
249 unsigned long mCRC32;
250 unsigned long mCompressedSize;
251 unsigned long mUncompressedSize;
252 unsigned short mFileNameLength;
253 unsigned short mExtraFieldLength;
254 unsigned char* mFileName;
255 unsigned char* mExtraField;
258 kSignature = 0x04034b50,
259 kLFHLen = 30, // LocalFileHdr len, excl. var fields
262 void dump(void) const;
266 * Every entry in the Zip archive has one of these in the "central
267 * directory" at the end of the file.
269 class CentralDirEntry {
271 CentralDirEntry(void) :
273 mVersionToExtract(0),
275 mCompressionMethod(0),
280 mUncompressedSize(0),
282 mExtraFieldLength(0),
283 mFileCommentLength(0),
287 mLocalHeaderRelOffset(0),
292 virtual ~CentralDirEntry(void) {
294 delete[] mExtraField;
295 delete[] mFileComment;
298 status_t read(FILE* fp);
299 status_t write(FILE* fp);
301 // unsigned long mSignature;
302 unsigned short mVersionMadeBy;
303 unsigned short mVersionToExtract;
304 unsigned short mGPBitFlag;
305 unsigned short mCompressionMethod;
306 unsigned short mLastModFileTime;
307 unsigned short mLastModFileDate;
308 unsigned long mCRC32;
309 unsigned long mCompressedSize;
310 unsigned long mUncompressedSize;
311 unsigned short mFileNameLength;
312 unsigned short mExtraFieldLength;
313 unsigned short mFileCommentLength;
314 unsigned short mDiskNumberStart;
315 unsigned short mInternalAttrs;
316 unsigned long mExternalAttrs;
317 unsigned long mLocalHeaderRelOffset;
318 unsigned char* mFileName;
319 unsigned char* mExtraField;
320 unsigned char* mFileComment;
322 void dump(void) const;
325 kSignature = 0x02014b50,
326 kCDELen = 46, // CentralDirEnt len, excl. var fields
331 //kDataDescriptorSignature = 0x08074b50, // currently unused
332 kDataDescriptorLen = 16, // four 32-bit fields
334 kDefaultVersion = 20, // need deflate, nothing much else
335 kDefaultMadeBy = 0x0317, // 03=UNIX, 17=spec v2.3
336 kUsesDataDescr = 0x0008, // GPBitFlag bit 3
339 LocalFileHeader mLFH;
340 CentralDirEntry mCDE;
343 }; // namespace android
345 #endif // __LIBS_ZIPENTRY_H