-/*
- * Reads a WIM resource.
- *
- * @fp: The FILE* for the WIM file.
- * @resource_size: The compressed size of the resource.
- * @resource_original_size: The uncompressed size of the resource.
- * @resource_offset: The offset of the resource in the stream @fp.
- * @resource_ctype: The compression type of the resource.
- * (WIM_COMPRESSION_TYPE_*)
- * @len: How many bytes of the resource should be read.
- * @offset: The offset within the resource at which the read
- * will occur.
- *
- * To read the whole file resource, specify offset =
- * 0 and len = resource_original_size, or call
- * read_full_resource().
- *
- * @contents_ret: An array, that must have length at least @len,
- * into which the uncompressed contents of
- * the file resource starting at @offset and
- * continuing for @len bytes will be written.
- *
- * @return: Zero on success, nonzero on failure. Failure may be due to
- * being unable to read the data from the WIM file at the
- * specified length and offset, or it may be due to the
- * compressed data (if the data is compressed) being
- * invalid.
- */
-int read_resource(FILE *fp, u64 resource_size, u64 resource_original_size,
- u64 resource_offset, int resource_ctype, u64 len,
- u64 offset, void *contents_ret)
-{
- if (resource_ctype == WIM_COMPRESSION_TYPE_NONE) {
- if (resource_size != resource_original_size) {
- ERROR("Resource with original size %"PRIu64" bytes is "
- "marked as uncompressed, but its actual size is "
- "%"PRIu64" bytes",
- resource_original_size, resource_size);
- return WIMLIB_ERR_INVALID_RESOURCE_SIZE;
- }
- return read_uncompressed_resource(fp,
- resource_offset + offset,
- len, contents_ret);
- } else {
- return read_compressed_resource(fp, resource_size,
- resource_original_size, resource_offset,
- resource_ctype, len, offset, contents_ret);
- }
-}
-
-
-/*
- * Extracts the first @size bytes file resource specified by @entry to the open
- * file @fd. Returns nonzero on error.
- *
- * XXX
- * This function is somewhat redundant with uncompress_resource(). The
- * main difference is that this function writes to a file descriptor using
- * low-level calls to write() rather than to a FILE* with fwrite(); also this
- * function allows only up to @size bytes to be extracted.
- */
-int extract_resource_to_fd(WIMStruct *w, const struct resource_entry *entry,
- int fd, u64 size)
-{
- u64 num_chunks;
- u64 n;
- u8 buf[min(size, WIM_CHUNK_SIZE)];
- int res_ctype;
- u64 offset;
- u64 i;
- int ret;
-
- errno = 0;
-
- num_chunks = (size + WIM_CHUNK_SIZE - 1) / WIM_CHUNK_SIZE;
- n = WIM_CHUNK_SIZE;
- res_ctype = wim_resource_compression_type(w, entry);
- offset = 0;
- for (i = 0; i < num_chunks; i++) {
- if (i == num_chunks - 1) {
- n = size % WIM_CHUNK_SIZE;
- if (n == 0) {
- n = WIM_CHUNK_SIZE;
- }
- }
-
- ret = read_resource(w->fp, entry->size, entry->original_size,
- entry->offset, res_ctype, n, offset, buf);
- if (ret != 0)
- return ret;
-
- if (full_write(fd, buf, n) != n)
- return WIMLIB_ERR_WRITE;
- offset += n;
- }
- return ret;
-}
-
-/*
- * Copies the file resource specified by the lookup table entry @lte from the
- * input WIM, pointed to by the fp field of the WIMStruct, to the output WIM,
- * pointed to by the out_fp field of the WIMStruct.
- *
- * The output_resource_entry, out_refcnt, and part_number fields of @lte are
- * updated.
- *
- * Metadata resources are not copied (they are handled elsewhere for joining and
- * splitting).
- */
-int copy_resource(struct lookup_table_entry *lte, void *w)
-{
- if ((lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) &&
- !((WIMStruct*)w)->write_metadata) {
- return 0;
- }
-
- FILE *in_fp = ((WIMStruct*)w)->fp;
- FILE *out_fp = ((WIMStruct*)w)->out_fp;
- int ret;
- u64 size = lte->resource_entry.size;
- u64 offset = lte->resource_entry.offset;
- off_t new_offset = ftello(out_fp);
-
- if (new_offset == -1)
- return WIMLIB_ERR_WRITE;