]>
git.saurik.com Git - android/aapt.git/blob - ZipFile.h
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 // General-purpose Zip archive access. This class allows both reading and
19 // writing to Zip archives, including deletion of existing entries.
21 #ifndef __LIBS_ZIPFILE_H
22 #define __LIBS_ZIPFILE_H
24 #include <utils/Vector.h>
25 #include <utils/Errors.h>
33 * Manipulate a Zip archive.
35 * Some changes will not be visible in the until until "flush" is called.
37 * The correct way to update a file archive is to make all changes to a
38 * copy of the archive in a temporary file, and then unlink/rename over
39 * the original after everything completes. Because we're only interested
40 * in using this for packaging, we don't worry about such things. Crashing
41 * after making changes and before flush() completes could leave us with
42 * an unusable Zip archive.
47 : mZipFp(NULL
), mReadOnly(false), mNeedCDRewrite(false)
58 * Open a new or existing archive.
62 kOpenReadWrite
= 0x02,
63 kOpenCreate
= 0x04, // create if it doesn't exist
64 kOpenTruncate
= 0x08, // if it exists, empty it
66 status_t
open(const char* zipFileName
, int flags
);
69 * Add a file to the end of the archive. Specify whether you want the
70 * library to try to store it compressed.
72 * If "storageName" is specified, the archive will use that instead
75 * If there is already an entry with the same name, the call fails.
76 * Existing entries with the same name must be removed first.
78 * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
80 status_t
add(const char* fileName
, int compressionMethod
,
83 return add(fileName
, fileName
, compressionMethod
, ppEntry
);
85 status_t
add(const char* fileName
, const char* storageName
,
86 int compressionMethod
, ZipEntry
** ppEntry
)
88 return addCommon(fileName
, NULL
, 0, storageName
,
89 ZipEntry::kCompressStored
,
90 compressionMethod
, ppEntry
);
94 * Add a file that is already compressed with gzip.
96 * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
98 status_t
addGzip(const char* fileName
, const char* storageName
,
101 return addCommon(fileName
, NULL
, 0, storageName
,
102 ZipEntry::kCompressDeflated
,
103 ZipEntry::kCompressDeflated
, ppEntry
);
107 * Add a file from an in-memory data buffer.
109 * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
111 status_t
add(const void* data
, size_t size
, const char* storageName
,
112 int compressionMethod
, ZipEntry
** ppEntry
)
114 return addCommon(NULL
, data
, size
, storageName
,
115 ZipEntry::kCompressStored
,
116 compressionMethod
, ppEntry
);
120 * Add an entry by copying it from another zip file. If "padding" is
121 * nonzero, the specified number of bytes will be added to the "extra"
122 * field in the header.
124 * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
126 status_t
add(const ZipFile
* pSourceZip
, const ZipEntry
* pSourceEntry
,
127 int padding
, ZipEntry
** ppEntry
);
130 * Mark an entry as having been removed. It is not actually deleted
131 * from the archive or our internal data structures until flush() is
134 status_t
remove(ZipEntry
* pEntry
);
137 * Flush changes. If mNeedCDRewrite is set, this writes the central dir.
139 status_t
flush(void);
142 * Expand the data into the buffer provided. The buffer must hold
143 * at least <uncompressed len> bytes. Variation expands directly
146 * Returns "false" if an error was encountered in the compressed data.
148 //bool uncompress(const ZipEntry* pEntry, void* buf) const;
149 //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
150 void* uncompress(const ZipEntry
* pEntry
);
153 * Get an entry, by name. Returns NULL if not found.
155 * Does not return entries pending deletion.
157 ZipEntry
* getEntryByName(const char* fileName
) const;
160 * Get the Nth entry in the archive.
162 * This will return an entry that is pending deletion.
164 int getNumEntries(void) const { return mEntries
.size(); }
165 ZipEntry
* getEntryByIndex(int idx
) const;
168 /* these are private and not defined */
169 ZipFile(const ZipFile
& src
);
170 ZipFile
& operator=(const ZipFile
& src
);
172 class EndOfCentralDir
{
174 EndOfCentralDir(void) :
176 mDiskWithCentralDir(0),
180 mCentralDirOffset(0),
184 virtual ~EndOfCentralDir(void) {
188 status_t
readBuf(const unsigned char* buf
, int len
);
189 status_t
write(FILE* fp
);
191 //unsigned long mSignature;
192 unsigned short mDiskNumber
;
193 unsigned short mDiskWithCentralDir
;
194 unsigned short mNumEntries
;
195 unsigned short mTotalNumEntries
;
196 unsigned long mCentralDirSize
;
197 unsigned long mCentralDirOffset
; // offset from first disk
198 unsigned short mCommentLen
;
199 unsigned char* mComment
;
202 kSignature
= 0x06054b50,
203 kEOCDLen
= 22, // EndOfCentralDir len, excl. comment
205 kMaxCommentLen
= 65535, // longest possible in ushort
206 kMaxEOCDSearch
= kMaxCommentLen
+ EndOfCentralDir::kEOCDLen
,
210 void dump(void) const;
214 /* read all entries in the central dir */
215 status_t
readCentralDir(void);
217 /* crunch deleted entries out */
218 status_t
crunchArchive(void);
220 /* clean up mEntries */
221 void discardEntries(void);
223 /* common handler for all "add" functions */
224 status_t
addCommon(const char* fileName
, const void* data
, size_t size
,
225 const char* storageName
, int sourceType
, int compressionMethod
,
228 /* copy all of "srcFp" into "dstFp" */
229 status_t
copyFpToFp(FILE* dstFp
, FILE* srcFp
, unsigned long* pCRC32
);
230 /* copy all of "data" into "dstFp" */
231 status_t
copyDataToFp(FILE* dstFp
,
232 const void* data
, size_t size
, unsigned long* pCRC32
);
233 /* copy some of "srcFp" into "dstFp" */
234 status_t
copyPartialFpToFp(FILE* dstFp
, FILE* srcFp
, long length
,
235 unsigned long* pCRC32
);
236 /* like memmove(), but on parts of a single file */
237 status_t
filemove(FILE* fp
, off_t dest
, off_t src
, size_t n
);
238 /* compress all of "srcFp" into "dstFp", using Deflate */
239 status_t
compressFpToFp(FILE* dstFp
, FILE* srcFp
,
240 const void* data
, size_t size
, unsigned long* pCRC32
);
242 /* get modification date from a file descriptor */
243 time_t getModTime(int fd
);
246 * We use stdio FILE*, which gives us buffering but makes dealing
247 * with files >2GB awkward. Until we support Zip64, we're fine.
249 FILE* mZipFp
; // Zip file pointer
251 /* one of these per file */
252 EndOfCentralDir mEOCD
;
254 /* did we open this read-only? */
257 /* set this when we trash the central dir */
261 * One ZipEntry per entry in the zip file. I'm using pointers instead
262 * of objects because it's easier than making operator= work for the
263 * classes and sub-classes.
265 Vector
<ZipEntry
*> mEntries
;
268 }; // namespace android
270 #endif // __LIBS_ZIPFILE_H