]> wimlib.net Git - wimlib/blobdiff - include/wimlib/resource.h
LCP-interval tree matchfinder improvements
[wimlib] / include / wimlib / resource.h
index 16e28dfcfaed616111392317ee654d5d48cb2ab2..5572f523819b2b844025c6c562fccae967241153 100644 (file)
@@ -2,25 +2,25 @@
 #define _WIMLIB_RESOURCE_H
 
 #include "wimlib/callback.h"
-#include "wimlib/file_io.h"
 #include "wimlib/list.h"
 #include "wimlib/sha1.h"
 #include "wimlib/types.h"
 
+struct filedes;
 struct wim_lookup_table_entry;
 struct wim_image_metadata;
 
-/* Specification of a resource in a WIM file.
+/*
+ * Specification of a resource in a WIM file.
  *
- * If a `struct wim_lookup_table_entry' lte has
- * (lte->resource_location == RESOURCE_IN_WIM), then lte->wim_res_spec points to
- * an instance of this structure.
+ * If a `struct wim_lookup_table_entry' lte has (lte->resource_location ==
+ * RESOURCE_IN_WIM), then lte->rspec points to an instance of this structure.
  *
- * Normally, there is a one-to-one correspondence between WIM lookup table
- * entries ("streams", each of which may be the contents of a file, for example)
- * and WIM resources.  However, WIM resources with the
- * WIM_RESHDR_FLAG_PACKED_STREAMS flag set may actually contain multiple streams
- * compressed together.  */
+ * Normally, there is a one-to-one correspondence between lookup table entries
+ * ("streams", each of which may be the contents of a file, for example) and
+ * resources.  However, a resource with the WIM_RESHDR_FLAG_SOLID flag set is a
+ * "solid" resource that may contain multiple streams compressed together.
+ */
 struct wim_resource_spec {
        /* The WIM containing this resource.  @wim->in_fd is expected to be a
         * file descriptor to the underlying WIM file, opened for reading.  */
@@ -31,7 +31,8 @@ struct wim_resource_spec {
        u64 offset_in_wim;
 
        /* The size of this resource in the WIM file.  For compressed resources
-        * this is the compressed size.  */
+        * this is the compressed size, including overhead such as the chunk
+        * table.  */
        u64 size_in_wim;
 
        /* The number of bytes of uncompressed data this resource decompresses
@@ -41,13 +42,23 @@ struct wim_resource_spec {
        /* The list of streams this resource contains.  */
        struct list_head stream_list;
 
-       /* Flags for this resource (WIM_RESHDR_FLAG_*)  */
+       /* Flags for this resource (WIM_RESHDR_FLAG_*).  */
        u32 flags : 8;
 
-       /* This flag will be set if the WIM is pipable.  In such cases, the
-        * resource will be in a slightly different format if it is compressed.
-        * This is a wimlib extension.  */
+       /* [wimlib extension] This flag will be set if the WIM is pipable.  In
+        * such cases, the resource will be in a slightly different format if it
+        * is compressed.  */
        u32 is_pipable : 1;
+
+       /* Temporary flag.  */
+       u32 raw_copy_ok : 1;
+
+       /* Compression type of this resource.  */
+       u32 compression_type : 22;
+
+       /* Compression chunk size of this resource.  Irrelevant if the resource
+        * is uncompressed.  */
+       u32 chunk_size;
 };
 
 /* On-disk version of a WIM resource header.  */
@@ -67,7 +78,7 @@ struct wim_reshdr_disk {
        le64 uncompressed_size;
 } _packed_attribute;
 
-/* In-memory version of a WIM resource header.  */
+/* In-memory version of a WIM resource header (`struct wim_reshdr_disk').  */
 struct wim_reshdr {
        u64 size_in_wim : 56;
        u64 flags : 8;
@@ -75,7 +86,8 @@ struct wim_reshdr {
        u64 uncompressed_size;
 };
 
-/* Flags for the `flags' field of WIM resource headers.  */
+/* Flags for the `flags' field of WIM resource headers (`struct wim_reshdr').
+ */
 
 /* Unknown meaning; may be intended to indicate spaces in the WIM that are free
  * to overwrite.  Currently ignored by wimlib.  */
@@ -85,28 +97,30 @@ struct wim_reshdr {
  * or XML data for the WIM.  */
 #define WIM_RESHDR_FLAG_METADATA        0x02
 
-/* The resource is compressed using the WIM's default compression type and uses
- * the regular chunk table format.  */
+/* The resource is a non-solid resource compressed using the WIM's default
+ * compression type.  */
 #define WIM_RESHDR_FLAG_COMPRESSED     0x04
 
 /* Unknown meaning; may be intended to indicate a partial stream.  Currently
  * ignored by wimlib.  */
 #define WIM_RESHDR_FLAG_SPANNED         0x08
 
-/* The resource is packed in a special format that may contain multiple
- * underlying streams, or this resource entry represents a stream packed into
- * one such resource.  When resources have this flag set, the WIM version number
- * should be WIM_VERSION_PACKED_STREAMS.  */
-#define WIM_RESHDR_FLAG_PACKED_STREAMS 0x10
+/* The resource is a solid compressed resource which may contain multiple
+ * streams.  This flag is only allowed if the WIM version number is
+ * WIM_VERSION_SOLID.  */
+#define WIM_RESHDR_FLAG_SOLID          0x10
+
+/* Magic number in the 'uncompressed_size' field of the resource header that
+ * identifies the main entry for a solid resource.  */
+#define SOLID_RESOURCE_MAGIC_NUMBER    0x100000000ULL
 
-/* Returns true if the specified WIM resource is compressed, using either the
- * original chunk table layout or the alternate layout for resources that may
- * contain multiple packed streams.  */
+/* Returns true if the specified WIM resource is compressed (may be either solid
+ * or non-solid)  */
 static inline bool
 resource_is_compressed(const struct wim_resource_spec *rspec)
 {
        return (rspec->flags & (WIM_RESHDR_FLAG_COMPRESSED |
-                               WIM_RESHDR_FLAG_PACKED_STREAMS));
+                               WIM_RESHDR_FLAG_SOLID));
 }
 
 static inline void
@@ -129,7 +143,7 @@ extern void
 wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
                    struct wim_reshdr *reshdr);
 
