Hack unicode support into libzip

This commit is contained in:
Henrik Rydgard 2013-11-20 19:38:23 +01:00
parent 857fa4426b
commit ae7c0827f2
8 changed files with 143 additions and 25 deletions

View File

@ -27,7 +27,9 @@
#endif
/* Define to 1 if you have the `MoveFileExA' function. */
/* #undef HAVE_MOVEFILEEXA */
#ifdef _WIN32
#define HAVE_MOVEFILEEXA 1
#endif
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

View File

@ -52,21 +52,33 @@ typedef int pid_t;
#define O_BINARY 0
#endif
int
#ifdef UNICODE
_zip_mkstemp(wchar_t *path)
#else
_zip_mkstemp(char *path)
#endif
{
int fd;
#ifdef UNICODE
wchar_t *start, *trv;
struct _stat sbuf;
#else
char *start, *trv;
struct stat sbuf;
#endif
pid_t pid;
/* To guarantee multiple calls generate unique names even if
the file is not created. 676 different possibilities with 7
or more X's, 26 with 6 or less. */
// Urgh, not threadsafe at all.
#ifdef UNICODE
static wchar_t xtra[3] = L"aa";
#else
static char xtra[3] = "aa";
#endif
int xcnt = 0;
pid = getpid();
@ -110,7 +122,11 @@ _zip_mkstemp(char *path)
break;
if (*trv == '/') {
*trv = '\0';
#ifdef UNICODE
if (_wstat(path, &sbuf))
#else
if (stat(path, &sbuf))
#endif
return (0);
#ifndef _WIN32
if (!S_ISDIR(sbuf.st_mode)) {

View File

@ -204,7 +204,11 @@ ZIP_EXTERN const char *zip_get_file_comment(struct zip *, int, int *, int);
ZIP_EXTERN const char *zip_get_name(struct zip *, int, int);
ZIP_EXTERN int zip_get_num_files(struct zip *);
ZIP_EXTERN int zip_name_locate(struct zip *, const char *, int);
#ifdef UNICODE
ZIP_EXTERN struct zip *zip_open(const wchar_t *, int, int *);
#else
ZIP_EXTERN struct zip *zip_open(const char *, int, int *);
#endif
ZIP_EXTERN int zip_rename(struct zip *, int, const char *);
ZIP_EXTERN int zip_replace(struct zip *, int, struct zip_source *);
ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, int);

View File

@ -53,7 +53,12 @@ static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
static int write_cdir(struct zip *, struct zip_cdir *, FILE *);
static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
static int _zip_changed(struct zip *, int *);
static char *_zip_create_temp_output(struct zip *, FILE **);
#ifdef UNICODE
static wchar_t *
#else
static char *
#endif
_zip_create_temp_output(struct zip *, FILE **);
static int _zip_torrentzip_cmp(const void *, const void *);
@ -70,7 +75,11 @@ zip_close(struct zip *za)
{
int survivors;
int i, j, error;
char *temp;
#ifdef UNICODE
wchar_t *temp;
#else
char *temp;
#endif
FILE *out;
mode_t mask;
struct zip_cdir *cd;
@ -92,9 +101,13 @@ zip_close(struct zip *za)
/* don't create zip files with no entries */
if (survivors == 0) {
if (za->zn && za->zp) {
if (remove(za->zn) != 0) {
_zip_error_set(&za->error, ZIP_ER_REMOVE, errno);
return -1;
#ifdef UNICODE
if (_wremove(za->zn) != 0) {
#else
if (remove(za->zn) != 0) {
#endif
_zip_error_set(&za->error, ZIP_ER_REMOVE, errno);
return -1;
}
}
_zip_free(za);
@ -133,7 +146,7 @@ zip_close(struct zip *za)
}
}
if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
if ((temp = _zip_create_temp_output(za, &out)) == NULL) {
_zip_cdir_free(cd);
free(filelist);
return -1;
@ -280,14 +293,22 @@ zip_close(struct zip *za)
if (error) {
_zip_dirent_finalize(&de);
fclose(out);
#ifdef UNICODE
_wremove(temp);
#else
remove(temp);
#endif
free(temp);
return -1;
}
if (fclose(out) != 0) {
_zip_error_set(&za->error, ZIP_ER_CLOSE, errno);
#ifdef UNICODE
_wremove(temp);
#else
remove(temp);
#endif
free(temp);
return -1;
}
@ -297,13 +318,21 @@ zip_close(struct zip *za)
za->zp = NULL;
reopen_on_error = 1;
}
if (_zip_rename(temp, za->zn) != 0) {
if (_zip_rename(temp, za->zn) != 0) {
_zip_error_set(&za->error, ZIP_ER_RENAME, errno);
#ifdef UNICODE
_wremove(temp);
#else
remove(temp);
#endif
free(temp);
if (reopen_on_error) {
/* ignore errors, since we're already in an error case */
za->zp = fopen(za->zn, "rb");
#ifdef UNICODE
za->zp = _wfopen(za->zn, L"rb");
#else
za->zp = fopen(za->zn, "rb");
#endif
}
return -1;
}
@ -636,19 +665,35 @@ _zip_changed(struct zip *za, int *survivorsp)
}
#ifdef UNICODE
static wchar_t *
#else
static char *
#endif
_zip_create_temp_output(struct zip *za, FILE **outp)
{
char *temp;
#ifdef UNICODE
wchar_t *temp;
#else
char *temp;
#endif
int tfd;
FILE *tfp;
if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) {
#ifdef UNICODE
if ((temp=(wchar_t *)malloc((wcslen(za->zn)+8)*2)) == NULL) {
#else
if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) {
#endif
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
sprintf(temp, "%s.XXXXXX", za->zn);
#ifdef UNICODE
swprintf(temp, L"%s.XXXXXX", za->zn);
#else
sprintf(temp, "%s.XXXXXX", za->zn);
#endif
if ((tfd=mkstemp(temp)) == -1) {
_zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno);
@ -661,7 +706,11 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
#ifndef _WIN32
close(tfd);
#endif
#ifdef UNICODE
_wremove(temp);
#else
remove(temp);
#endif
free(temp);
return NULL;
}

View File

@ -43,11 +43,16 @@
#include "zipint.h"
static void set_error(int *, struct zip_error *, int);
static struct zip *_zip_allocate_new(const char *, int *);
static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *);
static void _zip_check_torrentzip(struct zip *);
static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t);
#ifdef UNICODE
static struct zip *_zip_allocate_new(const wchar_t *, int *);
static int _zip_file_exists(const wchar_t *, int, int *);
#else
static struct zip *_zip_allocate_new(const char *, int *);
static int _zip_file_exists(const char *, int, int *);
#endif
static int _zip_headercomp(struct zip_dirent *, int,
struct zip_dirent *, int);
static unsigned char *_zip_memmem(const unsigned char *, int,
@ -56,9 +61,12 @@ static struct zip_cdir *_zip_readcdir(FILE *, unsigned char *, unsigned char *,
int, int, struct zip_error *);
ZIP_EXTERN struct zip *
#ifdef UNICODE
zip_open(const wchar_t *fn, int flags, int *zep)
#else
zip_open(const char *fn, int flags, int *zep)
#endif
{
FILE *fp;
struct zip *za;
@ -75,8 +83,12 @@ zip_open(const char *fn, int flags, int *zep)
break;
}
if ((fp=fopen(fn, "rb")) == NULL) {
set_error(zep, NULL, ZIP_ER_OPEN);
#ifdef UNICODE
if ((fp=_wfopen(fn, L"rb")) == NULL) {
#else
if ((fp=fopen(fn, "rb")) == NULL) {
#endif
set_error(zep, NULL, ZIP_ER_OPEN);
return NULL;
}
@ -417,7 +429,11 @@ _zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2,
static struct zip *
#ifdef _UNICODE
_zip_allocate_new(const wchar_t *fn, int *zep)
#else
_zip_allocate_new(const char *fn, int *zep)
#endif
{
struct zip *za;
struct zip_error error;
@ -426,8 +442,12 @@ _zip_allocate_new(const char *fn, int *zep)
set_error(zep, &error, 0);
return NULL;
}
za->zn = strdup(fn);
#ifdef UNICODE
za->zn = _wcsdup(fn);
#else
za->zn = strdup(fn);
#endif
if (!za->zn) {
_zip_free(za);
set_error(zep, NULL, ZIP_ER_MEMORY);
@ -439,16 +459,27 @@ _zip_allocate_new(const char *fn, int *zep)
static int
#ifdef UNICODE
_zip_file_exists(const wchar_t *fn, int flags, int *zep)
#else
_zip_file_exists(const char *fn, int flags, int *zep)
#endif
{
struct stat st;
#ifdef UNICODE
struct _stat st;
#else
struct stat st;
#endif
if (fn == NULL) {
set_error(zep, NULL, ZIP_ER_INVAL);
return -1;
}
if (stat(fn, &st) != 0) {
#ifdef UNICODE
if (_wstat(fn, &st) != 0) {
#else
if (stat(fn, &st) != 0) {
#endif
if (flags & ZIP_CREATE)
return 0;
else {

View File

@ -54,14 +54,18 @@ typedef int mode_t;
#include "config.h"
#ifndef HAVE_MKSTEMP
#ifdef UNICODE
int _zip_mkstemp(wchar_t *);
#else
int _zip_mkstemp(char *);
#endif
#define mkstemp _zip_mkstemp
#endif
#ifdef HAVE_MOVEFILEEXA
#include <windows.h>
#define _zip_rename(s, t) \
(!MoveFileExA((s), (t), \
(!MoveFileEx((s), (t), \
MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING))
#else
#define _zip_rename rename
@ -121,7 +125,11 @@ struct zip_error {
/* zip archive, part of API */
struct zip {
char *zn; /* file name */
#ifdef UNICODE
wchar_t *zn; /* file name */
#else
char *zn; /* file name */
#endif
FILE *zp; /* file */
struct zip_error error; /* error information */

View File

@ -171,6 +171,7 @@
</None>
<None Include="Android.mk" />
<None Include="base\CMakeLists.txt" />
<None Include="ext\libzip\Android.mk" />
<None Include="ext\stb_image\CMakeLists.txt" />
<None Include="file\CMakeLists.txt" />
<None Include="README.md" />
@ -206,6 +207,7 @@
<ClInclude Include="ext\cityhash\citycrc.h" />
<ClInclude Include="ext\jpge\jpgd.h" />
<ClInclude Include="ext\jpge\jpge.h" />
<ClInclude Include="ext\libzip\config.h" />
<ClInclude Include="ext\libzip\zip.h" />
<ClInclude Include="ext\libzip\zipint.h" />
<ClInclude Include="ext\rg_etc1\rg_etc1.h" />

View File

@ -19,6 +19,9 @@
<Filter>ui</Filter>
</None>
<None Include="..\ios\main.mm" />
<None Include="ext\libzip\Android.mk">
<Filter>ext\libzip</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="gfx\gl_debug_log.h">
@ -295,6 +298,9 @@
<ClInclude Include="ext\libzip\zipint.h">
<Filter>ext\libzip</Filter>
</ClInclude>
<ClInclude Include="ext\libzip\config.h">
<Filter>ext\libzip</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="gfx\gl_debug_log.cpp">