~xnox/ubuntu/trusty/gcc-arm-linux-androideabi/dima

« back to all changes in this revision

Viewing changes to android/build/tools/zipalign/ZipFile.h

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-07-05 10:12:24 UTC
  • Revision ID: package-import@ubuntu.com-20130705101224-6qo3e8jbz8p31aa1
Tags: upstream-0.20130705.1
ImportĀ upstreamĀ versionĀ 0.20130705.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006 The Android Open Source Project
 
3
 *
 
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
 
7
 *
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
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.
 
15
 */
 
16
 
 
17
//
 
18
// General-purpose Zip archive access.  This class allows both reading and
 
19
// writing to Zip archives, including deletion of existing entries.
 
20
//
 
21
#ifndef __LIBS_ZIPFILE_H
 
22
#define __LIBS_ZIPFILE_H
 
23
 
 
24
#include <utils/Vector.h>
 
25
#include <utils/Errors.h>
 
26
#include <stdio.h>
 
27
 
 
28
#include "ZipEntry.h"
 
29
 
 
30
namespace android {
 
31
 
 
32
/*
 
33
 * Manipulate a Zip archive.
 
34
 *
 
35
 * Some changes will not be visible in the until until "flush" is called.
 
36
 *
 
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.
 
43
 */
 
44
class ZipFile {
 
45
public:
 
46
    ZipFile(void)
 
47
      : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)
 
48
      {}
 
49
    ~ZipFile(void) {
 
50
        if (!mReadOnly)
 
51
            flush();
 
52
        if (mZipFp != NULL)
 
53
            fclose(mZipFp);
 
54
        discardEntries();
 
55
    }
 
56
 
 
57
    /*
 
58
     * Open a new or existing archive.
 
59
     */
 
60
    enum {
 
61
        kOpenReadOnly   = 0x01,
 
62
        kOpenReadWrite  = 0x02,
 
63
        kOpenCreate     = 0x04,     // create if it doesn't exist
 
64
        kOpenTruncate   = 0x08,     // if it exists, empty it
 
65
    };
 
66
    status_t open(const char* zipFileName, int flags);
 
67
 
 
68
    /*
 
69
     * Add a file to the end of the archive.  Specify whether you want the
 
70
     * library to try to store it compressed.
 
71
     *
 
72
     * If "storageName" is specified, the archive will use that instead
 
73
     * of "fileName".
 
74
     *
 
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.
 
77
     *
 
78
     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
 
79
     */
 
80
    status_t add(const char* fileName, int compressionMethod,
 
81
        ZipEntry** ppEntry)
 
82
    {
 
83
        return add(fileName, fileName, compressionMethod, ppEntry);
 
84
    }
 
85
    status_t add(const char* fileName, const char* storageName,
 
86
        int compressionMethod, ZipEntry** ppEntry)
 
87
    {
 
88
        return addCommon(fileName, NULL, 0, storageName,
 
89
                         ZipEntry::kCompressStored,
 
90
                         compressionMethod, ppEntry);
 
91
    }
 
92
 
 
93
    /*
 
94
     * Add a file that is already compressed with gzip.
 
95
     *
 
96
     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
 
97
     */
 
98
    status_t addGzip(const char* fileName, const char* storageName,
 
99
        ZipEntry** ppEntry)
 
100
    {
 
101
        return addCommon(fileName, NULL, 0, storageName,
 
102
                         ZipEntry::kCompressDeflated,
 
103
                         ZipEntry::kCompressDeflated, ppEntry);
 
104
    }
 
105
 
 
106
    /*
 
107
     * Add a file from an in-memory data buffer.
 
108
     *
 
109
     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
 
110
     */
 
111
    status_t add(const void* data, size_t size, const char* storageName,
 
112
        int compressionMethod, ZipEntry** ppEntry)
 
113
    {
 
114
        return addCommon(NULL, data, size, storageName,
 
115
                         ZipEntry::kCompressStored,
 
116
                         compressionMethod, ppEntry);
 
117
    }
 
118
 
 
119
    /*
 
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.
 
123
     *
 
124
     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
 
125
     */
 
126
    status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
 
127
        int padding, ZipEntry** ppEntry);
 
