if (filedes_seek(out_fd, begin_offset) == -1)
return 0;
- ret = extract_full_blob_to_fd(blob, out_fd);
+ ret = extract_blob_to_fd(blob, out_fd);
if (ret) {
/* Error reading the uncompressed data. */
if (out_fd->offset == begin_offset &&
}
static void
-remove_empty_blobs(struct list_head *blob_list)
+validate_blob_list(struct list_head *blob_list)
{
- struct blob_descriptor *blob, *tmp;
+ struct blob_descriptor *blob;
- list_for_each_entry_safe(blob, tmp, blob_list, write_blobs_list) {
+ list_for_each_entry(blob, blob_list, write_blobs_list) {
wimlib_assert(blob->will_be_in_output_wim);
- if (blob->size == 0) {
- list_del(&blob->write_blobs_list);
- blob->out_reshdr.offset_in_wim = 0;
- blob->out_reshdr.size_in_wim = 0;
- blob->out_reshdr.uncompressed_size = 0;
- blob->out_reshdr.flags = reshdr_flags_for_blob(blob);
- }
+ wimlib_assert(blob->size != 0);
}
}
(WRITE_RESOURCE_FLAG_SOLID |
WRITE_RESOURCE_FLAG_PIPABLE));
- remove_empty_blobs(blob_list);
+ validate_blob_list(blob_list);
if (list_empty(blob_list))
return 0;
/* Read the list of blobs needing to be compressed, using the specified
* callbacks to execute processing of the data. */
- struct read_blob_list_callbacks cbs = {
- .begin_blob = write_blob_begin_read,
- .begin_blob_ctx = &ctx,
- .consume_chunk = write_blob_process_chunk,
- .consume_chunk_ctx = &ctx,
- .end_blob = write_blob_end_read,
- .end_blob_ctx = &ctx,
+ struct read_blob_callbacks cbs = {
+ .begin_blob = write_blob_begin_read,
+ .consume_chunk = write_blob_process_chunk,
+ .end_blob = write_blob_end_read,
+ .ctx = &ctx,
};
ret = read_blob_list(blob_list,
write_resource_flags = write_flags_to_resource_flags(write_flags);
- /* wimlib v1.7.0: create a solid WIM file by default if the WIM version
- * has been set to WIM_VERSION_SOLID and at least one blob in the WIM's
- * blob table is located in a solid resource (may be the same WIM, or a
- * different one in the case of export). */
- if (wim->out_hdr.wim_version == WIM_VERSION_SOLID &&
- wim_has_solid_resources(wim))
- {
- write_resource_flags |= WRITE_RESOURCE_FLAG_SOLID;
- }
-
if (write_resource_flags & WRITE_RESOURCE_FLAG_SOLID) {
out_chunk_size = wim->out_solid_chunk_size;
out_ctype = wim->out_solid_compression_type;
int ret;
struct blob_descriptor blob;
+ if (unlikely(buf_size == 0)) {
+ zero_reshdr(out_reshdr);
+ if (hash_ret)
+ copy_hash(hash_ret, zero_hash);
+ return 0;
+ }
+
blob_set_is_located_in_attached_buffer(&blob, (void *)buf, buf_size);
sha1_buffer(buf, buf_size, blob.hash);
blob.unhashed = 0;
* finish_write(). */
}
+static bool
+should_default_to_solid_compression(WIMStruct *wim, int write_flags)
+{
+ return wim->out_hdr.wim_version == WIM_VERSION_SOLID &&
+ !(write_flags & (WIMLIB_WRITE_FLAG_SOLID |
+ WIMLIB_WRITE_FLAG_PIPABLE)) &&
+ wim_has_solid_resources(wim);
+}
+
/* Write a standalone WIM or split WIM (SWM) part to a new file or to a file
* descriptor. */
int
else
wim->out_hdr.wim_version = WIM_VERSION_DEFAULT;
+ /* Default to solid compression if it is valid in the chosen WIM file
+ * format and the WIMStruct references any solid resources. This is
+ * useful when exporting an image from a solid WIM. */
+ if (should_default_to_solid_compression(wim, write_flags))
+ write_flags |= WIMLIB_WRITE_FLAG_SOLID;
+
/* Set the header flags. */
wim->out_hdr.flags = (wim->hdr.flags & (WIM_HDR_FLAG_RP_FIX |
WIM_HDR_FLAG_READONLY));
if (write_flags & WIMLIB_WRITE_FLAG_RETAIN_GUID)
guid = wim->hdr.guid;
if (guid)
- memcpy(wim->out_hdr.guid, guid, WIMLIB_GUID_LEN);
+ copy_guid(wim->out_hdr.guid, guid);
else
- randomize_byte_array(wim->out_hdr.guid, WIMLIB_GUID_LEN);
+ generate_guid(wim->out_hdr.guid);
/* Set the part number and total parts. */
wim->out_hdr.part_number = part_number;
if (write_flags & WIMLIB_WRITE_FLAG_SOLID)
wim->out_hdr.wim_version = WIM_VERSION_SOLID;
+ /* Default to solid compression if it is valid in the chosen WIM file
+ * format and the WIMStruct references any solid resources. This is
+ * useful when updating a solid WIM. */
+ if (should_default_to_solid_compression(wim, write_flags))
+ write_flags |= WIMLIB_WRITE_FLAG_SOLID;
+
/* Set additional flags for overwrite. */
write_flags |= WIMLIB_WRITE_FLAG_OVERWRITE |
WIMLIB_WRITE_FLAG_STREAMS_OK;