207 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright 2006 The Android Open Source Project
 | 
						|
 *
 | 
						|
 * Simple Zip archive support.
 | 
						|
 */
 | 
						|
#ifndef _MINZIP_ZIP
 | 
						|
#define _MINZIP_ZIP
 | 
						|
 | 
						|
#include "inline_magic.h"
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <utime.h>
 | 
						|
 | 
						|
#include "Hash.h"
 | 
						|
#include "SysUtil.h"
 | 
						|
 | 
						|
/*
 | 
						|
 * One entry in the Zip archive.  Treat this as opaque -- use accessors below.
 | 
						|
 *
 | 
						|
 * TODO: we're now keeping the pages mapped so we don't have to copy the
 | 
						|
 * filename.  We can change the accessors to retrieve the various pieces
 | 
						|
 * directly from the source file instead of copying them out, for a very
 | 
						|
 * slight speed hit and a modest reduction in memory usage.
 | 
						|
 */
 | 
						|
typedef struct ZipEntry {
 | 
						|
    unsigned int fileNameLen;
 | 
						|
    const char*  fileName;       // not null-terminated
 | 
						|
    long         offset;
 | 
						|
    long         compLen;
 | 
						|
    long         uncompLen;
 | 
						|
    int          compression;
 | 
						|
    long         modTime;
 | 
						|
    long         crc32;
 | 
						|
    int          versionMadeBy;
 | 
						|
    long         externalFileAttributes;
 | 
						|
} ZipEntry;
 | 
						|
 | 
						|
/*
 | 
						|
 * One Zip archive.  Treat as opaque.
 | 
						|
 */
 | 
						|
typedef struct ZipArchive {
 | 
						|
    int         fd;
 | 
						|
    unsigned int numEntries;
 | 
						|
    ZipEntry*   pEntries;
 | 
						|
    HashTable*  pHash;          // maps file name to ZipEntry
 | 
						|
    MemMapping  map;
 | 
						|
} ZipArchive;
 | 
						|
 | 
						|
/*
 | 
						|
 * Represents a non-NUL-terminated string,
 | 
						|
 * which is how entry names are stored.
 | 
						|
 */
 | 
						|
typedef struct {
 | 
						|
    const char *str;
 | 
						|
    size_t len;
 | 
						|
} UnterminatedString;
 | 
						|
 | 
						|
/*
 | 
						|
 * Open a Zip archive.
 | 
						|
 *
 | 
						|
 * On success, returns 0 and populates "pArchive".  Returns nonzero errno
 | 
						|
 * value on failure.
 | 
						|
 */
 | 
						|
int mzOpenZipArchive(const char* fileName, ZipArchive* pArchive);
 | 
						|
 | 
						|
/*
 | 
						|
 * Close archive, releasing resources associated with it.
 | 
						|
 *
 | 
						|
 * Depending on the implementation this could unmap pages used by classes
 | 
						|
 * stored in a Jar.  This should only be done after unloading classes.
 | 
						|
 */
 | 
						|
void mzCloseZipArchive(ZipArchive* pArchive);
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Find an entry in the Zip archive, by name.
 | 
						|
 */
 | 
						|
const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
 | 
						|
        const char* entryName);
 | 
						|
 | 
						|
/*
 | 
						|
 * Get the number of entries in the Zip archive.
 | 
						|
 */
 | 
						|
