resource: pass blob and offset to consume_chunk
authorEric Biggers <ebiggers3@gmail.com>
Thu, 15 Dec 2016 04:49:55 +0000 (20:49 -0800)
committerEric Biggers <ebiggers3@gmail.com>
Thu, 15 Dec 2016 05:38:23 +0000 (21:38 -0800)
This makes it so that users don't need to keep track of the current blob
and offset themselves.

13 files changed:
include/wimlib/apply.h
include/wimlib/ntfs_3g.h
include/wimlib/resource.h
include/wimlib/win32.h
src/extract.c
src/ntfs-3g_apply.c
src/ntfs-3g_capture.c
src/resource.c
src/unix_apply.c
src/verify.c
src/win32_apply.c
src/win32_capture.c
src/write.c

index f77f9e9..da9087a 100644 (file)
@@ -72,8 +72,6 @@ struct apply_ctx {
        unsigned long num_blobs_remaining;
        struct list_head blob_list;
        const struct read_blob_callbacks *saved_cbs;
-       struct blob_descriptor *cur_blob;
-       u64 cur_blob_offset;
        struct filedes tmpfile_fd;
        tchar *tmpfile_name;
        unsigned int count_until_file_progress;
index 0328348..7909e43 100644 (file)
@@ -6,12 +6,12 @@
 #include "wimlib/types.h"
 
 struct blob_descriptor;
+struct consume_chunk_callback;
 struct ntfs_location;
-struct read_blob_callbacks;
 
 extern int
 read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size,
-                          const struct read_blob_callbacks *cbs);
+                          const struct consume_chunk_callback *cb);
 
 extern struct ntfs_location *
 clone_ntfs_location(const struct ntfs_location *loc);
index 2fea2f5..05ceed7 100644 (file)
@@ -192,6 +192,25 @@ wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim,
 extern int
 skip_wim_resource(const struct wim_resource_descriptor *rdesc);
 
