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
384600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath#include <stdint.h>
3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdio.h>
4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdlib.h>
4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <unistd.h>
4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <time.h>
4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
44560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamathtypedef void* ZipArchiveHandle;
45560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
4616c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android {
4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * integer.  We use NULL to indicate an invalid value.
5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
5216c4d154dca43c662571129af31b27433b919a32Adam Lesinskitypedef void* ZipEntryRO;
5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open a Zip archive for reading.
5616c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
57560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * Implemented as a thin wrapper over system/core/libziparchive.
58560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath *
59560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * "open" and "find entry by name" are fast operations and use as little
60560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * memory as possible.
6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
62560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * We also support fast iteration over all entries in the file (with a
63560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath * stable, but unspecified iteration order).
6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * NOTE: If this is used on file descriptors inherited from a fork() operation,
6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you must be on a platform that implements pread() to guarantee correctness
6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * on the shared file descriptors.
6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
6916c4d154dca43c662571129af31b27433b919a32Adam Lesinskiclass ZipFileRO {
7016c4d154dca43c662571129af31b27433b919a32Adam Lesinskipublic:
71560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    /* Zip compression methods we support */
724600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath    enum : uint16_t {
734600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath        kCompressStored = 0,
744600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath        kCompressDeflated = 8
75560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    };
7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Open an archive.
7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
80560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    static ZipFileRO* open(const char* zipFileName);
8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Find an entry, by name.  Returns the entry identifier, or NULL if
8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * not found.
8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
86560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ZipEntryRO findEntryByName(const char* entryName) const;
87560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
90560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * Start iterating over the list of entries in the zip file. Requires
91560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * a matching call to endIteration with the same cookie.
9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
93560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    bool startIteration(void** cookie);
9434fe3df8519523dbb4bc27010fa57f259d5e868dYusuke Sato    bool startIteration(void** cookie, const char* prefix, const char* suffix);
95560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
96560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    /**
97560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * Return the next entry in iteration order, or NULL if there are no more
98560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * entries in this archive.
99560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     */
100560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ZipEntryRO nextEntry(void* cookie);
101560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
102560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    void endIteration(void* cookie);
103560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath
104560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    void releaseEntry(ZipEntryRO entry) const;
10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
107560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath     * Return the #of entries in the Zip archive.
10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
109560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    int getNumEntries();
11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Copy the filename into the supplied buffer.  Returns 0 on success,
1134600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath     * -1 if "entry" is invalid, or the filename length if it didn't fit. The
11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * length, and the returned string, include the null-termination.
11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
1164600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath    int getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen) const;
11716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Get the vital stats for an entry.  Pass in NULL pointers for anything
12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * you don't need.
12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * "*pOffset" holds the Zip file offset of the entry's data.
12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Returns "false" if "entry" is bogus or if the data in the Zip file
12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * appears to be bad.
12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
1274600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath    bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen,
1284600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath        uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen,
1294600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath        uint32_t* pCrc32) const;
13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
13216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Create a new FileMap object that maps a subset of the archive.  For
13316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * an uncompressed entry this effectively provides a pointer to the
13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * actual data, for a compressed entry this provides the input buffer
13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * for inflate().
13616c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    FileMap* createEntryFileMap(ZipEntryRO entry) const;
13816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Uncompress the data into a buffer.  Depending on the compression
14116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * format, this is either an "inflate" operation or a memcpy.
14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Use "uncompLen" from getEntryInfo() to determine the required
14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * buffer size.
14516c4d154dca43c662571129af31b27433b919a32Adam Lesinski     *
14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Returns "true" on success.
14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
148560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    bool uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const;
14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /*
15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Uncompress the data to an open file descriptor.
15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool uncompressEntry(ZipEntryRO entry, int fd) const;
15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
155560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ~ZipFileRO();
15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15716c4d154dca43c662571129af31b27433b919a32Adam Lesinskiprivate:
158560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    /* these are private and not defined */
15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ZipFileRO(const ZipFileRO& src);
16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ZipFileRO& operator=(const ZipFileRO& src);
16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
162560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    ZipFileRO(ZipArchiveHandle handle, char* fileName) : mHandle(handle),
163560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath        mFileName(fileName)
164560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    {
165560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    }
16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
167560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    const ZipArchiveHandle mHandle;
168560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath    char* mFileName;
16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski};
17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17116c4d154dca43c662571129af31b27433b919a32Adam Lesinski}; // namespace android
17216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif /*__LIBS_ZIPFILERO_H*/
174