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 absolute file offset of the start of the compressed or
78 off_t getFileOffset(void) const {
79 return mCDE.mLocalHeaderRelOffset +
80 LocalFileHeader::kLFHLen +
81 mLFH.mFileNameLength +
82 mLFH.mExtraFieldLength;
86 * Return the data CRC.
88 unsigned long getCRC32(void) const { return mCDE.mCRC32; }
91 * Return file modification time in UNIX seconds-since-epoch.
93 time_t getModWhen(void) const;
96 * Return the archived file name.
98 const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
101 * Application-defined "mark". Can be useful when synchronizing the
102 * contents of an archive with contents on disk.
104 bool getMarked(void) const { return mMarked; }
105 void setMarked(bool val) { mMarked = val; }
108 * Some basic functions for raw data manipulation. "LE" means
111 static inline unsigned short getShortLE(const unsigned char* buf) {
112 return buf[0] | (buf[1] << 8);
114 static inline unsigned long getLongLE(const unsigned char* buf) {
115 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
117 static inline void putShortLE(unsigned char* buf, short val) {
118 buf[0] = (unsigned char) val;
119 buf[1] = (unsigned char) (val >> 8);
121 static inline void putLongLE(unsigned char* buf, long val) {
122 buf[0] = (unsigned char) val;
123 buf[1] = (unsigned char) (val >> 8);
124 buf[2] = (unsigned char) (val >> 16);
125 buf[3] = (unsigned char) (val >> 24);
128 /* defined for Zip archives */
130 kCompressStored = 0, // no compression
138 kCompressDeflated = 8, // standard deflate
140 // lib imploded = 10,
146 * Deletion flag. If set, the entry will be removed on the next
149 bool getDeleted(void) const { return mDeleted; }
153 * Initialize the structure from the file, which is pointing at
154 * our Central Directory entry.
156 status_t initFromCDE(FILE* fp);
159 * Initialize the structure for a new file. We need the filename
160 * and comment so that we can properly size the LFH area. The
161 * filename is mandatory, the comment is optional.
163 void initNew(const char* fileName, const char* comment);
166 * Initialize the structure with the contents of a ZipEntry from
169 status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);
172 * Add some pad bytes to the LFH. We do this by adding or resizing
175 status_t addPadding(int padding);
178 * Set information about the data for this entry.
180 void setDataInfo(long uncompLen, long compLen, unsigned long crc32,
181 int compressionMethod);
184 * Set the modification date.
186 void setModWhen(time_t when);
189 * Return the offset of the local file header.
191 off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
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