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>
36 * ZipEntry objects represent a single entry in a Zip archive.
38 * You can use one of these to get or set information about an entry, but
39 * there are no functions here for accessing the data itself. (We could
40 * tuck a pointer to the ZipFile in here for convenience, but that raises
41 * the likelihood of using ZipEntry objects after discarding the ZipFile.)
43 * File information is stored in two places: next to the file data (the Local
44 * File Header, and possibly a Data Descriptor), and at the end of the file
45 * (the Central Directory Entry). The two must be kept in sync.
52 : mDeleted(false), mMarked(false)
57 * Returns "true" if the data is compressed.
59 bool isCompressed(void) const {
60 return mCDE.mCompressionMethod != kCompressStored;
62 int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }
65 * Return the uncompressed length.
67 off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }
70 * Return the compressed length. For uncompressed data, this returns
71 * the same thing as getUncompresesdLen().
73 off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }
76 * Return the absolute file offset of the start of the compressed or
79 off_t getFileOffset(void) const {
80 return mCDE.mLocalHeaderRelOffset +
81 LocalFileHeader::kLFHLen +
82 mLFH.mFileNameLength +
83 mLFH.mExtraFieldLength;
87 * Return the data CRC.
89 uint32_t getCRC32(void) const { return mCDE.mCRC32; }
92 * Return file modification time in UNIX seconds-since-epoch.
94 time_t getModWhen(void) const;
97 * Return the archived file name.
99 const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
102 * Application-defined "mark". Can be useful when synchronizing the
103 * contents of an archive with contents on disk.
105 bool getMarked(void) const { return mMarked; }
106 void setMarked(bool val) { mMarked = val; }
109 * Some basic functions for raw data manipulation. "LE" means
112 static inline uint16_t getShortLE(const uint8_t* buf) {
113 return buf[0] | (buf[1] << 8);
115 static inline uint32_t getLongLE(const uint8_t* buf) {
116 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
118 static inline void putShortLE(uint8_t* buf, uint16_t val) {
119 buf[0] = (uint8_t) val;
120 buf[1] = (uint8_t) (val >> 8);
122 static inline void putLongLE(uint8_t* buf, uint32_t val) {
123 buf[0] = (uint8_t) val;
124 buf[1] = (uint8_t) (val >> 8);
125 buf[2] = (uint8_t) (val >> 16);
126 buf[3] = (uint8_t) (val >> 24);
129 /* defined for Zip archives */
131 kCompressStored = 0, // no compression
139 kCompressDeflated = 8, // standard deflate
141 // lib imploded = 10,
147 * Deletion flag. If set, the entry will be removed on the next
150 bool getDeleted(void) const { return mDeleted; }
154 * Initialize the structure from the file, which is pointing at
155 * our Central Directory entry.
157 status_t initFromCDE(FILE* fp);
160 * Initialize the structure for a new file. We need the filename
161 * and comment so that we can properly size the LFH area. The
162 * filename is mandatory, the comment is optional.
164 void initNew(const char* fileName, const char* comment);
167 * Initialize the structure with the contents of a ZipEntry from
170 status_t initFromExternal(const ZipEntry* pEntry);
173 * Add some pad bytes to the LFH. We do this by adding or resizing
176 status_t addPadding(int padding);
179 * Set information about the data for this entry.
181 void setDataInfo(long uncompLen, long compLen, uint32_t crc32,
182 int compressionMethod);
185 * Set the modification date.
187 void setModWhen(time_t when);
190 * Return the offset of the local file header.
192 off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
195 * Set the offset of the local file header, relative to the start of
198 void setLFHOffset(off_t offset) {
199 mCDE.mLocalHeaderRelOffset = (uint32_t) offset;
202 /* mark for deletion; used by ZipFile::remove() */
203 void setDeleted(void) { mDeleted = true; }
206 /* these are private and not defined */
207 ZipEntry(const ZipEntry& src);
208 ZipEntry& operator=(const ZipEntry& src);
210 /* returns "true" if the CDE and the LFH agree */
211 bool compareHeaders(void) const;
212 void copyCDEtoLFH(void);
214 bool mDeleted; // set if entry is pending deletion
215 bool mMarked; // app-defined marker
218 * Every entry in the Zip archive starts off with one of these.
220 class LocalFileHeader {
222 LocalFileHeader(void) :
223 mVersionToExtract(0),
225 mCompressionMethod(0),
230 mUncompressedSize(0),
232 mExtraFieldLength(0),
236 virtual ~LocalFileHeader(void) {
238 delete[] mExtraField;
241 status_t read(FILE* fp);
242 status_t write(FILE* fp);
244 // uint32_t mSignature;
245 uint16_t mVersionToExtract;
247 uint16_t mCompressionMethod;
248 uint16_t mLastModFileTime;
249 uint16_t mLastModFileDate;
251 uint32_t mCompressedSize;
252 uint32_t mUncompressedSize;
253 uint16_t mFileNameLength;
254 uint16_t mExtraFieldLength;
256 uint8_t* mExtraField;
259 kSignature = 0x04034b50,
260 kLFHLen = 30, // LocalFileHdr len, excl. var fields
263 void dump(void) const;
267 * Every entry in the Zip archive has one of these in the "central
268 * directory" at the end of the file.
270 class CentralDirEntry {
272 CentralDirEntry(void) :
274 mVersionToExtract(0),
276 mCompressionMethod(0),
281 mUncompressedSize(0),
283 mExtraFieldLength(0),
284 mFileCommentLength(0),
288 mLocalHeaderRelOffset(0),
293 virtual ~CentralDirEntry(void) {
295 delete[] mExtraField;
296 delete[] mFileComment;
299 status_t read(FILE* fp);
300 status_t write(FILE* fp);
302 // uint32_t mSignature;
303 uint16_t mVersionMadeBy;
304 uint16_t mVersionToExtract;
306 uint16_t mCompressionMethod;
307 uint16_t mLastModFileTime;
308 uint16_t mLastModFileDate;
310 uint32_t mCompressedSize;
311 uint32_t mUncompressedSize;
312 uint16_t mFileNameLength;
313 uint16_t mExtraFieldLength;
314 uint16_t mFileCommentLength;
315 uint16_t mDiskNumberStart;
316 uint16_t mInternalAttrs;
317 uint32_t mExternalAttrs;
318 uint32_t mLocalHeaderRelOffset;
320 uint8_t* mExtraField;
321 uint8_t* mFileComment;
323 void dump(void) const;
326 kSignature = 0x02014b50,
327 kCDELen = 46, // CentralDirEnt len, excl. var fields
332 //kDataDescriptorSignature = 0x08074b50, // currently unused
333 kDataDescriptorLen = 16, // four 32-bit fields
335 kDefaultVersion = 20, // need deflate, nothing much else
336 kDefaultMadeBy = 0x0317, // 03=UNIX, 17=spec v2.3
337 kUsesDataDescr = 0x0008, // GPBitFlag bit 3
340 LocalFileHeader mLFH;
341 CentralDirEntry mCDE;
344 }; // namespace android
346 #endif // __LIBS_ZIPENTRY_H