+/*
+ * Callback function for reading chunks.  Called whenever the next chunk of
+ * uncompressed data is available, passing 'ctx' as the last argument. 'size' is
+ * guaranteed to be nonzero.  Must return 0 on success, or a positive wimlib
+ * error code on failure.
+ */
+struct consume_chunk_callback {
+       int (*func)(const void *chunk, size_t size, void *ctx);
+       void *ctx;
+};
+
+/* Pass a chunk of data to the specified consume_chunk callback */
+static inline int
+consume_chunk(const struct consume_chunk_callback *cb,
+             const void *chunk, size_t size)
+{
+       return (*cb->func)(chunk, size, cb->ctx);
+}
+
 /* Callback functions for reading blobs  */
 struct read_blob_callbacks {
 
@@ -205,7 +224,8 @@ struct read_blob_callbacks {
        /* Called when the next chunk of uncompressed data is available.  'size'
         * is guaranteed to be nonzero.  Must return 0 on success, or a positive
         * wimlib error code on failure.  */
-       int (*consume_chunk)(const void *chunk, size_t size, void *ctx);
+       int (*continue_blob)(const struct blob_descriptor *blob, u64 offset,
+                            const void *chunk, size_t size, void *ctx);
 
        /* Called when a blob has been successfully read (status=0), or when
         * begin_blob() was successfully called but an error occurred before the
@@ -228,14 +248,15 @@ call_begin_blob(struct blob_descriptor *blob,
        return (*cbs->begin_blob)(blob, cbs->ctx);
 }
 
-/* Call cbs->consume_chunk() if present.  */
+/* Call cbs->continue_blob() if present.  */
 static inline int
-call_consume_chunk(const void *chunk, size_t size,
+call_continue_blob(const struct blob_descriptor *blob, u64 offset,
+                  const void *chunk, size_t size,
                   const struct read_blob_callbacks *cbs)
 {
-       if (!cbs->consume_chunk)
+       if (!cbs->continue_blob)
                return 0;
-       return (*cbs->consume_chunk)(chunk, size, cbs->ctx);
+       return (*cbs->continue_blob)(blob, offset, chunk, size, cbs->ctx);
 }
 
 /* Call cbs->end_blob() if present.  */
index f0f99cc..94511a8 100644 (file)
@@ -10,7 +10,7 @@
 #include "wimlib/types.h"
 
 struct blob_descriptor;
-struct read_blob_callbacks;
+struct consume_chunk_callback;
 struct windows_file;
 
 extern struct windows_file *
@@ -25,7 +25,7 @@ cmp_windows_files(const struct windows_file *file1,
 
 extern int
 read_windows_file_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct read_blob_callbacks *cbs);
+                        const struct consume_chunk_callback *cb);
 
 extern int
 win32_global_init(int init_flags);
index 01bc1a5..d3df861 100644 (file)
@@ -356,13 +356,10 @@ retry:
 }
 
 static int
-begin_extract_blob_wrapper(struct blob_descriptor *blob, void *_ctx)
+begin_extract_blob(struct blob_descriptor *blob, void *_ctx)
 {
        struct apply_ctx *ctx = _ctx;
 
-       ctx->cur_blob = blob;
-       ctx->cur_blob_offset = 0;
-
        if (unlikely(blob->out_refcnt > MAX_OPEN_FILES))
                return create_temporary_file(&ctx->tmpfile_fd, &ctx->tmpfile_name);
 
@@ -370,29 +367,29 @@ begin_extract_blob_wrapper(struct blob_descriptor *blob, void *_ctx)
 }
 
 static int
-extract_chunk_wrapper(const void *chunk, size_t size, void *_ctx)
+extract_chunk(const struct blob_descriptor *blob, u64 offset,
+             const void *chunk, size_t size, void *_ctx)
 {
        struct apply_ctx *ctx = _ctx;
        union wimlib_progress_info *progress = &ctx->progress;
+       bool last = (offset + size == blob->size);
        int ret;
 
-       ctx->cur_blob_offset += size;
-
        if (likely(ctx->supported_features.hard_links)) {
                progress->extract.completed_bytes +=
-                       (u64)size * ctx->cur_blob->out_refcnt;
-               if (ctx->cur_blob_offset == ctx->cur_blob->size)
-                       progress->extract.completed_streams += ctx->cur_blob->out_refcnt;
+                       (u64)size * blob->out_refcnt;
+               if (last)
+                       progress->extract.completed_streams += blob->out_refcnt;
        } else {
                const struct blob_extraction_target *targets =
-                       blob_extraction_targets(ctx->cur_blob);
-               for (u32 i = 0; i < ctx->cur_blob->out_refcnt; i++) {
+                       blob_extraction_targets(blob);
+               for (u32 i = 0; i < blob->out_refcnt; i++) {
                        const struct wim_inode *inode = targets[i].inode;
                        const struct wim_dentry *dentry;
 
                        inode_for_each_extraction_alias(dentry, inode) {
                                progress->extract.completed_bytes += size;
-                               if (ctx->cur_blob_offset == ctx->cur_blob->size)
+                               if (last)
                                        progress->extract.completed_streams++;
                        }
                }
@@ -419,7 +416,7 @@ extract_chunk_wrapper(const void *chunk, size_t size, void *_ctx)
                return ret;
        }
 
-       return call_consume_chunk(chunk, size, ctx->saved_cbs);
+       return call_continue_blob(blob, offset, chunk, size, ctx->saved_cbs);
 }
 
 /* Copy the blob's data from the temporary file to each of its targets.
@@ -450,7 +447,7 @@ extract_from_tmpfile(const tchar *tmpfile_name,
 }
 
 static int
-end_extract_blob_wrapper(struct blob_descriptor *blob, int status, void *_ctx)
+end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx)
 {
        struct apply_ctx *ctx = _ctx;
 
@@ -489,9 +486,9 @@ int
 extract_blob_list(struct apply_ctx *ctx, const struct read_blob_callbacks *cbs)
 {
        struct read_blob_callbacks wrapper_cbs = {
-               .begin_blob     = begin_extract_blob_wrapper,
-               .consume_chunk  = extract_chunk_wrapper,
-               .end_blob       = end_extract_blob_wrapper,
+               .begin_blob     = begin_extract_blob,
+               .continue_blob  = extract_chunk,
+               .end_blob       = end_extract_blob,
                .ctx            = ctx,
        };
        ctx->saved_cbs = cbs;
index 3697b33..27b0ab9 100644 (file)
@@ -87,9 +87,6 @@ struct ntfs_3g_apply_ctx {
        struct reparse_buffer_disk rpbuf;
        u8 *reparse_ptr;
 
-       /* Offset in the blob currently being read  */
-       u64 offset;
-
        unsigned num_reparse_inodes;
        ntfs_inode *ntfs_reparse_inodes[MAX_OPEN_FILES];
        struct wim_inode *wim_reparse_inodes[MAX_OPEN_FILES];
@@ -756,7 +753,6 @@ ntfs_3g_cleanup_blob_extract(struct ntfs_3g_apply_ctx *ctx)
        }
        ctx->num_open_inodes = 0;
 
-       ctx->offset = 0;
        ctx->reparse_ptr = NULL;
        ctx->num_reparse_inodes = 0;
        return ret;
@@ -842,13 +838,14 @@ ntfs_3g_full_pwrite(ntfs_attr *na, u64 offset, size_t size, const u8 *data)
 }
 
 static int
-ntfs_3g_extract_chunk(const void *chunk, size_t size, void *_ctx)
+ntfs_3g_extract_chunk(const struct blob_descriptor *blob, u64 offset,
+                     const void *chunk, size_t size, void *_ctx)
 {
        struct ntfs_3g_apply_ctx *ctx = _ctx;
 
        for (unsigned i = 0; i < ctx->num_open_attrs; i++) {
-               if (!ntfs_3g_full_pwrite(ctx->open_attrs[i],
-                                        ctx->offset, size, chunk))
+               if (!ntfs_3g_full_pwrite(ctx->open_attrs[i], offset,
+                                        size, chunk))
                {
                        ERROR_WITH_ERRNO("Error writing data to NTFS volume");
                        return WIMLIB_ERR_NTFS_3G;
@@ -856,7 +853,6 @@ ntfs_3g_extract_chunk(const void *chunk, size_t size, void *_ctx)
        }
        if (ctx->reparse_ptr)
                ctx->reparse_ptr = mempcpy(ctx->reparse_ptr, chunk, size);
-       ctx->offset += size;
        return 0;
 }
 
@@ -960,7 +956,7 @@ ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx)
        /* Extract blobs.  */
        struct read_blob_callbacks cbs = {
                .begin_blob     = ntfs_3g_begin_extract_blob,
-               .consume_chunk  = ntfs_3g_extract_chunk,
+               .continue_blob  = ntfs_3g_extract_chunk,
                .end_blob       = ntfs_3g_end_extract_blob,
                .ctx            = ctx,
        };
