X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fblob_table.c;h=bcccae8ba9ddb1ab96ef362cdab176756dcb375f;hb=f8223526610a6ed9410ed6ce2e704ef15ab8cade;hp=6cc0a98de30fe059beea7dc529e99a4abdbad4a4;hpb=15ded30b9bcce7ac0388dec90dd4d6ef3d6d1596;p=wimlib diff --git a/src/blob_table.c b/src/blob_table.c index 6cc0a98d..bcccae8b 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -99,17 +99,8 @@ free_blob_table(struct blob_table *table) struct blob_descriptor * new_blob_descriptor(void) { - struct blob_descriptor *blob; - - blob = CALLOC(1, sizeof(struct blob_descriptor)); - if (blob == NULL) - return NULL; - - /* blob->refcnt = 0 */ - /* blob->blob_location = BLOB_NONEXISTENT */ BUILD_BUG_ON(BLOB_NONEXISTENT != 0); - - return blob; + return CALLOC(1, sizeof(struct blob_descriptor)); } struct blob_descriptor * @@ -327,7 +318,7 @@ enlarge_blob_table(struct blob_table *table) size_t old_capacity, new_capacity; struct hlist_head *old_array, *new_array; struct blob_descriptor *blob; - struct hlist_node *cur, *tmp; + struct hlist_node *tmp; size_t i; old_capacity = table->capacity; @@ -340,7 +331,7 @@ enlarge_blob_table(struct blob_table *table) table->capacity = new_capacity; for (i = 0; i < old_capacity; i++) { - hlist_for_each_entry_safe(blob, cur, tmp, &old_array[i], hash_list) { + hlist_for_each_entry_safe(blob, tmp, &old_array[i], hash_list) { hlist_del(&blob->hash_list); blob_table_insert_raw(table, blob); } @@ -375,10 +366,9 @@ lookup_blob(const struct blob_table *table, const u8 *hash) { size_t i; struct blob_descriptor *blob; - struct hlist_node *pos; i = load_size_t_unaligned(hash) % table->capacity; - hlist_for_each_entry(blob, pos, &table->array[i], hash_list) + hlist_for_each_entry(blob, &table->array[i], hash_list) if (hashes_equal(hash, blob->hash)) return blob; return NULL; @@ -391,11 +381,11 @@ for_blob_in_table(struct blob_table *table, int (*visitor)(struct blob_descriptor *, void *), void *arg) { struct blob_descriptor *blob; - struct hlist_node *pos, *tmp; + struct hlist_node *tmp; int ret; for (size_t i = 0; i < table->capacity; i++) { - hlist_for_each_entry_safe(blob, pos, tmp, &table->array[i], + hlist_for_each_entry_safe(blob, tmp, &table->array[i], hash_list) { ret = visitor(blob, arg); @@ -738,11 +728,9 @@ assign_blob_to_solid_resource(const struct wim_reshdr *reshdr, /* XXX: This linear search will be slow in the degenerate case where the * number of solid resources in the run is huge. */ blob->size = reshdr->size_in_wim; - blob->flags = reshdr->flags; for (size_t i = 0; i < num_rdescs; i++) { if (offset + blob->size <= rdescs[i]->uncompressed_size) { - blob->offset_in_res = offset; - blob_set_is_located_in_wim_resource(blob, rdescs[i]); + blob_set_is_located_in_wim_resource(blob, rdescs[i], offset); return 0; } offset -= rdescs[i]->uncompressed_size; @@ -1012,11 +1000,7 @@ read_blob_table(WIMStruct *wim) wim_res_hdr_to_desc(&reshdr, wim, rdesc); - cur_blob->offset_in_res = 0; - cur_blob->size = reshdr.uncompressed_size; - cur_blob->flags = reshdr.flags; - - blob_set_is_located_in_wim_resource(cur_blob, rdesc); + blob_set_is_located_in_nonsolid_wim_resource(cur_blob, rdesc); } /* cur_blob is now a blob bound to a resource. */ @@ -1034,6 +1018,8 @@ read_blob_table(WIMStruct *wim) if (reshdr.flags & WIM_RESHDR_FLAG_METADATA) { + cur_blob->is_metadata = 1; + /* Blob table entry for a metadata resource. */ /* Metadata entries with no references must be ignored. @@ -1155,9 +1141,9 @@ write_blob_descriptor(struct blob_descriptor_disk *disk_entry, } /* Note: the list of blob descriptors must be sorted so that all entries for the - * same solid resource are consecutive. In addition, blob descriptors with - * WIM_RESHDR_FLAG_METADATA set must be in the same order as the indices of the - * underlying images. */ + * same solid resource are consecutive. In addition, blob descriptors for + * metadata resources must be in the same order as the indices of the underlying + * images. */ int write_blob_table_from_blob_list(struct list_head *blob_list, struct filedes *out_fd, @@ -1239,7 +1225,7 @@ write_blob_table_from_blob_list(struct list_head *blob_list, * compressed blob table, MS software cannot. */ ret = write_wim_resource_from_buffer(table_buf, table_size, - WIM_RESHDR_FLAG_METADATA, + true, out_fd, WIMLIB_COMPRESSION_TYPE_NONE, 0, @@ -1258,29 +1244,27 @@ new_blob_from_data_buffer(const void *buffer, size_t size, struct blob_table *blob_table) { u8 hash[SHA1_HASH_SIZE]; - struct blob_descriptor *blob, *existing_blob; + struct blob_descriptor *blob; + void *buffer_copy; sha1_buffer(buffer, size, hash); - existing_blob = lookup_blob(blob_table, hash); - if (existing_blob) { - wimlib_assert(existing_blob->size == size); - blob = existing_blob; - } else { - void *buffer_copy; - blob = new_blob_descriptor(); - if (blob == NULL) - return NULL; - buffer_copy = memdup(buffer, size); - if (buffer_copy == NULL) { - free_blob_descriptor(blob); - return NULL; - } - blob->blob_location = BLOB_IN_ATTACHED_BUFFER; - blob->attached_buffer = buffer_copy; - blob->size = size; - copy_hash(blob->hash, hash); - blob_table_insert(blob_table, blob); + + blob = lookup_blob(blob_table, hash); + if (blob) + return blob; + + blob = new_blob_descriptor(); + if (!blob) + return NULL; + + buffer_copy = memdup(buffer, size); + if (!buffer_copy) { + free_blob_descriptor(blob); + return NULL; } + blob_set_is_located_in_attached_buffer(blob, buffer_copy, size); + copy_hash(blob->hash, hash); + blob_table_insert(blob_table, blob); return blob; } @@ -1355,8 +1339,10 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob, wentry->uncompressed_size = blob->size; if (blob->blob_location == BLOB_IN_WIM) { + unsigned res_flags = blob->rdesc->flags; + wentry->part_number = blob->rdesc->wim->hdr.part_number; - if (blob->flags & WIM_RESHDR_FLAG_SOLID) { + if (res_flags & WIM_RESHDR_FLAG_SOLID) { wentry->offset = blob->offset_in_res; } else { wentry->compressed_size = blob->rdesc->size_in_wim; @@ -1365,14 +1351,15 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob, wentry->raw_resource_offset_in_wim = blob->rdesc->offset_in_wim; wentry->raw_resource_compressed_size = blob->rdesc->size_in_wim; wentry->raw_resource_uncompressed_size = blob->rdesc->uncompressed_size; + + wentry->is_compressed = (res_flags & WIM_RESHDR_FLAG_COMPRESSED) != 0; + wentry->is_free = (res_flags & WIM_RESHDR_FLAG_FREE) != 0; + wentry->is_spanned = (res_flags & WIM_RESHDR_FLAG_SPANNED) != 0; + wentry->packed = (res_flags & WIM_RESHDR_FLAG_SOLID) != 0; } copy_hash(wentry->sha1_hash, blob->hash); wentry->reference_count = blob->refcnt; - wentry->is_compressed = (blob->flags & WIM_RESHDR_FLAG_COMPRESSED) != 0; - wentry->is_metadata = (blob->flags & WIM_RESHDR_FLAG_METADATA) != 0; - wentry->is_free = (blob->flags & WIM_RESHDR_FLAG_FREE) != 0; - wentry->is_spanned = (blob->flags & WIM_RESHDR_FLAG_SPANNED) != 0; - wentry->packed = (blob->flags & WIM_RESHDR_FLAG_SOLID) != 0; + wentry->is_metadata = blob->is_metadata; } struct iterate_blob_context {