128
 
 
129
    /*
 
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
 
132
     * called.
 
133
     */
 
134
    status_t remove(ZipEntry* pEntry);
 
135
 
 
136
    /*
 
137
     * Flush changes.  If mNeedCDRewrite is set, this writes the central dir.
 
138
     */
 
139
    status_t flush(void);
 
140
 
 
141
    /*
 
142
     * Expand the data into the buffer provided.  The buffer must hold
 
143
     * at least <uncompressed len> bytes.  Variation expands directly
 
144
     * to a file.
 
145
     *
 
146
     * Returns "false" if an error was encountered in the compressed data.
 
147
     */
 
148
    //bool uncompress(const ZipEntry* pEntry, void* buf) const;
 
149
    //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
 
150
    void* uncompress(const ZipEntry* pEntry);
 
151
 
 
152
    /*
 
153
     * Get an entry, by name.  Returns NULL if not found.
 
154
     *
 
155
     * Does not return entries pending deletion.
 
156
     */
 
157
    ZipEntry* getEntryByName(const char* fileName) const;
 
158
 
 
159
    /*
 
160
     * Get the Nth entry in the archive.
 
161
     *
 
162
     * This will return an entry that is pending deletion.
 
163
     */
 
164
    int getNumEntries(void) const { return mEntries.size(); }
 
165
    ZipEntry* getEntryByIndex(int idx) const;
 
166
 
 
167
private:
 
168
    /* these are private and not defined */
 
169
    ZipFile(const ZipFile& src);
 
170
    ZipFile& operator=(const ZipFile& src);
 
171
 
 
172
    class EndOfCentralDir {
 
173
    public:
 
174
        EndOfCentralDir(void) :
 
175
            mDiskNumber(0),
 
176
            mDiskWithCentralDir(0),
 
177
            mNumEntries(0),
 
178
            mTotalNumEntries(0),
 
179
            mCentralDirSize(0),
 
180
            mCentralDirOffset(0),
 
181
            mCommentLen(0),
 
182
            mComment(NULL)
 
183
            {}
 
184
        virtual ~EndOfCentralDir(void) {
 
185
            delete[] mComment;
 
186
        }
 
187
 
 
188
        status_t readBuf(const unsigned char* buf, int len);
 
189
        status_t write(FILE* fp);
 
190
 
 
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;
 
200
 
 
201
        enum {
 
202
            kSignature      = 0x06054b50,
 
203
            kEOCDLen        = 22,       // EndOfCentralDir len, excl. comment
 
204
 
 
205
            kMaxCommentLen  = 65535,    // longest possible in ushort
 
206
            kMaxEOCDSearch  = kMaxCommentLen + EndOfCentralDir::kEOCDLen,
 
207
 
 
208
        };
 
209
 
 
210
        void dump(void) const;
 
211
    };
 
212
 
 
213
 
 
214
    /* read all entries in the central dir */
 
215
    status_t readCentralDir(void);
 
216
 
 
217
    /* crunch deleted entries out */
 
218
    status_t crunchArchive(void);
 
219
 
 
220
    /* clean up mEntries */
 
221
    void discardEntries(void);
 
222
 
 
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,
 
226
        ZipEntry** ppEntry);
 
227
 
 
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);
 
241
 
 
242
    /* get modification date from a file descriptor */
 
243
    time_t getModTime(int fd);
 
244
 
 
245
    /*
 
246
     * We use stdio FILE*, which gives us buffering but makes dealing
 
247
     * with files >2GB awkward.  Until we support Zip64, we're fine.
 
248
     */
 
249
    FILE*           mZipFp;             // Zip file pointer
 
250
 
 
251
    /* one of these per file */
 
252
    EndOfCentralDir mEOCD;
 
253
 
 
254
    /* did we open this read-only? */
 
255
    bool            mReadOnly;
 
256
 
 
257
    /* set this when we trash the central dir */
 
258
    bool            mNeedCDRewrite;
 
259
 
 
260
    /*
 
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.
 
264
     */
 
265
    Vector<ZipEntry*>   mEntries;
 
266
};
 
267
 
 
268
}; // namespace android
 
269
 
 
270
#endif // __LIBS_ZIPFILE_H