szip: add support for unpacking zip archives and simple zip files

pull/9562/head
koplenov 2021-04-02 02:59:01 +03:00 committed by GitHub
parent c11356be21
commit 9f7cf5cc37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 15 deletions

View File

@ -1007,6 +1007,10 @@ int zip_extract(const char *zipname, const char *dir,
return status; return status;
} }
int zip_extract_without_callback(const char *zipname, const char *dir) {
return zip_extract(zipname, dir, NULL, NULL);
} // for simple V bind ¯\_(ツ)_/¯
int zip_extract_stream(const char *stream, size_t size, const char *dir, int zip_extract_stream(const char *stream, size_t size, const char *dir,
int (*on_extract)(const char *filename, void *arg), int (*on_extract)(const char *filename, void *arg),
void *arg) { void *arg) {

View File

@ -312,6 +312,8 @@ extern int zip_create(const char *zipname, const char *filenames[], size_t len);
extern int zip_extract(const char *zipname, const char *dir, extern int zip_extract(const char *zipname, const char *dir,
int (*on_extract_entry)(const char *filename, void *arg), int (*on_extract_entry)(const char *filename, void *arg),
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.

View File

@ -39,6 +39,8 @@ fn C.zip_entry_fread(&Zip, byteptr) int
fn C.zip_total_entries(&Zip) int fn C.zip_total_entries(&Zip) int
fn C.zip_extract_without_callback(charptr, charptr) int
// 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 {
no_compression = 0 no_compression = 0
@ -201,16 +203,69 @@ pub fn (mut zentry Zip) extract_entry(path string) ? {
} }
} }
/*
extract extracts the current zip entry using a callback function (on_extract). // extract zip file to directory
fn (mut zentry Zip) extract(path string) bool { pub fn extract_zip_to_dir(file string, dir string) ?bool {
if C.access(path.str, 0) == -1 { if C.access(dir.str, 0) == -1 {
return false 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(zentry, path.str, 0, 0) res := C.zip_extract_without_callback(charptr(file.str), charptr(dir.str))
return res == 0 return res == 0
} }
// zip files (full path) to zip file
pub fn zip_files(path_to_file []string, path_to_export_zip string) ? {
// open or create new zip
mut zip := szip.open(path_to_export_zip, .no_compression, .write) or { panic(err) }
// add all files from the directory to the archive
for file in path_to_file {
// add file to zip
zip.open_entry(os.base(file)) or { panic(err) }
file_as_byte := os.read_bytes(file) or { panic(err) }
zip.write_entry(file_as_byte) or { panic(err) }
zip.close_entry()
}
// close zip
defer {
zip.close()
}
}
/*
TODO add
// zip all files in directory to zip file
pub fn zip_folder(path_to_dir string, path_to_export_zip string) {
// get list files from directory
files := os.ls(path_to_dir) or { panic(err) }
// open or create new zip
mut zip := szip.open(path_to_export_zip, .no_compression, .write) or { panic(err) }
// add all files from the directory to the archive
for file in files {
eprintln('Zipping $file to ${path_to_export_zip}...')
println(path_to_dir + file)
// add file to zip
zip.open_entry(file) or { panic(err) }
file_as_byte := os.read_bytes(path_to_dir + '/'+ file) or { panic(err) }
zip.write_entry(file_as_byte) or { panic(err) }
zip.close_entry()
}
// close zip
zip.close()
eprintln('Successfully')
}
*/ */
// 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.

View File

@ -2,12 +2,36 @@ import szip
import os import os
fn test_szip() { fn test_szip() {
mut z := szip.open('test_compile.zip', .best_speed, .write) or {
assert false // create temp files for zip/unzip test
return test_path := 'zip files'
} test_out_zip := 'v_test_zip.zip'
defer {
z.close() os.mkdir(test_path) or { panic(err) }
os.rm('test_compile.zip') or { } os.write_file(test_path + os.path_separator + 'file_1.txt', 'file one') or { panic(err) }
os.write_file(test_path + os.path_separator + 'file_2.txt', 'file file two') or { panic(err) }
// get list files from directory
mut files := os.ls(test_path) or { panic(err) }
for mut file in files {
file = os.getwd() + os.path_separator + test_path + os.path_separator + *file
} }
// zip files
szip.zip_files(files, test_out_zip) or { panic(err) }
assert os.exists(test_out_zip)
// remove files before next test
os.rm(test_path + os.path_separator + 'file_1.txt') or { panic(err) }
os.rm(test_path + os.path_separator + 'file_2.txt') or { panic(err) }
// extract test
szip.extract_zip_to_dir(test_out_zip, test_path) or { panic(err) }
assert os.exists(test_path + os.path_separator + 'file_1.txt')
assert os.exists(test_path + os.path_separator + 'file_2.txt')
// clear temp files
// remove temp files and dir
os.rmdir_all (test_path) or { panic(err) }
os.rm(test_out_zip) or { }
} }