-extern int
+extern void
 get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
               struct wim_reshdr *reshdr);
 
@@ -137,17 +151,38 @@ void
 put_wim_reshdr(const struct wim_reshdr *reshdr,
               struct wim_reshdr_disk *disk_reshdr);
 
-/* wimlib internal flags used when reading or writing resources.  */
-#define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS          0x00000001
-#define WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE             0x00000002
-#define WIMLIB_WRITE_RESOURCE_MASK                     0x0000ffff
-
-#define WIMLIB_READ_RESOURCE_FLAG_RAW_FULL             0x80000000
-#define WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS           0x40000000
-#define WIMLIB_READ_RESOURCE_FLAG_RAW          (WIMLIB_READ_RESOURCE_FLAG_RAW_FULL |  \
-                                                WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS)
-#define WIMLIB_READ_RESOURCE_MASK                      0xffff0000
+/* Alternate chunk table format for resources with WIM_RESHDR_FLAG_SOLID set.
+ */
+struct alt_chunk_table_header_disk {
+       /* Uncompressed size of the resource in bytes.  */
+       le64 res_usize;
+
+       /* Number of bytes each compressed chunk decompresses into, except
+        * possibly the last which decompresses into the remainder.  This
+        * overrides the chunk size specified by the WIM header.  */
+       le32 chunk_size;
+
+       /* Compression format used for compressed chunks:
+        * 0 = None
+        * 1 = XPRESS
+        * 2 = LZX
+        * 3 = LZMS
+        *
+        * This overrides the compression type specified by the WIM header.  */
+       le32 compression_format;
+
+       /* This header is directly followed by a table of compressed sizes of
+        * the chunks (4 bytes per entry).  */
+} _packed_attribute;
 
