zip.c splitting/rewriting begun --HG-- branch : HEAD
diff --git a/lib/zip.h b/lib/zip.h index 8373057..f635427 100644 --- a/lib/zip.h +++ b/lib/zip.h
@@ -7,7 +7,7 @@ enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, ZIP_ST_ADDED, ZIP_ST_RENAMED }; -enum zip_cmd { ZIP_CMD_INIT, ZIP_CMD_READ, ZIP_CMD_CRC, ZIP_CMD_CLOSE }; +enum zip_cmd { ZIP_CMD_INIT, ZIP_CMD_READ, ZIP_CMD_META, ZIP_CMD_CLOSE }; /* flags for zip_open */ #define ZIP_CREATE 1 @@ -39,7 +39,7 @@ /* zip file */ -typedef unsigned long (*zip_read_func)(void *state, char *buf, +typedef unsigned long (*zip_read_func)(void *state, void *data, int len, enum zip_cmd cmd); struct zip { @@ -85,17 +85,14 @@ char *fn, *ef, *fcom; char *fn_old; - + zip_read_func *ch_func; + void *ch_data; + int ch_comp; +}; - /* only use one of the following three for supplying new data - listed in order of priority, if more than one is set */ - struct zip *ch_data_zf; - char *ch_data_buf; - FILE *ch_data_fp; - /* offset & len of new data in ch_data_fp or ch_data_buf */ - unsigned int ch_data_offset, ch_data_len; - /* if source is another zipfile, number of file in zipfile */ - unsigned int ch_data_zf_fileno; +struct zip_meta { /* meta information needed to add compressed data */ + unsigned int crc, uncomp_size; + /* ... */ };
diff --git a/lib/zip_add_zip.c b/lib/zip_add_zip.c new file mode 100644 index 0000000..063a19b --- /dev/null +++ b/lib/zip_add_zip.c
@@ -0,0 +1,11 @@ +#include "zip.h" +#include "zipint.h" + + + +int +zip_add_zip(struct zip *zf, char *name, + struct zip *srczf, int srcidx, int start, int len) +{ + return zip_replace_zip(zf, -1, name, srczf, srcidx, start, len); +}
diff --git a/lib/zip_replace.c b/lib/zip_replace.c new file mode 100644 index 0000000..9adf5b7 --- /dev/null +++ b/lib/zip_replace.c
@@ -0,0 +1,32 @@ +#include "zip.h" +#include "zipint.h" + + + +int +zip_replace(struct zip *zf, int idx, char *name, + zip_read_func *fn, void *state, int comp) +{ + if (idx == -1) + zip_add(zf, name, fn, state, comp); + + if (idx < 0 || idx >= zf->nentry) { + zip_err = ZERR_NOENT; + return -1; + } + + if (_zip_unchange_data(zf, idx) != 0) + return -1; + + if (_zip_set_name(zf, idx, name) != 0) + return -1; + + zf->changes = 1; + zf->entry[idx].state = Z_REPLACED; + + zf->entry[idx].ch_func = fn; + zf->entry[idx].ch_data = state; + zf->entry[idx].ch_comp = comp; + + return 0; +}
diff --git a/lib/zip_replace_zip.c b/lib/zip_replace_zip.c new file mode 100644 index 0000000..9bd4d24 --- /dev/null +++ b/lib/zip_replace_zip.c
@@ -0,0 +1,136 @@ +#include "zip.h" +#include "zipint.h" + +struct read_zip { + struct zip *zf; + int idx; + /* ... */ +}; + +struct read_part { + struct zip *zf; + int idx; + struct zip_file *zff; + int off, len; + /* ... */ +} + +static zip_read_func read_zip; +static zip_read_func read_part; + + + +int +zip_replace_zip(struct zip *zf, int idx, char *name, + struct zip *srczf, int srcidx, int start, int len) +{ + struct read_zip *z; + struct read_part *p; + + if (srcidx < 0 || srcidx >= srczf->nentry) { + zip_err = ZERR_NOENT; + return -1; + } + + if (start == 0 && (len == 0 || len == -1)) { + if ((z=(struct read_zip *)malloc(sizeof(struct read_zip))) == NULL) { + zip_err = ZERR_MEMORY; + return -1; + } + z->zf = srczf; + z->idx = srcidx; + return zip_replace(zf, idx, name, read_zip, z, 1); + } + else { + if ((p=(struct read_part *)malloc(sizeof(struct read_part))) == NULL) { + zip_err = ZERR_MEMORY; + return -1; + } + p->zf = srczf; + p->idx = srcidx; + p->off = start; + p->len = len; + p->zff = NULL; + return zip_replace(zf, idx, name, read_part, z, 0); + } +} + + + +static unsigned long +read_zip(void *state, void *data, int len, enum zip_cmd cmd); +{ + struct read_zip *z; + + z = (struct read_zip *)state; + + switch (cmd) { + case ZIP_CMD_INIT: + /* XXX */ + break; + + case ZIP_CMD_READ: + /* XXX */ + break; + + case ZIP_CMD_META: + /* XXX */ + break; + + case ZIP_CMD_CLOSE: + return 0; + } +} + + + +static unsigned long +read_part(void *state, void *data, int len, enum zip_cmd cmd); +{ + struct read_part *z; + char b[8192], *buf; + int i, n; + + z = (struct read_part *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_CMD_INIT: + if ((z->zff=zip_fopen_index(z->zf, idx) ) == NULL) + return -1; + + for (n=0; n<z->off; n+= i) { + i = (z->off-n > 8192 ? 8192 : z->off-n); + if ((i=zip_fread(z->zff, b, n)) < 0) { + zip_fclose(z->zff); + z->zff = NULL; + return -1; + } + } + return 0; + + case ZIP_CMD_READ: + if (z->len != -1) + n = len > z->len ? z->len : len; + else + n = len; + + if ((i=zip_fread(z->zff, buf, n)) < 0) + return -1; + + if (z->len != -1) + z->len -= i; + + return i; + + case ZIP_CMD_CRC: + return -1; + + case ZIP_CMD_CLOSE: + if (z->zff) { + zip_fclose(z->zff); + z->zff = NULL; + } + return 0; + } +}
diff --git a/lib/zip_set_name.c b/lib/zip_set_name.c new file mode 100644 index 0000000..715d321 --- /dev/null +++ b/lib/zip_set_name.c
@@ -0,0 +1,29 @@ +#include "zip.h" +#include "zipint.h" + + + +int +_zip_set_name(struct zip *zf, int idx, char *name) +{ + if (idx >= zf->nentry || idx < 0) { + zip_err = ZERR_NOENT; + return -1; + } + + if (name != NULL) { + if (zf->entry[idx].fn_old == NULL) + zf->entry[idx].fn_old = zf->entry[idx].fn; + else + free(zf->entry[idx].fn); + zf->entry[idx].fn = strdup(name); + if (zf->entry[idx].fn) { + /* XXX: fn is NULL; very bad */ + zip_err = ZERR_MEMORY; + return -1; + } + zf->entry[idx].fnlen = strlen(name); + } + + return idx; +}
diff --git a/lib/zipint.h b/lib/zipint.h index 3929c64..1e8e504 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -20,5 +20,6 @@ void *_zip_memdup(const void *mem, int len); void _zip_new_entry(struct zip *zf); void _zip_entry_init(struct zip *zf, int idx); +int _zip_set_name(struct zip *zf, int idx, char *name); #endif /* zipint.h */