aboutsummaryrefslogtreecommitdiffstats
path: root/minzip
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
commitffb48f64fec674c6dd923eb8b1eb3f743e05a8ba (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /minzip
parentd4ae69739ebb67374d62229829df07bf2de85103 (diff)
downloadbootable_recovery-ffb48f64fec674c6dd923eb8b1eb3f743e05a8ba.zip
bootable_recovery-ffb48f64fec674c6dd923eb8b1eb3f743e05a8ba.tar.gz
bootable_recovery-ffb48f64fec674c6dd923eb8b1eb3f743e05a8ba.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'minzip')
-rw-r--r--minzip/Android.mk19
-rw-r--r--minzip/Bits.h357
-rw-r--r--minzip/DirUtil.c280
-rw-r--r--minzip/DirUtil.h51
-rw-r--r--minzip/Hash.c390
-rw-r--r--minzip/Hash.h186
-rw-r--r--minzip/Inlines.c25
-rw-r--r--minzip/Log.h207
-rw-r--r--minzip/SysUtil.c212
-rw-r--r--minzip/SysUtil.h61
-rw-r--r--minzip/Zip.c1098
-rw-r--r--minzip/Zip.h206
-rw-r--r--minzip/inline_magic.h26
13 files changed, 0 insertions, 3118 deletions
diff --git a/minzip/Android.mk b/minzip/Android.mk
deleted file mode 100644
index b1ee674..0000000
--- a/minzip/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- Hash.c \
- SysUtil.c \
- DirUtil.c \
- Inlines.c \
- Zip.c
-
-LOCAL_C_INCLUDES += \
- external/zlib \
- external/safe-iop/include
-
-LOCAL_MODULE := libminzip
-
-LOCAL_CFLAGS += -Wall
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/minzip/Bits.h b/minzip/Bits.h
deleted file mode 100644
index f96e6c4..0000000
--- a/minzip/Bits.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Some handy functions for manipulating bits and bytes.
- */
-#ifndef _MINZIP_BITS
-#define _MINZIP_BITS
-
-#include "inline_magic.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * Get 1 byte. (Included to make the code more legible.)
- */
-INLINE unsigned char get1(unsigned const char* pSrc)
-{
- return *pSrc;
-}
-
-/*
- * Get 2 big-endian bytes.
- */
-INLINE unsigned short get2BE(unsigned char const* pSrc)
-{
- unsigned short result;
-
- result = *pSrc++ << 8;
- result |= *pSrc++;
-
- return result;
-}
-
-/*
- * Get 4 big-endian bytes.
- */
-INLINE unsigned int get4BE(unsigned char const* pSrc)
-{
- unsigned int result;
-
- result = *pSrc++ << 24;
- result |= *pSrc++ << 16;
- result |= *pSrc++ << 8;
- result |= *pSrc++;
-
- return result;
-}
-
-/*
- * Get 8 big-endian bytes.
- */
-INLINE unsigned long long get8BE(unsigned char const* pSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *pSrc++ << 56;
- result |= (unsigned long long) *pSrc++ << 48;
- result |= (unsigned long long) *pSrc++ << 40;
- result |= (unsigned long long) *pSrc++ << 32;
- result |= (unsigned long long) *pSrc++ << 24;
- result |= (unsigned long long) *pSrc++ << 16;
- result |= (unsigned long long) *pSrc++ << 8;
- result |= (unsigned long long) *pSrc++;
-
- return result;
-}
-
-/*
- * Get 2 little-endian bytes.
- */
-INLINE unsigned short get2LE(unsigned char const* pSrc)
-{
- unsigned short result;
-
- result = *pSrc++;
- result |= *pSrc++ << 8;
-
- return result;
-}
-
-/*
- * Get 4 little-endian bytes.
- */
-INLINE unsigned int get4LE(unsigned char const* pSrc)
-{
- unsigned int result;
-
- result = *pSrc++;
- result |= *pSrc++ << 8;
- result |= *pSrc++ << 16;
- result |= *pSrc++ << 24;
-
- return result;
-}
-
-/*
- * Get 8 little-endian bytes.
- */
-INLINE unsigned long long get8LE(unsigned char const* pSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *pSrc++;
- result |= (unsigned long long) *pSrc++ << 8;
- result |= (unsigned long long) *pSrc++ << 16;
- result |= (unsigned long long) *pSrc++ << 24;
- result |= (unsigned long long) *pSrc++ << 32;
- result |= (unsigned long long) *pSrc++ << 40;
- result |= (unsigned long long) *pSrc++ << 48;
- result |= (unsigned long long) *pSrc++ << 56;
-
- return result;
-}
-
-/*
- * Grab 1 byte and advance the data pointer.
- */
-INLINE unsigned char read1(unsigned const char** ppSrc)
-{
- return *(*ppSrc)++;
-}
-
-/*
- * Grab 2 big-endian bytes and advance the data pointer.
- */
-INLINE unsigned short read2BE(unsigned char const** ppSrc)
-{
- unsigned short result;
-
- result = *(*ppSrc)++ << 8;
- result |= *(*ppSrc)++;
-
- return result;
-}
-
-/*
- * Grab 4 big-endian bytes and advance the data pointer.
- */
-INLINE unsigned int read4BE(unsigned char const** ppSrc)
-{
- unsigned int result;
-
- result = *(*ppSrc)++ << 24;
- result |= *(*ppSrc)++ << 16;
- result |= *(*ppSrc)++ << 8;
- result |= *(*ppSrc)++;
-
- return result;
-}
-
-/*
- * Get 8 big-endian bytes.
- */
-INLINE unsigned long long read8BE(unsigned char const** ppSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *(*ppSrc)++ << 56;
- result |= (unsigned long long) *(*ppSrc)++ << 48;
- result |= (unsigned long long) *(*ppSrc)++ << 40;
- result |= (unsigned long long) *(*ppSrc)++ << 32;
- result |= (unsigned long long) *(*ppSrc)++ << 24;
- result |= (unsigned long long) *(*ppSrc)++ << 16;
- result |= (unsigned long long) *(*ppSrc)++ << 8;
- result |= (unsigned long long) *(*ppSrc)++;
-
- return result;
-}
-
-/*
- * Grab 2 little-endian bytes and advance the data pointer.
- */
-INLINE unsigned short read2LE(unsigned char const** ppSrc)
-{
- unsigned short result;
-
- result = *(*ppSrc)++;
- result |= *(*ppSrc)++ << 8;
-
- return result;
-}
-
-/*
- * Grab 4 little-endian bytes and advance the data pointer.
- */
-INLINE unsigned int read4LE(unsigned char const** ppSrc)
-{
- unsigned int result;
-
- result = *(*ppSrc)++;
- result |= *(*ppSrc)++ << 8;
- result |= *(*ppSrc)++ << 16;
- result |= *(*ppSrc)++ << 24;
-
- return result;
-}
-
-/*
- * Get 8 little-endian bytes.
- */
-INLINE unsigned long long read8LE(unsigned char const** ppSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *(*ppSrc)++;
- result |= (unsigned long long) *(*ppSrc)++ << 8;
- result |= (unsigned long long) *(*ppSrc)++ << 16;
- result |= (unsigned long long) *(*ppSrc)++ << 24;
- result |= (unsigned long long) *(*ppSrc)++ << 32;
- result |= (unsigned long long) *(*ppSrc)++ << 40;
- result |= (unsigned long long) *(*ppSrc)++ << 48;
- result |= (unsigned long long) *(*ppSrc)++ << 56;
-
- return result;
-}
-
-/*
- * Skip over a UTF-8 string.
- */
-INLINE void skipUtf8String(unsigned char const** ppSrc)
-{
- unsigned int length = read4BE(ppSrc);
-
- (*ppSrc) += length;
-}
-
-/*
- * Read a UTF-8 string into a fixed-size buffer, and null-terminate it.
- *
- * Returns the length of the original string.
- */
-INLINE int readUtf8String(unsigned char const** ppSrc, char* buf, size_t bufLen)
-{
- unsigned int length = read4BE(ppSrc);
- size_t copyLen = (length < bufLen) ? length : bufLen-1;
-
- memcpy(buf, *ppSrc, copyLen);
- buf[copyLen] = '\0';
-
- (*ppSrc) += length;
- return length;
-}
-
-/*
- * Read a UTF-8 string into newly-allocated storage, and null-terminate it.
- *
- * Returns the string and its length. (The latter is probably unnecessary
- * for the way we're using UTF8.)
- */
-INLINE char* readNewUtf8String(unsigned char const** ppSrc, size_t* pLength)
-{
- unsigned int length = read4BE(ppSrc);
- char* buf;
-
- buf = (char*) malloc(length+1);
-
- memcpy(buf, *ppSrc, length);
- buf[length] = '\0';
-
- (*ppSrc) += length;
-
- *pLength = length;
- return buf;
-}
-
-
-/*
- * Set 1 byte. (Included to make the code more legible.)
- */
-INLINE void set1(unsigned char* buf, unsigned char val)
-{
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 2 big-endian bytes.
- */
-INLINE void set2BE(unsigned char* buf, unsigned short val)
-{
- *buf++ = (unsigned char)(val >> 8);
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 4 big-endian bytes.
- */
-INLINE void set4BE(unsigned char* buf, unsigned int val)
-{
- *buf++ = (unsigned char)(val >> 24);
- *buf++ = (unsigned char)(val >> 16);
- *buf++ = (unsigned char)(val >> 8);
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 8 big-endian bytes.
- */
-INLINE void set8BE(unsigned char* buf, unsigned long long val)
-{
- *buf++ = (unsigned char)(val >> 56);
- *buf++ = (unsigned char)(val >> 48);
- *buf++ = (unsigned char)(val >> 40);
- *buf++ = (unsigned char)(val >> 32);
- *buf++ = (unsigned char)(val >> 24);
- *buf++ = (unsigned char)(val >> 16);
- *buf++ = (unsigned char)(val >> 8);
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 2 little-endian bytes.
- */
-INLINE void set2LE(unsigned char* buf, unsigned short val)
-{
- *buf++ = (unsigned char)(val);
- *buf = (unsigned char)(val >> 8);
-}
-
-/*
- * Set 4 little-endian bytes.
- */
-INLINE void set4LE(unsigned char* buf, unsigned int val)
-{
- *buf++ = (unsigned char)(val);
- *buf++ = (unsigned char)(val >> 8);
- *buf++ = (unsigned char)(val >> 16);
- *buf = (unsigned char)(val >> 24);
-}
-
-/*
- * Set 8 little-endian bytes.
- */
-INLINE void set8LE(unsigned char* buf, unsigned long long val)
-{
- *buf++ = (unsigned char)(val);
- *buf++ = (unsigned char)(val >> 8);
- *buf++ = (unsigned char)(val >> 16);
- *buf++ = (unsigned char)(val >> 24);
- *buf++ = (unsigned char)(val >> 32);
- *buf++ = (unsigned char)(val >> 40);
- *buf++ = (unsigned char)(val >> 48);
- *buf = (unsigned char)(val >> 56);
-}
-
-/*
- * Stuff a UTF-8 string into the buffer.
- */
-INLINE void setUtf8String(unsigned char* buf, const unsigned char* str)
-{
- unsigned int strLen = strlen((const char*)str);
-
- set4BE(buf, strLen);
- memcpy(buf + sizeof(unsigned int), str, strLen);
-}
-
-#endif /*_MINZIP_BITS*/
diff --git a/minzip/DirUtil.c b/minzip/DirUtil.c
deleted file mode 100644
index 20c89cd..0000000
--- a/minzip/DirUtil.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-
-#include "DirUtil.h"
-
-typedef enum { DMISSING, DDIR, DILLEGAL } DirStatus;
-
-static DirStatus
-getPathDirStatus(const char *path)
-{
- struct stat st;
- int err;
-
- err = stat(path, &st);
- if (err == 0) {
- /* Something's there; make sure it's a directory.
- */
- if (S_ISDIR(st.st_mode)) {
- return DDIR;
- }
- errno = ENOTDIR;
- return DILLEGAL;
- } else if (errno != ENOENT) {
- /* Something went wrong, or something in the path
- * is bad. Can't do anything in this situation.
- */
- return DILLEGAL;
- }
- return DMISSING;
-}
-
-int
-dirCreateHierarchy(const char *path, int mode,
- const struct utimbuf *timestamp, bool stripFileName)
-{
- DirStatus ds;
-
- /* Check for an empty string before we bother
- * making any syscalls.
- */
- if (path[0] == '\0') {
- errno = ENOENT;
- return -1;
- }
-
- /* Allocate a path that we can modify; stick a slash on
- * the end to make things easier.
- */
- size_t pathLen = strlen(path);
- char *cpath = (char *)malloc(pathLen + 2);
- if (cpath == NULL) {
- errno = ENOMEM;
- return -1;
- }
- memcpy(cpath, path, pathLen);
- if (stripFileName) {
- /* Strip everything after the last slash.
- */
- char *c = cpath + pathLen - 1;
- while (c != cpath && *c != '/') {
- c--;
- }
- if (c == cpath) {
-//xxx test this path
- /* No directory component. Act like the path was empty.
- */
- errno = ENOENT;
- free(cpath);
- return -1;
- }
- c[1] = '\0'; // Terminate after the slash we found.
- } else {
- /* Make sure that the path ends in a slash.
- */
- cpath[pathLen] = '/';
- cpath[pathLen + 1] = '\0';
- }
-
- /* See if it already exists.
- */
- ds = getPathDirStatus(cpath);
- if (ds == DDIR) {
- return 0;
- } else if (ds == DILLEGAL) {
- return -1;
- }
-
- /* Walk up the path from the root and make each level.
- * If a directory already exists, no big deal.
- */
- char *p = cpath;
- while (*p != '\0') {
- /* Skip any slashes, watching out for the end of the string.
- */
- while (*p != '\0' && *p == '/') {
- p++;
- }
- if (*p == '\0') {
- break;
- }
-
- /* Find the end of the next path component.
- * We know that we'll see a slash before the NUL,
- * because we added it, above.
- */
- while (*p != '/') {
- p++;
- }
- *p = '\0';
-
- /* Check this part of the path and make a new directory
- * if necessary.
- */
- ds = getPathDirStatus(cpath);
- if (ds == DILLEGAL) {
- /* Could happen if some other process/thread is
- * messing with the filesystem.
- */
- free(cpath);
- return -1;
- } else if (ds == DMISSING) {
- int err;
-
- err = mkdir(cpath, mode);
- if (err != 0) {
- free(cpath);
- return -1;
- }
- if (timestamp != NULL && utime(cpath, timestamp)) {
- free(cpath);
- return -1;
- }
- }
- // else, this directory already exists.
-
- /* Repair the path and continue.
- */
- *p = '/';
- }
- free(cpath);
-
- return 0;
-}
-
-int
-dirUnlinkHierarchy(const char *path)
-{
- struct stat st;
- DIR *dir;
- struct dirent *de;
- int fail = 0;
-
- /* is it a file or directory? */
- if (lstat(path, &st) < 0) {
- return -1;
- }
-
- /* a file, so unlink it */
- if (!S_ISDIR(st.st_mode)) {
- return unlink(path);
- }
-
- /* a directory, so open handle */
- dir = opendir(path);
- if (dir == NULL) {
- return -1;
- }
-
- /* recurse over components */
- errno = 0;
- while ((de = readdir(dir)) != NULL) {
-//TODO: don't blow the stack
- char dn[PATH_MAX];
- if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
- continue;
- }
- snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
- if (dirUnlinkHierarchy(dn) < 0) {
- fail = 1;
- break;
- }
- errno = 0;
- }
- /* in case readdir or unlink_recursive failed */
- if (fail || errno < 0) {
- int save = errno;
- closedir(dir);
- errno = save;
- return -1;
- }
-
- /* close directory handle */
- if (closedir(dir) < 0) {
- return -1;
- }
-
- /* delete target directory */
- return rmdir(path);
-}
-
-int
-dirSetHierarchyPermissions(const char *path,
- int uid, int gid, int dirMode, int fileMode)
-{
- struct stat st;
- if (lstat(path, &st)) {
- return -1;
- }
-
- /* ignore symlinks */
- if (S_ISLNK(st.st_mode)) {
- return 0;
- }
-
- /* directories and files get different permissions */
- if (chown(path, uid, gid) ||
- chmod(path, S_ISDIR(st.st_mode) ? dirMode : fileMode)) {
- return -1;
- }
-
- /* recurse over directory components */
- if (S_ISDIR(st.st_mode)) {
- DIR *dir = opendir(path);
- if (dir == NULL) {
- return -1;
- }
-
- errno = 0;
- const struct dirent *de;
- while (errno == 0 && (de = readdir(dir)) != NULL) {
- if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
- continue;
- }
-
- char dn[PATH_MAX];
- snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
- if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode)) {
- errno = 0;
- } else if (errno == 0) {
- errno = -1;
- }
- }
-
- if (errno != 0) {
- int save = errno;
- closedir(dir);
- errno = save;
- return -1;
- }
-
- if (closedir(dir)) {
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/minzip/DirUtil.h b/minzip/DirUtil.h
deleted file mode 100644
index 5d881f5..0000000
--- a/minzip/DirUtil.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINZIP_DIRUTIL_H_
-#define MINZIP_DIRUTIL_H_
-
-#include <stdbool.h>
-#include <utime.h>
-
-/* Like "mkdir -p", try to guarantee that all directories
- * specified in path are present, creating as many directories
- * as necessary. The specified mode is passed to all mkdir
- * calls; no modifications are made to umask.
- *
- * If stripFileName is set, everything after the final '/'
- * is stripped before creating the directory hierarchy.
- *
- * If timestamp is non-NULL, new directories will be timestamped accordingly.
- *
- * Returns 0 on success; returns -1 (and sets errno) on failure
- * (usually if some element of path is not a directory).
- */
-int dirCreateHierarchy(const char *path, int mode,
- const struct utimbuf *timestamp, bool stripFileName);
-
-/* rm -rf <path>
- */
-int dirUnlinkHierarchy(const char *path);
-
-/* chown -R <uid>:<gid> <path>
- * chmod -R <mode> <path>
- *
- * Sets directories to <dirMode> and files to <fileMode>. Skips symlinks.
- */
-int dirSetHierarchyPermissions(const char *path,
- int uid, int gid, int dirMode, int fileMode);
-
-#endif // MINZIP_DIRUTIL_H_
diff --git a/minzip/Hash.c b/minzip/Hash.c
deleted file mode 100644
index 8c6ca9b..0000000
--- a/minzip/Hash.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Hash table. The dominant calls are add and lookup, with removals
- * happening very infrequently. We use probing, and don't worry much
- * about tombstone removal.
- */
-#include <stdlib.h>
-#include <assert.h>
-
-#define LOG_TAG "minzip"
-#include "Log.h"
-#include "Hash.h"
-
-/* table load factor, i.e. how full can it get before we resize */
-//#define LOAD_NUMER 3 // 75%
-//#define LOAD_DENOM 4
-#define LOAD_NUMER 5 // 62.5%
-#define LOAD_DENOM 8
-//#define LOAD_NUMER 1 // 50%
-//#define LOAD_DENOM 2
-
-/*
- * Compute the capacity needed for a table to hold "size" elements.
- */
-size_t mzHashSize(size_t size) {
- return (size * LOAD_DENOM) / LOAD_NUMER +1;
-}
-
-/*
- * Round up to the next highest power of 2.
- *
- * Found on http://graphics.stanford.edu/~seander/bithacks.html.
- */
-unsigned int roundUpPower2(unsigned int val)
-{
- val--;
- val |= val >> 1;
- val |= val >> 2;
- val |= val >> 4;
- val |= val >> 8;
- val |= val >> 16;
- val++;
-
- return val;
-}
-
-/*
- * Create and initialize a hash table.
- */
-HashTable* mzHashTableCreate(size_t initialSize, HashFreeFunc freeFunc)
-{
- HashTable* pHashTable;
-
- assert(initialSize > 0);
-
- pHashTable = (HashTable*) malloc(sizeof(*pHashTable));
- if (pHashTable == NULL)
- return NULL;
-
- pHashTable->tableSize = roundUpPower2(initialSize);
- pHashTable->numEntries = pHashTable->numDeadEntries = 0;
- pHashTable->freeFunc = freeFunc;
- pHashTable->pEntries =
- (HashEntry*) calloc((size_t)pHashTable->tableSize, sizeof(HashTable));
- if (pHashTable->pEntries == NULL) {
- free(pHashTable);
- return NULL;
- }
-
- return pHashTable;
-}
-
-/*
- * Clear out all entries.
- */
-void mzHashTableClear(HashTable* pHashTable)
-{
- HashEntry* pEnt;
- int i;
-
- pEnt = pHashTable->pEntries;
- for (i = 0; i < pHashTable->tableSize; i++, pEnt++) {
- if (pEnt->data == HASH_TOMBSTONE) {
- // nuke entry
- pEnt->data = NULL;
- } else if (pEnt->data != NULL) {
- // call free func then nuke entry
- if (pHashTable->freeFunc != NULL)
- (*pHashTable->freeFunc)(pEnt->data);
- pEnt->data = NULL;
- }
- }
-
- pHashTable->numEntries = 0;
- pHashTable->numDeadEntries = 0;
-}
-
-/*
- * Free the table.
- */
-void mzHashTableFree(HashTable* pHashTable)
-{
- if (pHashTable == NULL)
- return;
- mzHashTableClear(pHashTable);
- free(pHashTable->pEntries);
- free(pHashTable);
-}
-
-#ifndef NDEBUG
-/*
- * Count up the number of tombstone entries in the hash table.
- */
-static int countTombStones(HashTable* pHashTable)
-{
- int i, count;
-
- for (count = i = 0; i < pHashTable->tableSize; i++) {
- if (pHashTable->pEntries[i].data == HASH_TOMBSTONE)
- count++;
- }
- return count;
-}
-#endif
-
-/*
- * Resize a hash table. We do this when adding an entry increased the
- * size of the table beyond its comfy limit.
- *
- * This essentially requires re-inserting all elements into the new storage.
- *
- * If multiple threads can access the hash table, the table's lock should
- * have been grabbed before issuing the "lookup+add" call that led to the
- * resize, so we don't have a synchronization problem here.
- */
-static bool resizeHash(HashTable* pHashTable, int newSize)
-{
- HashEntry* pNewEntries;
- int i;
-
- assert(countTombStones(pHashTable) == pHashTable->numDeadEntries);
- //LOGI("before: dead=%d\n", pHashTable->numDeadEntries);
-
- pNewEntries = (HashEntry*) calloc(newSize, sizeof(HashTable));
- if (pNewEntries == NULL)
- return false;
-
- for (i = 0; i < pHashTable->tableSize; i++) {
- void* data = pHashTable->pEntries[i].data;
- if (data != NULL && data != HASH_TOMBSTONE) {
- int hashValue = pHashTable->pEntries[i].hashValue;
- int newIdx;
-
- /* probe for new spot, wrapping around */
- newIdx = hashValue & (newSize-1);
- while (pNewEntries[newIdx].data != NULL)
- newIdx = (newIdx + 1) & (newSize-1);
-
- pNewEntries[newIdx].hashValue = hashValue;
- pNewEntries[newIdx].data = data;
- }
- }
-
- free(pHashTable->pEntries);
- pHashTable->pEntries = pNewEntries;
- pHashTable->tableSize = newSize;
- pHashTable->numDeadEntries = 0;
-
- assert(countTombStones(pHashTable) == 0);
- return true;
-}
-
-/*
- * Look up an entry.
- *
- * We probe on collisions, wrapping around the table.
- */
-void* mzHashTableLookup(HashTable* pHashTable, unsigned int itemHash, void* item,
- HashCompareFunc cmpFunc, bool doAdd)
-{
- HashEntry* pEntry;
- HashEntry* pEnd;
- void* result = NULL;
-
- assert(pHashTable->tableSize > 0);
- assert(item != HASH_TOMBSTONE);
- assert(item != NULL);
-
- /* jump to the first entry and probe for a match */
- pEntry = &pHashTable->pEntries[itemHash & (pHashTable->tableSize-1)];
- pEnd = &pHashTable->pEntries[pHashTable->tableSize];
- while (pEntry->data != NULL) {
- if (pEntry->data != HASH_TOMBSTONE &&
- pEntry->hashValue == itemHash &&
- (*cmpFunc)(pEntry->data, item) == 0)
- {
- /* match */
- //LOGD("+++ match on entry %d\n", pEntry - pHashTable->pEntries);
- break;
- }
-
- pEntry++;
- if (pEntry == pEnd) { /* wrap around to start */
- if (pHashTable->tableSize == 1)
- break; /* edge case - single-entry table */
- pEntry = pHashTable->pEntries;
- }
-
- //LOGI("+++ look probing %d...\n", pEntry - pHashTable->pEntries);
- }
-
- if (pEntry->data == NULL) {
- if (doAdd) {
- pEntry->hashValue = itemHash;
- pEntry->data = item;
- pHashTable->numEntries++;
-
- /*
- * We've added an entry. See if this brings us too close to full.
- */
- if ((pHashTable->numEntries+pHashTable->numDeadEntries) * LOAD_DENOM
- > pHashTable->tableSize * LOAD_NUMER)
- {
- if (!resizeHash(pHashTable, pHashTable->tableSize * 2)) {
- /* don't really have a way to indicate failure */
- LOGE("Dalvik hash resize failure\n");
- abort();
- }
- /* note "pEntry" is now invalid */
- } else {
- //LOGW("okay %d/%d/%d\n",
- // pHashTable->numEntries, pHashTable->tableSize,
- // (pHashTable->tableSize * LOAD_NUMER) / LOAD_DENOM);
- }
-
- /* full table is bad -- search for nonexistent never halts */
- assert(pHashTable->numEntries < pHashTable->tableSize);
- result = item;
- } else {
- assert(result == NULL);
- }
- } else {
- result = pEntry->data;
- }
-
- return result;
-}
-
-/*
- * Remove an entry from the table.
- *
- * Does NOT invoke the "free" function on the item.
- */
-bool mzHashTableRemove(HashTable* pHashTable, unsigned int itemHash, void* item)
-{
- HashEntry* pEntry;
- HashEntry* pEnd;
-
- assert(pHashTable->tableSize > 0);
-
- /* jump to the first entry and probe for a match */
- pEntry = &pHashTable->pEntries[itemHash & (pHashTable->tableSize-1)];
- pEnd = &pHashTable->pEntries[pHashTable->tableSize];
- while (pEntry->data != NULL) {
- if (pEntry->data == item) {
- //LOGI("+++ stepping on entry %d\n", pEntry - pHashTable->pEntries);
- pEntry->data = HASH_TOMBSTONE;
- pHashTable->numEntries--;
- pHashTable->numDeadEntries++;
- return true;
- }
-
- pEntry++;
- if (pEntry == pEnd) { /* wrap around to start */
- if (pHashTable->tableSize == 1)
- break; /* edge case - single-entry table */
- pEntry = pHashTable->pEntries;
- }
-
- //LOGI("+++ del probing %d...\n", pEntry - pHashTable->pEntries);
- }
-
- return false;
-}
-
-/*
- * Execute a function on every entry in the hash table.
- *
- * If "func" returns a nonzero value, terminate early and return the value.
- */
-int mzHashForeach(HashTable* pHashTable, HashForeachFunc func, void* arg)
-{
- int i, val;
-
- for (i = 0; i < pHashTable->tableSize; i++) {
- HashEntry* pEnt = &pHashTable->pEntries[i];
-
- if (pEnt->data != NULL && pEnt->data != HASH_TOMBSTONE) {
- val = (*func)(pEnt->data, arg);
- if (val != 0)
- return val;
- }
- }
-
- return 0;
-}
-
-
-/*
- * Look up an entry, counting the number of times we have to probe.
- *
- * Returns -1 if the entry wasn't found.
- */
-int countProbes(HashTable* pHashTable, unsigned int itemHash, const void* item,
- HashCompareFunc cmpFunc)
-{
- HashEntry* pEntry;
- HashEntry* pEnd;
- int count = 0;
-
- assert(pHashTable->tableSize > 0);
- assert(item != HASH_TOMBSTONE);
- assert(item != NULL);
-
- /* jump to the first entry and probe for a match */
- pEntry = &pHashTable->pEntries[itemHash & (pHashTable->tableSize-1)];
- pEnd = &pHashTable->pEntries[pHashTable->tableSize];
- while (pEntry->data != NULL) {
- if (pEntry->data != HASH_TOMBSTONE &&
- pEntry->hashValue == itemHash &&
- (*cmpFunc)(pEntry->data, item) == 0)
- {
- /* match */
- break;
- }
-
- pEntry++;
- if (pEntry == pEnd) { /* wrap around to start */
- if (pHashTable->tableSize == 1)
- break; /* edge case - single-entry table */
- pEntry = pHashTable->pEntries;
- }
-
- count++;
- }
- if (pEntry->data == NULL)
- return -1;
-
- return count;
-}
-
-/*
- * Evaluate the amount of probing required for the specified hash table.
- *
- * We do this by running through all entries in the hash table, computing
- * the hash value and then doing a lookup.
- *
- * The caller should lock the table before calling here.
- */
-void mzHashTableProbeCount(HashTable* pHashTable, HashCalcFunc calcFunc,
- HashCompareFunc cmpFunc)
-{
- int numEntries, minProbe, maxProbe, totalProbe;
- HashIter iter;
-
- numEntries = maxProbe = totalProbe = 0;
- minProbe = 65536*32767;
-
- for (mzHashIterBegin(pHashTable, &iter); !mzHashIterDone(&iter);
- mzHashIterNext(&iter))
- {
- const void* data = (const void*)mzHashIterData(&iter);
- int count;
-
- count = countProbes(pHashTable, (*calcFunc)(data), data, cmpFunc);
-
- numEntries++;
-
- if (count < minProbe)
- minProbe = count;
- if (count > maxProbe)
- maxProbe = count;
- totalProbe += count;
- }
-
- LOGI("Probe: min=%d max=%d, total=%d in %d (%d), avg=%.3f\n",
- minProbe, maxProbe, totalProbe, numEntries, pHashTable->tableSize,
- (float) totalProbe / (float) numEntries);
-}
diff --git a/minzip/Hash.h b/minzip/Hash.h
deleted file mode 100644
index 8194537..0000000
--- a/minzip/Hash.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2007 The Android Open Source Project
- *
- * General purpose hash table, used for finding classes, methods, etc.
- *
- * When the number of elements reaches 3/4 of the table's capacity, the
- * table will be resized.
- */
-#ifndef _MINZIP_HASH
-#define _MINZIP_HASH
-
-#include "inline_magic.h"
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <assert.h>
-
-/* compute the hash of an item with a specific type */
-typedef unsigned int (*HashCompute)(const void* item);
-
-/*
- * Compare a hash entry with a "loose" item after their hash values match.
- * Returns { <0, 0, >0 } depending on ordering of items (same semantics
- * as strcmp()).
- */
-typedef int (*HashCompareFunc)(const void* tableItem, const void* looseItem);
-
-/*
- * This function will be used to free entries in the table. This can be
- * NULL if no free is required, free(), or a custom function.
- */
-typedef void (*HashFreeFunc)(void* ptr);
-
-/*
- * Used by mzHashForeach().
- */
-typedef int (*HashForeachFunc)(void* data, void* arg);
-
-/*
- * One entry in the hash table. "data" values are expected to be (or have
- * the same characteristics as) valid pointers. In particular, a NULL
- * value for "data" indicates an empty slot, and HASH_TOMBSTONE indicates
- * a no-longer-used slot that must be stepped over during probing.
- *
- * Attempting to add a NULL or tombstone value is an error.
- *
- * When an entry is released, we will call (HashFreeFunc)(entry->data).
- */
-typedef struct HashEntry {
- unsigned int hashValue;
- void* data;
-} HashEntry;
-
-#define HASH_TOMBSTONE ((void*) 0xcbcacccd) // invalid ptr value
-
-/*
- * Expandable hash table.
- *
- * This structure should be considered opaque.
- */
-typedef struct HashTable {
- int tableSize; /* must be power of 2 */
- int numEntries; /* current #of "live" entries */
- int numDeadEntries; /* current #of tombstone entries */
- HashEntry* pEntries; /* array on heap */
- HashFreeFunc freeFunc;
-} HashTable;
-
-/*
- * Create and initialize a HashTable structure, using "initialSize" as
- * a basis for the initial capacity of the table. (The actual initial
- * table size may be adjusted upward.) If you know exactly how many
- * elements the table will hold, pass the result from mzHashSize() in.)
- *
- * Returns "false" if unable to allocate the table.
- */
-HashTable* mzHashTableCreate(size_t initialSize, HashFreeFunc freeFunc);
-
-/*
- * Compute the capacity needed for a table to hold "size" elements. Use
- * this when you know ahead of time how many elements the table will hold.
- * Pass this value into mzHashTableCreate() to ensure that you can add
- * all elements without needing to reallocate the table.
- */
-size_t mzHashSize(size_t size);
-
-/*
- * Clear out a hash table, freeing the contents of any used entries.
- */
-void mzHashTableClear(HashTable* pHashTable);
-
-/*
- * Free a hash table.
- */
-void mzHashTableFree(HashTable* pHashTable);
-
-/*
- * Get #of entries in hash table.
- */
-INLINE int mzHashTableNumEntries(HashTable* pHashTable) {
- return pHashTable->numEntries;
-}
-
-/*
- * Get total size of hash table (for memory usage calculations).
- */
-INLINE int mzHashTableMemUsage(HashTable* pHashTable) {
- return sizeof(HashTable) + pHashTable->tableSize * sizeof(HashEntry);
-}
-
-/*
- * Look up an entry in the table, possibly adding it if it's not there.
- *
- * If "item" is not found, and "doAdd" is false, NULL is returned.
- * Otherwise, a pointer to the found or added item is returned. (You can
- * tell the difference by seeing if return value == item.)
- *
- * An "add" operation may cause the entire table to be reallocated.
- */
-void* mzHashTableLookup(HashTable* pHashTable, unsigned int itemHash, void* item,
- HashCompareFunc cmpFunc, bool doAdd);
-
-/*
- * Remove an item from the hash table, given its "data" pointer. Does not
- * invoke the "free" function; just detaches it from the table.
- */
-bool mzHashTableRemove(HashTable* pHashTable, unsigned int hash, void* item);
-
-/*
- * Execute "func" on every entry in the hash table.
- *
- * If "func" returns a nonzero value, terminate early and return the value.
- */
-int mzHashForeach(HashTable* pHashTable, HashForeachFunc func, void* arg);
-
-/*
- * An alternative to mzHashForeach(), using an iterator.
- *
- * Use like this:
- * HashIter iter;
- * for (mzHashIterBegin(hashTable, &iter); !mzHashIterDone(&iter);
- * mzHashIterNext(&iter))
- * {
- * MyData* data = (MyData*)mzHashIterData(&iter);
- * }
- */
-typedef struct HashIter {
- void* data;
- HashTable* pHashTable;
- int idx;
-} HashIter;
-INLINE void mzHashIterNext(HashIter* pIter) {
- int i = pIter->idx +1;
- int lim = pIter->pHashTable->tableSize;
- for ( ; i < lim; i++) {
- void* data = pIter->pHashTable->pEntries[i].data;
- if (data != NULL && data != HASH_TOMBSTONE)
- break;
- }
- pIter->idx = i;
-}
-INLINE void mzHashIterBegin(HashTable* pHashTable, HashIter* pIter) {
- pIter->pHashTable = pHashTable;
- pIter->idx = -1;
- mzHashIterNext(pIter);
-}
-INLINE bool mzHashIterDone(HashIter* pIter) {
- return (pIter->idx >= pIter->pHashTable->tableSize);
-}
-INLINE void* mzHashIterData(HashIter* pIter) {
- assert(pIter->idx >= 0 && pIter->idx < pIter->pHashTable->tableSize);
- return pIter->pHashTable->pEntries[pIter->idx].data;
-}
-
-
-/*
- * Evaluate hash table performance by examining the number of times we
- * have to probe for an entry.
- *
- * The caller should lock the table beforehand.
- */
-typedef unsigned int (*HashCalcFunc)(const void* item);
-void mzHashTableProbeCount(HashTable* pHashTable, HashCalcFunc calcFunc,
- HashCompareFunc cmpFunc);
-
-#endif /*_MINZIP_HASH*/
diff --git a/minzip/Inlines.c b/minzip/Inlines.c
deleted file mode 100644
index 91f8775..0000000
--- a/minzip/Inlines.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Make sure that non-inlined versions of INLINED-marked functions
- * exist so that debug builds (which don't generally do inlining)
- * don't break.
- */
-#define MINZIP_GENERATE_INLINES 1
-#include "Bits.h"
-#include "Hash.h"
-#include "SysUtil.h"
-#include "Zip.h"
diff --git a/minzip/Log.h b/minzip/Log.h
deleted file mode 100644
index 36e62f5..0000000
--- a/minzip/Log.h
+++ /dev/null
@@ -1,207 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-// C/C++ logging functions. See the logging documentation for API details.
-//
-// We'd like these to be available from C code (in case we import some from
-// somewhere), so this has a C interface.
-//
-// The output will be correct when the log file is shared between multiple
-// threads and/or multiple processes so long as the operating system
-// supports O_APPEND. These calls have mutex-protected data structures
-// and so are NOT reentrant. Do not use LOG in a signal handler.
-//
-#ifndef _MINZIP_LOG_H
-#define _MINZIP_LOG_H
-
-#include <stdio.h>
-
-// ---------------------------------------------------------------------
-
-/*
- * Normally we strip LOGV (VERBOSE messages) from release builds.
- * You can modify this (for example with "#define LOG_NDEBUG 0"
- * at the top of your source file) to change that behavior.
- */
-#ifndef LOG_NDEBUG
-#ifdef NDEBUG
-#define LOG_NDEBUG 1
-#else
-#define LOG_NDEBUG 0
-#endif
-#endif
-
-/*
- * This is the local tag used for the following simplified
- * logging macros. You can change this preprocessor definition
- * before using the other macros to change the tag.
- */
-#ifndef LOG_TAG
-#define LOG_TAG NULL
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Simplified macro to send a verbose log message using the current LOG_TAG.
- */
-#ifndef LOGV
-#if LOG_NDEBUG
-#define LOGV(...) ((void)0)
-#else
-#define LOGV(...) ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
-#endif
-#endif
-
-#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
-
-#ifndef LOGV_IF
-#if LOG_NDEBUG
-#define LOGV_IF(cond, ...) ((void)0)
-#else
-#define LOGV_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-#endif
-
-#define LOGVV LOGV
-#define LOGVV_IF LOGV_IF
-
-/*
- * Simplified macro to send a debug log message using the current LOG_TAG.
- */
-#ifndef LOGD
-#define LOGD(...) ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGD_IF
-#define LOGD_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an info log message using the current LOG_TAG.
- */
-#ifndef LOGI
-#define LOGI(...) ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGI_IF
-#define LOGI_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send a warning log message using the current LOG_TAG.
- */
-#ifndef LOGW
-#define LOGW(...) ((void)LOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGW_IF
-#define LOGW_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an error log message using the current LOG_TAG.
- */
-#ifndef LOGE
-#define LOGE(...) ((void)LOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGE_IF
-#define LOGE_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * verbose priority.
- */
-#ifndef IF_LOGV
-#if LOG_NDEBUG
-#define IF_LOGV() if (false)
-#else
-#define IF_LOGV() IF_LOG(LOG_VERBOSE, LOG_TAG)
-#endif
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * debug priority.
- */
-#ifndef IF_LOGD
-#define IF_LOGD() IF_LOG(LOG_DEBUG, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * info priority.
- */
-#ifndef IF_LOGI
-#define IF_LOGI() IF_LOG(LOG_INFO, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * warn priority.
- */
-#ifndef IF_LOGW
-#define IF_LOGW() IF_LOG(LOG_WARN, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * error priority.
- */
-#ifndef IF_LOGE
-#define IF_LOGE() IF_LOG(LOG_ERROR, LOG_TAG)
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Basic log message macro.
- *
- * Example:
- * LOG(LOG_WARN, NULL, "Failed with error %d", errno);
- *
- * The second argument may be NULL or "" to indicate the "global" tag.
- *
- * Non-gcc probably won't have __FUNCTION__. It's not vital. gcc also
- * offers __PRETTY_FUNCTION__, which is rather more than we need.
- */
-#ifndef LOG
-#define LOG(priority, tag, ...) \
- LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
-#endif
-
-/*
- * Log macro that allows you to specify a number for the priority.
- */
-#ifndef LOG_PRI
-#define LOG_PRI(priority, tag, ...) \
- printf(tag ": " __VA_ARGS__)
-#endif
-
-/*
- * Conditional given a desired logging priority and tag.
- */
-#ifndef IF_LOG
-#define IF_LOG(priority, tag) \
- if (1)
-#endif
-
-#endif // _MINZIP_LOG_H
diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c
deleted file mode 100644
index 49a2522..0000000
--- a/minzip/SysUtil.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * System utilities.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <limits.h>
-#include <errno.h>
-#include <assert.h>
-
-#define LOG_TAG "minzip"
-#include "Log.h"
-#include "SysUtil.h"
-
-/*
- * Having trouble finding a portable way to get this. sysconf(_SC_PAGE_SIZE)
- * seems appropriate, but we don't have that on the device. Some systems
- * have getpagesize(2), though the linux man page has some odd cautions.
- */
-#define DEFAULT_PAGE_SIZE 4096
-
-
-/*
- * Create an anonymous shared memory segment large enough to hold "length"
- * bytes. The actual segment may be larger because mmap() operates on
- * page boundaries (usually 4K).
- */
-static void* sysCreateAnonShmem(size_t length)
-{
- void* ptr;
-
- ptr = mmap(NULL, length, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANON, -1, 0);
- if (ptr == MAP_FAILED) {
- LOGW("mmap(%d, RW, SHARED|ANON) failed: %s\n", (int) length,
- strerror(errno));
- return NULL;
- }
-
- return ptr;
-}
-
-static int getFileStartAndLength(int fd, off_t *start_, size_t *length_)
-{
- off_t start, end;
- size_t length;
-
- assert(start_ != NULL);
- assert(length_ != NULL);
-
- start = lseek(fd, 0L, SEEK_CUR);
- end = lseek(fd, 0L, SEEK_END);
- (void) lseek(fd, start, SEEK_SET);
-
- if (start == (off_t) -1 || end == (off_t) -1) {
- LOGE("could not determine length of file\n");
- return -1;
- }
-
- length = end - start;
- if (length == 0) {
- LOGE("file is empty\n");
- return -1;
- }
-
- *start_ = start;
- *length_ = length;
-
- return 0;
-}
-
-/*
- * Pull the contents of a file into an new shared memory segment. We grab
- * everything from fd's current offset on.
- *
- * We need to know the length ahead of time so we can allocate a segment
- * of sufficient size.
- */
-int sysLoadFileInShmem(int fd, MemMapping* pMap)
-{
- off_t start;
- size_t length, actual;
- void* memPtr;
-
- assert(pMap != NULL);
-
- if (getFileStartAndLength(fd, &start, &length) < 0)
- return -1;
-
- memPtr = sysCreateAnonShmem(length);
- if (memPtr == NULL)
- return -1;
-
- actual = read(fd, memPtr, length);
- if (actual != length) {
- LOGE("only read %d of %d bytes\n", (int) actual, (int) length);
- sysReleaseShmem(pMap);
- return -1;
- }
-
- pMap->baseAddr = pMap->addr = memPtr;
- pMap->baseLength = pMap->length = length;
-
- return 0;
-}
-
-/*
- * Map a file (from fd's current offset) into a shared, read-only memory
- * segment. The file offset must be a multiple of the page size.
- *
- * On success, returns 0 and fills out "pMap". On failure, returns a nonzero
- * value and does not disturb "pMap".
- */
-int sysMapFileInShmem(int fd, MemMapping* pMap)
-{
- off_t start;
- size_t length;
- void* memPtr;
-
- assert(pMap != NULL);
-
- if (getFileStartAndLength(fd, &start, &length) < 0)
- return -1;
-
- memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start);
- if (memPtr == MAP_FAILED) {
- LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", (int) length,
- fd, (int) start, strerror(errno));
- return -1;
- }
-
- pMap->baseAddr = pMap->addr = memPtr;
- pMap->baseLength = pMap->length = length;
-
- return 0;
-}
-
-/*
- * Map part of a file (from fd's current offset) into a shared, read-only
- * memory segment.
- *
- * On success, returns 0 and fills out "pMap". On failure, returns a nonzero
- * value and does not disturb "pMap".
- */
-int sysMapFileSegmentInShmem(int fd, off_t start, long length,
- MemMapping* pMap)
-{
- off_t dummy;
- size_t fileLength, actualLength;
- off_t actualStart;
- int adjust;
- void* memPtr;
-
- assert(pMap != NULL);
-
- if (getFileStartAndLength(fd, &dummy, &fileLength) < 0)
- return -1;
-
- if (start + length > (long)fileLength) {
- LOGW("bad segment: st=%d len=%ld flen=%d\n",
- (int) start, length, (int) fileLength);
- return -1;
- }
-
- /* adjust to be page-aligned */
- adjust = start % DEFAULT_PAGE_SIZE;
- actualStart = start - adjust;
- actualLength = length + adjust;
-
- memPtr = mmap(NULL, actualLength, PROT_READ, MAP_FILE | MAP_SHARED,
- fd, actualStart);
- if (memPtr == MAP_FAILED) {
- LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n",
- (int) actualLength, fd, (int) actualStart, strerror(errno));
- return -1;
- }
-
- pMap->baseAddr = memPtr;
- pMap->baseLength = actualLength;
- pMap->addr = (char*)memPtr + adjust;
- pMap->length = length;
-
- LOGVV("mmap seg (st=%d ln=%d): bp=%p bl=%d ad=%p ln=%d\n",
- (int) start, (int) length,
- pMap->baseAddr, (int) pMap->baseLength,
- pMap->addr, (int) pMap->length);
-
- return 0;
-}
-
-/*
- * Release a memory mapping.
- */
-void sysReleaseShmem(MemMapping* pMap)
-{
- if (pMap->baseAddr == NULL && pMap->baseLength == 0)
- return;
-
- if (munmap(pMap->baseAddr, pMap->baseLength) < 0) {
- LOGW("munmap(%p, %d) failed: %s\n",
- pMap->baseAddr, (int)pMap->baseLength, strerror(errno));
- } else {
- LOGV("munmap(%p, %d) succeeded\n", pMap->baseAddr, pMap->baseLength);
- pMap->baseAddr = NULL;
- pMap->baseLength = 0;
- }
-}
-
diff --git a/minzip/SysUtil.h b/minzip/SysUtil.h
deleted file mode 100644
index ec3a4bc..0000000
--- a/minzip/SysUtil.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * System utilities.
- */
-#ifndef _MINZIP_SYSUTIL
-#define _MINZIP_SYSUTIL
-
-#include "inline_magic.h"
-
-#include <sys/types.h>
-
-/*
- * Use this to keep track of mapped segments.
- */
-typedef struct MemMapping {
- void* addr; /* start of data */
- size_t length; /* length of data */
-
- void* baseAddr; /* page-aligned base address */
- size_t baseLength; /* length of mapping */
-} MemMapping;
-
-/* copy a map */
-INLINE void sysCopyMap(MemMapping* dst, const MemMapping* src) {
- *dst = *src;
-}
-
-/*
- * Load a file into a new shared memory segment. All data from the current
- * offset to the end of the file is pulled in.
- *
- * The segment is read-write, allowing VM fixups. (It should be modified
- * to support .gz/.zip compressed data.)
- *
- * On success, "pMap" is filled in, and zero is returned.
- */
-int sysLoadFileInShmem(int fd, MemMapping* pMap);
-
-/*
- * Map a file (from fd's current offset) into a shared,
- * read-only memory segment.
- *
- * On success, "pMap" is filled in, and zero is returned.
- */
-int sysMapFileInShmem(int fd, MemMapping* pMap);
-
-/*
- * Like sysMapFileInShmem, but on only part of a file.
- */
-int sysMapFileSegmentInShmem(int fd, off_t start, long length,
- MemMapping* pMap);
-
-/*
- * Release the pages associated with a shared memory segment.
- *
- * This does not free "pMap"; it just releases the memory.
- */
-void sysReleaseShmem(MemMapping* pMap);
-
-#endif /*_MINZIP_SYSUTIL*/
diff --git a/minzip/Zip.c b/minzip/Zip.c
deleted file mode 100644
index 100c833..0000000
--- a/minzip/Zip.c
+++ /dev/null
@@ -1,1098 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Simple Zip file support.
- */
-#include "safe_iop.h"
-#include "zlib.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdint.h> // for uintptr_t
-#include <stdlib.h>
-#include <sys/stat.h> // for S_ISLNK()
-#include <unistd.h>
-
-#define LOG_TAG "minzip"
-#include "Zip.h"
-#include "Bits.h"
-#include "Log.h"
-#include "DirUtil.h"
-
-#undef NDEBUG // do this after including Log.h
-#include <assert.h>
-
-#define SORT_ENTRIES 1
-
-/*
- * Offset and length constants (java.util.zip naming convention).
- */
-enum {
- CENSIG = 0x02014b50, // PK12
- CENHDR = 46,
-
- CENVEM = 4,
- CENVER = 6,
- CENFLG = 8,
- CENHOW = 10,
- CENTIM = 12,
- CENCRC = 16,
- CENSIZ = 20,
- CENLEN = 24,
- CENNAM = 28,
- CENEXT = 30,
- CENCOM = 32,
- CENDSK = 34,
- CENATT = 36,
- CENATX = 38,
- CENOFF = 42,
-
- ENDSIG = 0x06054b50, // PK56
- ENDHDR = 22,
-
- ENDSUB = 8,
- ENDTOT = 10,
- ENDSIZ = 12,
- ENDOFF = 16,
- ENDCOM = 20,
-
- EXTSIG = 0x08074b50, // PK78
- EXTHDR = 16,
-
- EXTCRC = 4,
- EXTSIZ = 8,
- EXTLEN = 12,
-
- LOCSIG = 0x04034b50, // PK34
- LOCHDR = 30,
-
- LOCVER = 4,
- LOCFLG = 6,
- LOCHOW = 8,
- LOCTIM = 10,
- LOCCRC = 14,
- LOCSIZ = 18,
- LOCLEN = 22,
- LOCNAM = 26,
- LOCEXT = 28,
-
- STORED = 0,
- DEFLATED = 8,
-
- CENVEM_UNIX = 3 << 8, // the high byte of CENVEM
-};
-
-
-/*
- * For debugging, dump the contents of a ZipEntry.
- */
-#if 0
-static void dumpEntry(const ZipEntry* pEntry)
-{
- LOGI(" %p '%.*s'\n", pEntry->fileName,pEntry->fileNameLen,pEntry->fileName);
- LOGI(" off=%ld comp=%ld uncomp=%ld how=%d\n", pEntry->offset,
- pEntry->compLen, pEntry->uncompLen, pEntry->compression);
-}
-#endif
-
-/*
- * (This is a mzHashTableLookup callback.)
- *
- * Compare two ZipEntry structs, by name.
- */
-static int hashcmpZipEntry(const void* ventry1, const void* ventry2)
-{
- const ZipEntry* entry1 = (const ZipEntry*) ventry1;
- const ZipEntry* entry2 = (const ZipEntry*) ventry2;
-
- if (entry1->fileNameLen != entry2->fileNameLen)
- return entry1->fileNameLen - entry2->fileNameLen;
- return memcmp(entry1->fileName, entry2->fileName, entry1->fileNameLen);
-}
-
-/*
- * (This is a mzHashTableLookup callback.)
- *
- * find a ZipEntry struct by name.
- */
-static int hashcmpZipName(const void* ventry, const void* vname)
-{
- const ZipEntry* entry = (const ZipEntry*) ventry;
- const char* name = (const char*) vname;
- unsigned int nameLen = strlen(name);
-
- if (entry->fileNameLen != nameLen)
- return entry->fileNameLen - nameLen;
- return memcmp(entry->fileName, name, nameLen);
-}
-
-/*
- * Compute the hash code for a ZipEntry filename.
- *
- * Not expected to be compatible with any other hash function, so we init
- * to 2 to ensure it doesn't happen to match.
- */
-static unsigned int computeHash(const char* name, int nameLen)
-{
- unsigned int hash = 2;
-
- while (nameLen--)
- hash = hash * 31 + *name++;
-
- return hash;
-}
-
-static void addEntryToHashTable(HashTable* pHash, ZipEntry* pEntry)
-{
- unsigned int itemHash = computeHash(pEntry->fileName, pEntry->fileNameLen);
- const ZipEntry* found;
-
- found = (const ZipEntry*)mzHashTableLookup(pHash,
- itemHash, pEntry, hashcmpZipEntry, true);
- if (found != pEntry) {
- LOGW("WARNING: duplicate entry '%.*s' in Zip\n",
- found->fileNameLen, found->fileName);
- /* keep going */
- }
-}
-
-static int validFilename(const char *fileName, unsigned int fileNameLen)
-{
- // Forbid super long filenames.
- if (fileNameLen >= PATH_MAX) {
- LOGW("Filename too long (%d chatacters)\n", fileNameLen);
- return 0;
- }
-
- // Require all characters to be printable ASCII (no NUL, no UTF-8, etc).
- unsigned int i;
- for (i = 0; i < fileNameLen; ++i) {
- if (fileName[i] < 32 || fileName[i] >= 127) {
- LOGW("Filename contains invalid character '\%03o'\n", fileName[i]);
- return 0;
- }
- }
-
- return 1;
-}
-
-/*
- * Parse the contents of a Zip archive. After confirming that the file
- * is in fact a Zip, we scan out the contents of the central directory and
- * store it in a hash table.
- *
- * Returns "true" on success.
- */
-static bool parseZipArchive(ZipArchive* pArchive, const MemMapping* pMap)
-{
- bool result = false;
- const unsigned char* ptr;
- unsigned int i, numEntries, cdOffset;
- unsigned int val;
-
- /*
- * The first 4 bytes of the file will either be the local header
- * signature for the first file (LOCSIG) or, if the archive doesn't
- * have any files in it, the end-of-central-directory signature (ENDSIG).
- */
- val = get4LE(pMap->addr);
- if (val == ENDSIG) {
- LOGI("Found Zip archive, but it looks empty\n");
- goto bail;
- } else if (val != LOCSIG) {
- LOGV("Not a Zip archive (found 0x%08x)\n", val);
- goto bail;
- }
-
- /*
- * Find the EOCD. We'll find it immediately unless they have a file
- * comment.
- */
- ptr = pMap->addr + pMap->length - ENDHDR;
-
- while (ptr >= (const unsigned char*) pMap->addr) {
- if (*ptr == (ENDSIG & 0xff) && get4LE(ptr) == ENDSIG)
- break;
- ptr--;
- }
- if (ptr < (const unsigned char*) pMap->addr) {
- LOGI("Could not find end-of-central-directory in Zip\n");
- goto bail;
- }
-
- /*
- * There are two interesting items in the EOCD block: the number of
- * entries in the file, and the file offset of the start of the
- * central directory.
- */
- numEntries = get2LE(ptr + ENDSUB);
- cdOffset = get4LE(ptr + ENDOFF);
-
- LOGVV("numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
- if (numEntries == 0 || cdOffset >= pMap->length) {
- LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
- numEntries, cdOffset, pMap->length);
- goto bail;
- }
-
- /*
- * Create data structures to hold entries.
- */
- pArchive->numEntries = numEntries;
- pArchive->pEntries = (ZipEntry*) calloc(numEntries, sizeof(ZipEntry));
- pArchive->pHash = mzHashTableCreate(mzHashSize(numEntries), NULL);
- if (pArchive->pEntries == NULL || pArchive->pHash == NULL)
- goto bail;
-
- ptr = pMap->addr + cdOffset;
- for (i = 0; i < numEntries; i++) {
- ZipEntry* pEntry;
- unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
- const unsigned char* localHdr;
- const char *fileName;
-
- if (ptr + CENHDR > (const unsigned char*)pMap->addr + pMap->length) {
- LOGW("Ran off the end (at %d)\n", i);
- goto bail;
- }
- if (get4LE(ptr) != CENSIG) {
- LOGW("Missed a central dir sig (at %d)\n", i);
- goto bail;
- }
-
- localHdrOffset = get4LE(ptr + CENOFF);
- fileNameLen = get2LE(ptr + CENNAM);
- extraLen = get2LE(ptr + CENEXT);
- commentLen = get2LE(ptr + CENCOM);
- fileName = (const char*)ptr + CENHDR;
- if (fileName + fileNameLen > (const char*)pMap->addr + pMap->length) {
- LOGW("Filename ran off the end (at %d)\n", i);
- goto bail;
- }
- if (!validFilename(fileName, fileNameLen)) {
- LOGW("Invalid filename (at %d)\n", i);
- goto bail;
- }
-
-#if SORT_ENTRIES
- /* Figure out where this entry should go (binary search).
- */
- if (i > 0) {
- int low, high;
-
- low = 0;
- high = i - 1;
- while (low <= high) {
- int mid;
- int diff;
- int diffLen;
-
- mid = low + ((high - low) / 2); // avoid overflow
-
- if (pArchive->pEntries[mid].fileNameLen < fileNameLen) {
- diffLen = pArchive->pEntries[mid].fileNameLen;
- } else {
- diffLen = fileNameLen;
- }
- diff = strncmp(pArchive->pEntries[mid].fileName, fileName,
- diffLen);
- if (diff == 0) {
- diff = pArchive->pEntries[mid].fileNameLen - fileNameLen;
- }
- if (diff < 0) {
- low = mid + 1;
- } else if (diff > 0) {
- high = mid - 1;
- } else {
- high = mid;
- break;
- }
- }
-
- unsigned int target = high + 1;
- assert(target <= i);
- if (target != i) {
- /* It belongs somewhere other than at the end of
- * the list. Make some room at [target].
- */
- memmove(pArchive->pEntries + target + 1,
- pArchive->pEntries + target,
- (i - target) * sizeof(ZipEntry));
- }
- pEntry = &pArchive->pEntries[target];
- } else {
- pEntry = &pArchive->pEntries[0];
- }
-#else
- pEntry = &pArchive->pEntries[i];
-#endif
-
- //LOGI("%d: localHdr=%d fnl=%d el=%d cl=%d\n",
- // i, localHdrOffset, fileNameLen, extraLen, commentLen);
-
- pEntry->fileNameLen = fileNameLen;
- pEntry->fileName = fileName;
-
- pEntry->compLen = get4LE(ptr + CENSIZ);
- pEntry->uncompLen = get4LE(ptr + CENLEN);
- pEntry->compression = get2LE(ptr + CENHOW);
- pEntry->modTime = get4LE(ptr + CENTIM);
- pEntry->crc32 = get4LE(ptr + CENCRC);
-
- /* These two are necessary for finding the mode of the file.
- */
- pEntry->versionMadeBy = get2LE(ptr + CENVEM);
- if ((pEntry->versionMadeBy & 0xff00) != 0 &&
- (pEntry->versionMadeBy & 0xff00) != CENVEM_UNIX)
- {
- LOGW("Incompatible \"version made by\": 0x%02x (at %d)\n",
- pEntry->versionMadeBy >> 8, i);
- goto bail;
- }
- pEntry->externalFileAttributes = get4LE(ptr + CENATX);
-
- // Perform pMap->addr + localHdrOffset, ensuring that it won't
- // overflow. This is needed because localHdrOffset is untrusted.
- if (!safe_add((uintptr_t *)&localHdr, (uintptr_t)pMap->addr,
- (uintptr_t)localHdrOffset)) {
- LOGW("Integer overflow adding in parseZipArchive\n");
- goto bail;
- }
- if ((uintptr_t)localHdr + LOCHDR >
- (uintptr_t)pMap->addr + pMap->length) {
- LOGW("Bad offset to local header: %d (at %d)\n", localHdrOffset, i);
- goto bail;
- }
- if (get4LE(localHdr) != LOCSIG) {
- LOGW("Missed a local header sig (at %d)\n", i);
- goto bail;
- }
- pEntry->offset = localHdrOffset + LOCHDR
- + get2LE(localHdr + LOCNAM) + get2LE(localHdr + LOCEXT);
- if (!safe_add(NULL, pEntry->offset, pEntry->compLen)) {
- LOGW("Integer overflow adding in parseZipArchive\n");
- goto bail;
- }
- if ((size_t)pEntry->offset + pEntry->compLen > pMap->length) {
- LOGW("Data ran off the end (at %d)\n", i);
- goto bail;
- }
-
-#if !SORT_ENTRIES
- /* Add to hash table; no need to lock here.
- * Can't do this now if we're sorting, because entries
- * will move around.
- */
- addEntryToHashTable(pArchive->pHash, pEntry);
-#endif
-
- //dumpEntry(pEntry);
- ptr += CENHDR + fileNameLen + extraLen + commentLen;
- }
-
-#if SORT_ENTRIES
- /* If we're sorting, we have to wait until all entries
- * are in their final places, otherwise the pointers will
- * probably point to the wrong things.
- */
- for (i = 0; i < numEntries; i++) {
- /* Add to hash table; no need to lock here.
- */
- addEntryToHashTable(pArchive->pHash, &pArchive->pEntries[i]);
- }
-#endif
-
- result = true;
-
-bail:
- if (!result) {
- mzHashTableFree(pArchive->pHash);
- pArchive->pHash = NULL;
- }
- return result;
-}
-
-/*
- * Open a Zip archive and scan out the contents.
- *
- * The easiest way to do this is to mmap() the whole thing and do the
- * traditional backward scan for central directory. Since the EOCD is
- * a relatively small bit at the end, we should end up only touching a
- * small set of pages.
- *
- * This will be called on non-Zip files, especially during startup, so
- * we don't want to be too noisy about failures. (Do we want a "quiet"
- * flag?)
- *
- * On success, we fill out the contents of "pArchive".
- */
-int mzOpenZipArchive(const char* fileName, ZipArchive* pArchive)
-{
- MemMapping map;
- int err;
-
- LOGV("Opening archive '%s' %p\n", fileName, pArchive);
-
- map.addr = NULL;
- memset(pArchive, 0, sizeof(*pArchive));
-
- pArchive->fd = open(fileName, O_RDONLY, 0);
- if (pArchive->fd < 0) {
- err = errno ? errno : -1;
- LOGV("Unable to open '%s': %s\n", fileName, strerror(err));
- goto bail;
- }
-
- if (sysMapFileInShmem(pArchive->fd, &map) != 0) {
- err = -1;
- LOGW("Map of '%s' failed\n", fileName);
- goto bail;
- }
-
- if (map.length < ENDHDR) {
- err = -1;
- LOGV("File '%s' too small to be zip (%zd)\n", fileName, map.length);
- goto bail;
- }
-
- if (!parseZipArchive(pArchive, &map)) {
- err = -1;
- LOGV("Parsing '%s' failed\n", fileName);
- goto bail;
- }
-
- err = 0;
- sysCopyMap(&pArchive->map, &map);
- map.addr = NULL;
-
-bail:
- if (err != 0)
- mzCloseZipArchive(pArchive);
- if (map.addr != NULL)
- sysReleaseShmem(&map);
- return err;
-}
-
-/*
- * Close a ZipArchive, closing the file and freeing the contents.
- *
- * NOTE: the ZipArchive may not have been fully created.
- */
-void mzCloseZipArchive(ZipArchive* pArchive)
-{
- LOGV("Closing archive %p\n", pArchive);
-
- if (pArchive->fd >= 0)
- close(pArchive->fd);
- if (pArchive->map.addr != NULL)
- sysReleaseShmem(&pArchive->map);
-
- free(pArchive->pEntries);
-
- mzHashTableFree(pArchive->pHash);
-
- pArchive->fd = -1;
- pArchive->pHash = NULL;
- pArchive->pEntries = NULL;
-}
-
-/*
- * Find a matching entry.
- *
- * Returns NULL if no matching entry found.
- */
-const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
- const char* entryName)
-{
- unsigned int itemHash = computeHash(entryName, strlen(entryName));
-
- return (const ZipEntry*)mzHashTableLookup(pArchive->pHash,
- itemHash, (char*) entryName, hashcmpZipName, false);
-}
-
-/*
- * Return true if the entry is a symbolic link.
- */
-bool mzIsZipEntrySymlink(const ZipEntry* pEntry)
-{
- if ((pEntry->versionMadeBy & 0xff00) == CENVEM_UNIX) {
- return S_ISLNK(pEntry->externalFileAttributes >> 16);
- }
- return false;
-}
-
-/* Call processFunction on the uncompressed data of a STORED entry.
- */
-static bool processStoredEntry(const ZipArchive *pArchive,
- const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
- void *cookie)
-{
- size_t bytesLeft = pEntry->compLen;
- while (bytesLeft > 0) {
- unsigned char buf[32 * 1024];
- ssize_t n;
- size_t count;
- bool ret;
-
- count = bytesLeft;
- if (count > sizeof(buf)) {
- count = sizeof(buf);
- }
- n = read(pArchive->fd, buf, count);
- if (n < 0 || (size_t)n != count) {
- LOGE("Can't read %zu bytes from zip file: %ld\n", count, n);
- return false;
- }
- ret = processFunction(buf, n, cookie);
- if (!ret) {
- return false;
- }
- bytesLeft -= count;
- }
- return true;
-}
-
-static bool processDeflatedEntry(const ZipArchive *pArchive,
- const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
- void *cookie)
-{
- long result = -1;
- unsigned char readBuf[32 * 1024];
- unsigned char procBuf[32 * 1024];
- z_stream zstream;
- int zerr;
- long compRemaining;
-
- compRemaining = pEntry->compLen;
-
- /*
- * Initialize the zlib stream.
- */
- memset(&zstream, 0, sizeof(zstream));
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.opaque = Z_NULL;
- zstream.next_in = NULL;
- zstream.avail_in = 0;
- zstream.next_out = (Bytef*) procBuf;
- zstream.avail_out = sizeof(procBuf);
- zstream.data_type = Z_UNKNOWN;
-
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
- zerr = inflateInit2(&zstream, -MAX_WBITS);
- if (zerr != Z_OK) {
- if (zerr == Z_VERSION_ERROR) {
- LOGE("Installed zlib is not compatible with linked version (%s)\n",
- ZLIB_VERSION);
- } else {
- LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
- }
- goto bail;
- }
-
- /*
- * Loop while we have data.
- */
- do {
- /* read as much as we can */
- if (zstream.avail_in == 0) {
- long getSize = (compRemaining > (long)sizeof(readBuf)) ?
- (long)sizeof(readBuf) : compRemaining;
- LOGVV("+++ reading %ld bytes (%ld left)\n",
- getSize, compRemaining);
-
- int cc = read(pArchive->fd, readBuf, getSize);
- if (cc != (int) getSize) {
- LOGW("inflate read failed (%d vs %ld)\n", cc, getSize);
- goto z_bail;
- }
-
- compRemaining -= getSize;
-
- zstream.next_in = readBuf;
- zstream.avail_in = getSize;
- }
-
- /* uncompress the data */
- zerr = inflate(&zstream, Z_NO_FLUSH);
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
- goto z_bail;
- }
-
- /* write when we're full or when we're done */
- if (zstream.avail_out == 0 ||
- (zerr == Z_STREAM_END && zstream.avail_out != sizeof(procBuf)))
- {
- long procSize = zstream.next_out - procBuf;
- LOGVV("+++ processing %d bytes\n", (int) procSize);
- bool ret = processFunction(procBuf, procSize, cookie);
- if (!ret) {
- LOGW("Process function elected to fail (in inflate)\n");
- goto z_bail;
- }
-
- zstream.next_out = procBuf;
- zstream.avail_out = sizeof(procBuf);
- }
- } while (zerr == Z_OK);
-
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
-
- // success!
- result = zstream.total_out;
-
-z_bail:
- inflateEnd(&zstream); /* free up any allocated structures */
-
-bail:
- if (result != pEntry->uncompLen) {
- if (result != -1) // error already shown?
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- result, pEntry->uncompLen);
- return false;
- }
- return true;
-}
-
-/*
- * 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)
-{
- bool ret = false;
- off_t oldOff;
-
- /* save current offset */
- oldOff = lseek(pArchive->fd, 0, SEEK_CUR);
-
- /* Seek to the beginning of the entry's compressed data. */
- lseek(pArchive->fd, pEntry->offset, SEEK_SET);
-
- switch (pEntry->compression) {
- case STORED:
- ret = processStoredEntry(pArchive, pEntry, processFunction, cookie);
- break;
- case DEFLATED:
- ret = processDeflatedEntry(pArchive, pEntry, processFunction, cookie);
- break;
- default:
- LOGE("Unsupported compression type %d for entry '%s'\n",
- pEntry->compression, pEntry->fileName);
- break;
- }
-
- /* restore file offset */
- lseek(pArchive->fd, oldOff, SEEK_SET);
- return ret;
-}
-
-static bool crcProcessFunction(const unsigned char *data, int dataLen,
- void *crc)
-{
- *(unsigned long *)crc = crc32(*(unsigned long *)crc, data, dataLen);
- return true;
-}
-
-/*
- * 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)
-{
- unsigned long crc;
- bool ret;
-
- crc = crc32(0L, Z_NULL, 0);
- ret = mzProcessZipEntryContents(pArchive, pEntry, crcProcessFunction,
- (void *)&crc);
- if (!ret) {
- LOGE("Can't calculate CRC for entry\n");
- return false;
- }
- if (crc != (unsigned long)pEntry->crc32) {
- LOGW("CRC for entry %.*s (0x%08lx) != expected (0x%08lx)\n",
- pEntry->fileNameLen, pEntry->fileName, crc, pEntry->crc32);
- return false;
- }
- return true;
-}
-
-typedef struct {
- char *buf;
- int bufLen;
-} CopyProcessArgs;
-
-static bool copyProcessFunction(const unsigned char *data, int dataLen,
- void *cookie)
-{
- CopyProcessArgs *args = (CopyProcessArgs *)cookie;
- if (dataLen <= args->bufLen) {
- memcpy(args->buf, data, dataLen);
- args->buf += dataLen;
- args->bufLen -= dataLen;
- return true;
- }
- return false;
-}
-
-/*
- * Read an entry into a buffer allocated by the caller.
- */
-bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
- char *buf, int bufLen)
-{
- CopyProcessArgs args;
- bool ret;
-
- args.buf = buf;
- args.bufLen = bufLen;
- ret = mzProcessZipEntryContents(pArchive, pEntry, copyProcessFunction,
- (void *)&args);
- if (!ret) {
- LOGE("Can't extract entry to buffer.\n");
- return false;
- }
- return true;
-}
-
-static bool writeProcessFunction(const unsigned char *data, int dataLen,
- void *fd)
-{
- ssize_t n = write((int)fd, data, dataLen);
- if (n != dataLen) {
- LOGE("Can't write %d bytes (only %ld) from zip file: %s\n",
- dataLen, n, strerror(errno));
- return false;
- }
- return true;
-}
-
-/*
- * Uncompress "pEntry" in "pArchive" to "fd" at the current offset.
- */
-bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
- const ZipEntry *pEntry, int fd)
-{
- bool ret = mzProcessZipEntryContents(pArchive, pEntry, writeProcessFunction,
- (void *)fd);
- if (!ret) {
- LOGE("Can't extract entry to file.\n");
- return false;
- }
- return true;
-}
-
-/* Helper state to make path translation easier and less malloc-happy.
- */
-typedef struct {
- const char *targetDir;
- const char *zipDir;
- char *buf;
- int targetDirLen;
- int zipDirLen;
- int bufLen;
-} MzPathHelper;
-
-/* Given the values of targetDir and zipDir in the helper,
- * return the target filename of the provided entry.
- * The helper must be initialized first.
- */
-static const char *targetEntryPath(MzPathHelper *helper, ZipEntry *pEntry)
-{
- int needLen;
- bool firstTime = (helper->buf == NULL);
-
- /* target file <-- targetDir + / + entry[zipDirLen:]
- */
- needLen = helper->targetDirLen + 1 +
- pEntry->fileNameLen - helper->zipDirLen + 1;
- if (needLen > helper->bufLen) {
- char *newBuf;
-
- needLen *= 2;
- newBuf = (char *)realloc(helper->buf, needLen);
- if (newBuf == NULL) {
- return NULL;
- }
- helper->buf = newBuf;
- helper->bufLen = needLen;
- }
-
- /* Every path will start with the target path and a slash.
- */
- if (firstTime) {
- char *p = helper->buf;
- memcpy(p, helper->targetDir, helper->targetDirLen);
- p += helper->targetDirLen;
- if (p == helper->buf || p[-1] != '/') {
- helper->targetDirLen += 1;
- *p++ = '/';
- }
- }
-
- /* Replace the custom part of the path with the appropriate
- * part of the entry's path.
- */
- char *epath = helper->buf + helper->targetDirLen;
- memcpy(epath, pEntry->fileName + helper->zipDirLen,
- pEntry->fileNameLen - helper->zipDirLen);
- epath += pEntry->fileNameLen - helper->zipDirLen;
- *epath = '\0';
-
- return helper->buf;
-}
-
-/*
- * 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
- *
- * Returns true on success, false on failure.
- */
-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)
-{
- if (zipDir[0] == '/') {
- LOGE("mzExtractRecursive(): zipDir must be a relative path.\n");
- return false;
- }
- if (targetDir[0] != '/') {
- LOGE("mzExtractRecursive(): targetDir must be an absolute path.\n");
- return false;
- }
-
- unsigned int zipDirLen;
- char *zpath;
-
- zipDirLen = strlen(zipDir);
- zpath = (char *)malloc(zipDirLen + 2);
- if (zpath == NULL) {
- LOGE("Can't allocate %d bytes for zip path\n", zipDirLen + 2);
- return false;
- }
- /* If zipDir is empty, we'll extract the entire zip file.
- * Otherwise, canonicalize the path.
- */
- if (zipDirLen > 0) {
- /* Make sure there's (hopefully, exactly one) slash at the
- * end of the path. This way we don't need to worry about
- * accidentally extracting "one/twothree" when a path like
- * "one/two" is specified.
- */
- memcpy(zpath, zipDir, zipDirLen);
- if (zpath[zipDirLen-1] != '/') {
- zpath[zipDirLen++] = '/';
- }
- }
- zpath[zipDirLen] = '\0';
-
- /* Set up the helper structure that we'll use to assemble paths.
- */
- MzPathHelper helper;
- helper.targetDir = targetDir;
- helper.targetDirLen = strlen(helper.targetDir);
- helper.zipDir = zpath;
- helper.zipDirLen = strlen(helper.zipDir);
- helper.buf = NULL;
- helper.bufLen = 0;
-
- /* Walk through the entries and extract anything whose path begins
- * with zpath.
-//TODO: since the entries are sorted, binary search for the first match
-// and stop after the first non-match.
- */
- unsigned int i;
- bool seenMatch = false;
- int ok = true;
- for (i = 0; i < pArchive->numEntries; i++) {
- ZipEntry *pEntry = pArchive->pEntries + i;
- if (pEntry->fileNameLen < zipDirLen) {
-//TODO: look out for a single empty directory entry that matches zpath, but
-// missing the trailing slash. Most zip files seem to include
-// the trailing slash, but I think it's legal to leave it off.
-// e.g., zpath "a/b/", entry "a/b", with no children of the entry.
- /* No chance of matching.
- */
-#if SORT_ENTRIES
- if (seenMatch) {
- /* Since the entries are sorted, we can give up
- * on the first mismatch after the first match.
- */
- break;
- }
-#endif
- continue;
- }
- /* If zpath is empty, this strncmp() will match everything,
- * which is what we want.
- */
- if (strncmp(pEntry->fileName, zpath, zipDirLen) != 0) {
-#if SORT_ENTRIES
- if (seenMatch) {
- /* Since the entries are sorted, we can give up
- * on the first mismatch after the first match.
- */
- break;
- }
-#endif
- continue;
- }
- /* This entry begins with zipDir, so we'll extract it.
- */
- seenMatch = true;
-
- /* Find the target location of the entry.
- */
- const char *targetFile = targetEntryPath(&helper, pEntry);
- if (targetFile == NULL) {
- LOGE("Can't assemble target path for \"%.*s\"\n",
- pEntry->fileNameLen, pEntry->fileName);
- ok = false;
- break;
- }
-
- /* With DRY_RUN set, invoke the callback but don't do anything else.
- */
- if (flags & MZ_EXTRACT_DRY_RUN) {
- if (callback != NULL) callback(targetFile, cookie);
- continue;
- }
-
- /* Create the file or directory.
- */
-#define UNZIP_DIRMODE 0755
-#define UNZIP_FILEMODE 0644
- if (pEntry->fileName[pEntry->fileNameLen-1] == '/') {
- if (!(flags & MZ_EXTRACT_FILES_ONLY)) {
- int ret = dirCreateHierarchy(
- targetFile, UNZIP_DIRMODE, timestamp, false);
- if (ret != 0) {
- LOGE("Can't create containing directory for \"%s\": %s\n",
- targetFile, strerror(errno));
- ok = false;
- break;
- }
- LOGD("Extracted dir \"%s\"\n", targetFile);
- }
- } else {
- /* This is not a directory. First, make sure that
- * the containing directory exists.
- */
- int ret = dirCreateHierarchy(
- targetFile, UNZIP_DIRMODE, timestamp, true);
- if (ret != 0) {
- LOGE("Can't create containing directory for \"%s\": %s\n",
- targetFile, strerror(errno));
- ok = false;
- break;
- }
-
- /* With FILES_ONLY set, we need to ignore metadata entirely,
- * so treat symlinks as regular files.
- */
- if (!(flags & MZ_EXTRACT_FILES_ONLY) && mzIsZipEntrySymlink(pEntry)) {
- /* The entry is a symbolic link.
- * The relative target of the symlink is in the
- * data section of this entry.
- */
- if (pEntry->uncompLen == 0) {
- LOGE("Symlink entry \"%s\" has no target\n",
- targetFile);
- ok = false;
- break;
- }
- char *linkTarget = malloc(pEntry->uncompLen + 1);
- if (linkTarget == NULL) {
- ok = false;
- break;
- }
- ok = mzReadZipEntry(pArchive, pEntry, linkTarget,
- pEntry->uncompLen);
- if (!ok) {
- LOGE("Can't read symlink target for \"%s\"\n",
- targetFile);
- free(linkTarget);
- break;
- }
- linkTarget[pEntry->uncompLen] = '\0';
-
- /* Make the link.
- */
- ret = symlink(linkTarget, targetFile);
- if (ret != 0) {
- LOGE("Can't symlink \"%s\" to \"%s\": %s\n",
- targetFile, linkTarget, strerror(errno));
- free(linkTarget);
- ok = false;
- break;
- }
- LOGD("Extracted symlink \"%s\" -> \"%s\"\n",
- targetFile, linkTarget);
- free(linkTarget);
- } else {
- /* The entry is a regular file.
- * Open the target for writing.
- */
- int fd = creat(targetFile, UNZIP_FILEMODE);
- if (fd < 0) {
- LOGE("Can't create target file \"%s\": %s\n",
- targetFile, strerror(errno));
- ok = false;
- break;
- }
-
- bool ok = mzExtractZipEntryToFile(pArchive, pEntry, fd);
- close(fd);
- if (!ok) {
- LOGE("Error extracting \"%s\"\n", targetFile);
- ok = false;
- break;
- }
-
- if (timestamp != NULL && utime(targetFile, timestamp)) {
- LOGE("Error touching \"%s\"\n", targetFile);
- ok = false;
- break;
- }
-
- LOGD("Extracted file \"%s\"\n", targetFile);
- }
- }
-
- if (callback != NULL) callback(targetFile, cookie);
- }
-
- free(helper.buf);
- free(zpath);
-
- return ok;
-}
diff --git a/minzip/Zip.h b/minzip/Zip.h
deleted file mode 100644
index 1c1df2f..0000000
--- a/minzip/Zip.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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*/
diff --git a/minzip/inline_magic.h b/minzip/inline_magic.h
deleted file mode 100644
index 8c185e1..0000000
--- a/minzip/inline_magic.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINZIP_INLINE_MAGIC_H_
-#define MINZIP_INLINE_MAGIC_H_
-
-#ifndef MINZIP_GENERATE_INLINES
-#define INLINE extern __inline__
-#else
-#define INLINE
-#endif
-
-#endif // MINZIP_INLINE_MAGIC_H_