index b496e02..ca8d1b2 100644 (file)
@@ -117,7 +117,7 @@ open_ntfs_attr(ntfs_inode *ni, const struct ntfs_location *loc)
 
 int
 read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size,
-                          const struct read_blob_callbacks *cbs)
+                          const struct consume_chunk_callback *cb)
 {
        const struct ntfs_location *loc = blob->ntfs_loc;
        ntfs_volume *vol = loc->volume->vol;
@@ -154,7 +154,7 @@ read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size,
                }
                pos += to_read;
                bytes_remaining -= to_read;
-               ret = call_consume_chunk(buf, to_read, cbs);
+               ret = consume_chunk(cb, buf, to_read);
                if (ret)
                        goto out_close_ntfs_attr;
        }
index 385f9f6..9f119c4 100644 (file)
@@ -93,11 +93,11 @@ struct data_range {
  *     read, sorted by increasing offset.
  * @num_ranges
  *     Number of ranges in @ranges; must be at least 1.
- * @cbs
- *     Structure which provides the consume_chunk() callback to feed the data
- *     being read.  Each call provides the next chunk of the requested data,
- *     uncompressed.  Each chunk will be nonempty and will not cross range
- *     boundaries but otherwise will be of unspecified size.
+ * @cb
+ *     Structure which provides the consume_chunk callback into which to feed
+ *     the data being read.  Each call provides the next chunk of the requested
+ *     data, uncompressed.  Each chunk will be nonempty and will not cross
+ *     range boundaries but otherwise will be of unspecified size.
  *
  * Possible return values:
  *
@@ -108,13 +108,13 @@ struct data_range {
  *     WIMLIB_ERR_DECOMPRESSION          (errno set to EINVAL)
  *     WIMLIB_ERR_INVALID_CHUNK_SIZE     (errno set to EINVAL)
  *
- *     or other error code returned by the cbs->consume_chunk() function.
+ *     or other error code returned by the callback function.
  */
 static int
 read_compressed_wim_resource(const struct wim_resource_descriptor * const rdesc,
                             const struct data_range * const ranges,
                             const size_t num_ranges,
-                            const struct read_blob_callbacks *cbs)
+                            const struct consume_chunk_callback *cb)
 {
        int ret;
        u64 *chunk_offsets = NULL;
@@ -473,7 +473,7 @@ read_compressed_wim_resource(const struct wim_resource_descriptor * const rdesc,
                                end = min(cur_range_end, chunk_end_offset) - chunk_start_offset;
                                size = end - start;
 
-                               ret = call_consume_chunk(&ubuf[start], size, cbs);
+                               ret = consume_chunk(cb, &ubuf[start], size);
                                if (unlikely(ret))
                                        goto out_cleanup;
 
@@ -533,10 +533,10 @@ read_error:
 }
 
 /* Read raw data from a file descriptor at the specified offset, feeding the
- * data in nonempty chunks into the cbs->consume_chunk() function.  */
+ * data in nonempty chunks into the specified callback function.  */
 static int
 read_raw_file_data(struct filedes *in_fd, u64 offset, u64 size,
-                  const struct read_blob_callbacks *cbs,
+                  const struct consume_chunk_callback *cb,
                   const tchar *filename)
 {
        u8 buf[BUFFER_SIZE];
@@ -548,7 +548,7 @@ read_raw_file_data(struct filedes *in_fd, u64 offset, u64 size,
                ret = full_pread(in_fd, buf, bytes_to_read, offset);
                if (unlikely(ret))
                        goto read_error;
-               ret = call_consume_chunk(buf, bytes_to_read, cbs);
+               ret = consume_chunk(cb, buf, bytes_to_read);
                if (unlikely(ret))
                        return ret;
                size -= bytes_to_read;
@@ -568,7 +568,7 @@ read_error:
        return ret;
 }
 
-/* A consume_chunk() implementation that simply concatenates all chunks into an
+/* A consume_chunk implementation which simply concatenates all chunks into an
  * in-memory buffer.  */
 static int
 bufferer_cb(const void *chunk, size_t size, void *_ctx)
@@ -581,7 +581,7 @@ bufferer_cb(const void *chunk, size_t size, void *_ctx)
 
 /*
  * Read @size bytes at @offset in the WIM resource described by @rdesc and feed
- * the data into the @cbs->consume_chunk callback function.
+ * the data into the @cb callback function.
  *
  * @offset and @size are assumed to have already been validated against the
  * resource's uncompressed size.
@@ -592,7 +592,7 @@ bufferer_cb(const void *chunk, size_t size, void *_ctx)
 static int
 read_partial_wim_resource(const struct wim_resource_descriptor *rdesc,
                          const u64 offset, const u64 size,
-                         const struct read_blob_callbacks *cbs)
+                         const struct consume_chunk_callback *cb)
 {
        if (rdesc->flags & (WIM_RESHDR_FLAG_COMPRESSED |
                            WIM_RESHDR_FLAG_SOLID))
@@ -604,13 +604,13 @@ read_partial_wim_resource(const struct wim_resource_descriptor *rdesc,
                        .offset = offset,
                        .size = size,
                };
-               return read_compressed_wim_resource(rdesc, &range, 1, cbs);
+               return read_compressed_wim_resource(rdesc, &range, 1, cb);
        }
 
        /* Uncompressed resource  */
        return read_raw_file_data(&rdesc->wim->in_fd,
                                  rdesc->offset_in_wim + offset,
-                                 size, cbs, NULL);
+                                 size, cb, NULL);
 }
 
 /* Read the specified range of uncompressed data from the specified blob, which
@@ -619,32 +619,39 @@ int
 read_partial_wim_blob_into_buf(const struct blob_descriptor *blob,
                               u64 offset, size_t size, void *buf)
 {
-       struct read_blob_callbacks cbs = {
-               .consume_chunk  = bufferer_cb,
-               .ctx            = &buf,
+       struct consume_chunk_callback cb = {
+               .func   = bufferer_cb,
+               .ctx    = &buf,
        };
        return read_partial_wim_resource(blob->rdesc,
                                         blob->offset_in_res + offset,
                                         size,
-                                        &cbs);
+                                        &cb);
+}
+
+static int
+noop_cb(const void *chunk, size_t size, void *_ctx)
+{
+       return 0;
 }
 
 /* Skip over the data of the specified WIM resource.  */
 int
 skip_wim_resource(const struct wim_resource_descriptor *rdesc)
 {
-       struct read_blob_callbacks cbs = {
+       struct consume_chunk_callback cb = {
+               .func = noop_cb,
        };
        return read_partial_wim_resource(rdesc, 0,
-                                        rdesc->uncompressed_size, &cbs);
+                                        rdesc->uncompressed_size, &cb);
 }
 
 static int
 read_wim_blob_prefix(const struct blob_descriptor *blob, u64 size,
-                    const struct read_blob_callbacks *cbs)
+                    const struct consume_chunk_callback *cb)
 {
        return read_partial_wim_resource(blob->rdesc, blob->offset_in_res,
-                                        size, cbs);
+                                        size, cb);
 }
 
 /* This function handles reading blob data that is located in an external file,
@@ -657,7 +664,7 @@ read_wim_blob_prefix(const struct blob_descriptor *blob, u64 size,
  * encrypted), so Windows uses its own code for its equivalent case.  */
 static int
 read_file_on_disk_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct read_blob_callbacks *cbs)
