zip-reader: Make the zip_reader reference counted.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 23 Jan 2021 23:25:29 +0000 (15:25 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 25 Jan 2021 04:51:49 +0000 (20:51 -0800)
This will be useful in an upcoming commit.

src/data/ods-reader.c
src/libpspp/zip-reader.c
src/libpspp/zip-reader.h
src/output/output-item.c
src/output/spv/spv.c
tests/libpspp/zip-test.c

index d15c24a238a2e69772acaea5909c94e94893d28a..123ad3ba571c0fb67f3cbd828cbba7c853692474 100644 (file)
@@ -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;
 }
index 7b5aabadfbf870c9e54899984f33adb3d0edba91..b28ac75f8ba4e93c846f3227ab32e283f9013cd3 100644 (file)
 
 #include <config.h>
 
+#include "libpspp/zip-reader.h"
+#include "libpspp/zip-private.h"
+
+#include <errno.h>
 #include <inttypes.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include <errno.h>
-#include <xalloc.h>
-#include <libpspp/assertion.h>
-#include <libpspp/compiler.h>
+#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++;
index b02981d365f81a9235f7827a6276ba089e9f7a86..d245e3c6d3eb776f03da770271fba7a946b32c22 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef ZIP_READER_H
 #define ZIP_READER_H 1
 
+#include <stdbool.h>
+#include <stddef.h>
 #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. */
index 9febcfabd5ba9cf8166d44276207754a27a6fde7..1b7b4b7d1c06c90714fce02a49ec45e6f70680e5 100644 (file)
@@ -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;
 }
index e23bb1b1960eba26a964fc1fc69647802dfde671..fc058281eccd633f1e1824cd78c12a728de8fb51 100644 (file)
@@ -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);
index 6590eb8e7817694933f4841e86e66cdee88badf1..3556926d6c2c01b77c078eb0d6a8fcd4c406df80 100644 (file)
@@ -107,7 +107,7 @@ main (int argc, char **argv)
              check_die ();
            }
        }
-      zip_reader_destroy (zr);
+      zip_reader_unref (zr);
     }
   else
     exit (1);