/*
* Copyright (C) 2012, 2013 Eric Biggers
*
- * This file is part of wimlib, a library for working with WIM files.
+ * 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
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version.
*
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3 of the License, or (at your option) any later
- * version.
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
*
- * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "wimlib/alloca.h"
#include "wimlib/assert.h"
+#include "wimlib/bitops.h"
#include "wimlib/endianness.h"
#include "wimlib/error.h"
#include "wimlib/file_io.h"
# include "wimlib/ntfs_3g.h"
#endif
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
/*
* Compressed WIM resources
int errno_save;
u64 *chunk_offsets = NULL;
- u8 *_ubuf = NULL;
u8 *ubuf = NULL;
void *cbuf = NULL;
bool chunk_offsets_malloced = false;
const bool is_pipe_read = (rspec->is_pipable && !filedes_is_seekable(in_fd));
/* Determine if the chunk table is in an alternate format. */
- const bool alt_chunk_table = (rspec->flags & WIM_RESHDR_FLAG_PACKED_STREAMS)
+ const bool alt_chunk_table = (rspec->flags & WIM_RESHDR_FLAG_SOLID)
&& !is_pipe_read;
/* Get the maximum size of uncompressed chunks in this resource, which
}
}
- const u32 chunk_order = bsr32(chunk_size);
+ const u32 chunk_order = fls32(chunk_size);
/* Calculate the total number of chunks the resource is divided into. */
const u64 num_chunks = (rspec->uncompressed_size + chunk_size - 1) >> chunk_order;
/* Now fill in chunk_offsets from the entries we have read in
* chunk_tab_data. We break aliasing rules here to avoid having
* to allocate yet another array. */
- typedef le64 __attribute__((may_alias)) aliased_le64_t;
- typedef le32 __attribute__((may_alias)) aliased_le32_t;
+ typedef le64 _may_alias_attribute aliased_le64_t;
+ typedef le32 _may_alias_attribute aliased_le32_t;
u64 * chunk_offsets_p = chunk_offsets;
if (alt_chunk_table) {
/* Allocate buffer for holding the uncompressed data of each chunk. */
if (chunk_size <= STACK_MAX) {
- _ubuf = alloca(chunk_size + 15);
+ ubuf = alloca(chunk_size);
} else {
- _ubuf = MALLOC(chunk_size + 15);
- if (_ubuf == NULL)
+ ubuf = MALLOC(chunk_size);
+ if (ubuf == NULL)
goto oom;
ubuf_malloced = true;
}
- ubuf = (u8 *)(((uintptr_t)_ubuf + 15) & ~15);
/* Allocate a temporary buffer for reading compressed chunks, each of
* which can be at most @chunk_size - 1 bytes. This excludes compressed
if (chunk_offsets_malloced)
FREE(chunk_offsets);
if (ubuf_malloced)
- FREE(_ubuf);
+ FREE(ubuf);
if (cbuf_malloced)
FREE(cbuf);
errno = errno_save;
skip_wim_stream(struct wim_lookup_table_entry *lte)
{
wimlib_assert(lte->resource_location == RESOURCE_IN_WIM);
- wimlib_assert(!(lte->flags & WIM_RESHDR_FLAG_PACKED_STREAMS));
+ wimlib_assert(!(lte->flags & WIM_RESHDR_FLAG_SOLID));
DEBUG("Skipping stream (size=%"PRIu64")", lte->size);
return read_partial_wim_resource(lte->rspec,
0,
return (*ctx->cbs.consume_chunk)(chunk, size, ctx->cbs.consume_chunk_ctx);
}
-static void
-get_sha1_string(const u8 md[SHA1_HASH_SIZE], tchar *str)
-{
- for (size_t i = 0; i < SHA1_HASH_SIZE; i++)
- str += tsprintf(str, T("%02x"), md[i]);
-}
-
/* Callback for finishing reading a stream while calculating its SHA1 message
* digest. */
static int
if (wimlib_print_errors) {
tchar expected_hashstr[SHA1_HASH_SIZE * 2 + 1];
tchar actual_hashstr[SHA1_HASH_SIZE * 2 + 1];
- get_sha1_string(lte->hash, expected_hashstr);
- get_sha1_string(hash, actual_hashstr);
+ sprint_hash(lte->hash, expected_hashstr);
+ sprint_hash(hash, actual_hashstr);
ERROR("The stream is corrupted!\n"
" (Expected SHA1=%"TS",\n"
" got SHA1=%"TS")",
}
static int
-read_packed_streams(struct wim_lookup_table_entry *first_stream,
- struct wim_lookup_table_entry *last_stream,
- u64 stream_count,
- size_t list_head_offset,
- const struct read_stream_list_callbacks *sink_cbs)
+read_streams_in_solid_resource(struct wim_lookup_table_entry *first_stream,
+ struct wim_lookup_table_entry *last_stream,
+ u64 stream_count,
+ size_t list_head_offset,
+ const struct read_stream_list_callbacks *sink_cbs)
{
struct data_range *ranges;
bool ranges_malloced;
* Read a list of streams, each of which may be in any supported location (e.g.
* in a WIM or in an external file). Unlike read_stream_prefix() or the
* functions which call it, this function optimizes the case where multiple
- * streams are packed into a single compressed WIM resource and reads them all
- * consecutively, only decompressing the data one time.
+ * streams are combined into a single solid compressed WIM resource and reads
+ * them all consecutively, only decompressing the data one time.
*
* @stream_list
* List of streams (represented as `struct wim_lookup_table_entry's) to
{
lte = (struct wim_lookup_table_entry*)((u8*)cur - list_head_offset);
- if (lte->flags & WIM_RESHDR_FLAG_PACKED_STREAMS &&
+ if (lte->flags & WIM_RESHDR_FLAG_SOLID &&
lte->size != lte->rspec->uncompressed_size)
{
* read and @lte_last specifies the last stream
* in the resource that needs to be read. */
next = next2;
- ret = read_packed_streams(lte, lte_last,
- stream_count,
- list_head_offset,
- sink_cbs);
+ ret = read_streams_in_solid_resource(lte, lte_last,
+ stream_count,
+ list_head_offset,
+ sink_cbs);
if (ret)
return ret;
continue;
/* Convert a short WIM resource header to a stand-alone WIM resource
* specification.
*
- * Note: for packed resources some fields still need to be overridden.
+ * Note: for solid resources some fields still need to be overridden.
*/
void
wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,