INLINE unsigned int mzZipEntryCount(const ZipArchive* pArchive) {
 | 
						|
    return pArchive->numEntries;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Get an entry by index.  Returns NULL if the index is out-of-bounds.
 | 
						|
 */
 | 
						|
INLINE const ZipEntry*
 | 
						|
mzGetZipEntryAt(const ZipArchive* pArchive, unsigned int index)
 | 
						|
{
 | 
						|
    if (index < pArchive->numEntries) {
 | 
						|
        return pArchive->pEntries + index;
 | 
						|
    }
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Get the index number of an entry in the archive.
 | 
						|
 */
 | 
						|
INLINE unsigned int
 | 
						|
mzGetZipEntryIndex(const ZipArchive *pArchive, const ZipEntry *pEntry) {
 | 
						|
    return pEntry - pArchive->pEntries;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Simple accessors.
 | 
						|
 */
 | 
						|
INLINE UnterminatedString mzGetZipEntryFileName(const ZipEntry* pEntry) {
 | 
						|
    UnterminatedString ret;
 | 
						|
    ret.str = pEntry->fileName;
 | 
						|
    ret.len = pEntry->fileNameLen;
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
 | 
						|
    return pEntry->offset;
 | 
						|
}
 | 
						|
INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
 | 
						|
    return pEntry->uncompLen;
 | 
						|
}
 | 
						|
INLINE long mzGetZipEntryModTime(const ZipEntry* pEntry) {
 | 
						|
    return pEntry->modTime;
 | 
						|
}
 | 
						|
INLINE long mzGetZipEntryCrc32(const ZipEntry* pEntry) {
 | 
						|
    return pEntry->crc32;
 | 
						|
}
 | 
						|
bool mzIsZipEntrySymlink(const ZipEntry* pEntry);
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Type definition for the callback function used by
 | 
						|
 * mzProcessZipEntryContents().
 | 
						|
 */
 | 
						|
typedef bool (*ProcessZipEntryContentsFunction)(const unsigned char *data,
 | 
						|
    int dataLen, void *cookie);
 | 
						|
 | 
						|
/*
 | 
						|
 * Stream the uncompressed data through the supplied function,
 | 
						|
 * passing cookie to it each time it gets called.  processFunction
 | 
						|
 * may be called more than once.
 | 
						|
 *
 | 
						|
 * If processFunction returns false, the operation is abandoned and
 | 
						|
 * mzProcessZipEntryContents() immediately returns false.
 | 
						|
 *
 | 
						|
 * This is useful for calculating the hash of an entry's uncompressed contents.
 | 
						|
 */
 | 
						|
bool mzProcessZipEntryContents(const ZipArchive *pArchive,
 | 
						|
    const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
 | 
						|
    void *cookie);
 | 
						|
 | 
						|
/*
 | 
						|
 * Read an entry into a buffer allocated by the caller.
 | 
						|
 */
 | 
						|
bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
 | 
						|
        char* buf, int bufLen);
 | 
						|
 | 
						|
/*
 | 
						|
 * Check the CRC on this entry; return true if it is correct.
 | 
						|
 * May do other internal checks as well.
 | 
						|
 */
 | 
						|
bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
 | 
						|
 | 
						|
/*
 | 
						|
 * Inflate and write an entry to a file.
 | 
						|
 */
 | 
						|
bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
 | 
						|
    const ZipEntry *pEntry, int fd);
 | 
						|
 | 
						|
/*
 | 
						|
 * Inflate all entries under zipDir to the directory specified by
 | 
						|
 * targetDir, which must exist and be a writable directory.
 | 
						|
 *
 | 
						|
 * The immediate children of zipDir will become the immediate
 | 
						|
 * children of targetDir; e.g., if the archive contains the entries
 | 
						|
 *
 | 
						|
 *     a/b/c/one
 | 
						|
 *     a/b/c/two
 | 
						|
 *     a/b/c/d/three
 | 
						|
 *
 | 
						|
 * and mzExtractRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting
 | 
						|
 * files will be
 | 
						|
 *
 | 
						|
 *     /tmp/one
 | 
						|
 *     /tmp/two
 | 
						|
 *     /tmp/d/three
 | 
						|
 *
 | 
						|
 * flags is zero or more of the following:
 | 
						|
 *
 | 
						|
 *     MZ_EXTRACT_FILES_ONLY - only unpack files, not directories or symlinks
 | 
						|
 *     MZ_EXTRACT_DRY_RUN - don't do anything, but do invoke the callback
 | 
						|
 *
 | 
						|
 * If timestamp is non-NULL, file timestamps will be set accordingly.
 | 
						|
 *
 | 
						|
 * If callback is non-NULL, it will be invoked with each unpacked file.
 | 
						|
 *
 | 
						|
 * Returns true on success, false on failure.
 | 
						|
 */
 | 
						|
enum { MZ_EXTRACT_FILES_ONLY = 1, MZ_EXTRACT_DRY_RUN = 2 };
 | 
						|
bool mzExtractRecursive(const ZipArchive *pArchive,
 | 
						|
        const char *zipDir, const char *targetDir,
 | 
						|
        int flags, const struct utimbuf *timestamp,
 | 
						|
        void (*callback)(const char *fn, void*), void *cookie);
 | 
						|
 | 
						|
#endif /*_MINZIP_ZIP*/
 |