From 5999a0e594fac0da99ed99d065a52d3865581b28 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 25 Nov 2018 16:20:29 -0800 Subject: [PATCH] zip-reader: New function zip_member_read_all(). This will have its first user in an upcoming commit. --- src/libpspp/zip-reader.c | 33 +++++++++++++++++++++++++++++++++ src/libpspp/zip-reader.h | 6 ++++++ 2 files changed, 39 insertions(+) diff --git a/src/libpspp/zip-reader.c b/src/libpspp/zip-reader.c index 52d2b029e7..d46af3415f 100644 --- a/src/libpspp/zip-reader.c +++ b/src/libpspp/zip-reader.c @@ -232,6 +232,39 @@ zip_member_read (struct zip_member *zm, void *buf, size_t bytes) return bytes_read; } +/* Read all of ZM into memory, storing the data in *DATAP and its size in *NP. + Returns NULL if successful, otherwise an error string that the caller + must eventually free(). */ +char * WARN_UNUSED_RESULT +zip_member_read_all (struct zip_reader *zr, const char *member_name, + void **datap, size_t *np) +{ + struct zip_member *zm = zip_member_open (zr, member_name); + if (!zm) + { + *datap = NULL; + *np = 0; + return ds_steal_cstr (zr->errs); + } + + *datap = xmalloc (zm->ucomp_size); + *np = zm->ucomp_size; + + uint8_t *data = *datap; + while (zm->bytes_unread) + if (zip_member_read (zm, data + (zm->ucomp_size - zm->bytes_unread), + zm->bytes_unread) == -1) + { + zip_member_finish (zm); + free (*datap); + *datap = NULL; + *np = 0; + return ds_steal_cstr (zr->errs); + } + + zip_member_finish (zm); + return NULL; +} /* Read a central directory header from FILE and initializes ZE with it. Returns true if successful, false otherwise. On error, appends error diff --git a/src/libpspp/zip-reader.h b/src/libpspp/zip-reader.h index 225c5fecc5..7293aba318 100644 --- a/src/libpspp/zip-reader.h +++ b/src/libpspp/zip-reader.h @@ -43,6 +43,12 @@ struct zip_member *zip_member_open (struct zip_reader *zr, const char *member); Returns the number of bytes read, or -1 on error */ int zip_member_read (struct zip_member *zm, void *buf, size_t n); +/* Read all of ZM into memory, storing the data in *DATAP and its size in *NP. + Returns NULL if successful, otherwise an error string that the caller + must eventually free(). */ +char *zip_member_read_all (struct zip_reader *, const char *member_name, + void **datap, size_t *np) WARN_UNUSED_RESULT; + void zip_member_finish (struct zip_member *zm); -- 2.30.2