2013-10-03 17:29:39 +00:00
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
|
2013-12-03 13:16:03 +00:00
|
|
|
typedef void* ZipArchiveHandle;
|
|
|
|
|
2013-10-03 17:29:39 +00:00
|
|
|
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.
|
|
|
|
*
|
2013-12-03 13:16:03 +00:00
|
|
|
* Implemented as a thin wrapper over system/core/libziparchive.
|
|
|
|
*
|
|
|
|
* "open" and "find entry by name" are fast operations and use as little
|
|
|
|
* memory as possible.
|
2013-10-03 17:29:39 +00:00
|
|
|
*
|
2013-12-03 13:16:03 +00:00
|
|
|
* We also support fast iteration over all entries in the file (with a
|
|
|
|
* stable, but unspecified iteration order).
|
2013-10-03 17:29:39 +00:00
|
|
|
*
|
|
|
|
* 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:
|
2013-12-03 13:16:03 +00:00
|
|
|
/* Zip compression methods we support */
|
|
|
|
enum {
|
|
|
|
kCompressStored = 0, // no compression
|
|
|
|
kCompressDeflated = 8, // standard deflate
|
|
|
|
};
|
2013-10-03 17:29:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open an archive.
|
|
|
|
*/
|
2013-12-03 13:16:03 +00:00
|
|
|
static ZipFileRO* open(const char* zipFileName);
|
2013-10-03 17:29:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Find an entry, by name. Returns the entry identifier, or NULL if
|
|
|
|
* not found.
|
|
|
|
*/
|
2013-12-03 13:16:03 +00:00
|
|
|
ZipEntryRO findEntryByName(const char* entryName) const;
|
|
|
|
|
2013-10-03 17:29:39 +00:00
|
|
|
|
|
|
|
/*
|
2013-12-03 13:16:03 +00:00
|
|
|
* Start iterating over the list of entries in the zip file. Requires
|
|
|
|
* a matching call to endIteration with the same cookie.
|
2013-10-03 17:29:39 +00:00
|
|
|
*/
|
2013-12-03 13:16:03 +00:00
|
|
|
bool startIteration(void** cookie);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the next entry in iteration order, or NULL if there are no more
|
|
|
|
* entries in this archive.
|
|
|
|
*/
|
|
|
|
ZipEntryRO nextEntry(void* cookie);
|
|
|
|
|
|
|
|
void endIteration(void* cookie);
|
|
|
|
|
|
|
|
void releaseEntry(ZipEntryRO entry) const;
|
2013-10-03 17:29:39 +00:00
|
|
|
|
|
|
|
/*
|
2013-12-03 13:16:03 +00:00
|
|
|
* Return the #of entries in the Zip archive.
|
2013-10-03 17:29:39 +00:00
|
|
|
*/
|
2013-12-03 13:16:03 +00:00
|
|
|
int getNumEntries();
|
2013-10-03 17:29:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-12-03 13:16:03 +00:00
|
|
|
bool uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const;
|
2013-10-03 17:29:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Uncompress the data to an open file descriptor.
|
|
|
|
*/
|
|
|
|
bool uncompressEntry(ZipEntryRO entry, int fd) const;
|
|
|
|
|
2013-12-03 13:16:03 +00:00
|
|
|
~ZipFileRO();
|
2013-10-03 17:29:39 +00:00
|
|
|
|
|
|
|
private:
|
2013-12-03 13:16:03 +00:00
|
|
|
/* these are private and not defined */
|
2013-10-03 17:29:39 +00:00
|
|
|
ZipFileRO(const ZipFileRO& src);
|
|
|
|
ZipFileRO& operator=(const ZipFileRO& src);
|
|
|
|
|
2013-12-03 13:16:03 +00:00
|
|
|
ZipFileRO(ZipArchiveHandle handle, char* fileName) : mHandle(handle),
|
|
|
|
mFileName(fileName)
|
|
|
|
{
|
|
|
|
}
|
2013-10-03 17:29:39 +00:00
|
|
|
|
2013-12-03 13:16:03 +00:00
|
|
|
const ZipArchiveHandle mHandle;
|
|
|
|
char* mFileName;
|
2013-10-03 17:29:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}; // namespace android
|
|
|
|
|
|
|
|
#endif /*__LIBS_ZIPFILERO_H*/
|