This will be useful in an upcoming commit.
dict_unref (r->spreadsheet.dict);
- zip_reader_destroy (r->zreader);
+ zip_reader_unref (r->zreader);
free (r->spreadsheet.sheets);
free (s->file_name);
return &r->spreadsheet;
error:
- zip_reader_destroy (r->zreader);
+ zip_reader_unref (r->zreader);
free (r);
return NULL;
}
#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)
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. */
}
}
+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);
}
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++)
if (error)
{
fclose (file);
- zip_reader_destroy (zr);
+ zip_reader_unref (zr);
return error;
}
zr->n_entries++;
#ifndef ZIP_READER_H
#define ZIP_READER_H 1
+#include <stdbool.h>
+#include <stddef.h>
#include "libpspp/compiler.h"
struct zip_member;
/* 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. */
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;
}
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;
}
{
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);
check_die ();
}
}
- zip_reader_destroy (zr);
+ zip_reader_unref (zr);
}
else
exit (1);