+                        const struct consume_chunk_callback *cb)
 {
        int ret;
        int raw_fd;
@@ -669,7 +676,7 @@ read_file_on_disk_prefix(const struct blob_descriptor *blob, u64 size,
                return WIMLIB_ERR_OPEN;
        }
        filedes_init(&fd, raw_fd);
-       ret = read_raw_file_data(&fd, 0, size, cbs, blob->file_on_disk);
+       ret = read_raw_file_data(&fd, 0, size, cb, blob->file_on_disk);
        filedes_close(&fd);
        return ret;
 }
@@ -677,7 +684,7 @@ read_file_on_disk_prefix(const struct blob_descriptor *blob, u64 size,
 #ifdef WITH_FUSE
 static int
 read_staging_file_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct read_blob_callbacks *cbs)
+                        const struct consume_chunk_callback *cb)
 {
        int raw_fd;
        struct filedes fd;
@@ -691,7 +698,7 @@ read_staging_file_prefix(const struct blob_descriptor *blob, u64 size,
                return WIMLIB_ERR_OPEN;
        }
        filedes_init(&fd, raw_fd);
-       ret = read_raw_file_data(&fd, 0, size, cbs, blob->staging_file_name);
+       ret = read_raw_file_data(&fd, 0, size, cb, blob->staging_file_name);
        filedes_close(&fd);
        return ret;
 }
