diff options
author | Mathias Agopian <mathias@google.com> | 2013-05-06 20:20:34 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-05-07 17:09:46 -0700 |
commit | 1f5762e646bed2290934280464832782766ee68e (patch) | |
tree | 123bcdf3ba4c98f885631b02bb90803b7885e438 /include/androidfw | |
parent | 9f3e1175657425115e863fdb256b83cadedc33e9 (diff) | |
download | frameworks_base-1f5762e646bed2290934280464832782766ee68e.zip frameworks_base-1f5762e646bed2290934280464832782766ee68e.tar.gz frameworks_base-1f5762e646bed2290934280464832782766ee68e.tar.bz2 |
libutils clean-up
Change-Id: I11ee943da23a66828455a9770fc3c5ceb4bbcaa9
Diffstat (limited to 'include/androidfw')
-rw-r--r-- | include/androidfw/AssetDir.h | 2 | ||||
-rw-r--r-- | include/androidfw/AssetManager.h | 2 | ||||
-rw-r--r-- | include/androidfw/ZipFileCRO.h | 61 | ||||
-rw-r--r-- | include/androidfw/ZipFileRO.h | 262 | ||||
-rw-r--r-- | include/androidfw/ZipUtils.h | 67 | ||||
-rw-r--r-- | include/androidfw/misc.h | 49 |
6 files changed, 441 insertions, 2 deletions
diff --git a/include/androidfw/AssetDir.h b/include/androidfw/AssetDir.h index abf8a35..bd89d7d 100644 --- a/include/androidfw/AssetDir.h +++ b/include/androidfw/AssetDir.h @@ -20,10 +20,10 @@ #ifndef __LIBS_ASSETDIR_H #define __LIBS_ASSETDIR_H +#include <androidfw/misc.h> #include <utils/String8.h> #include <utils/Vector.h> #include <utils/SortedVector.h> -#include <utils/misc.h> #include <sys/types.h> namespace android { diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h index d153c31..d95b45e 100644 --- a/include/androidfw/AssetManager.h +++ b/include/androidfw/AssetManager.h @@ -22,13 +22,13 @@ #include <androidfw/Asset.h> #include <androidfw/AssetDir.h> +#include <androidfw/ZipFileRO.h> #include <utils/KeyedVector.h> #include <utils/SortedVector.h> #include <utils/String16.h> #include <utils/String8.h> #include <utils/threads.h> #include <utils/Vector.h> -#include <utils/ZipFileRO.h> /* * Native-app access is via the opaque typedef struct AAssetManager in the C namespace. diff --git a/include/androidfw/ZipFileCRO.h b/include/androidfw/ZipFileCRO.h new file mode 100644 index 0000000..3e42a95 --- /dev/null +++ b/include/androidfw/ZipFileCRO.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 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. + */ + +// +// C API for ead-only access to Zip archives, with minimal heap allocation. +// +#ifndef __LIBS_ZIPFILECRO_H +#define __LIBS_ZIPFILECRO_H + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <utils/Compat.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Trivial typedef to ensure that ZipFileCRO is not treated as a simple integer. + */ +typedef void* ZipFileCRO; + +/* + * Trivial typedef to ensure that ZipEntryCRO is not treated as a simple + * integer. We use NULL to indicate an invalid value. + */ +typedef void* ZipEntryCRO; + +extern ZipFileCRO ZipFileXRO_open(const char* path); + +extern void ZipFileCRO_destroy(ZipFileCRO zip); + +extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip, + const char* fileName); + +extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry, + int* pMethod, size_t* pUncompLen, + size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32); + +extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd); + +#ifdef __cplusplus +} +#endif + +#endif /*__LIBS_ZIPFILECRO_H*/ diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h new file mode 100644 index 0000000..547e36a --- /dev/null +++ b/include/androidfw/ZipFileRO.h @@ -0,0 +1,262 @@ +/* + * 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. + */ + +/* + * Read-only access to Zip archives, with minimal heap allocation. + * + * This is similar to the more-complete ZipFile class, but no attempt + * has been made to make them interchangeable. This class operates under + * a very different set of assumptions and constraints. + * + * One such assumption is that if you're getting file descriptors for + * use with this class as a child of a fork() operation, you must be on + * a pread() to guarantee correct operation. This is because pread() can + * atomically read at a file offset without worrying about a lock around an + * lseek() + read() pair. + */ +#ifndef __LIBS_ZIPFILERO_H +#define __LIBS_ZIPFILERO_H + +#include <utils/Compat.h> +#include <utils/Errors.h> +#include <utils/FileMap.h> +#include <utils/threads.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> + +namespace android { + +/* + * Trivial typedef to ensure that ZipEntryRO is not treated as a simple + * integer. We use NULL to indicate an invalid value. + */ +typedef void* ZipEntryRO; + +/* + * Open a Zip archive for reading. + * + * We want "open" and "find entry by name" to be fast operations, and we + * want to use as little memory as possible. We memory-map the file, + * and load a hash table with pointers to the filenames (which aren't + * null-terminated). The other fields are at a fixed offset from the + * filename, so we don't need to extract those (but we do need to byte-read + * and endian-swap them every time we want them). + * + * To speed comparisons when doing a lookup by name, we could make the mapping + * "private" (copy-on-write) and null-terminate the filenames after verifying + * the record structure. However, this requires a private mapping of + * every page that the Central Directory touches. Easier to tuck a copy + * of the string length into the hash table entry. + * + * NOTE: If this is used on file descriptors inherited from a fork() operation, + * you must be on a platform that implements pread() to guarantee correctness + * on the shared file descriptors. + */ +class ZipFileRO { +public: + ZipFileRO() + : mFd(-1), mFileName(NULL), mFileLength(-1), + mDirectoryMap(NULL), + mNumEntries(-1), mDirectoryOffset(-1), + mHashTableSize(-1), mHashTable(NULL) + {} + + ~ZipFileRO(); + + /* + * Open an archive. + */ + status_t open(const char* zipFileName); + + /* + * Find an entry, by name. Returns the entry identifier, or NULL if + * not found. + * + * If two entries have the same name, one will be chosen at semi-random. + */ + ZipEntryRO findEntryByName(const char* fileName) const; + + /* + * Return the #of entries in the Zip archive. + */ + int getNumEntries(void) const { + return mNumEntries; + } + + /* + * Return the Nth entry. Zip file entries are not stored in sorted + * order, and updated entries may appear at the end, so anyone walking + * the archive needs to avoid making ordering assumptions. We take + * that further by returning the Nth non-empty entry in the hash table + * rather than the Nth entry in the archive. + * + * Valid values are [0..numEntries). + * + * [This is currently O(n). If it needs to be fast we can allocate an + * additional data structure or provide an iterator interface.] + */ + ZipEntryRO findEntryByIndex(int idx) const; + + /* + * Copy the filename into the supplied buffer. Returns 0 on success, + * -1 if "entry" is invalid, or the filename length if it didn't fit. The + * length, and the returned string, include the null-termination. + */ + int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const; + + /* + * Get the vital stats for an entry. Pass in NULL pointers for anything + * you don't need. + * + * "*pOffset" holds the Zip file offset of the entry's data. + * + * Returns "false" if "entry" is bogus or if the data in the Zip file + * appears to be bad. + */ + bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen, + size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const; + + /* + * Create a new FileMap object that maps a subset of the archive. For + * an uncompressed entry this effectively provides a pointer to the + * actual data, for a compressed entry this provides the input buffer + * for inflate(). + */ + FileMap* createEntryFileMap(ZipEntryRO entry) const; + + /* + * Uncompress the data into a buffer. Depending on the compression + * format, this is either an "inflate" operation or a memcpy. + * + * Use "uncompLen" from getEntryInfo() to determine the required + * buffer size. + * + * Returns "true" on success. + */ + bool uncompressEntry(ZipEntryRO entry, void* buffer) const; + + /* + * Uncompress the data to an open file descriptor. + */ + bool uncompressEntry(ZipEntryRO entry, int fd) const; + + /* Zip compression methods we support */ + enum { + kCompressStored = 0, // no compression + kCompressDeflated = 8, // standard deflate + }; + + /* + * Utility function: uncompress deflated data, buffer to buffer. + */ + static bool inflateBuffer(void* outBuf, const void* inBuf, + size_t uncompLen, size_t compLen); + + /* + * Utility function: uncompress deflated data, buffer to fd. + */ + static bool inflateBuffer(int fd, const void* inBuf, + size_t uncompLen, size_t compLen); + + /* + * Utility function to convert ZIP's time format to a timespec struct. + */ + static inline void zipTimeToTimespec(long when, struct tm* timespec) { + const long date = when >> 16; + timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980 + timespec->tm_mon = (date >> 5) & 0x0F; + timespec->tm_mday = date & 0x1F; + + timespec->tm_hour = (when >> 11) & 0x1F; + timespec->tm_min = (when >> 5) & 0x3F; + timespec->tm_sec = (when & 0x1F) << 1; + } + + /* + * Some basic functions for raw data manipulation. "LE" means + * Little Endian. + */ + static inline unsigned short get2LE(const unsigned char* buf) { + return buf[0] | (buf[1] << 8); + } + static inline unsigned long get4LE(const unsigned char* buf) { + return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + } + +private: + /* these are private and not defined */ + ZipFileRO(const ZipFileRO& src); + ZipFileRO& operator=(const ZipFileRO& src); + + /* locate and parse the central directory */ + bool mapCentralDirectory(void); + + /* parse the archive, prepping internal structures */ + bool parseZipArchive(void); + + /* add a new entry to the hash table */ + void addToHash(const char* str, int strLen, unsigned int hash); + + /* compute string hash code */ + static unsigned int computeHash(const char* str, int len); + + /* convert a ZipEntryRO back to a hash table index */ + int entryToIndex(const ZipEntryRO entry) const; + + /* + * One entry in the hash table. + */ + typedef struct HashEntry { + const char* name; + unsigned short nameLen; + //unsigned int hash; + } HashEntry; + + /* open Zip archive */ + int mFd; + + /* Lock for handling the file descriptor (seeks, etc) */ + mutable Mutex mFdLock; + + /* zip file name */ + char* mFileName; + + /* length of file */ + size_t mFileLength; + + /* mapped file */ + FileMap* mDirectoryMap; + + /* number of entries in the Zip archive */ + int mNumEntries; + + /* CD directory offset in the Zip archive */ + off64_t mDirectoryOffset; + + /* + * We know how many entries are in the Zip archive, so we have a + * fixed-size hash table. We probe for an empty slot. + */ + int mHashTableSize; + HashEntry* mHashTable; +}; + +}; // namespace android + +#endif /*__LIBS_ZIPFILERO_H*/ diff --git a/include/androidfw/ZipUtils.h b/include/androidfw/ZipUtils.h new file mode 100644 index 0000000..42c42b6 --- /dev/null +++ b/include/androidfw/ZipUtils.h @@ -0,0 +1,67 @@ +/* + * 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. + */ + +// +// Miscellaneous zip/gzip utility functions. +// +#ifndef __LIBS_ZIPUTILS_H +#define __LIBS_ZIPUTILS_H + +#include <stdio.h> + +namespace android { + +/* + * Container class for utility functions, primarily for namespace reasons. + */ +class ZipUtils { +public: + /* + * General utility function for uncompressing "deflate" data from a file + * to a buffer. + */ + static bool inflateToBuffer(int fd, void* buf, long uncompressedLen, + long compressedLen); + static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen, + long compressedLen); + + /* + * Someday we might want to make this generic and handle bzip2 ".bz2" + * files too. + * + * We could declare gzip to be a sub-class of zip that has exactly + * one always-compressed entry, but we currently want to treat Zip + * and gzip as distinct, so there's no value. + * + * The zlib library has some gzip utilities, but it has no interface + * for extracting the uncompressed length of the file (you do *not* + * want to gzseek to the end). + * + * Pass in a seeked file pointer for the gzip file. If this is a gzip + * file, we set our return values appropriately and return "true" with + * the file seeked to the start of the compressed data. + */ + static bool examineGzip(FILE* fp, int* pCompressionMethod, + long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32); + +private: + ZipUtils() {} + ~ZipUtils() {} +}; + +}; // namespace android + +#endif /*__LIBS_ZIPUTILS_H*/ diff --git a/include/androidfw/misc.h b/include/androidfw/misc.h new file mode 100644 index 0000000..5a5a0e2 --- /dev/null +++ b/include/androidfw/misc.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2005 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 <sys/types.h> + +// +// Handy utility functions and portability code. +// +#ifndef _LIBS_ANDROID_FW_MISC_H +#define _LIBS_ANDROID_FW_MISC_H + +namespace android { + +/* + * Some utility functions for working with files. These could be made + * part of a "File" class. + */ +typedef enum FileType { + kFileTypeUnknown = 0, + kFileTypeNonexistent, // i.e. ENOENT + kFileTypeRegular, + kFileTypeDirectory, + kFileTypeCharDev, + kFileTypeBlockDev, + kFileTypeFifo, + kFileTypeSymlink, + kFileTypeSocket, +} FileType; +/* get the file's type; follows symlinks */ +FileType getFileType(const char* fileName); +/* get the file's modification date; returns -1 w/errno set on failure */ +time_t getFileModDate(const char* fileName); + +}; // namespace android + +#endif // _LIBS_ANDROID_FW_MISC_H |