From bd5e8f74de87b9061ff62615f48fb378e844e87d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 23 Jan 2021 15:25:29 -0800 Subject: [PATCH] zip-reader: Make the zip_reader reference counted. This will be useful in an upcoming commit. --- src/data/ods-reader.c | 4 ++-- src/libpspp/zip-reader.c | 40 +++++++++++++++++++++++++++------------- src/libpspp/zip-reader.h | 11 ++++++++--- src/output/output-item.c | 1 + src/output/spv/spv.c | 4 ++-- tests/libpspp/zip-test.c | 2 +- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/data/ods-reader.c b/src/data/ods-reader.c index d15c24a238..123ad3ba57 100644 --- a/src/data/ods-reader.c +++ b/src/data/ods-reader.c @@ -163,7 +163,7 @@ ods_destroy (struct spreadsheet *s) dict_unref (r->spreadsheet.dict); - zip_reader_destroy (r->zreader); + zip_reader_unref (r->zreader); free (r->spreadsheet.sheets); free (s->file_name); @@ -1192,7 +1192,7 @@ ods_probe (const char *filename, bool report_errors) return &r->spreadsheet; error: - zip_reader_destroy (r->zreader); + zip_reader_unref (r->zreader); free (r); return NULL; } diff --git a/src/libpspp/zip-reader.c b/src/libpspp/zip-reader.c index 7b5aabadfb..b28ac75f8b 100644 --- a/src/libpspp/zip-reader.c +++ b/src/libpspp/zip-reader.c @@ -16,22 +16,23 @@ #include +#include "libpspp/zip-reader.h" +#include "libpspp/zip-private.h" + +#include #include #include #include #include #include -#include -#include -#include -#include +#include "libpspp/assertion.h" +#include "libpspp/cast.h" +#include "libpspp/compiler.h" +#include "libpspp/integer-format.h" +#include "libpspp/str.h" -#include "str.h" - -#include "integer-format.h" -#include "zip-reader.h" -#include "zip-private.h" +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -81,6 +82,7 @@ get_decompressor (uint16_t c) struct zip_reader { + int ref_cnt; char *file_name; /* The name of the file from which the data is read */ uint16_t n_entries; /* Number of directory entries. */ struct zip_entry *entries; /* Directory entries. */ @@ -116,17 +118,28 @@ zip_member_finish (struct zip_member *zm) } } +struct zip_reader * +zip_reader_ref (const struct zip_reader *zr_) +{ + struct zip_reader *zr = CONST_CAST (struct zip_reader *, zr_); + assert (zr->ref_cnt > 0); + zr->ref_cnt++; + return zr; +} + /* Destroy the zip reader */ void -zip_reader_destroy (struct zip_reader *zr) +zip_reader_unref (struct zip_reader *zr) { - int i; if (zr == NULL) return; + assert (zr->ref_cnt > 0); + if (--zr->ref_cnt) + return; free (zr->file_name); - for (i = 0; i < zr->n_entries; ++i) + for (int i = 0; i < zr->n_entries; ++i) { struct zip_entry *ze = &zr->entries[i]; free (ze->name); @@ -366,6 +379,7 @@ zip_reader_create (const char *file_name, struct zip_reader **zrp) } struct zip_reader *zr = xzalloc (sizeof *zr); + zr->ref_cnt = 1; zr->file_name = xstrdup (file_name); zr->entries = xcalloc (n_members, sizeof *zr->entries); for (int i = 0; i < n_members; i++) @@ -375,7 +389,7 @@ zip_reader_create (const char *file_name, struct zip_reader **zrp) if (error) { fclose (file); - zip_reader_destroy (zr); + zip_reader_unref (zr); return error; } zr->n_entries++; diff --git a/src/libpspp/zip-reader.h b/src/libpspp/zip-reader.h index b02981d365..d245e3c6d3 100644 --- a/src/libpspp/zip-reader.h +++ b/src/libpspp/zip-reader.h @@ -18,6 +18,8 @@ #ifndef ZIP_READER_H #define ZIP_READER_H 1 +#include +#include #include "libpspp/compiler.h" struct zip_member; @@ -26,12 +28,15 @@ struct string; /* Create zip reader to read the file called FILENAME. If successful, stores the new zip_reader in *ZRP and returns NULL; on error, returns an error - message that the caller must free and stores NULL in *ZRP. */ + message that the caller must free and stores NULL in *ZRP. + + The client must eventually unref *ZRP. */ char *zip_reader_create (const char *filename, struct zip_reader **zrp) WARN_UNUSED_RESULT; -/* Destroy the zip reader */ -void zip_reader_destroy (struct zip_reader *zr); +/* Reference counting. */ +struct zip_reader *zip_reader_ref (const struct zip_reader *); +void zip_reader_unref (struct zip_reader *zr); /* Returns the name of ZR's member IDX, IDX >= 0. Returns NULL if ZR has fewer than (IDX + 1) members. */ diff --git a/src/output/output-item.c b/src/output/output-item.c index 9febcfabd5..1b7b4b7d1c 100644 --- a/src/output/output-item.c +++ b/src/output/output-item.c @@ -45,6 +45,7 @@ struct output_item * output_item_ref (const struct output_item *item_) { struct output_item *item = CONST_CAST (struct output_item *, item_); + assert (item->ref_cnt > 0); item->ref_cnt++; return item; } diff --git a/src/output/spv/spv.c b/src/output/spv/spv.c index e23bb1b196..fc058281ec 100644 --- a/src/output/spv/spv.c +++ b/src/output/spv/spv.c @@ -1160,7 +1160,7 @@ spv_detect (const char *filename) if (spv_detect__ (zip, &error) <= 0 && !error) error = xasprintf("%s: not an SPV file", filename); - zip_reader_destroy (zip); + zip_reader_unref (zip); return error; } @@ -1215,7 +1215,7 @@ spv_close (struct spv_reader *spv) { if (spv) { - zip_reader_destroy (spv->zip); + zip_reader_unref (spv->zip); spv_item_destroy (spv->root); page_setup_destroy (spv->page_setup); free (spv); diff --git a/tests/libpspp/zip-test.c b/tests/libpspp/zip-test.c index 6590eb8e78..3556926d6c 100644 --- a/tests/libpspp/zip-test.c +++ b/tests/libpspp/zip-test.c @@ -107,7 +107,7 @@ main (int argc, char **argv) check_die (); } } - zip_reader_destroy (zr); + zip_reader_unref (zr); } else exit (1); -- 2.30.2