Add WIMLIB_EXPORT_FLAG_GIFT
authorEric Biggers <ebiggers3@gmail.com>
Wed, 14 May 2014 06:36:19 +0000 (01:36 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Wed, 14 May 2014 06:36:19 +0000 (01:36 -0500)
include/wimlib.h
programs/imagex.c
src/export_image.c

index 5b85631..0684d62 100644 (file)
@@ -1435,6 +1435,11 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour
 /** Give the exported image(s) no descriptions.  */
 #define WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS             0x00000004
 
+/** This advises the library that the program is finished with the source
+ * WIMStruct and will not attempt to access it after the call to
+ * wimlib_export_image(), with the exception of the call to wimlib_free().  */
+#define WIMLIB_EXPORT_FLAG_GIFT                                0x00000008
+
 /** @} */
 /** @ingroup G_extracting_wims
  * @{ */
index fc2dd45..64a1d8d 100644 (file)
@@ -2556,7 +2556,7 @@ imagex_export(int argc, tchar **argv, int cmd)
 {
        int c;
        int open_flags = 0;
-       int export_flags = 0;
+       int export_flags = WIMLIB_EXPORT_FLAG_GIFT;
        int write_flags = 0;
        int compression_type = WIMLIB_COMPRESSION_TYPE_INVALID;
        const tchar *src_wimfile;
index 8d449ea..8304ea0 100644 (file)
@@ -36,8 +36,9 @@
 
 static int
 inode_export_streams(struct wim_inode *inode,
-                    const struct wim_lookup_table *src_lookup_table,
-                    struct wim_lookup_table *dest_lookup_table)
+                    struct wim_lookup_table *src_lookup_table,
+                    struct wim_lookup_table *dest_lookup_table,
+                    bool gift)
 {
        unsigned i;
        const u8 *hash;
@@ -62,9 +63,14 @@ inode_export_streams(struct wim_inode *inode,
                        if (!src_lte)
                                return stream_not_found_error(inode, hash);
 
-                       dest_lte = clone_lookup_table_entry(src_lte);
-                       if (!dest_lte)
-                               return WIMLIB_ERR_NOMEM;
+                       if (gift) {
+                               dest_lte = src_lte;
+                               lookup_table_unlink(src_lookup_table, src_lte);
+                       } else {
+                               dest_lte = clone_lookup_table_entry(src_lte);
+                               if (!dest_lte)
+                                       return WIMLIB_ERR_NOMEM;
+                       }
                        dest_lte->refcnt = 0;
                        dest_lte->out_refcnt = 0;
                        lookup_table_insert(dest_lookup_table, dest_lte);
@@ -117,7 +123,8 @@ wimlib_export_image(WIMStruct *src_wim,
        /* Check for sane parameters.  */
        if (export_flags & ~(WIMLIB_EXPORT_FLAG_BOOT |
                             WIMLIB_EXPORT_FLAG_NO_NAMES |
-                            WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS))
+                            WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS |
+                            WIMLIB_EXPORT_FLAG_GIFT))
                return WIMLIB_ERR_INVALID_PARAM;
 
        if (src_wim == NULL || dest_wim == NULL)
@@ -222,7 +229,8 @@ wimlib_export_image(WIMStruct *src_wim,
                image_for_each_inode(inode, src_imd) {
                        ret = inode_export_streams(inode,
                                                   src_wim->lookup_table,
-                                                  dest_wim->lookup_table);
+                                                  dest_wim->lookup_table,
+                                                  export_flags & WIMLIB_EXPORT_FLAG_GIFT);
                        if (ret)
                                goto out_rollback;
                }
@@ -260,6 +268,11 @@ wimlib_export_image(WIMStruct *src_wim,
         * is set on the source WIM. */
        if (src_wim->hdr.flags & WIM_HDR_FLAG_RP_FIX)
                dest_wim->hdr.flags |= WIM_HDR_FLAG_RP_FIX;
+
+       if (export_flags & WIMLIB_EXPORT_FLAG_GIFT) {
+               free_lookup_table(src_wim->lookup_table);
+               src_wim->lookup_table = NULL;
+       }
        DEBUG("Export operation successful.");
        return 0;