This source file includes following definitions.
- ZipOpenFunc
- FdOpenFileFunc
- CloseFileFunc
- FillFdOpenFileFunc
- HandleOpenFileFunc
- OpenZipBuffer
- ReadZipBuffer
- WriteZipBuffer
- GetOffsetOfZipBuffer
- SeekZipBuffer
- CloseZipBuffer
- GetErrorOfZipBuffer
- OpenForUnzipping
- OpenFdForUnzipping
- OpenHandleForUnzipping
- PreprareMemoryForUnzipping
- OpenForZipping
- OpenFdForZipping
#include "third_party/zlib/google/zip.h"
#include <algorithm>
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#if defined(USE_SYSTEM_MINIZIP)
#include <minizip/ioapi.h>
#include <minizip/unzip.h>
#include <minizip/zip.h>
#else
#include "third_party/zlib/contrib/minizip/unzip.h"
#include "third_party/zlib/contrib/minizip/zip.h"
#if defined(OS_WIN)
#include "third_party/zlib/contrib/minizip/iowin32.h"
#elif defined(OS_POSIX)
#include "third_party/zlib/contrib/minizip/ioapi.h"
#endif
#endif
namespace {
#if defined(OS_WIN)
typedef struct {
HANDLE hf;
int error;
} WIN32FILE_IOWIN;
void* ZipOpenFunc(void *opaque, const char* filename, int mode) {
DWORD desired_access, creation_disposition;
DWORD share_mode, flags_and_attributes;
HANDLE file = 0;
void* ret = NULL;
desired_access = share_mode = flags_and_attributes = 0;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) {
desired_access = GENERIC_READ;
creation_disposition = OPEN_EXISTING;
share_mode = FILE_SHARE_READ;
} else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) {
desired_access = GENERIC_WRITE | GENERIC_READ;
creation_disposition = OPEN_EXISTING;
} else if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
desired_access = GENERIC_WRITE | GENERIC_READ;
creation_disposition = CREATE_ALWAYS;
}
base::string16 filename16 = base::UTF8ToUTF16(filename);
if ((filename != NULL) && (desired_access != 0)) {
file = CreateFile(filename16.c_str(), desired_access, share_mode,
NULL, creation_disposition, flags_and_attributes, NULL);
}
if (file == INVALID_HANDLE_VALUE)
file = NULL;
if (file != NULL) {
WIN32FILE_IOWIN file_ret;
file_ret.hf = file;
file_ret.error = 0;
ret = malloc(sizeof(WIN32FILE_IOWIN));
if (ret == NULL)
CloseHandle(file);
else
*(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret;
}
return ret;
}
#endif
#if defined(OS_POSIX)
void* FdOpenFileFunc(void* opaque, const char* filename, int mode) {
FILE* file = NULL;
const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename != NULL) && (mode_fopen != NULL))
file = fdopen(*static_cast<int*>(opaque), mode_fopen);
return file;
}
int CloseFileFunc(void* opaque, void* stream) {
fflush(static_cast<FILE*>(stream));
free(opaque);
return 0;
}
void FillFdOpenFileFunc(zlib_filefunc_def* pzlib_filefunc_def, int fd) {
fill_fopen_filefunc(pzlib_filefunc_def);
pzlib_filefunc_def->zopen_file = FdOpenFileFunc;
pzlib_filefunc_def->zclose_file = CloseFileFunc;
int* ptr_fd = static_cast<int*>(malloc(sizeof(fd)));
*ptr_fd = fd;
pzlib_filefunc_def->opaque = ptr_fd;
}
#endif
#if defined(OS_WIN)
void* HandleOpenFileFunc(void* opaque, const char* filename, int mode) {
WIN32FILE_IOWIN file_ret;
file_ret.hf = static_cast<HANDLE>(opaque);
file_ret.error = 0;
if (file_ret.hf == INVALID_HANDLE_VALUE)
return NULL;
void* ret = malloc(sizeof(WIN32FILE_IOWIN));
if (ret != NULL)
*(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret;
return ret;
}
#endif
struct ZipBuffer {
const char* data;
size_t length;
size_t offset;
};
void* OpenZipBuffer(void* opaque, const char* , int mode) {
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) != ZLIB_FILEFUNC_MODE_READ) {
NOTREACHED();
return NULL;
}
ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
if (!buffer || !buffer->data || !buffer->length)
return NULL;
buffer->offset = 0;
return opaque;
}
uLong ReadZipBuffer(void* opaque, void* , void* buf, uLong size) {
ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
DCHECK_LE(buffer->offset, buffer->length);
size_t remaining_bytes = buffer->length - buffer->offset;
if (!buffer || !buffer->data || !remaining_bytes)
return 0;
size = std::min(size, static_cast<uLong>(remaining_bytes));
memcpy(buf, &buffer->data[buffer->offset], size);
buffer->offset += size;
return size;
}
uLong WriteZipBuffer(void* ,
void* ,
const void* ,
uLong ) {
NOTREACHED();
return 0;
}
long GetOffsetOfZipBuffer(void* opaque, void* ) {
ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
if (!buffer)
return -1;
return static_cast<long>(buffer->offset);
}
long SeekZipBuffer(void* opaque, void* , uLong offset, int origin) {
ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
if (!buffer)
return -1;
if (origin == ZLIB_FILEFUNC_SEEK_CUR) {
buffer->offset = std::min(buffer->offset + static_cast<size_t>(offset),
buffer->length);
return 0;
}
if (origin == ZLIB_FILEFUNC_SEEK_END) {
buffer->offset = (buffer->length > offset) ? buffer->length - offset : 0;
return 0;
}
if (origin == ZLIB_FILEFUNC_SEEK_SET) {
buffer->offset = std::min(buffer->length, static_cast<size_t>(offset));
return 0;
}
NOTREACHED();
return -1;
}
int CloseZipBuffer(void* opaque, void* ) {
if (opaque)
free(opaque);
return 0;
}
int GetErrorOfZipBuffer(void* , void* ) {
return 0;
}
}
namespace zip {
namespace internal {
unzFile OpenForUnzipping(const std::string& file_name_utf8) {
zlib_filefunc_def* zip_func_ptrs = NULL;
#if defined(OS_WIN)
zlib_filefunc_def zip_funcs;
fill_win32_filefunc(&zip_funcs);
zip_funcs.zopen_file = ZipOpenFunc;
zip_func_ptrs = &zip_funcs;
#endif
return unzOpen2(file_name_utf8.c_str(), zip_func_ptrs);
}
#if defined(OS_POSIX)
unzFile OpenFdForUnzipping(int zip_fd) {
zlib_filefunc_def zip_funcs;
FillFdOpenFileFunc(&zip_funcs, zip_fd);
return unzOpen2("fd", &zip_funcs);
}
#endif
#if defined(OS_WIN)
unzFile OpenHandleForUnzipping(HANDLE zip_handle) {
zlib_filefunc_def zip_funcs;
fill_win32_filefunc(&zip_funcs);
zip_funcs.zopen_file = HandleOpenFileFunc;
zip_funcs.opaque = zip_handle;
return unzOpen2("fd", &zip_funcs);
}
#endif
unzFile PreprareMemoryForUnzipping(const std::string& data) {
if (data.empty())
return NULL;
ZipBuffer* buffer = static_cast<ZipBuffer*>(malloc(sizeof(ZipBuffer)));
if (!buffer)
return NULL;
buffer->data = data.data();
buffer->length = data.length();
buffer->offset = 0;
zlib_filefunc_def zip_functions;
zip_functions.zopen_file = OpenZipBuffer;
zip_functions.zread_file = ReadZipBuffer;
zip_functions.zwrite_file = WriteZipBuffer;
zip_functions.ztell_file = GetOffsetOfZipBuffer;
zip_functions.zseek_file = SeekZipBuffer;
zip_functions.zclose_file = CloseZipBuffer;
zip_functions.zerror_file = GetErrorOfZipBuffer;
zip_functions.opaque = static_cast<void*>(buffer);
return unzOpen2(NULL, &zip_functions);
}
zipFile OpenForZipping(const std::string& file_name_utf8, int append_flag) {
zlib_filefunc_def* zip_func_ptrs = NULL;
#if defined(OS_WIN)
zlib_filefunc_def zip_funcs;
fill_win32_filefunc(&zip_funcs);
zip_funcs.zopen_file = ZipOpenFunc;
zip_func_ptrs = &zip_funcs;
#endif
return zipOpen2(file_name_utf8.c_str(),
append_flag,
NULL,
zip_func_ptrs);
}
#if defined(OS_POSIX)
zipFile OpenFdForZipping(int zip_fd, int append_flag) {
zlib_filefunc_def zip_funcs;
FillFdOpenFileFunc(&zip_funcs, zip_fd);
return zipOpen2("fd", append_flag, NULL, &zip_funcs);
}
#endif
}
}