116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2007 The Android Open Source Project
316c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you may not use this file except in compliance with the License.
616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * You may obtain a copy of the License at
716c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
816c4d154dca43c662571129af31b27433b919a32Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
916c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
1016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Unless required by applicable law or agreed to in writing, software
1116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
1216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * See the License for the specific language governing permissions and
1416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * limitations under the License.
1516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
1616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
1716c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Read-only access to Zip archives, with minimal heap allocation.
1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This is similar to the more-complete ZipFile class, but no attempt
2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * has been made to make them interchangeable.  This class operates under
2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * a very different set of assumptions and constraints.
2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * One such assumption is that if you're getting file descriptors for
2516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * use with this class as a child of a fork() operation, you must be on
2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * a pread() to guarantee correct operation. This is because pread() can
2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * atomically read at a file offset without worrying about a lock around an
2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * lseek() + read() pair.
2916c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifndef __LIBS_ZIPFILERO_H
3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define __LIBS_ZIPFILERO_H
3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Compat.h>
3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Errors.h>
3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/FileMap.h>
3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/threads.h>
3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdio.h>
3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdlib.h>
4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <unistd.h>
4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <time.h>
4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
43560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamathtypedef void* ZipArchiveHandle;
44560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
4516c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android {
4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * integer.  We use NULL to indicate an invalid value.
5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
5116c4d154dca43c662571129af31b27433b919a32Adam Lesinskitypedef void* ZipEntryRO;
5216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open a Zip archive for reading.
5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
56560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * Implemented as a thin wrapper over system/core/libziparchive.
57560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath *
58560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * "open" and "find entry by name" are fast operations and use as little
59560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * memory as possible.
6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
61560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * We also support fast iteration over all entries in the file (with a
62560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * stable, but unspecified iteration order).
6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * NOTE: If this is used on file descriptors inherited from a fork() operation,
6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you must be on a platform that implements pread() to guarantee correctness
6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * on the shared file descriptors.
6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
6816c4d154dca43c662571129af31b27433b919a32Adam Lesinskiclass ZipFileRO {
6916c4d154dca43c662571129af31b27433b919a32Adam Lesinskipublic:
70560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    /* Zip compression methods we support */
71560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    enum {
72560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath        kCompressStored     = 0,        // no compression
73560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath        kCompressDeflated   = 8,        // standard deflate
74560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    };
7516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Open an archive.
7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
79560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    static ZipFileRO* open(const char* zipFileName);
8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Find an entry, by name.  Returns the entry identifier, or NULL if
8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * not found.
8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
85560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ZipEntryRO findEntryByName(const char* entryName) const;
86560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
8716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
89560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * Start iterating over the list of entries in the zip file. Requires
90560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * a matching call to endIteration with the same cookie.
9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
92560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    bool startIteration(void** cookie);
93560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
94560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    /**
95560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * Return the next entry in iteration order, or NULL if there are no more
96560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * entries in this archive.
97560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     */
98560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ZipEntryRO nextEntry(void* cookie);
99560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
100560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    void endIteration(void* cookie);
101560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
102560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    void releaseEntry(ZipEntryRO entry) const;
10316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
105560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * Return the #of entries in the Zip archive.
10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
107560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    int getNumEntries();
10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Copy the filename into the supplied buffer.  Returns 0 on success,
11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * -1 if "entry" is invalid, or the filename length if it didn't fit.  The
11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * length, and the returned string, include the null-termination.
11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
11716c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Get the vital stats for an entry.  Pass in NULL pointers for anything
11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * you don't need.
11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * "*pOffset" holds the Zip file offset of the entry's data.
12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Returns "false" if "entry" is bogus or if the data in the Zip file
12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * appears to be bad.
12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Create a new FileMap object that maps a subset of the archive.  For
13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * an uncompressed entry this effectively provides a pointer to the
13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * actual data, for a compressed entry this provides the input buffer
13216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * for inflate().
13316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    FileMap* createEntryFileMap(ZipEntryRO entry) const;
13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Uncompress the data into a buffer.  Depending on the compression
13816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * format, this is either an "inflate" operation or a memcpy.
13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Use "uncompLen" from getEntryInfo() to determine the required
14116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * buffer size.
14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Returns "true" on success.
14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
145560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    bool uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const;
14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
14816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Uncompress the data to an open file descriptor.
14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool uncompressEntry(ZipEntryRO entry, int fd) const;
15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
152560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ~ZipFileRO();
15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15416c4d154dca43c662571129af31b27433b919a32Adam Lesinskiprivate:
155560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    /* these are private and not defined */
15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ZipFileRO(const ZipFileRO& src);
15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ZipFileRO& operator=(const ZipFileRO& src);
15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
159560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ZipFileRO(ZipArchiveHandle handle, char* fileName) : mHandle(handle),
160560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath        mFileName(fileName)
161560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    {
162560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    }
16316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
164560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    const ZipArchiveHandle mHandle;
165560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    char* mFileName;
16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski};
16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
16816c4d154dca43c662571129af31b27433b919a32Adam Lesinski}; // namespace android
16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif /*__LIBS_ZIPFILERO_H*/
171