Skip to content

Commit

Permalink
zip: read in memory (#10960)
Browse files Browse the repository at this point in the history
  • Loading branch information
penguindark authored Jul 25, 2021
1 parent ee2e817 commit e4e6c90
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
22 changes: 22 additions & 0 deletions vlib/szip/szip.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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) {
Expand Down
55 changes: 53 additions & 2 deletions vlib/szip/szip_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -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() ? {
Expand Down Expand Up @@ -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()
}

0 comments on commit e4e6c90

Please sign in to comment.