szip: fix extracting dot folders (#13387)
parent
8519996201
commit
4400f9891e
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -12,17 +12,29 @@
|
||||||
#ifndef ZIP_H
|
#ifndef ZIP_H
|
||||||
#define ZIP_H
|
#define ZIP_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifndef ZIP_SHARED
|
||||||
|
#define ZIP_EXPORT
|
||||||
|
#else
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef ZIP_BUILD_SHARED
|
||||||
|
#define ZIP_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define ZIP_EXPORT __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define ZIP_EXPORT __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) && \
|
#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
|
||||||
!defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) && \
|
|
||||||
!defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DECLARED)
|
|
||||||
|
|
||||||
// 64-bit Windows is the only mainstream platform
|
// 64-bit Windows is the only mainstream platform
|
||||||
// where sizeof(long) != sizeof(void*)
|
// where sizeof(long) != sizeof(void*)
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -30,19 +42,10 @@ typedef long long ssize_t; /* byte count or error */
|
||||||
#else
|
#else
|
||||||
typedef long ssize_t; /* byte count or error */
|
typedef long ssize_t; /* byte count or error */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _SSIZE_T_DEFINED
|
|
||||||
#define _SSIZE_T_DEFINED_
|
|
||||||
#define __DEFINED_ssize_t
|
|
||||||
#define __ssize_t_defined
|
|
||||||
#define _SSIZE_T
|
|
||||||
#define _SSIZE_T_
|
|
||||||
#define _SSIZE_T_DECLARED
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX_PATH
|
#ifndef MAX_PATH
|
||||||
#define MAX_PATH 32767 /* # chars in a path name including NULL */
|
#define MAX_PATH 1024 /* # chars in a path name including NULL */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,9 +62,49 @@ typedef long ssize_t; /* byte count or error */
|
||||||
/**
|
/**
|
||||||
* Default zip compression level.
|
* Default zip compression level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
|
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error codes
|
||||||
|
*/
|
||||||
|
#define ZIP_ENOINIT -1 // not initialized
|
||||||
|
#define ZIP_EINVENTNAME -2 // invalid entry name
|
||||||
|
#define ZIP_ENOENT -3 // entry not found
|
||||||
|
#define ZIP_EINVMODE -4 // invalid zip mode
|
||||||
|
#define ZIP_EINVLVL -5 // invalid compression level
|
||||||
|
#define ZIP_ENOSUP64 -6 // no zip 64 support
|
||||||
|
#define ZIP_EMEMSET -7 // memset error
|
||||||
|
#define ZIP_EWRTENT -8 // cannot write data to entry
|
||||||
|
#define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor
|
||||||
|
#define ZIP_EINVIDX -10 // invalid index
|
||||||
|
#define ZIP_ENOHDR -11 // header not found
|
||||||
|
#define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer
|
||||||
|
#define ZIP_ECRTHDR -13 // cannot create entry header
|
||||||
|
#define ZIP_EWRTHDR -14 // cannot write entry header
|
||||||
|
#define ZIP_EWRTDIR -15 // cannot write to central dir
|
||||||
|
#define ZIP_EOPNFILE -16 // cannot open file
|
||||||
|
#define ZIP_EINVENTTYPE -17 // invalid entry type
|
||||||
|
#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation
|
||||||
|
#define ZIP_ENOFILE -19 // file not found
|
||||||
|
#define ZIP_ENOPERM -20 // no permission
|
||||||
|
#define ZIP_EOOMEM -21 // out of memory
|
||||||
|
#define ZIP_EINVZIPNAME -22 // invalid zip archive name
|
||||||
|
#define ZIP_EMKDIR -23 // make dir error
|
||||||
|
#define ZIP_ESYMLINK -24 // symlink error
|
||||||
|
#define ZIP_ECLSZIP -25 // close archive error
|
||||||
|
#define ZIP_ECAPSIZE -26 // capacity size too small
|
||||||
|
#define ZIP_EFSEEK -27 // fseek error
|
||||||
|
#define ZIP_EFREAD -28 // fread error
|
||||||
|
#define ZIP_EFWRITE -29 // fwrite error
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up the error message string coresponding to an error number.
|
||||||
|
* @param errnum error number
|
||||||
|
* @return error message string coresponding to errnum or NULL if error is not
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT const char *zip_strerror(int errnum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct zip_t
|
* @struct zip_t
|
||||||
*
|
*
|
||||||
|
@ -82,14 +125,15 @@ struct zip_t;
|
||||||
*
|
*
|
||||||
* @return the zip archive handler or NULL on error
|
* @return the zip archive handler or NULL on error
|
||||||
*/
|
*/
|
||||||
extern struct zip_t *zip_open(const char *zipname, int level, char mode);
|
extern ZIP_EXPORT struct zip_t *zip_open(const char *zipname, int level,
|
||||||
|
char mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the zip archive, releases resources - always finalize.
|
* Closes the zip archive, releases resources - always finalize.
|
||||||
*
|
*
|
||||||
* @param zip zip archive handler.
|
* @param zip zip archive handler.
|
||||||
*/
|
*/
|
||||||
extern void zip_close(struct zip_t *zip);
|
extern ZIP_EXPORT void zip_close(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the archive has a zip64 end of central directory headers.
|
* Determines if the archive has a zip64 end of central directory headers.
|
||||||
|
@ -99,7 +143,7 @@ extern void zip_close(struct zip_t *zip);
|
||||||
* @return the return code - 1 (true), 0 (false), negative number (< 0) on
|
* @return the return code - 1 (true), 0 (false), negative number (< 0) on
|
||||||
* error.
|
* error.
|
||||||
*/
|
*/
|
||||||
extern int zip_is64(struct zip_t *zip);
|
extern ZIP_EXPORT int zip_is64(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens an entry by name in the zip archive.
|
* Opens an entry by name in the zip archive.
|
||||||
|
@ -113,7 +157,22 @@ extern int zip_is64(struct zip_t *zip);
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_open(struct zip_t *zip, const char *entryname);
|
extern ZIP_EXPORT int zip_entry_open(struct zip_t *zip, const char *entryname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an entry by name in the zip archive.
|
||||||
|
*
|
||||||
|
* For zip archive opened in 'w' or 'a' mode the function will append
|
||||||
|
* a new entry. In readonly mode the function tries to locate the entry
|
||||||
|
* in global dictionary (case sensitive).
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
* @param entryname an entry name in local dictionary (case sensitive).
|
||||||
|
*
|
||||||
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT int zip_entry_opencasesensitive(struct zip_t *zip,
|
||||||
|
const char *entryname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a new entry by index in the zip archive.
|
* Opens a new entry by index in the zip archive.
|
||||||
|
@ -125,7 +184,7 @@ extern int zip_entry_open(struct zip_t *zip, const char *entryname);
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_openbyindex(struct zip_t *zip, int index);
|
extern ZIP_EXPORT int zip_entry_openbyindex(struct zip_t *zip, size_t index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes a zip entry, flushes buffer and releases resources.
|
* Closes a zip entry, flushes buffer and releases resources.
|
||||||
|
@ -134,7 +193,7 @@ extern int zip_entry_openbyindex(struct zip_t *zip, int index);
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_close(struct zip_t *zip);
|
extern ZIP_EXPORT int zip_entry_close(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a local name of the current zip entry.
|
* Returns a local name of the current zip entry.
|
||||||
|
@ -150,7 +209,7 @@ extern int zip_entry_close(struct zip_t *zip);
|
||||||
*
|
*
|
||||||
* @return the pointer to the current zip entry name, or NULL on error.
|
* @return the pointer to the current zip entry name, or NULL on error.
|
||||||
*/
|
*/
|
||||||
extern const char *zip_entry_name(struct zip_t *zip);
|
extern ZIP_EXPORT const char *zip_entry_name(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an index of the current zip entry.
|
* Returns an index of the current zip entry.
|
||||||
|
@ -159,7 +218,7 @@ extern const char *zip_entry_name(struct zip_t *zip);
|
||||||
*
|
*
|
||||||
* @return the index on success, negative number (< 0) on error.
|
* @return the index on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_index(struct zip_t *zip);
|
extern ZIP_EXPORT ssize_t zip_entry_index(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the current zip entry is a directory entry.
|
* Determines if the current zip entry is a directory entry.
|
||||||
|
@ -169,16 +228,35 @@ extern int zip_entry_index(struct zip_t *zip);
|
||||||
* @return the return code - 1 (true), 0 (false), negative number (< 0) on
|
* @return the return code - 1 (true), 0 (false), negative number (< 0) on
|
||||||
* error.
|
* error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_isdir(struct zip_t *zip);
|
extern ZIP_EXPORT int zip_entry_isdir(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an uncompressed size of the current zip entry.
|
* Returns the uncompressed size of the current zip entry.
|
||||||
|
* Alias for zip_entry_uncomp_size (for backward compatibility).
|
||||||
*
|
*
|
||||||
* @param zip zip archive handler.
|
* @param zip zip archive handler.
|
||||||
*
|
*
|
||||||
* @return the uncompressed size in bytes.
|
* @return the uncompressed size in bytes.
|
||||||
*/
|
*/
|
||||||
extern unsigned long long zip_entry_size(struct zip_t *zip);
|
extern ZIP_EXPORT unsigned long long zip_entry_size(struct zip_t *zip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the uncompressed size of the current zip entry.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
*
|
||||||
|
* @return the uncompressed size in bytes.
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT unsigned long long zip_entry_uncomp_size(struct zip_t *zip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the compressed size of the current zip entry.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
*
|
||||||
|
* @return the compressed size in bytes.
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT unsigned long long zip_entry_comp_size(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns CRC-32 checksum of the current zip entry.
|
* Returns CRC-32 checksum of the current zip entry.
|
||||||
|
@ -187,7 +265,7 @@ extern unsigned long long zip_entry_size(struct zip_t *zip);
|
||||||
*
|
*
|
||||||
* @return the CRC-32 checksum.
|
* @return the CRC-32 checksum.
|
||||||
*/
|
*/
|
||||||
extern unsigned int zip_entry_crc32(struct zip_t *zip);
|
extern ZIP_EXPORT unsigned int zip_entry_crc32(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compresses an input buffer for the current zip entry.
|
* Compresses an input buffer for the current zip entry.
|
||||||
|
@ -198,7 +276,8 @@ extern unsigned int zip_entry_crc32(struct zip_t *zip);
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
|
extern ZIP_EXPORT int zip_entry_write(struct zip_t *zip, const void *buf,
|
||||||
|
size_t bufsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compresses a file for the current zip entry.
|
* Compresses a file for the current zip entry.
|
||||||
|
@ -208,7 +287,7 @@ extern int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_fwrite(struct zip_t *zip, const char *filename);
|
extern ZIP_EXPORT int zip_entry_fwrite(struct zip_t *zip, const char *filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the current zip entry into output buffer.
|
* Extracts the current zip entry into output buffer.
|
||||||
|
@ -223,9 +302,10 @@ extern int zip_entry_fwrite(struct zip_t *zip, const char *filename);
|
||||||
* for large entries, please take a look at zip_entry_extract function.
|
* for large entries, please take a look at zip_entry_extract function.
|
||||||
*
|
*
|
||||||
* @return the return code - the number of bytes actually read on success.
|
* @return the return code - the number of bytes actually read on success.
|
||||||
* Otherwise a -1 on error.
|
* Otherwise a negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
|
extern ZIP_EXPORT ssize_t zip_entry_read(struct zip_t *zip, void **buf,
|
||||||
|
size_t *bufsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the current zip entry into a memory buffer using no memory
|
* Extracts the current zip entry into a memory buffer using no memory
|
||||||
|
@ -237,13 +317,14 @@ extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
|
||||||
*
|
*
|
||||||
* @note ensure supplied output buffer is large enough.
|
* @note ensure supplied output buffer is large enough.
|
||||||
* zip_entry_size function (returns uncompressed size for the current
|
* zip_entry_size function (returns uncompressed size for the current
|
||||||
* entry) can be handy to estimate how big buffer is needed. for large
|
* entry) can be handy to estimate how big buffer is needed.
|
||||||
* entries, please take a look at zip_entry_extract function.
|
* For large entries, please take a look at zip_entry_extract function.
|
||||||
*
|
*
|
||||||
* @return the return code - the number of bytes actually read on success.
|
* @return the return code - the number of bytes actually read on success.
|
||||||
* Otherwise a -1 on error (e.g. bufsize is not large enough).
|
* Otherwise a negative number (< 0) on error (e.g. bufsize is not large
|
||||||
|
* enough).
|
||||||
*/
|
*/
|
||||||
extern ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf,
|
extern ZIP_EXPORT ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf,
|
||||||
size_t bufsize);
|
size_t bufsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,7 +335,7 @@ extern ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf,
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_entry_fread(struct zip_t *zip, const char *filename);
|
extern ZIP_EXPORT int zip_entry_fread(struct zip_t *zip, const char *filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the current zip entry using a callback function (on_extract).
|
* Extracts the current zip entry using a callback function (on_extract).
|
||||||
|
@ -266,9 +347,9 @@ extern int zip_entry_fread(struct zip_t *zip, const char *filename);
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int
|
extern ZIP_EXPORT int
|
||||||
zip_entry_extract(struct zip_t *zip,
|
zip_entry_extract(struct zip_t *zip,
|
||||||
size_t (*on_extract)(void *arg, unsigned long long offset,
|
size_t (*on_extract)(void *arg, uint64_t offset,
|
||||||
const void *data, size_t size),
|
const void *data, size_t size),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
|
@ -280,40 +361,18 @@ zip_entry_extract(struct zip_t *zip,
|
||||||
* @return the return code - the number of entries on success, negative number
|
* @return the return code - the number of entries on success, negative number
|
||||||
* (< 0) on error.
|
* (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_total_entries(struct zip_t *zip);
|
extern ZIP_EXPORT ssize_t zip_entries_total(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new archive and puts files into a single zip archive.
|
* Deletes zip archive entries.
|
||||||
*
|
*
|
||||||
* @param zipname zip archive file.
|
* @param zip zip archive handler.
|
||||||
* @param filenames input files.
|
* @param entries array of zip archive entries to be deleted.
|
||||||
* @param len: number of input files.
|
* @param len the number of entries to be deleted.
|
||||||
*
|
* @return the number of deleted entries, or negative number (< 0) on error.
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
|
||||||
*/
|
*/
|
||||||
extern int zip_create(const char *zipname, const char *filenames[], size_t len);
|
extern ZIP_EXPORT ssize_t zip_entries_delete(struct zip_t *zip,
|
||||||
|
char *const entries[], size_t len);
|
||||||
/**
|
|
||||||
* Extracts a zip archive file into directory.
|
|
||||||
*
|
|
||||||
* If on_extract_entry is not NULL, the callback will be called after
|
|
||||||
* successfully extracted each zip entry.
|
|
||||||
* Returning a negative value from the callback will cause abort and return an
|
|
||||||
* error. The last argument (void *arg) is optional, which you can use to pass
|
|
||||||
* data to the on_extract_entry callback.
|
|
||||||
*
|
|
||||||
* @param zipname zip archive file.
|
|
||||||
* @param dir output directory.
|
|
||||||
* @param on_extract_entry on extract callback.
|
|
||||||
* @param arg opaque pointer.
|
|
||||||
*
|
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
|
||||||
*/
|
|
||||||
extern int zip_extract(const char *zipname, const char *dir,
|
|
||||||
int (*on_extract_entry)(const char *filename, void *arg),
|
|
||||||
void *arg);
|
|
||||||
// temporary working unzip solution
|
|
||||||
extern int zip_extract_without_callback(const char *zipname, const char *dir);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts a zip archive stream into directory.
|
* Extracts a zip archive stream into directory.
|
||||||
|
@ -332,12 +391,76 @@ extern int zip_extract_without_callback(const char *zipname, const char *dir);
|
||||||
*
|
*
|
||||||
* @return the return code - 0 on success, negative number (< 0) on error.
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_extract_stream(const char *stream, size_t size, const char *dir,
|
extern ZIP_EXPORT int
|
||||||
int (*on_extract)(const char *filename,
|
zip_stream_extract(const char *stream, size_t size, const char *dir,
|
||||||
|
int (*on_extract)(const char *filename, void *arg),
|
||||||
|
void *arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens zip archive stream into memory.
|
||||||
|
*
|
||||||
|
* @param stream zip archive stream.
|
||||||
|
* @param size stream size.
|
||||||
|
*
|
||||||
|
* @return the zip archive handler or NULL on error
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT struct zip_t *zip_stream_open(const char *stream, size_t size,
|
||||||
|
int level, char mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy zip archive stream output buffer.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
* @param buf output buffer. User should free buf.
|
||||||
|
* @param bufsize output buffer size (in bytes).
|
||||||
|
*
|
||||||
|
* @return copy size
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT ssize_t zip_stream_copy(struct zip_t *zip, void **buf,
|
||||||
|
size_t *bufsize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close zip archive releases resources.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT void zip_stream_close(struct zip_t *zip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new archive and puts files into a single zip archive.
|
||||||
|
*
|
||||||
|
* @param zipname zip archive file.
|
||||||
|
* @param filenames input files.
|
||||||
|
* @param len: number of input files.
|
||||||
|
*
|
||||||
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT int zip_create(const char *zipname, const char *filenames[],
|
||||||
|
size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a zip archive file into directory.
|
||||||
|
*
|
||||||
|
* If on_extract_entry is not NULL, the callback will be called after
|
||||||
|
* successfully extracted each zip entry.
|
||||||
|
* Returning a negative value from the callback will cause abort and return an
|
||||||
|
* error. The last argument (void *arg) is optional, which you can use to pass
|
||||||
|
* data to the on_extract_entry callback.
|
||||||
|
*
|
||||||
|
* @param zipname zip archive file.
|
||||||
|
* @param dir output directory.
|
||||||
|
* @param on_extract_entry on extract callback.
|
||||||
|
* @param arg opaque pointer.
|
||||||
|
*
|
||||||
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
|
*/
|
||||||
|
extern ZIP_EXPORT int zip_extract(const char *zipname, const char *dir,
|
||||||
|
int (*on_extract_entry)(const char *filename,
|
||||||
void *arg),
|
void *arg),
|
||||||
void *arg);
|
void *arg);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,20 +4,21 @@ import os
|
||||||
|
|
||||||
#flag -I @VEXEROOT/thirdparty/zip
|
#flag -I @VEXEROOT/thirdparty/zip
|
||||||
#include "zip.c"
|
#include "zip.c"
|
||||||
#include "zip.h"
|
|
||||||
|
|
||||||
struct C.zip_t {
|
struct C.zip_t {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Zip = C.zip_t
|
type Zip = C.zip_t
|
||||||
|
|
||||||
|
pub type Fn_on_extract_entry = fn (&&char, &&char) int
|
||||||
|
|
||||||
fn C.zip_open(&char, int, char) &Zip
|
fn C.zip_open(&char, int, char) &Zip
|
||||||
|
|
||||||
fn C.zip_close(&Zip)
|
fn C.zip_close(&Zip)
|
||||||
|
|
||||||
fn C.zip_entry_open(&Zip, &u8) int
|
fn C.zip_entry_open(&Zip, &u8) int
|
||||||
|
|
||||||
fn C.zip_entry_openbyindex(&Zip, int) int
|
fn C.zip_entry_openbyindex(&Zip, usize) int
|
||||||
|
|
||||||
fn C.zip_entry_close(&Zip) int
|
fn C.zip_entry_close(&Zip) int
|
||||||
|
|
||||||
|
@ -41,9 +42,13 @@ fn C.zip_entry_noallocread(&Zip, voidptr, usize) int
|
||||||
|
|
||||||
fn C.zip_entry_fread(&Zip, &char) int
|
fn C.zip_entry_fread(&Zip, &char) int
|
||||||
|
|
||||||
fn C.zip_total_entries(&Zip) int
|
fn C.zip_entries_total(&Zip) int
|
||||||
|
|
||||||
fn C.zip_extract_without_callback(&char, &char) int
|
fn C.zip_extract(&char, &char, Fn_on_extract_entry, voidptr) int
|
||||||
|
|
||||||
|
fn cb_zip_extract(filename &&char, arg &&char) int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// CompressionLevel lists compression levels, see in "thirdparty/zip/miniz.h"
|
// CompressionLevel lists compression levels, see in "thirdparty/zip/miniz.h"
|
||||||
pub enum CompressionLevel {
|
pub enum CompressionLevel {
|
||||||
|
@ -216,9 +221,6 @@ pub fn (mut zentry Zip) read_entry_buf(buf voidptr, in_bsize int) ?int {
|
||||||
|
|
||||||
// extract_entry extracts the current zip entry into output file.
|
// extract_entry extracts the current zip entry into output file.
|
||||||
pub fn (mut zentry Zip) extract_entry(path string) ? {
|
pub fn (mut zentry Zip) extract_entry(path string) ? {
|
||||||
if !os.is_file(path) {
|
|
||||||
return error('szip: cannot open file for extracting, "$path" not exists')
|
|
||||||
}
|
|
||||||
res := C.zip_entry_fread(zentry, &char(path.str))
|
res := C.zip_entry_fread(zentry, &char(path.str))
|
||||||
if res != 0 {
|
if res != 0 {
|
||||||
return error('szip: failed to extract entry')
|
return error('szip: failed to extract entry')
|
||||||
|
@ -230,7 +232,7 @@ pub fn extract_zip_to_dir(file string, dir string) ?bool {
|
||||||
if C.access(&char(dir.str), 0) == -1 {
|
if C.access(&char(dir.str), 0) == -1 {
|
||||||
return error('szip: cannot open directory for extracting, directory not exists')
|
return error('szip: cannot open directory for extracting, directory not exists')
|
||||||
}
|
}
|
||||||
res := C.zip_extract_without_callback(&char(file.str), &char(dir.str))
|
res := C.zip_extract(&char(file.str), &char(dir.str), cb_zip_extract, 0)
|
||||||
return res == 0
|
return res == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +290,7 @@ pub fn zip_folder(path_to_dir string, path_to_export_zip string) {
|
||||||
|
|
||||||
// total returns the number of all entries (files and directories) in the zip archive.
|
// total returns the number of all entries (files and directories) in the zip archive.
|
||||||
pub fn (mut zentry Zip) total() ?int {
|
pub fn (mut zentry Zip) total() ?int {
|
||||||
tentry := int(C.zip_total_entries(zentry))
|
tentry := int(C.zip_entries_total(zentry))
|
||||||
if tentry == -1 {
|
if tentry == -1 {
|
||||||
return error('szip: cannot count total entries')
|
return error('szip: cannot count total entries')
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,19 @@ import os
|
||||||
const (
|
const (
|
||||||
test_out_zip = 'v_test_zip.zip'
|
test_out_zip = 'v_test_zip.zip'
|
||||||
test_path = 'zip files'
|
test_path = 'zip files'
|
||||||
|
test_path2 = '.zip folder'
|
||||||
fname1 = 'file_1.txt'
|
fname1 = 'file_1.txt'
|
||||||
fpath1 = os.join_path(test_path, fname1)
|
fpath1 = os.join_path(test_path, fname1)
|
||||||
fname2 = 'file_2.txt'
|
fname2 = 'file_2.txt'
|
||||||
fpath2 = os.join_path(test_path, fname2)
|
fpath2 = os.join_path(test_path, fname2)
|
||||||
|
fname3 = '.New Text Document.txt'
|
||||||
|
fpath3 = os.join_path(test_path2, fname3)
|
||||||
)
|
)
|
||||||
|
|
||||||
fn cleanup() {
|
fn cleanup() {
|
||||||
os.chdir(os.temp_dir()) or {}
|
os.chdir(os.temp_dir()) or {}
|
||||||
os.rmdir_all(test_path) or {}
|
os.rmdir_all(test_path) or {}
|
||||||
|
os.rmdir_all(test_path2) or {}
|
||||||
os.rm(test_out_zip) or {}
|
os.rm(test_out_zip) or {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,28 +30,35 @@ fn testsuite_end() ? {
|
||||||
|
|
||||||
fn test_szip_create_temp_files() ? {
|
fn test_szip_create_temp_files() ? {
|
||||||
os.mkdir(test_path) ?
|
os.mkdir(test_path) ?
|
||||||
|
os.mkdir(test_path2) ?
|
||||||
os.write_file(fpath1, 'file one') ?
|
os.write_file(fpath1, 'file one') ?
|
||||||
os.write_file(fpath2, 'file two') ?
|
os.write_file(fpath2, 'file two') ?
|
||||||
|
os.write_file(fpath3, 'file three') ?
|
||||||
assert os.exists(fpath1)
|
assert os.exists(fpath1)
|
||||||
assert os.exists(fpath2)
|
assert os.exists(fpath2)
|
||||||
|
assert os.exists(fpath3)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_zipping_files() ? {
|
fn test_zipping_files() ? {
|
||||||
files := (os.ls(test_path) ?).map(os.join_path(test_path, it))
|
mut files := (os.ls(test_path) ?).map(os.join_path(test_path, it))
|
||||||
|
files << (os.ls(test_path2) ?).map(os.join_path(test_path2, it))
|
||||||
szip.zip_files(files, test_out_zip) ?
|
szip.zip_files(files, test_out_zip) ?
|
||||||
assert os.exists(test_out_zip)
|
assert os.exists(test_out_zip)
|
||||||
|
os.rm(fpath1) ?
|
||||||
|
os.rm(fpath2) ?
|
||||||
|
os.rm(fpath3) ?
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_extract_zipped_files() ? {
|
fn test_extract_zipped_files() ? {
|
||||||
os.rm(fpath1) ?
|
|
||||||
os.rm(fpath2) ?
|
|
||||||
szip.extract_zip_to_dir(test_out_zip, test_path) ?
|
szip.extract_zip_to_dir(test_out_zip, test_path) ?
|
||||||
|
szip.extract_zip_to_dir(test_out_zip, test_path2) ?
|
||||||
assert os.exists(fpath1)
|
assert os.exists(fpath1)
|
||||||
assert os.exists(fpath2)
|
assert os.exists(fpath2)
|
||||||
|
assert os.exists(fpath3)
|
||||||
assert (os.read_file(fpath1) ?) == 'file one'
|
assert (os.read_file(fpath1) ?) == 'file one'
|
||||||
assert (os.read_file(fpath2) ?) == 'file two'
|
assert (os.read_file(fpath2) ?) == 'file two'
|
||||||
os.rmdir_all(test_path) ?
|
assert (os.read_file(fpath3) ?) == 'file three'
|
||||||
os.rm(test_out_zip) or {}
|
cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_reading_zipping_files() ? {
|
fn test_reading_zipping_files() ? {
|
||||||
|
@ -57,9 +68,10 @@ fn test_reading_zipping_files() ? {
|
||||||
file_name_list << 'file_${i:02}.txt'
|
file_name_list << 'file_${i:02}.txt'
|
||||||
}
|
}
|
||||||
|
|
||||||
os.chdir(os.temp_dir()) or {}
|
cleanup()
|
||||||
os.rmdir_all(test_path) or {}
|
|
||||||
os.mkdir(test_path) ?
|
os.mkdir(test_path) ?
|
||||||
|
os.mkdir(test_path2) ?
|
||||||
|
os.write_file(fpath3, 'file three') ?
|
||||||
for c, f_name in file_name_list {
|
for c, f_name in file_name_list {
|
||||||
tmp_path := os.join_path(test_path, f_name)
|
tmp_path := os.join_path(test_path, f_name)
|
||||||
os.write_file(tmp_path, 'file ${c:02}') ?
|
os.write_file(tmp_path, 'file ${c:02}') ?
|
||||||
|
|
Loading…
Reference in New Issue