+static inline unsigned int
+get_chunk_entry_size(u64 res_size, bool is_alt)
+{
+       if (res_size <= UINT32_MAX || is_alt)
+               return 4;
+       else
+               return 8;
+}
 
 /* Functions to read streams  */
 
@@ -167,20 +202,50 @@ wim_reshdr_to_data(const struct wim_reshdr *reshdr,
                   WIMStruct *wim, void **buf_ret);
 
 extern int
-skip_wim_stream(struct wim_lookup_table_entry *lte);
+wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim,
+                  u8 hash[SHA1_HASH_SIZE]);
 
 extern int
-read_stream_prefix(const struct wim_lookup_table_entry *lte,
-                  u64 size, consume_data_callback_t cb,
-                  void *cb_ctx, int flags);
+skip_wim_stream(struct wim_lookup_table_entry *lte);
 
+/*
+ * Type of callback function for beginning to read a stream.
+ *
+ * @lte:
+ *     Stream that is about to be read.
+ *
+ * @ctx:
+ *     User-provided context.
+ *
+ * Must return 0 on success, a positive error code on failure, or the special
+ * value BEGIN_STREAM_STATUS_SKIP_STREAM to indicate that the stream should not
+ * be read, and read_stream_list() should continue on to the next stream
+ * (without calling @consume_chunk or @end_stream).
+ */
 typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte,
-                                              bool is_partial_res,
                                               void *ctx);
+
+#define BEGIN_STREAM_STATUS_SKIP_STREAM        -1
+
+/*
+ * Type of callback function for finishing reading a stream.
+ *
+ * @lte:
+ *     Stream that has been fully read, or stream that started being read but
+ *     could not be fully read due to a read error.
+ *
+ * @status:
+ *     0 if reading the stream was successful; otherwise a nonzero error code
+ *     that specifies the return status.
+ *
+ * @ctx:
+ *     User-provided context.
+ */
 typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte,
                                             int status,
                                             void *ctx);
 
+
 /* Callback functions and contexts for read_stream_list().  */
 struct read_stream_list_callbacks {
 
@@ -190,7 +255,8 @@ struct read_stream_list_callbacks {
        /* Called when a chunk of data has been read.  */
        consume_data_callback_t consume_chunk;
 
-       /* Called when a stream has been fully read.  */
+       /* Called when a stream has been fully read.  A successful call to
+        * @begin_stream will always be matched by a call to @end_stream.  */
        read_stream_list_end_stream_t end_stream;
 
        /* Parameter passed to @begin_stream.  */
@@ -203,11 +269,16 @@ struct read_stream_list_callbacks {
        void *end_stream_ctx;
 };
 
+/* Flags for read_stream_list()  */
+#define VERIFY_STREAM_HASHES           0x1
+#define COMPUTE_MISSING_STREAM_HASHES  0x2
+#define STREAM_LIST_ALREADY_SORTED     0x4
+
 extern int
 read_stream_list(struct list_head *stream_list,
                 size_t list_head_offset,
-                u32 cb_chunk_size,
-                const struct read_stream_list_callbacks *cbs);
+                const struct read_stream_list_callbacks *cbs,
+                int flags);
 
 /* Functions to extract streams.  */
 
@@ -222,7 +293,8 @@ extract_stream_to_fd(struct wim_lookup_table_entry *lte,
                     struct filedes *fd, u64 size);
 
 extern int
-extract_chunk_to_fd(const void *chunk, size_t size, void *_fd_p);
+extract_full_stream_to_fd(struct wim_lookup_table_entry *lte,
+                         struct filedes *fd);
 
 /* Miscellaneous stream functions.  */
 
@@ -232,8 +304,7 @@ sha1_stream(struct wim_lookup_table_entry *lte);
 /* Functions to read/write metadata resources.  */
 
 extern int
-read_metadata_resource(WIMStruct *wim,
-                      struct wim_image_metadata *image_metadata);
+read_metadata_resource(struct wim_image_metadata *imd);
 
 extern int
 write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags);