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