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;
#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);
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 {
/* 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
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. */
#include "wimlib/types.h"
struct blob_descriptor;
-struct read_blob_callbacks;
+struct consume_chunk_callback;
struct windows_file;
extern struct windows_file *
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);
}
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);
}
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++;
}
}
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.
}
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;
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;
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];
}
ctx->num_open_inodes = 0;
- ctx->offset = 0;
ctx->reparse_ptr = NULL;
ctx->num_reparse_inodes = 0;
return ret;
}
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;
}
if (ctx->reparse_ptr)
ctx->reparse_ptr = mempcpy(ctx->reparse_ptr, chunk, size);
- ctx->offset += size;
return 0;
}
/* 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,
};
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;
}
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;
}
* 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:
*
* 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;
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;
}
/* 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];
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;
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)
/*
* 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.
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))
.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
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,
* 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;
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;
}
#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;
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;
}
* 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,
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
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);
}
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
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)
{
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;
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
};
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,
};
.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);
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,
};
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
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);
/* 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;
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,
};
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;
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,
};
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);
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;
}
}
-/* 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;
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);
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 = {
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;
}
}
struct win32_encrypted_read_ctx {
- const struct read_blob_callbacks *cbs;
+ const struct consume_chunk_callback *cb;
int wimlib_err_code;
u64 bytes_remaining;
};
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
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;
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;
* 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);
}
/*
* @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;
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(),
/* 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;
ret = write_chunk(ctx, chunk, size, size);
if (ret)
return ret;
- ctx->cur_read_blob_offset += size;
return 0;
}
} 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,
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) {
{
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
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,
};