@@ -701,32 +708,31 @@ read_staging_file_prefix(const struct blob_descriptor *blob, u64 size,
  * already located in an in-memory buffer.  */
 static int
 read_buffer_prefix(const struct blob_descriptor *blob,
-                  u64 size, const struct read_blob_callbacks *cbs)
+                  u64 size, const struct consume_chunk_callback *cb)
 {
        if (unlikely(!size))
                return 0;
-       return call_consume_chunk(blob->attached_buffer, size, cbs);
+       return consume_chunk(cb, blob->attached_buffer, size);
 }
 
 typedef int (*read_blob_prefix_handler_t)(const struct blob_descriptor *blob,
                                          u64 size,
-                                         const struct read_blob_callbacks *cbs);
+                                         const struct consume_chunk_callback *cb);
 
 /*
  * Read the first @size bytes from a generic "blob", which may be located in any
  * one of several locations, such as in a WIM resource (possibly compressed), in
  * an external file, or directly in an in-memory buffer.  The blob data will be
- * fed to the cbs->consume_chunk() callback function in chunks that are nonempty
- * but otherwise are of unspecified size.
+ * fed to @cb in chunks that are nonempty but otherwise are of unspecified size.
  *
  * Returns 0 on success; nonzero on error.  A nonzero value will be returned if
  * the blob data cannot be successfully read (for a number of different reasons,
- * depending on the blob location), or if cbs->consume_chunk() returned nonzero
- * in which case that error code will be returned.
+ * depending on the blob location), or if @cb returned nonzero in which case
+ * that error code will be returned.
  */
 static int
 read_blob_prefix(const struct blob_descriptor *blob, u64 size,
-                const struct read_blob_callbacks *cbs)
+                const struct consume_chunk_callback *cb)
 {
        static const read_blob_prefix_handler_t handlers[] = {
                [BLOB_IN_WIM] = read_wim_blob_prefix,
@@ -745,7 +751,24 @@ read_blob_prefix(const struct blob_descriptor *blob, u64 size,
        wimlib_assert(blob->blob_location < ARRAY_LEN(handlers)
                      && handlers[blob->blob_location] != NULL);
        wimlib_assert(size <= blob->size);
-       return handlers[blob->blob_location](blob, size, cbs);
+       return handlers[blob->blob_location](blob, size, cb);
+}
+
+struct blob_chunk_ctx {
+       const struct blob_descriptor *blob;
+       const struct read_blob_callbacks *cbs;
+       u64 offset;
+};
+
+static int
+consume_blob_chunk(const void *chunk, size_t size, void *_ctx)
+{
+       struct blob_chunk_ctx *ctx = _ctx;
+       int ret;
+
+       ret = call_continue_blob(ctx->blob, ctx->offset, chunk, size, ctx->cbs);
+       ctx->offset += size;
+       return ret;
 }
 
 /* Read the full data of the specified blob, passing the data into the specified
@@ -755,12 +778,21 @@ read_blob_with_cbs(struct blob_descriptor *blob,
                   const struct read_blob_callbacks *cbs)
 {
        int ret;
+       struct blob_chunk_ctx ctx = {
+               .blob = blob,
+               .offset = 0,
+               .cbs = cbs,
+       };
+       struct consume_chunk_callback cb = {
+               .func = consume_blob_chunk,
+               .ctx = &ctx,
+       };
 
        ret = call_begin_blob(blob, cbs);
        if (unlikely(ret))
                return ret;
 
-       ret = read_blob_prefix(blob, blob->size, cbs);
+       ret = read_blob_prefix(blob, blob->size, &cb);
 
        return call_end_blob(blob, ret, cbs);
 }
@@ -771,11 +803,11 @@ read_blob_with_cbs(struct blob_descriptor *blob,
 int
 read_blob_into_buf(const struct blob_descriptor *blob, void *buf)
 {
-       struct read_blob_callbacks cbs = {
-               .consume_chunk  = bufferer_cb,
-               .ctx            = &buf,
+       struct consume_chunk_callback cb = {
+               .func   = bufferer_cb,
+               .ctx    = &buf,
        };
-       return read_blob_prefix(blob, blob->size, &cbs);
+       return read_blob_prefix(blob, blob->size, &cb);
 }
 
 /* Retrieve the full uncompressed data of the specified blob.  A buffer large
@@ -861,9 +893,10 @@ next_blob(struct blob_descriptor *blob, size_t list_head_offset)
        return (struct blob_descriptor*)((u8*)cur->next - list_head_offset);
 }
 
-/* A consume_chunk() implementation that translates raw resource data into
- * blobs, calling the begin_blob, consume_chunk, and end_blob callbacks as
- * appropriate.  */
+/*
+ * A consume_chunk implementation that translates raw resource data into blobs,
+ * calling the begin_blob, continue_blob, and end_blob callbacks as appropriate.
+ */
 static int
 blobifier_cb(const void *chunk, size_t size, void *_ctx)
 {
@@ -880,9 +913,9 @@ blobifier_cb(const void *chunk, size_t size, void *_ctx)
                        return ret;
        }
 
+       ret = call_continue_blob(ctx->cur_blob, ctx->cur_blob_offset,
+                                chunk, size, &ctx->cbs);
        ctx->cur_blob_offset += size;
-
-       ret = call_consume_chunk(chunk, size, &ctx->cbs);
        if (ret)
                return ret;
 
@@ -926,18 +959,21 @@ hasher_begin_blob(struct blob_descriptor *blob, void *_ctx)
        return call_begin_blob(blob, &ctx->cbs);
 }
 
-/* A consume_chunk() implementation that continues calculating the SHA-1 message
+/*
+ * A continue_blob() implementation that continues calculating the SHA-1 message
  * digest of the blob being read, then optionally passes the data on to another
- * consume_chunk() implementation.  This allows checking the SHA-1 message
- * digest of a blob being extracted, for example.  */
+ * continue_blob() implementation.  This allows checking the SHA-1 message
+ * digest of a blob being extracted, for example.
+ */
 static int
-hasher_consume_chunk(const void *chunk, size_t size, void *_ctx)
+hasher_continue_blob(const struct blob_descriptor *blob, u64 offset,
+                    const void *chunk, size_t size, void *_ctx)
 {
        struct hasher_context *ctx = _ctx;
 
        sha1_update(&ctx->sha_ctx, chunk, size);
 
-       return call_consume_chunk(chunk, size, &ctx->cbs);
+       return call_continue_blob(blob, offset, chunk, size, &ctx->cbs);
 }
 
 static int
@@ -1043,7 +1079,7 @@ read_blob_with_sha1(struct blob_descriptor *blob,
        };
        struct read_blob_callbacks hasher_cbs = {
                .begin_blob     = hasher_begin_blob,
-               .consume_chunk  = hasher_consume_chunk,
+               .continue_blob  = hasher_continue_blob,
                .end_blob       = hasher_end_blob,
                .ctx            = &hasher_ctx,
        };
@@ -1099,13 +1135,13 @@ read_blobs_in_solid_resource(struct blob_descriptor *first_blob,
                .final_blob             = last_blob,
                .list_head_offset       = list_head_offset,
        };
-       struct read_blob_callbacks cbs = {
-               .consume_chunk  = blobifier_cb,
-               .ctx            = &blobifier_ctx,
+       struct consume_chunk_callback cb = {
+               .func   = blobifier_cb,
+               .ctx    = &blobifier_ctx,
        };
 
        ret = read_compressed_wim_resource(first_blob->rdesc, ranges,
-                                          blob_count, &cbs);
+                                          blob_count, &cb);
 
        if (ranges_malloced)
                FREE(ranges);
@@ -1185,7 +1221,7 @@ read_blob_list(struct list_head *blob_list, size_t list_head_offset,
                sink_cbs = alloca(sizeof(*sink_cbs));
                *sink_cbs = (struct read_blob_callbacks) {
                        .begin_blob     = hasher_begin_blob,
-                       .consume_chunk  = hasher_consume_chunk,
+                       .continue_blob  = hasher_continue_blob,
                        .end_blob       = hasher_end_blob,
                        .ctx            = hasher_ctx,
                };
@@ -1261,17 +1297,24 @@ extract_chunk_to_fd(const void *chunk, size_t size, void *_fd)
        return ret;
 }
 
+static int
+extract_blob_chunk_to_fd(const struct blob_descriptor *blob, u64 offset,
+                        const void *chunk, size_t size, void *_fd)
+{
+       return extract_chunk_to_fd(chunk, size, _fd);
+}
+
 /* Extract the first @size bytes of the specified blob to the specified file
  * descriptor.  This does *not* check the SHA-1 message digest.  */
 int
 extract_blob_prefix_to_fd(struct blob_descriptor *blob, u64 size,
                          struct filedes *fd)
 {
-       struct read_blob_callbacks cbs = {
-               .consume_chunk  = extract_chunk_to_fd,
-               .ctx            = fd,
+       struct consume_chunk_callback cb = {
+               .func   = extract_chunk_to_fd,
+               .ctx    = fd,
        };
-       return read_blob_prefix(blob, size, &cbs);
+       return read_blob_prefix(blob, size, &cb);
 }
 
 /* Extract the full uncompressed contents of the specified blob to the specified
@@ -1280,7 +1323,7 @@ int
 extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd)
 {
        struct read_blob_callbacks cbs = {
-               .consume_chunk  = extract_chunk_to_fd,
+               .continue_blob  = extract_blob_chunk_to_fd,
                .ctx            = fd,
        };
        return read_blob_with_sha1(blob, &cbs);
index 3746f50..672f39e 100644 (file)
@@ -611,7 +611,8 @@ unix_begin_extract_blob(struct blob_descriptor *blob, void *_ctx)
 
 /* Called when the next chunk of a blob has been read for extraction  */
 static int
-unix_extract_chunk(const void *chunk, size_t size, void *_ctx)
+unix_extract_chunk(const struct blob_descriptor *blob, u64 offset,
+                  const void *chunk, size_t size, void *_ctx)
 {
        struct unix_apply_ctx *ctx = _ctx;
        int ret;
@@ -765,7 +766,7 @@ unix_extract(struct list_head *dentry_list, struct apply_ctx *_ctx)
 
        struct read_blob_callbacks cbs = {
                .begin_blob     = unix_begin_extract_blob,
-               .consume_chunk  = unix_extract_chunk,
+               .continue_blob  = unix_extract_chunk,
                .end_blob       = unix_end_extract_blob,
                .ctx            = ctx,
        };
index e11561e..41fcff7 100644 (file)
@@ -44,28 +44,16 @@ struct verify_blob_list_ctx {
        void *progctx;
        union wimlib_progress_info *progress;
        u64 next_progress;
-       u64 cur_blob_offset;
-       u64 cur_blob_size;
 };
 
 static int
-verify_begin_blob(struct blob_descriptor *blob, void *_ctx)
-{
-       struct verify_blob_list_ctx *ctx = _ctx;
-
-       ctx->cur_blob_offset = 0;
-       ctx->cur_blob_size = blob->size;
-       return 0;
-}
-
-static int
-verify_consume_chunk(const void *chunk, size_t size, void *_ctx)
+verify_continue_blob(const struct blob_descriptor *blob, u64 offset,
+                    const void *chunk, size_t size, void *_ctx)
 {
        struct verify_blob_list_ctx *ctx = _ctx;
        union wimlib_progress_info *progress = ctx->progress;
 
-       ctx->cur_blob_offset += size;
-       if (ctx->cur_blob_offset == ctx->cur_blob_size)
+       if (offset + size == blob->size)
                progress->verify_streams.completed_streams++;
 
        progress->verify_streams.completed_bytes += size;
@@ -110,8 +98,7 @@ wimlib_verify_wim(WIMStruct *wim, int verify_flags)
        struct verify_blob_list_ctx ctx;
        struct blob_descriptor *blob;
        struct read_blob_callbacks cbs = {
-               .begin_blob     = verify_begin_blob,
-               .consume_chunk  = verify_consume_chunk,
+               .continue_blob  = verify_continue_blob,
                .ctx            = &ctx,
        };
 
index a4f8175..b55ce92 100644 (file)
@@ -2257,9 +2257,9 @@ retry:
        return 0;
 }
 
-/* Called when starting to read a blob for extraction on Windows  */
+/* Called when starting to read a blob for extraction */
 static int
-begin_extract_blob(struct blob_descriptor *blob, void *_ctx)
+win32_begin_extract_blob(struct blob_descriptor *blob, void *_ctx)
 {
        struct win32_apply_ctx *ctx = _ctx;
        const struct blob_extraction_target *targets = blob_extraction_targets(blob);
@@ -2302,10 +2302,10 @@ fail:
        return ret;
 }
 
-/* Called when the next chunk of a blob has been read for extraction on Windows
- */
+/* Called when the next chunk of a blob has been read for extraction */
 static int
-extract_chunk(const void *chunk, size_t size, void *_ctx)
+win32_extract_chunk(const struct blob_descriptor *blob, u64 offset,
+                   const void *chunk, size_t size, void *_ctx)
 {
        struct win32_apply_ctx *ctx = _ctx;
 
@@ -2590,9 +2590,9 @@ handle_system_compression(struct blob_descriptor *blob, struct win32_apply_ctx *
        }
 }
 
-/* Called when a blob has been fully read for extraction on Windows  */
+/* Called when a blob has been fully read for extraction */
 static int
-end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx)
+win32_end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx)
 {
        struct win32_apply_ctx *ctx = _ctx;
        int ret;
@@ -3071,9 +3071,9 @@ win32_extract(struct list_head *dentry_list, struct apply_ctx *_ctx)
                goto out;
 
        struct read_blob_callbacks cbs = {
-               .begin_blob     = begin_extract_blob,
-               .consume_chunk  = extract_chunk,
-               .end_blob       = end_extract_blob,
+               .begin_blob     = win32_begin_extract_blob,
+               .continue_blob  = win32_extract_chunk,
+               .end_blob       = win32_end_extract_blob,
                .ctx            = ctx,
        };
        ret = extract_blob_list(&ctx->common, &cbs);
index b5b8bc5..a93427e 100644 (file)
@@ -315,7 +315,7 @@ windows_file_to_string(const struct windows_file *file, u8 *buf, size_t bufsize)
 
 static int
 read_winnt_stream_prefix(const struct windows_file *file,
-                        u64 size, const struct read_blob_callbacks *cbs)
+                        u64 size, const struct consume_chunk_callback *cb)
 {
        IO_STATUS_BLOCK iosb;
        UNICODE_STRING name = {
@@ -401,7 +401,7 @@ read_winnt_stream_prefix(const struct windows_file *file,
                bytes_read = iosb.Information;
 
                bytes_remaining -= bytes_read;
-               ret = call_consume_chunk(buf, bytes_read, cbs);
+               ret = consume_chunk(cb, buf, bytes_read);
                if (ret)
                        break;
        }
@@ -410,7 +410,7 @@ read_winnt_stream_prefix(const struct windows_file *file,
 }
 
 struct win32_encrypted_read_ctx {
-       const struct read_blob_callbacks *cbs;
+       const struct consume_chunk_callback *cb;
        int wimlib_err_code;
        u64 bytes_remaining;
 };
@@ -425,7 +425,7 @@ win32_encrypted_export_cb(unsigned char *data, void *_ctx, unsigned long len)
        if (bytes_to_consume == 0)
                return ERROR_SUCCESS;
 
-       ret = call_consume_chunk(data, bytes_to_consume, ctx->cbs);
+       ret = consume_chunk(ctx->cb, data, bytes_to_consume);
        if (ret) {
                ctx->wimlib_err_code = ret;
                /* It doesn't matter what error code is returned here, as long
@@ -438,7 +438,7 @@ win32_encrypted_export_cb(unsigned char *data, void *_ctx, unsigned long len)
 
 static int
 read_win32_encrypted_file_prefix(const wchar_t *path, bool is_dir, u64 size,
-                                const struct read_blob_callbacks *cbs)
+                                const struct consume_chunk_callback *cb)
 {
        struct win32_encrypted_read_ctx export_ctx;
        DWORD err;
@@ -449,7 +449,7 @@ read_win32_encrypted_file_prefix(const wchar_t *path, bool is_dir, u64 size,
        if (is_dir)
                flags |= CREATE_FOR_DIR;
 
-       export_ctx.cbs = cbs;
+       export_ctx.cb = cb;
        export_ctx.wimlib_err_code = 0;
        export_ctx.bytes_remaining = size;
 
@@ -487,16 +487,16 @@ read_win32_encrypted_file_prefix(const wchar_t *path, bool is_dir, u64 size,
  * described by @blob.  */
 int
 read_windows_file_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct read_blob_callbacks *cbs)
+                        const struct consume_chunk_callback *cb)
 {
        const struct windows_file *file = blob->windows_file;
 
        if (unlikely(file->is_encrypted)) {
                bool is_dir = (blob->file_inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY);
-               return read_win32_encrypted_file_prefix(file->path, is_dir, size, cbs);
+               return read_win32_encrypted_file_prefix(file->path, is_dir, size, cb);
        }
 
-       return read_winnt_stream_prefix(file, size, cbs);
+       return read_winnt_stream_prefix(file, size, cb);
 }
 
 /*
index f5a9935..7eaa0df 100644 (file)
@@ -377,12 +377,6 @@ struct write_blobs_ctx {
         * @blobs_being_compressed only when writing a solid resource.  */
        struct list_head blobs_in_solid_resource;
 
-       /* Current uncompressed offset in the blob being read.  */
-       u64 cur_read_blob_offset;
-
-       /* Uncompressed size of the blob currently being read.  */
-       u64 cur_read_blob_size;
-
        /* Current uncompressed offset in the blob being written.  */
        u64 cur_write_blob_offset;
 
@@ -689,9 +683,6 @@ write_blob_begin_read(struct blob_descriptor *blob, void *_ctx)
 
        wimlib_assert(blob->size > 0);
 
-       ctx->cur_read_blob_offset = 0;
-       ctx->cur_read_blob_size = blob->size;
-
        /* As an optimization, we allow some blobs to be "unhashed", meaning
         * their SHA-1 message digests are unknown.  This is the case with blobs
         * that are added by scanning a directory tree with wimlib_add_image(),
@@ -1019,7 +1010,8 @@ prepare_chunk_buffer(struct write_blobs_ctx *ctx)
 
 /* Process the next chunk of data to be written to a WIM resource.  */
 static int
-write_blob_process_chunk(const void *chunk, size_t size, void *_ctx)
+write_blob_process_chunk(const struct blob_descriptor *blob, u64 offset,
+                        const void *chunk, size_t size, void *_ctx)
 {
        struct write_blobs_ctx *ctx = _ctx;
        int ret;
@@ -1032,7 +1024,6 @@ write_blob_process_chunk(const void *chunk, size_t size, void *_ctx)
                 ret = write_chunk(ctx, chunk, size, size);
                 if (ret)
                         return ret;
-                ctx->cur_read_blob_offset += size;
                 return 0;
        }
 
@@ -1056,8 +1047,7 @@ write_blob_process_chunk(const void *chunk, size_t size, void *_ctx)
                } else {
                        needed_chunk_size = min(ctx->out_chunk_size,
                                                ctx->cur_chunk_buf_filled +
-                                                       (ctx->cur_read_blob_size -
-                                                        ctx->cur_read_blob_offset));
+                                                       (blob->size - offset));
                }
 
                bytes_consumed = min(chunkend - chunkptr,
@@ -1067,7 +1057,7 @@ write_blob_process_chunk(const void *chunk, size_t size, void *_ctx)
                       chunkptr, bytes_consumed);
 
                chunkptr += bytes_consumed;
-               ctx->cur_read_blob_offset += bytes_consumed;
+               offset += bytes_consumed;
                ctx->cur_chunk_buf_filled += bytes_consumed;
 
                if (ctx->cur_chunk_buf_filled == needed_chunk_size) {
@@ -1088,8 +1078,6 @@ write_blob_end_read(struct blob_descriptor *blob, int status, void *_ctx)
 {
        struct write_blobs_ctx *ctx = _ctx;
 
-       wimlib_assert(ctx->cur_read_blob_offset == ctx->cur_read_blob_size || status);
-
        if (!blob->will_be_in_output_wim) {
                /* The blob was a duplicate.  Now that its data has finished
                 * being read, it is being discarded in favor of the duplicate
@@ -1616,7 +1604,7 @@ write_blob_list(struct list_head *blob_list,
 
        struct read_blob_callbacks cbs = {
                .begin_blob     = write_blob_begin_read,
-               .consume_chunk  = write_blob_process_chunk,
+               .continue_blob  = write_blob_process_chunk,
                .end_blob       = write_blob_end_read,
                .ctx            = &ctx,
        };