]> wimlib.net Git - wimlib/blobdiff - src/write.c
read_utf8_file_contents(): Move check for BOM here
[wimlib] / src / write.c
index 3702585bf3e9b6992a009470aa44d1dbbcadc09c..bcf282ba3fe882126e929b208baa593c426d402a 100644 (file)
@@ -709,27 +709,48 @@ write_stream_begin_read(struct wim_lookup_table_entry *lte,
        return 0;
 }
 
+/* Rewrite a stream that was just written compressed as uncompressed instead.
+ * This function is optional, but if a stream did not compress to less than its
+ * original size, it might as well be written uncompressed.  */
 static int
 write_stream_uncompressed(struct wim_lookup_table_entry *lte,
                          struct filedes *out_fd)
 {
        int ret;
+       u64 begin_offset = lte->out_reshdr.offset_in_wim;
+       u64 end_offset = out_fd->offset;
 
-       if (-1 == lseek(out_fd->fd, lte->out_reshdr.offset_in_wim, SEEK_SET) ||
-           0 != ftruncate(out_fd->fd, lte->out_reshdr.offset_in_wim))
+       if (filedes_seek(out_fd, begin_offset) == -1)
+               return 0;
+
+       ret = extract_full_stream_to_fd(lte, out_fd);
+       if (ret) {
+               /* Error reading the uncompressed data.  */
+               if (out_fd->offset == begin_offset &&
+                   filedes_seek(out_fd, end_offset) != -1)
+               {
+                       /* Nothing was actually written yet, and we successfully
+                        * seeked to the end of the compressed resource, so
+                        * don't issue a hard error; just keep the compressed
+                        * resource instead.  */
+                       WARNING("Recovered compressed stream of "
+                               "size %"PRIu64", continuing on.",
+                               lte->size);
+                       return 0;
+               }
+               return ret;
+       }
+
+       wimlib_assert(out_fd->offset - begin_offset == lte->size);
+
+       if (out_fd->offset < end_offset &&
+           0 != ftruncate(out_fd->fd, out_fd->offset))
        {
                ERROR_WITH_ERRNO("Can't truncate output file to "
-                                "offset %"PRIu64, lte->out_reshdr.offset_in_wim);
+                                "offset %"PRIu64, out_fd->offset);
                return WIMLIB_ERR_WRITE;
        }
 
-       out_fd->offset = lte->out_reshdr.offset_in_wim;
-
-       ret = extract_stream_to_fd(lte, out_fd, lte->size);
-       if (ret)
-               return ret;
-
-       wimlib_assert(out_fd->offset - lte->out_reshdr.offset_in_wim == lte->size);
        lte->out_reshdr.size_in_wim = lte->size;
        lte->out_reshdr.flags &= ~(WIM_RESHDR_FLAG_COMPRESSED |
                                   WIM_RESHDR_FLAG_PACKED_STREAMS);
@@ -804,10 +825,6 @@ write_chunk(struct write_streams_ctx *ctx, const void *cchunk,
        if (ctx->cur_write_res_offset == ctx->cur_write_res_size &&
            !(ctx->write_resource_flags & WRITE_RESOURCE_FLAG_PACK_STREAMS))
        {
-               struct wim_lookup_table_entry *lte;
-
-               lte = list_entry(ctx->pending_streams.next,
-                                struct wim_lookup_table_entry, write_streams_list);
                wimlib_assert(ctx->cur_write_res_offset == lte->size);
 
                /* Finished writing a stream in non-packed mode.  */
@@ -936,8 +953,6 @@ write_stream_process_chunk(const void *chunk, size_t size, void *_ctx)
                        memcpy(&ctx->chunk_buf[ctx->chunk_buf_filled],
                               chunkptr, bytes_consumed);
 
-                       resized_chunk = ctx->chunk_buf;
-
                        chunkptr += bytes_consumed;
                        ctx->cur_read_res_offset += bytes_consumed;
                        ctx->chunk_buf_filled += bytes_consumed;
@@ -1337,7 +1352,8 @@ write_stream_list(struct list_head *stream_list,
        ctx.write_resource_flags = write_resource_flags;
        ctx.filter_ctx = filter_ctx;
 
-       if (out_chunk_size != 0) {
+       if (out_ctype != WIMLIB_COMPRESSION_TYPE_NONE) {
+               wimlib_assert(out_chunk_size != 0);
                if (out_chunk_size <= STACK_MAX) {
                        ctx.chunk_buf = alloca(out_chunk_size);
                } else {
@@ -1485,7 +1501,7 @@ out_write_raw_copy_resources:
                                       &ctx.progress_data);
 
 out_destroy_context:
-       if (out_chunk_size > STACK_MAX)
+       if (out_ctype != WIMLIB_COMPRESSION_TYPE_NONE && out_chunk_size > STACK_MAX)
                FREE(ctx.chunk_buf);
        FREE(ctx.chunk_csizes);
        if (ctx.compressor)