1769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski/*
2769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Copyright (C) 2006 The Android Open Source Project
3769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski *
4769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * you may not use this file except in compliance with the License.
6769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * You may obtain a copy of the License at
7769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski *
8769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski *
10769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * See the License for the specific language governing permissions and
14769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * limitations under the License.
15769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski */
16769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
17769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski//
18769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski// General-purpose Zip archive access.  This class allows both reading and
19769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski// writing to Zip archives, including deletion of existing entries.
20769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski//
21769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#ifndef __LIBS_ZIPFILE_H
22769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#define __LIBS_ZIPFILE_H
23769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
24769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#include "BigBuffer.h"
25769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#include "ZipEntry.h"
26769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
27769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#include <stdio.h>
28769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#include <utils/Errors.h>
29769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#include <vector>
30769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
31769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinskinamespace aapt {
32769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
33769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinskiusing android::status_t;
34769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
35769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski/*
36769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Manipulate a Zip archive.
37769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski *
38769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Some changes will not be visible in the until until "flush" is called.
39769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski *
40769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * The correct way to update a file archive is to make all changes to a
41769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * copy of the archive in a temporary file, and then unlink/rename over
42769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * the original after everything completes.  Because we're only interested
43769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * in using this for packaging, we don't worry about such things.  Crashing
44769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * after making changes and before flush() completes could leave us with
45769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * an unusable Zip archive.
46769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski */
47769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinskiclass ZipFile {
48769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinskipublic:
49769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    ZipFile(void)
50769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski      : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)
51769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski      {}
52769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    ~ZipFile(void) {
53769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        if (!mReadOnly)
54769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            flush();
55769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        if (mZipFp != NULL)
56769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            fclose(mZipFp);
57769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        discardEntries();
58769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    }
59769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
60769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
61769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Open a new or existing archive.
62769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
63769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    enum {
64769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        kOpenReadOnly   = 0x01,
65769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        kOpenReadWrite  = 0x02,
66769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        kOpenCreate     = 0x04,     // create if it doesn't exist
67769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        kOpenTruncate   = 0x08,     // if it exists, empty it
68769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    };
69769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t open(const char* zipFileName, int flags);
70769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
71769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
72769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Add a file to the end of the archive.  Specify whether you want the
73769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * library to try to store it compressed.
74769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
75769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * If "storageName" is specified, the archive will use that instead
76769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * of "fileName".
77769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
78769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * If there is already an entry with the same name, the call fails.
79769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Existing entries with the same name must be removed first.
80769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
81769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
82769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
83769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t add(const char* fileName, int compressionMethod,
84769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        ZipEntry** ppEntry)
85769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    {
86769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        return add(fileName, fileName, compressionMethod, ppEntry);
87769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    }
88769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t add(const char* fileName, const char* storageName,
89769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        int compressionMethod, ZipEntry** ppEntry)
90769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    {
91769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        return addCommon(fileName, NULL, 0, storageName,
92769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski                         ZipEntry::kCompressStored,
93769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski                         compressionMethod, ppEntry);
94769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    }
95769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
96769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
97769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Add a file that is already compressed with gzip.
98769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
99769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
100769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
101769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t addGzip(const char* fileName, const char* storageName,
102769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        ZipEntry** ppEntry)
103769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    {
104769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        return addCommon(fileName, NULL, 0, storageName,
105769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski                         ZipEntry::kCompressDeflated,
106769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski                         ZipEntry::kCompressDeflated, ppEntry);
107769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    }
108769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
109769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
110769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Add a file from an in-memory data buffer.
111769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
112769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
113769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
114769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t add(const void* data, size_t size, const char* storageName,
115769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        int compressionMethod, ZipEntry** ppEntry)
116769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    {
117769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        return addCommon(NULL, data, size, storageName,
118769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski                         ZipEntry::kCompressStored,
119769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski                         compressionMethod, ppEntry);
120769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    }
121769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
122769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t add(const BigBuffer& data, const char* storageName,
123769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        int compressionMethod, ZipEntry** ppEntry);
124769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
125769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
126d5c4f8723c2b2c85b588fa07a5d4e7afb671d257Adam Lesinski     * Add an entry by copying it from another zip file.  If storageName is
127d5c4f8723c2b2c85b588fa07a5d4e7afb671d257Adam Lesinski     * non-NULL, the entry will be inserted with the name storageName, otherwise
128d5c4f8723c2b2c85b588fa07a5d4e7afb671d257Adam Lesinski     * it will have the same name as the source entry.  If "padding" is
129769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * nonzero, the specified number of bytes will be added to the "extra"
130769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * field in the header.
131769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
132769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
133769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
134769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
135d5c4f8723c2b2c85b588fa07a5d4e7afb671d257Adam Lesinski                 const char* storageName, int padding, ZipEntry** ppEntry);
136769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
137769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
138769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Mark an entry as having been removed.  It is not actually deleted
139769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * from the archive or our internal data structures until flush() is
140769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * called.
141769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
142769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t remove(ZipEntry* pEntry);
143769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
144769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
145769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Flush changes.  If mNeedCDRewrite is set, this writes the central dir.
146769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
147769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t flush(void);
148769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
149769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
150769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Expand the data into the buffer provided.  The buffer must hold
151769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * at least <uncompressed len> bytes.  Variation expands directly
152769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * to a file.
153769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
154769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Returns "false" if an error was encountered in the compressed data.
155769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
156769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    //bool uncompress(const ZipEntry* pEntry, void* buf) const;
157769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
158769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    void* uncompress(const ZipEntry* pEntry);
159769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
160769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
161769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Get an entry, by name.  Returns NULL if not found.
162769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
163769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Does not return entries pending deletion.
164769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
165769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    ZipEntry* getEntryByName(const char* fileName) const;
166769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
167769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
168769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Get the Nth entry in the archive.
169769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     *
170769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * This will return an entry that is pending deletion.
171769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
172769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    int getNumEntries(void) const { return mEntries.size(); }
173769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    ZipEntry* getEntryByIndex(int idx) const;
174769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
175769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinskiprivate:
176769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* these are private and not defined */
177769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    ZipFile(const ZipFile& src);
178769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    ZipFile& operator=(const ZipFile& src);
179769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
180769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    class EndOfCentralDir {
181769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    public:
182769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        EndOfCentralDir(void) :
183769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mDiskNumber(0),
184769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mDiskWithCentralDir(0),
185769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mNumEntries(0),
186769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mTotalNumEntries(0),
187769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mCentralDirSize(0),
188769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mCentralDirOffset(0),
189769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mCommentLen(0),
190769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            mComment(NULL)
191769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            {}
192769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        virtual ~EndOfCentralDir(void) {
193769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            delete[] mComment;
194769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        }
195769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
196769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        status_t readBuf(const unsigned char* buf, int len);
197769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        status_t write(FILE* fp);
198769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
199769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        //unsigned long   mSignature;
200769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned short  mDiskNumber;
201769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned short  mDiskWithCentralDir;
202769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned short  mNumEntries;
203769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned short  mTotalNumEntries;
204769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned long   mCentralDirSize;
205769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned long   mCentralDirOffset;      // offset from first disk
206769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned short  mCommentLen;
207769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned char*  mComment;
208769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
209769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        enum {
210769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            kSignature      = 0x06054b50,
211769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            kEOCDLen        = 22,       // EndOfCentralDir len, excl. comment
212769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
213769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            kMaxCommentLen  = 65535,    // longest possible in ushort
214769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            kMaxEOCDSearch  = kMaxCommentLen + EndOfCentralDir::kEOCDLen,
215769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
216769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        };
217769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
218769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        void dump(void) const;
219769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    };
220769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
221769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
222769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* read all entries in the central dir */
223769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t readCentralDir(void);
224769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
225769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* crunch deleted entries out */
226769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t crunchArchive(void);
227769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
228769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* clean up mEntries */
229769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    void discardEntries(void);
230769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
231769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* common handler for all "add" functions */
232769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t addCommon(const char* fileName, const void* data, size_t size,
233769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        const char* storageName, int sourceType, int compressionMethod,
234769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        ZipEntry** ppEntry);
235769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
236769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* copy all of "srcFp" into "dstFp" */
237769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);
238769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* copy all of "data" into "dstFp" */
239769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t copyDataToFp(FILE* dstFp,
240769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        const void* data, size_t size, unsigned long* pCRC32);
241769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* copy some of "srcFp" into "dstFp" */
242769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
243769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        unsigned long* pCRC32);
244769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* like memmove(), but on parts of a single file */
245769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);
246769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* compress all of "srcFp" into "dstFp", using Deflate */
247769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    status_t compressFpToFp(FILE* dstFp, FILE* srcFp,
248769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        const void* data, size_t size, unsigned long* pCRC32);
249769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
250769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* get modification date from a file descriptor */
251769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    time_t getModTime(int fd);
252769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
253769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
254769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * We use stdio FILE*, which gives us buffering but makes dealing
255769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * with files >2GB awkward.  Until we support Zip64, we're fine.
256769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
257769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    FILE*           mZipFp;             // Zip file pointer
258769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
259769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* one of these per file */
260769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    EndOfCentralDir mEOCD;
261769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
262769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* did we open this read-only? */
263769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    bool            mReadOnly;
264769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
265769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /* set this when we trash the central dir */
266769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    bool            mNeedCDRewrite;
267769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
268769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /*
269769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * One ZipEntry per entry in the zip file.  I'm using pointers instead
270769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * of objects because it's easier than making operator= work for the
271769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * classes and sub-classes.
272769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
273769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    std::vector<ZipEntry*>   mEntries;
274769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski};
275769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
276769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski}; // namespace aapt
277769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
278769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#endif // __LIBS_ZIPFILE_H
279