X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Freference.c;h=a380d4eeff1dd89715a4993e04aa6c5d21477e34;hb=3d9eb49da969c4ac2c8579db7baf96ae3fd04e1c;hp=013b285d504f73148d1e91186522cb16c9abdc28;hpb=f448d994fe935614b586bd6797e20d5596a3e1a3;p=wimlib diff --git a/src/reference.c b/src/reference.c index 013b285d..a380d4ee 100644 --- a/src/reference.c +++ b/src/reference.c @@ -1,11 +1,11 @@ /* * reference.c * - * Reference resources from external WIM file(s). + * Reference blobs from external WIM file(s). */ /* - * Copyright (C) 2013, 2014 Eric Biggers + * Copyright (C) 2013, 2014, 2015 Eric Biggers * * This file is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -26,9 +26,9 @@ #endif #include "wimlib.h" +#include "wimlib/blob_table.h" #include "wimlib/error.h" #include "wimlib/glob.h" -#include "wimlib/lookup_table.h" #include "wimlib/wim.h" #define WIMLIB_REF_MASK_PUBLIC (WIMLIB_REF_FLAG_GLOB_ENABLE | \ @@ -36,10 +36,9 @@ struct reference_info { WIMStruct *dest_wim; - struct list_head new_streams; - struct list_head new_subwims; + struct list_head new_blobs; int ref_flags; - struct wim_lookup_table *src_table; + struct blob_table *src_table; }; static void @@ -47,81 +46,47 @@ init_reference_info(struct reference_info *info, WIMStruct *dest_wim, int ref_flags) { info->dest_wim = dest_wim; - INIT_LIST_HEAD(&info->new_streams); - INIT_LIST_HEAD(&info->new_subwims); + INIT_LIST_HEAD(&info->new_blobs); info->ref_flags = ref_flags; } -static void -commit_reference_info(struct reference_info *info) -{ - list_splice(&info->new_subwims, &info->dest_wim->subwims); -} - static void rollback_reference_info(struct reference_info *info) { - WIMStruct *subwim; - struct wim_lookup_table_entry *lte; - - while (!list_empty(&info->new_subwims)) { - subwim = list_first_entry(&info->new_subwims, - WIMStruct, subwim_node); - list_del(&subwim->subwim_node); - wimlib_free(subwim); - } - - while (!list_empty(&info->new_streams)) { - lte = list_first_entry(&info->new_streams, - struct wim_lookup_table_entry, - lookup_table_list); - list_del(<e->lookup_table_list); - lookup_table_unlink(info->dest_wim->lookup_table, lte); - free_lookup_table_entry(lte); + struct blob_descriptor *blob; + + while (!list_empty(&info->new_blobs)) { + blob = list_first_entry(&info->new_blobs, + struct blob_descriptor, blob_table_list); + list_del(&blob->blob_table_list); + blob_table_unlink(info->dest_wim->blob_table, blob); + free_blob_descriptor(blob); } } -static int -commit_or_rollback_reference_info(struct reference_info *info, int ret) -{ - if (unlikely(ret)) - rollback_reference_info(info); - else - commit_reference_info(info); - return ret; -} - static bool -need_stream(const struct reference_info *info, - const struct wim_lookup_table_entry *lte) -{ - return !lookup_stream(info->dest_wim->lookup_table, lte->hash); -} - -static void -reference_stream(struct reference_info *info, - struct wim_lookup_table_entry *lte) +need_blob(const struct reference_info *info, const struct blob_descriptor *blob) { - lookup_table_insert(info->dest_wim->lookup_table, lte); - list_add(<e->lookup_table_list, &info->new_streams); + return !lookup_blob(info->dest_wim->blob_table, blob->hash); } static void -reference_subwim(struct reference_info *info, WIMStruct *subwim) +reference_blob(struct reference_info *info, struct blob_descriptor *blob) { - list_add(&subwim->subwim_node, &info->new_subwims); + blob_table_insert(info->dest_wim->blob_table, blob); + list_add(&blob->blob_table_list, &info->new_blobs); } static int -lte_clone_if_new(struct wim_lookup_table_entry *lte, void *_info) +blob_clone_if_new(struct blob_descriptor *blob, void *_info) { struct reference_info *info = _info; - if (need_stream(info, lte)) { - lte = clone_lookup_table_entry(lte); - if (unlikely(!lte)) + if (need_blob(info, blob)) { + blob = clone_blob_descriptor(blob); + if (unlikely(!blob)) return WIMLIB_ERR_NOMEM; - reference_stream(info, lte); + reference_blob(info, blob); } return 0; } @@ -151,25 +116,27 @@ wimlib_reference_resources(WIMStruct *wim, WIMStruct **resource_wims, init_reference_info(&info, wim, ref_flags); for (i = 0; i < num_resource_wims; i++) { - ret = for_lookup_table_entry(resource_wims[i]->lookup_table, - lte_clone_if_new, &info); + ret = for_blob_in_table(resource_wims[i]->blob_table, + blob_clone_if_new, &info); if (ret) break; } - return commit_or_rollback_reference_info(&info, ret); + if (unlikely(ret)) + rollback_reference_info(&info); + return ret; } static int -lte_gift(struct wim_lookup_table_entry *lte, void *_info) +blob_gift(struct blob_descriptor *blob, void *_info) { struct reference_info *info = _info; - lookup_table_unlink(info->src_table, lte); - if (need_stream(info, lte)) - reference_stream(info, lte); + blob_table_unlink(info->src_table, blob); + if (need_blob(info, blob)) + reference_blob(info, blob); else - free_lookup_table_entry(lte); + free_blob_descriptor(blob); return 0; } @@ -186,9 +153,9 @@ reference_resource_path(struct reference_info *info, const tchar *path, if (ret) return ret; - info->src_table = src_wim->lookup_table; - for_lookup_table_entry(src_wim->lookup_table, lte_gift, info); - reference_subwim(info, src_wim); + info->src_table = src_wim->blob_table; + for_blob_in_table(src_wim->blob_table, blob_gift, info); + wimlib_free(src_wim); return 0; } @@ -272,5 +239,7 @@ wimlib_reference_resource_files(WIMStruct *wim, else ret = reference_resource_paths(&info, paths_or_globs, count, open_flags); - return commit_or_rollback_reference_info(&info, ret); + if (unlikely(ret)) + rollback_reference_info(&info); + return ret; }