zip: read in memory (#10960)
parent
ee2e81742b
commit
e4e6c90292
|
@ -17,6 +17,8 @@ fn C.zip_close(&Zip)
|
|||
|
||||
fn C.zip_entry_open(&Zip, &byte) int
|
||||
|
||||
fn C.zip_entry_openbyindex(&Zip, int) int
|
||||
|
||||
fn C.zip_entry_close(&Zip) int
|
||||
|
||||
fn C.zip_entry_name(&Zip) &byte
|
||||
|
@ -35,6 +37,8 @@ fn C.zip_entry_fwrite(&Zip, &char) int
|
|||
|
||||
fn C.zip_entry_read(&Zip, &voidptr, &size_t) int
|
||||
|
||||
fn C.zip_entry_noallocread(&Zip, voidptr, size_t) int
|
||||
|
||||
fn C.zip_entry_fread(&Zip, &char) int
|
||||
|
||||
fn C.zip_total_entries(&Zip) int
|
||||
|
@ -108,6 +112,14 @@ pub fn (mut zentry Zip) open_entry(name string) ? {
|
|||
}
|
||||
}
|
||||
|
||||
// open_entry_by_index opens an entry by index in the archive.
|
||||
pub fn (mut z Zip) open_entry_by_index(index int) ? {
|
||||
res := C.zip_entry_openbyindex(z, index)
|
||||
if res == -1 {
|
||||
return error('szip: cannot open archive entry at index $index')
|
||||
}
|
||||
}
|
||||
|
||||
// close_entry closes a zip entry, flushes buffer and releases resources.
|
||||
[inline]
|
||||
pub fn (mut zentry Zip) close_entry() {
|
||||
|
@ -192,6 +204,16 @@ pub fn (mut zentry Zip) read_entry() ?voidptr {
|
|||
return buf
|
||||
}
|
||||
|
||||
// read_entry_buf extracts the current zip entry into user specified buffer
|
||||
pub fn (mut zentry Zip) read_entry_buf(buf voidptr, in_bsize int) ?int {
|
||||
bsize := size_t(in_bsize)
|
||||
res := C.zip_entry_noallocread(zentry, buf, bsize)
|
||||
if res == -1 {
|
||||
return error('szip: cannot read properly data from entry')
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// extract_entry extracts the current zip entry into output file.
|
||||
pub fn (mut zentry Zip) extract_entry(path string) ? {
|
||||
if !os.is_file(path) {
|
||||
|
|
|
@ -4,8 +4,10 @@ import os
|
|||
const (
|
||||
test_out_zip = 'v_test_zip.zip'
|
||||
test_path = 'zip files'
|
||||
fpath1 = os.join_path(test_path, 'file_1.txt')
|
||||
fpath2 = os.join_path(test_path, 'file_2.txt')
|
||||
fname1 = 'file_1.txt'
|
||||
fpath1 = os.join_path(test_path, fname1)
|
||||
fname2 = 'file_2.txt'
|
||||
fpath2 = os.join_path(test_path, fname2)
|
||||
)
|
||||
|
||||
fn test_szip_create_temp_files() ? {
|
||||
|
@ -35,3 +37,52 @@ fn test_extract_zipped_files() ? {
|
|||
os.rmdir_all(test_path) ?
|
||||
os.rm(test_out_zip) or {}
|
||||
}
|
||||
|
||||
fn test_reading_zipping_files() ? {
|
||||
n_files := 2
|
||||
mut file_name_list := []string{}
|
||||
for i in 0 .. n_files {
|
||||
file_name_list << 'file_${i:02}.txt'
|
||||
}
|
||||
|
||||
os.chdir(os.temp_dir())
|
||||
os.rmdir_all(test_path) or {}
|
||||
os.mkdir(test_path) ?
|
||||
for c, f_name in file_name_list {
|
||||
tmp_path := os.join_path(test_path, f_name)
|
||||
os.write_file(tmp_path, 'file ${c:02}') ?
|
||||
assert os.exists(tmp_path)
|
||||
}
|
||||
files := (os.ls(test_path) ?).map(os.join_path(test_path, it))
|
||||
|
||||
szip.zip_files(files, test_out_zip) ?
|
||||
assert os.exists(test_out_zip)
|
||||
|
||||
mut zp := szip.open(test_out_zip, szip.CompressionLevel.no_compression, szip.OpenMode.read_only) ?
|
||||
n_entries := zp.total() ?
|
||||
assert n_entries == n_files
|
||||
|
||||
unsafe {
|
||||
data_len := 'file XX'.len
|
||||
buf_size := 32
|
||||
buf := malloc(data_len * 2)
|
||||
|
||||
for _ in 0 .. n_files {
|
||||
zp.open_entry_by_index(0) ?
|
||||
name := zp.name()
|
||||
assert name in file_name_list
|
||||
|
||||
zp.read_entry_buf(buf, buf_size) ?
|
||||
buf[data_len] = 0
|
||||
tmp_str := tos(buf, data_len)
|
||||
|
||||
assert tmp_str[0..4] == 'file'
|
||||
assert tmp_str[5..7] == name[5..7]
|
||||
|
||||
zp.close_entry()
|
||||
}
|
||||
|
||||
free(buf)
|
||||
}
|
||||
zp.close()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue