Skip to content

Commit

Permalink
delete by index
Browse files Browse the repository at this point in the history
  • Loading branch information
kuba-- committed Nov 24, 2023
1 parent d15aa0c commit 4b9c8fc
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 0 deletions.
105 changes: 105 additions & 0 deletions src/zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,62 @@ static ssize_t zip_entry_mark(struct zip_t *zip,
return err;
}

static ssize_t zip_entry_markbyindex(struct zip_t *zip,
struct zip_entry_mark_t *entry_mark,
const ssize_t n, size_t entries[],
const size_t len) {
ssize_t i = 0;
ssize_t err = 0;
if (!zip || !entry_mark || !entries) {
return ZIP_ENOINIT;
}

mz_zip_archive_file_stat file_stat;
mz_uint64 d_pos = UINT64_MAX;
for (i = 0; i < n; ++i) {
if ((err = zip_entry_openbyindex(zip, i))) {
return (ssize_t)err;
}

mz_bool matches = MZ_FALSE;
{
size_t j;
for (j = 0; j < len; ++j) {
if ((size_t)i == entries[j]) {
matches = MZ_TRUE;
break;
}
}
}
if (matches) {
entry_mark[i].type = MZ_DELETE;
} else {
entry_mark[i].type = MZ_KEEP;
}

if (!mz_zip_reader_file_stat(&zip->archive, i, &file_stat)) {
return ZIP_ENOENT;
}

zip_entry_close(zip);

entry_mark[i].m_local_header_ofs = file_stat.m_local_header_ofs;
entry_mark[i].file_index = (ssize_t)-1;
entry_mark[i].lf_length = 0;
if ((entry_mark[i].type) == MZ_DELETE &&
(d_pos > entry_mark[i].m_local_header_ofs)) {
d_pos = entry_mark[i].m_local_header_ofs;
}
}

for (i = 0; i < n; ++i) {
if ((entry_mark[i].m_local_header_ofs > d_pos) &&
(entry_mark[i].type != MZ_DELETE)) {
entry_mark[i].type = MZ_MOVE;
}
}
return err;
}
static ssize_t zip_index_next(mz_uint64 *local_header_ofs_array,
ssize_t cur_index) {
ssize_t new_index = 0, i;
Expand Down Expand Up @@ -583,6 +639,20 @@ static ssize_t zip_entry_set(struct zip_t *zip,
return 0;
}

static ssize_t zip_entry_setbyindex(struct zip_t *zip,
struct zip_entry_mark_t *entry_mark, ssize_t n,
size_t entries[], const size_t len) {
ssize_t err = 0;

if ((err = zip_entry_markbyindex(zip, entry_mark, n, entries, len)) < 0) {
return err;
}
if ((err = zip_entry_finalize(zip, entry_mark, n)) < 0) {
return err;
}
return 0;
}

static ssize_t zip_file_move(MZ_FILE *m_pFile, const mz_uint64 to,
const mz_uint64 from, const size_t length,
mz_uint8 *move_buf, const size_t capacity_size) {
Expand Down Expand Up @@ -1633,6 +1703,41 @@ ssize_t zip_entries_delete(struct zip_t *zip, char *const entries[],
return err;
}

ssize_t zip_entries_deletebyindex(struct zip_t *zip, size_t entries[], size_t len)
{
ssize_t n = 0;
ssize_t err = 0;
struct zip_entry_mark_t *entry_mark = NULL;

if (zip == NULL || (entries == NULL && len != 0)) {
return ZIP_ENOINIT;
}

if (entries == NULL && len == 0) {
return 0;
}

n = zip_entries_total(zip);

entry_mark = (struct zip_entry_mark_t *)calloc(
(size_t)n, sizeof(struct zip_entry_mark_t));
if (!entry_mark) {
return ZIP_EOOMEM;
}

zip->archive.m_zip_mode = MZ_ZIP_MODE_READING;

err = zip_entry_setbyindex(zip, entry_mark, n, entries, len);
if (err < 0) {
CLEANUP(entry_mark);
return err;
}

err = zip_entries_delete_mark(zip, entry_mark, (int)n);
CLEANUP(entry_mark);
return err;
}

int zip_stream_extract(const char *stream, size_t size, const char *dir,
int (*on_extract)(const char *filename, void *arg),
void *arg) {
Expand Down
10 changes: 10 additions & 0 deletions src/zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,16 @@ extern ZIP_EXPORT ssize_t zip_entries_total(struct zip_t *zip);
extern ZIP_EXPORT ssize_t zip_entries_delete(struct zip_t *zip,
char *const entries[], size_t len);

/**
* Deletes zip archive entries.
*
* @param zip zip archive handler.
* @param entries array of zip archive entries indices to be deleted.
* @param len the number of entries to be deleted.
* @return the number of deleted entries, or negative number (< 0) on error.
*/
extern ZIP_EXPORT ssize_t zip_entries_deletebyindex(struct zip_t *zip, size_t entries[], size_t len);

/**
* Extracts a zip archive stream into directory.
*
Expand Down
53 changes: 53 additions & 0 deletions test/test_entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,58 @@ MU_TEST(test_list_entries) {
zip_close(zip);
}

MU_TEST(test_entries_deletebyindex) {
size_t entries[] = {5, 6, 7, 9, 8};

struct zip_t *zip = zip_open(ZIPNAME, 0, 'd');
mu_check(zip != NULL);

mu_assert_int_eq(5, zip_entries_deletebyindex(zip, entries, 5));

zip_close(zip);

zip = zip_open(ZIPNAME, 0, 'r');
mu_check(zip != NULL);

mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "delete.me"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete.me: %s\n", zip_strerror(ZIP_ENOENT));

mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "_"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "_: %s\n", zip_strerror(ZIP_ENOENT));

mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "delete/file.1"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete/file.1: %s\n", zip_strerror(ZIP_ENOENT));

mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "deleteme/file.3"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete/file.3: %s\n", zip_strerror(ZIP_ENOENT));

mu_assert_int_eq(ZIP_ENOENT, zip_entry_open(zip, "delete/file.2"));
mu_assert_int_eq(0, zip_entry_close(zip));
fprintf(stdout, "delete/file.2: %s\n", zip_strerror(ZIP_ENOENT));

mu_assert_int_eq(total_entries - 5, zip_entries_total(zip));

mu_assert_int_eq(0, zip_entry_open(zip, "delete/file.4"));

size_t buftmp = 0;
char *buf = NULL;
ssize_t bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);

mu_assert_int_eq(bufsize, strlen(TESTDATA2));
mu_assert_int_eq((size_t)bufsize, buftmp);
mu_assert_int_eq(0, strncmp(buf, TESTDATA2, bufsize));
mu_assert_int_eq(0, zip_entry_close(zip));

free(buf);
buf = NULL;

zip_close(zip);
}

MU_TEST(test_entries_delete) {
char *entries[] = {"delete.me", "_", "delete/file.1", "deleteme/file.3",
"delete/file.2"};
Expand Down Expand Up @@ -282,6 +334,7 @@ MU_TEST_SUITE(test_entry_suite) {
MU_RUN_TEST(test_entry_openbyindex);
MU_RUN_TEST(test_entry_read);
MU_RUN_TEST(test_list_entries);
MU_RUN_TEST(test_entries_deletebyindex);
MU_RUN_TEST(test_entries_delete);
}

Expand Down

0 comments on commit 4b9c8fc

Please sign in to comment.