14d1abfb2Sjoerg /**
24d1abfb2Sjoerg  * \file        lzma/index.h
34d1abfb2Sjoerg  * \brief       Handling of .xz Index and related information
44d1abfb2Sjoerg  */
54d1abfb2Sjoerg 
64d1abfb2Sjoerg /*
74d1abfb2Sjoerg  * Author: Lasse Collin
84d1abfb2Sjoerg  *
94d1abfb2Sjoerg  * This file has been put into the public domain.
104d1abfb2Sjoerg  * You can do whatever you want with this file.
114d1abfb2Sjoerg  *
124d1abfb2Sjoerg  * See ../lzma.h for information about liblzma as a whole.
134d1abfb2Sjoerg  */
144d1abfb2Sjoerg 
154d1abfb2Sjoerg #ifndef LZMA_H_INTERNAL
164d1abfb2Sjoerg #	error Never include this file directly. Use <lzma.h> instead.
174d1abfb2Sjoerg #endif
184d1abfb2Sjoerg 
194d1abfb2Sjoerg 
204d1abfb2Sjoerg /**
214d1abfb2Sjoerg  * \brief       Opaque data type to hold the Index(es) and other information
224d1abfb2Sjoerg  *
234d1abfb2Sjoerg  * lzma_index often holds just one .xz Index and possibly the Stream Flags
244d1abfb2Sjoerg  * of the same Stream and size of the Stream Padding field. However,
254d1abfb2Sjoerg  * multiple lzma_indexes can be concatenated with lzma_index_cat() and then
264d1abfb2Sjoerg  * there may be information about multiple Streams in the same lzma_index.
274d1abfb2Sjoerg  *
284d1abfb2Sjoerg  * Notes about thread safety: Only one thread may modify lzma_index at
294d1abfb2Sjoerg  * a time. All functions that take non-const pointer to lzma_index
304d1abfb2Sjoerg  * modify it. As long as no thread is modifying the lzma_index, getting
314d1abfb2Sjoerg  * information from the same lzma_index can be done from multiple threads
324d1abfb2Sjoerg  * at the same time with functions that take a const pointer to
334d1abfb2Sjoerg  * lzma_index or use lzma_index_iter. The same iterator must be used
344d1abfb2Sjoerg  * only by one thread at a time, of course, but there can be as many
354d1abfb2Sjoerg  * iterators for the same lzma_index as needed.
364d1abfb2Sjoerg  */
374d1abfb2Sjoerg typedef struct lzma_index_s lzma_index;
384d1abfb2Sjoerg 
394d1abfb2Sjoerg 
404d1abfb2Sjoerg /**
414d1abfb2Sjoerg  * \brief       Iterator to get information about Blocks and Streams
424d1abfb2Sjoerg  */
434d1abfb2Sjoerg typedef struct {
444d1abfb2Sjoerg 	struct {
454d1abfb2Sjoerg 		/**
464d1abfb2Sjoerg 		 * \brief       Pointer to Stream Flags
474d1abfb2Sjoerg 		 *
484d1abfb2Sjoerg 		 * This is NULL if Stream Flags have not been set for
494d1abfb2Sjoerg 		 * this Stream with lzma_index_stream_flags().
504d1abfb2Sjoerg 		 */
514d1abfb2Sjoerg 		const lzma_stream_flags *flags;
524d1abfb2Sjoerg 
534d1abfb2Sjoerg 		const void *reserved_ptr1;
544d1abfb2Sjoerg 		const void *reserved_ptr2;
554d1abfb2Sjoerg 		const void *reserved_ptr3;
564d1abfb2Sjoerg 
574d1abfb2Sjoerg 		/**
584d1abfb2Sjoerg 		 * \brief       Stream number in the lzma_index
594d1abfb2Sjoerg 		 *
604d1abfb2Sjoerg 		 * The first Stream is 1.
614d1abfb2Sjoerg 		 */
624d1abfb2Sjoerg 		lzma_vli number;
634d1abfb2Sjoerg 
644d1abfb2Sjoerg 		/**
654d1abfb2Sjoerg 		 * \brief       Number of Blocks in the Stream
664d1abfb2Sjoerg 		 *
674d1abfb2Sjoerg 		 * If this is zero, the block structure below has
684d1abfb2Sjoerg 		 * undefined values.
694d1abfb2Sjoerg 		 */
704d1abfb2Sjoerg 		lzma_vli block_count;
714d1abfb2Sjoerg 
724d1abfb2Sjoerg 		/**
734d1abfb2Sjoerg 		 * \brief       Compressed start offset of this Stream
744d1abfb2Sjoerg 		 *
754d1abfb2Sjoerg 		 * The offset is relative to the beginning of the lzma_index
764d1abfb2Sjoerg 		 * (i.e. usually the beginning of the .xz file).
774d1abfb2Sjoerg 		 */
784d1abfb2Sjoerg 		lzma_vli compressed_offset;
794d1abfb2Sjoerg 
804d1abfb2Sjoerg 		/**
814d1abfb2Sjoerg 		 * \brief       Uncompressed start offset of this Stream
824d1abfb2Sjoerg 		 *
834d1abfb2Sjoerg 		 * The offset is relative to the beginning of the lzma_index
844d1abfb2Sjoerg 		 * (i.e. usually the beginning of the .xz file).
854d1abfb2Sjoerg 		 */
864d1abfb2Sjoerg 		lzma_vli uncompressed_offset;
874d1abfb2Sjoerg 
884d1abfb2Sjoerg 		/**
894d1abfb2Sjoerg 		 * \brief       Compressed size of this Stream
904d1abfb2Sjoerg 		 *
914d1abfb2Sjoerg 		 * This includes all headers except the possible
924d1abfb2Sjoerg 		 * Stream Padding after this Stream.
934d1abfb2Sjoerg 		 */
944d1abfb2Sjoerg 		lzma_vli compressed_size;
954d1abfb2Sjoerg 
964d1abfb2Sjoerg 		/**
974d1abfb2Sjoerg 		 * \brief       Uncompressed size of this Stream
984d1abfb2Sjoerg 		 */
994d1abfb2Sjoerg 		lzma_vli uncompressed_size;
1004d1abfb2Sjoerg 
1014d1abfb2Sjoerg 		/**
1024d1abfb2Sjoerg 		 * \brief       Size of Stream Padding after this Stream
1034d1abfb2Sjoerg 		 *
1044d1abfb2Sjoerg 		 * If it hasn't been set with lzma_index_stream_padding(),
1054d1abfb2Sjoerg 		 * this defaults to zero. Stream Padding is always
1064d1abfb2Sjoerg 		 * a multiple of four bytes.
1074d1abfb2Sjoerg 		 */
1084d1abfb2Sjoerg 		lzma_vli padding;
1094d1abfb2Sjoerg 
1104d1abfb2Sjoerg 		lzma_vli reserved_vli1;
1114d1abfb2Sjoerg 		lzma_vli reserved_vli2;
1124d1abfb2Sjoerg 		lzma_vli reserved_vli3;
1134d1abfb2Sjoerg 		lzma_vli reserved_vli4;
1144d1abfb2Sjoerg 	} stream;
1154d1abfb2Sjoerg 
1164d1abfb2Sjoerg 	struct {
1174d1abfb2Sjoerg 		/**
1184d1abfb2Sjoerg 		 * \brief       Block number in the file
1194d1abfb2Sjoerg 		 *
1204d1abfb2Sjoerg 		 * The first Block is 1.
1214d1abfb2Sjoerg 		 */
1224d1abfb2Sjoerg 		lzma_vli number_in_file;
1234d1abfb2Sjoerg 
1244d1abfb2Sjoerg 		/**
1254d1abfb2Sjoerg 		 * \brief       Compressed start offset of this Block
1264d1abfb2Sjoerg 		 *
1274d1abfb2Sjoerg 		 * This offset is relative to the beginning of the
1284d1abfb2Sjoerg 		 * lzma_index (i.e. usually the beginning of the .xz file).
1294d1abfb2Sjoerg 		 * Normally this is where you should seek in the .xz file
1304d1abfb2Sjoerg 		 * to start decompressing this Block.
1314d1abfb2Sjoerg 		 */
1324d1abfb2Sjoerg 		lzma_vli compressed_file_offset;
1334d1abfb2Sjoerg 
1344d1abfb2Sjoerg 		/**
1354d1abfb2Sjoerg 		 * \brief       Uncompressed start offset of this Block
1364d1abfb2Sjoerg 		 *
1374d1abfb2Sjoerg 		 * This offset is relative to the beginning of the lzma_index
1384d1abfb2Sjoerg 		 * (i.e. usually the beginning of the .xz file).
1394d1abfb2Sjoerg 		 *
1404d1abfb2Sjoerg 		 * When doing random-access reading, it is possible that
1414d1abfb2Sjoerg 		 * the target offset is not exactly at Block boundary. One
1424d1abfb2Sjoerg 		 * will need to compare the target offset against
1434d1abfb2Sjoerg 		 * uncompressed_file_offset or uncompressed_stream_offset,
1444d1abfb2Sjoerg 		 * and possibly decode and throw away some amount of data
1454d1abfb2Sjoerg 		 * before reaching the target offset.
1464d1abfb2Sjoerg 		 */
1474d1abfb2Sjoerg 		lzma_vli uncompressed_file_offset;
1484d1abfb2Sjoerg 
1494d1abfb2Sjoerg 		/**
1504d1abfb2Sjoerg 		 * \brief       Block number in this Stream
1514d1abfb2Sjoerg 		 *
1524d1abfb2Sjoerg 		 * The first Block is 1.
1534d1abfb2Sjoerg 		 */
1544d1abfb2Sjoerg 		lzma_vli number_in_stream;
1554d1abfb2Sjoerg 
1564d1abfb2Sjoerg 		/**
1574d1abfb2Sjoerg 		 * \brief       Compressed start offset of this Block
1584d1abfb2Sjoerg 		 *
1594d1abfb2Sjoerg 		 * This offset is relative to the beginning of the Stream
1604d1abfb2Sjoerg 		 * containing this Block.
1614d1abfb2Sjoerg 		 */
1624d1abfb2Sjoerg 		lzma_vli compressed_stream_offset;
1634d1abfb2Sjoerg 
1644d1abfb2Sjoerg 		/**
1654d1abfb2Sjoerg 		 * \brief       Uncompressed start offset of this Block
1664d1abfb2Sjoerg 		 *
1674d1abfb2Sjoerg 		 * This offset is relative to the beginning of the Stream
1684d1abfb2Sjoerg 		 * containing this Block.
1694d1abfb2Sjoerg 		 */
1704d1abfb2Sjoerg 		lzma_vli uncompressed_stream_offset;
1714d1abfb2Sjoerg 
1724d1abfb2Sjoerg 		/**
1734d1abfb2Sjoerg 		 * \brief       Uncompressed size of this Block
1744d1abfb2Sjoerg 		 *
1754d1abfb2Sjoerg 		 * You should pass this to the Block decoder if you will
1764d1abfb2Sjoerg 		 * decode this Block. It will allow the Block decoder to
1774d1abfb2Sjoerg 		 * validate the uncompressed size.
1784d1abfb2Sjoerg 		 */
1794d1abfb2Sjoerg 		lzma_vli uncompressed_size;
1804d1abfb2Sjoerg 
1814d1abfb2Sjoerg 		/**
1824d1abfb2Sjoerg 		 * \brief       Unpadded size of this Block
1834d1abfb2Sjoerg 		 *
1844d1abfb2Sjoerg 		 * You should pass this to the Block decoder if you will
1854d1abfb2Sjoerg 		 * decode this Block. It will allow the Block decoder to
1864d1abfb2Sjoerg 		 * validate the unpadded size.
1874d1abfb2Sjoerg 		 */
1884d1abfb2Sjoerg 		lzma_vli unpadded_size;
1894d1abfb2Sjoerg 
1904d1abfb2Sjoerg 		/**
1914d1abfb2Sjoerg 		 * \brief       Total compressed size
1924d1abfb2Sjoerg 		 *
1934d1abfb2Sjoerg 		 * This includes all headers and padding in this Block.
1944d1abfb2Sjoerg 		 * This is useful if you need to know how many bytes
1954d1abfb2Sjoerg 		 * the Block decoder will actually read.
1964d1abfb2Sjoerg 		 */
1974d1abfb2Sjoerg 		lzma_vli total_size;
1984d1abfb2Sjoerg 
1994d1abfb2Sjoerg 		lzma_vli reserved_vli1;
2004d1abfb2Sjoerg 		lzma_vli reserved_vli2;
2014d1abfb2Sjoerg 		lzma_vli reserved_vli3;
2024d1abfb2Sjoerg 		lzma_vli reserved_vli4;
2034d1abfb2Sjoerg 
2044d1abfb2Sjoerg 		const void *reserved_ptr1;
2054d1abfb2Sjoerg 		const void *reserved_ptr2;
2064d1abfb2Sjoerg 		const void *reserved_ptr3;
2074d1abfb2Sjoerg 		const void *reserved_ptr4;
2084d1abfb2Sjoerg 	} block;
2094d1abfb2Sjoerg 
2104d1abfb2Sjoerg 	/*
2114d1abfb2Sjoerg 	 * Internal data which is used to store the state of the iterator.
2124d1abfb2Sjoerg 	 * The exact format may vary between liblzma versions, so don't
2134d1abfb2Sjoerg 	 * touch these in any way.
2144d1abfb2Sjoerg 	 */
2154d1abfb2Sjoerg 	union {
2164d1abfb2Sjoerg 		const void *p;
2174d1abfb2Sjoerg 		size_t s;
2184d1abfb2Sjoerg 		lzma_vli v;
2194d1abfb2Sjoerg 	} internal[6];
2204d1abfb2Sjoerg } lzma_index_iter;
2214d1abfb2Sjoerg 
2224d1abfb2Sjoerg 
2234d1abfb2Sjoerg /**
2244d1abfb2Sjoerg  * \brief       Operation mode for lzma_index_iter_next()
2254d1abfb2Sjoerg  */
2264d1abfb2Sjoerg typedef enum {
2274d1abfb2Sjoerg 	LZMA_INDEX_ITER_ANY             = 0,
2284d1abfb2Sjoerg 		/**<
2294d1abfb2Sjoerg 		 * \brief       Get the next Block or Stream
2304d1abfb2Sjoerg 		 *
2314d1abfb2Sjoerg 		 * Go to the next Block if the current Stream has at least
2324d1abfb2Sjoerg 		 * one Block left. Otherwise go to the next Stream even if
2334d1abfb2Sjoerg 		 * it has no Blocks. If the Stream has no Blocks
2344d1abfb2Sjoerg 		 * (lzma_index_iter.stream.block_count == 0),
2354d1abfb2Sjoerg 		 * lzma_index_iter.block will have undefined values.
2364d1abfb2Sjoerg 		 */
2374d1abfb2Sjoerg 
2384d1abfb2Sjoerg 	LZMA_INDEX_ITER_STREAM          = 1,
2394d1abfb2Sjoerg 		/**<
2404d1abfb2Sjoerg 		 * \brief       Get the next Stream
2414d1abfb2Sjoerg 		 *
2424d1abfb2Sjoerg 		 * Go to the next Stream even if the current Stream has
2434d1abfb2Sjoerg 		 * unread Blocks left. If the next Stream has at least one
2444d1abfb2Sjoerg 		 * Block, the iterator will point to the first Block.
2454d1abfb2Sjoerg 		 * If there are no Blocks, lzma_index_iter.block will have
2464d1abfb2Sjoerg 		 * undefined values.
2474d1abfb2Sjoerg 		 */
2484d1abfb2Sjoerg 
2494d1abfb2Sjoerg 	LZMA_INDEX_ITER_BLOCK           = 2,
2504d1abfb2Sjoerg 		/**<
2514d1abfb2Sjoerg 		 * \brief       Get the next Block
2524d1abfb2Sjoerg 		 *
2534d1abfb2Sjoerg 		 * Go to the next Block if the current Stream has at least
2544d1abfb2Sjoerg 		 * one Block left. If the current Stream has no Blocks left,
2554d1abfb2Sjoerg 		 * the next Stream with at least one Block is located and
2564d1abfb2Sjoerg 		 * the iterator will be made to point to the first Block of
2574d1abfb2Sjoerg 		 * that Stream.
2584d1abfb2Sjoerg 		 */
2594d1abfb2Sjoerg 
2604d1abfb2Sjoerg 	LZMA_INDEX_ITER_NONEMPTY_BLOCK  = 3
2614d1abfb2Sjoerg 		/**<
2624d1abfb2Sjoerg 		 * \brief       Get the next non-empty Block
2634d1abfb2Sjoerg 		 *
2644d1abfb2Sjoerg 		 * This is like LZMA_INDEX_ITER_BLOCK except that it will
2654d1abfb2Sjoerg 		 * skip Blocks whose Uncompressed Size is zero.
2664d1abfb2Sjoerg 		 */
2674d1abfb2Sjoerg 
2684d1abfb2Sjoerg } lzma_index_iter_mode;
2694d1abfb2Sjoerg 
2704d1abfb2Sjoerg 
2714d1abfb2Sjoerg /**
2724d1abfb2Sjoerg  * \brief       Calculate memory usage of lzma_index
2734d1abfb2Sjoerg  *
2744d1abfb2Sjoerg  * On disk, the size of the Index field depends on both the number of Records
2754d1abfb2Sjoerg  * stored and how big values the Records store (due to variable-length integer
2764d1abfb2Sjoerg  * encoding). When the Index is kept in lzma_index structure, the memory usage
2774d1abfb2Sjoerg  * depends only on the number of Records/Blocks stored in the Index(es), and
2784d1abfb2Sjoerg  * in case of concatenated lzma_indexes, the number of Streams. The size in
2794d1abfb2Sjoerg  * RAM is almost always significantly bigger than in the encoded form on disk.
2804d1abfb2Sjoerg  *
2814d1abfb2Sjoerg  * This function calculates an approximate amount of memory needed hold
2824d1abfb2Sjoerg  * the given number of Streams and Blocks in lzma_index structure. This
2834d1abfb2Sjoerg  * value may vary between CPU architectures and also between liblzma versions
2844d1abfb2Sjoerg  * if the internal implementation is modified.
2854d1abfb2Sjoerg  */
2864d1abfb2Sjoerg extern LZMA_API(uint64_t) lzma_index_memusage(
2874d1abfb2Sjoerg 		lzma_vli streams, lzma_vli blocks) lzma_nothrow;
2884d1abfb2Sjoerg 
2894d1abfb2Sjoerg 
2904d1abfb2Sjoerg /**
2914d1abfb2Sjoerg  * \brief       Calculate the memory usage of an existing lzma_index
2924d1abfb2Sjoerg  *
2934d1abfb2Sjoerg  * This is a shorthand for lzma_index_memusage(lzma_index_stream_count(i),
2944d1abfb2Sjoerg  * lzma_index_block_count(i)).
2954d1abfb2Sjoerg  */
2964d1abfb2Sjoerg extern LZMA_API(uint64_t) lzma_index_memused(const lzma_index *i)
2974d1abfb2Sjoerg 		lzma_nothrow;
2984d1abfb2Sjoerg 
2994d1abfb2Sjoerg 
3004d1abfb2Sjoerg /**
3014d1abfb2Sjoerg  * \brief       Allocate and initialize a new lzma_index structure
3024d1abfb2Sjoerg  *
3034d1abfb2Sjoerg  * \return      On success, a pointer to an empty initialized lzma_index is
3044d1abfb2Sjoerg  *              returned. If allocation fails, NULL is returned.
3054d1abfb2Sjoerg  */
3067653b22fSchristos extern LZMA_API(lzma_index *) lzma_index_init(const lzma_allocator *allocator)
3074d1abfb2Sjoerg 		lzma_nothrow;
3084d1abfb2Sjoerg 
3094d1abfb2Sjoerg 
3104d1abfb2Sjoerg /**
3114d1abfb2Sjoerg  * \brief       Deallocate lzma_index
3124d1abfb2Sjoerg  *
3134d1abfb2Sjoerg  * If i is NULL, this does nothing.
3144d1abfb2Sjoerg  */
3157653b22fSchristos extern LZMA_API(void) lzma_index_end(
3167653b22fSchristos 		lzma_index *i, const lzma_allocator *allocator) lzma_nothrow;
3174d1abfb2Sjoerg 
3184d1abfb2Sjoerg 
3194d1abfb2Sjoerg /**
3204d1abfb2Sjoerg  * \brief       Add a new Block to lzma_index
3214d1abfb2Sjoerg  *
3224d1abfb2Sjoerg  * \param       i                 Pointer to a lzma_index structure
3234d1abfb2Sjoerg  * \param       allocator         Pointer to lzma_allocator, or NULL to
3244d1abfb2Sjoerg  *                                use malloc()
3254d1abfb2Sjoerg  * \param       unpadded_size     Unpadded Size of a Block. This can be
3264d1abfb2Sjoerg  *                                calculated with lzma_block_unpadded_size()
3274d1abfb2Sjoerg  *                                after encoding or decoding the Block.
3284d1abfb2Sjoerg  * \param       uncompressed_size Uncompressed Size of a Block. This can be
3294d1abfb2Sjoerg  *                                taken directly from lzma_block structure
3304d1abfb2Sjoerg  *                                after encoding or decoding the Block.
3314d1abfb2Sjoerg  *
3324d1abfb2Sjoerg  * Appending a new Block does not invalidate iterators. For example,
3334d1abfb2Sjoerg  * if an iterator was pointing to the end of the lzma_index, after
3344d1abfb2Sjoerg  * lzma_index_append() it is possible to read the next Block with
3354d1abfb2Sjoerg  * an existing iterator.
3364d1abfb2Sjoerg  *
3374d1abfb2Sjoerg  * \return      - LZMA_OK
3384d1abfb2Sjoerg  *              - LZMA_MEM_ERROR
3394d1abfb2Sjoerg  *              - LZMA_DATA_ERROR: Compressed or uncompressed size of the
3404d1abfb2Sjoerg  *                Stream or size of the Index field would grow too big.
3414d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
3424d1abfb2Sjoerg  */
3434d1abfb2Sjoerg extern LZMA_API(lzma_ret) lzma_index_append(
3447653b22fSchristos 		lzma_index *i, const lzma_allocator *allocator,
3454d1abfb2Sjoerg 		lzma_vli unpadded_size, lzma_vli uncompressed_size)
3464d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
3474d1abfb2Sjoerg 
3484d1abfb2Sjoerg 
3494d1abfb2Sjoerg /**
3504d1abfb2Sjoerg  * \brief       Set the Stream Flags
3514d1abfb2Sjoerg  *
3524d1abfb2Sjoerg  * Set the Stream Flags of the last (and typically the only) Stream
3534d1abfb2Sjoerg  * in lzma_index. This can be useful when reading information from the
3544d1abfb2Sjoerg  * lzma_index, because to decode Blocks, knowing the integrity check type
3554d1abfb2Sjoerg  * is needed.
3564d1abfb2Sjoerg  *
3574d1abfb2Sjoerg  * The given Stream Flags are copied into internal preallocated structure
3584d1abfb2Sjoerg  * in the lzma_index, thus the caller doesn't need to keep the *stream_flags
3594d1abfb2Sjoerg  * available after calling this function.
3604d1abfb2Sjoerg  *
3614d1abfb2Sjoerg  * \return      - LZMA_OK
3624d1abfb2Sjoerg  *              - LZMA_OPTIONS_ERROR: Unsupported stream_flags->version.
3634d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
3644d1abfb2Sjoerg  */
3654d1abfb2Sjoerg extern LZMA_API(lzma_ret) lzma_index_stream_flags(
3664d1abfb2Sjoerg 		lzma_index *i, const lzma_stream_flags *stream_flags)
3674d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
3684d1abfb2Sjoerg 
3694d1abfb2Sjoerg 
3704d1abfb2Sjoerg /**
3714d1abfb2Sjoerg  * \brief       Get the types of integrity Checks
3724d1abfb2Sjoerg  *
3734d1abfb2Sjoerg  * If lzma_index_stream_flags() is used to set the Stream Flags for
3744d1abfb2Sjoerg  * every Stream, lzma_index_checks() can be used to get a bitmask to
3754d1abfb2Sjoerg  * indicate which Check types have been used. It can be useful e.g. if
3764d1abfb2Sjoerg  * showing the Check types to the user.
3774d1abfb2Sjoerg  *
3784d1abfb2Sjoerg  * The bitmask is 1 << check_id, e.g. CRC32 is 1 << 1 and SHA-256 is 1 << 10.
3794d1abfb2Sjoerg  */
3804d1abfb2Sjoerg extern LZMA_API(uint32_t) lzma_index_checks(const lzma_index *i)
3814d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
3824d1abfb2Sjoerg 
3834d1abfb2Sjoerg 
3844d1abfb2Sjoerg /**
3854d1abfb2Sjoerg  * \brief       Set the amount of Stream Padding
3864d1abfb2Sjoerg  *
3874d1abfb2Sjoerg  * Set the amount of Stream Padding of the last (and typically the only)
3884d1abfb2Sjoerg  * Stream in the lzma_index. This is needed when planning to do random-access
3894d1abfb2Sjoerg  * reading within multiple concatenated Streams.
3904d1abfb2Sjoerg  *
3914d1abfb2Sjoerg  * By default, the amount of Stream Padding is assumed to be zero bytes.
3924d1abfb2Sjoerg  *
3934d1abfb2Sjoerg  * \return      - LZMA_OK
3944d1abfb2Sjoerg  *              - LZMA_DATA_ERROR: The file size would grow too big.
3954d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
3964d1abfb2Sjoerg  */
3974d1abfb2Sjoerg extern LZMA_API(lzma_ret) lzma_index_stream_padding(
3984d1abfb2Sjoerg 		lzma_index *i, lzma_vli stream_padding)
3994d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
4004d1abfb2Sjoerg 
4014d1abfb2Sjoerg 
4024d1abfb2Sjoerg /**
4034d1abfb2Sjoerg  * \brief       Get the number of Streams
4044d1abfb2Sjoerg  */
4054d1abfb2Sjoerg extern LZMA_API(lzma_vli) lzma_index_stream_count(const lzma_index *i)
4064d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
4074d1abfb2Sjoerg 
4084d1abfb2Sjoerg 
4094d1abfb2Sjoerg /**
4104d1abfb2Sjoerg  * \brief       Get the number of Blocks
4114d1abfb2Sjoerg  *
4124d1abfb2Sjoerg  * This returns the total number of Blocks in lzma_index. To get number
4134d1abfb2Sjoerg  * of Blocks in individual Streams, use lzma_index_iter.
4144d1abfb2Sjoerg  */
4154d1abfb2Sjoerg extern LZMA_API(lzma_vli) lzma_index_block_count(const lzma_index *i)
4164d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
4174d1abfb2Sjoerg 
4184d1abfb2Sjoerg 
4194d1abfb2Sjoerg /**
4204d1abfb2Sjoerg  * \brief       Get the size of the Index field as bytes
4214d1abfb2Sjoerg  *
4224d1abfb2Sjoerg  * This is needed to verify the Backward Size field in the Stream Footer.
4234d1abfb2Sjoerg  */
4244d1abfb2Sjoerg extern LZMA_API(lzma_vli) lzma_index_size(const lzma_index *i)
4254d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
4264d1abfb2Sjoerg 
4274d1abfb2Sjoerg 
4284d1abfb2Sjoerg /**
4294d1abfb2Sjoerg  * \brief       Get the total size of the Stream
4304d1abfb2Sjoerg  *
4314d1abfb2Sjoerg  * If multiple lzma_indexes have been combined, this works as if the Blocks
4324d1abfb2Sjoerg  * were in a single Stream. This is useful if you are going to combine
4334d1abfb2Sjoerg  * Blocks from multiple Streams into a single new Stream.
4344d1abfb2Sjoerg  */
4354d1abfb2Sjoerg extern LZMA_API(lzma_vli) lzma_index_stream_size(const lzma_index *i)
4364d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
4374d1abfb2Sjoerg 
4384d1abfb2Sjoerg 
4394d1abfb2Sjoerg /**
4404d1abfb2Sjoerg  * \brief       Get the total size of the Blocks
4414d1abfb2Sjoerg  *
4424d1abfb2Sjoerg  * This doesn't include the Stream Header, Stream Footer, Stream Padding,
4434d1abfb2Sjoerg  * or Index fields.
4444d1abfb2Sjoerg  */
4454d1abfb2Sjoerg extern LZMA_API(lzma_vli) lzma_index_total_size(const lzma_index *i)
4464d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
4474d1abfb2Sjoerg 
4484d1abfb2Sjoerg 
4494d1abfb2Sjoerg /**
4504d1abfb2Sjoerg  * \brief       Get the total size of the file
4514d1abfb2Sjoerg  *
4524d1abfb2Sjoerg  * When no lzma_indexes have been combined with lzma_index_cat() and there is
4534d1abfb2Sjoerg  * no Stream Padding, this function is identical to lzma_index_stream_size().
4544d1abfb2Sjoerg  * If multiple lzma_indexes have been combined, this includes also the headers
4554d1abfb2Sjoerg  * of each separate Stream and the possible Stream Padding fields.
4564d1abfb2Sjoerg  */
4574d1abfb2Sjoerg extern LZMA_API(lzma_vli) lzma_index_file_size(const lzma_index *i)
4584d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
4594d1abfb2Sjoerg 
4604d1abfb2Sjoerg 
4614d1abfb2Sjoerg /**
4624d1abfb2Sjoerg  * \brief       Get the uncompressed size of the file
4634d1abfb2Sjoerg  */
4644d1abfb2Sjoerg extern LZMA_API(lzma_vli) lzma_index_uncompressed_size(const lzma_index *i)
4654d1abfb2Sjoerg 		lzma_nothrow lzma_attr_pure;
4664d1abfb2Sjoerg 
4674d1abfb2Sjoerg 
4684d1abfb2Sjoerg /**
4694d1abfb2Sjoerg  * \brief       Initialize an iterator
4704d1abfb2Sjoerg  *
4714d1abfb2Sjoerg  * \param       iter    Pointer to a lzma_index_iter structure
4724d1abfb2Sjoerg  * \param       i       lzma_index to which the iterator will be associated
4734d1abfb2Sjoerg  *
4744d1abfb2Sjoerg  * This function associates the iterator with the given lzma_index, and calls
4754d1abfb2Sjoerg  * lzma_index_iter_rewind() on the iterator.
4764d1abfb2Sjoerg  *
4774d1abfb2Sjoerg  * This function doesn't allocate any memory, thus there is no
4784d1abfb2Sjoerg  * lzma_index_iter_end(). The iterator is valid as long as the
4794d1abfb2Sjoerg  * associated lzma_index is valid, that is, until lzma_index_end() or
4804d1abfb2Sjoerg  * using it as source in lzma_index_cat(). Specifically, lzma_index doesn't
4814d1abfb2Sjoerg  * become invalid if new Blocks are added to it with lzma_index_append() or
4824d1abfb2Sjoerg  * if it is used as the destination in lzma_index_cat().
4834d1abfb2Sjoerg  *
4844d1abfb2Sjoerg  * It is safe to make copies of an initialized lzma_index_iter, for example,
4854d1abfb2Sjoerg  * to easily restart reading at some particular position.
4864d1abfb2Sjoerg  */
4874d1abfb2Sjoerg extern LZMA_API(void) lzma_index_iter_init(
4884d1abfb2Sjoerg 		lzma_index_iter *iter, const lzma_index *i) lzma_nothrow;
4894d1abfb2Sjoerg 
4904d1abfb2Sjoerg 
4914d1abfb2Sjoerg /**
4924d1abfb2Sjoerg  * \brief       Rewind the iterator
4934d1abfb2Sjoerg  *
4944d1abfb2Sjoerg  * Rewind the iterator so that next call to lzma_index_iter_next() will
4954d1abfb2Sjoerg  * return the first Block or Stream.
4964d1abfb2Sjoerg  */
4974d1abfb2Sjoerg extern LZMA_API(void) lzma_index_iter_rewind(lzma_index_iter *iter)
4984d1abfb2Sjoerg 		lzma_nothrow;
4994d1abfb2Sjoerg 
5004d1abfb2Sjoerg 
5014d1abfb2Sjoerg /**
5024d1abfb2Sjoerg  * \brief       Get the next Block or Stream
5034d1abfb2Sjoerg  *
5044d1abfb2Sjoerg  * \param       iter    Iterator initialized with lzma_index_iter_init()
5054d1abfb2Sjoerg  * \param       mode    Specify what kind of information the caller wants
5064d1abfb2Sjoerg  *                      to get. See lzma_index_iter_mode for details.
5074d1abfb2Sjoerg  *
5084d1abfb2Sjoerg  * \return      If next Block or Stream matching the mode was found, *iter
5094d1abfb2Sjoerg  *              is updated and this function returns false. If no Block or
5104d1abfb2Sjoerg  *              Stream matching the mode is found, *iter is not modified
5114d1abfb2Sjoerg  *              and this function returns true. If mode is set to an unknown
5124d1abfb2Sjoerg  *              value, *iter is not modified and this function returns true.
5134d1abfb2Sjoerg  */
5144d1abfb2Sjoerg extern LZMA_API(lzma_bool) lzma_index_iter_next(
5154d1abfb2Sjoerg 		lzma_index_iter *iter, lzma_index_iter_mode mode)
5164d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
5174d1abfb2Sjoerg 
5184d1abfb2Sjoerg 
5194d1abfb2Sjoerg /**
5204d1abfb2Sjoerg  * \brief       Locate a Block
5214d1abfb2Sjoerg  *
5224d1abfb2Sjoerg  * If it is possible to seek in the .xz file, it is possible to parse
5234d1abfb2Sjoerg  * the Index field(s) and use lzma_index_iter_locate() to do random-access
5244d1abfb2Sjoerg  * reading with granularity of Block size.
5254d1abfb2Sjoerg  *
5264d1abfb2Sjoerg  * \param       iter    Iterator that was earlier initialized with
5274d1abfb2Sjoerg  *                      lzma_index_iter_init().
5284d1abfb2Sjoerg  * \param       target  Uncompressed target offset which the caller would
5294d1abfb2Sjoerg  *                      like to locate from the Stream
5304d1abfb2Sjoerg  *
5314d1abfb2Sjoerg  * If the target is smaller than the uncompressed size of the Stream (can be
5324d1abfb2Sjoerg  * checked with lzma_index_uncompressed_size()):
5334d1abfb2Sjoerg  *  - Information about the Stream and Block containing the requested
5344d1abfb2Sjoerg  *    uncompressed offset is stored into *iter.
5354d1abfb2Sjoerg  *  - Internal state of the iterator is adjusted so that
5364d1abfb2Sjoerg  *    lzma_index_iter_next() can be used to read subsequent Blocks or Streams.
5374d1abfb2Sjoerg  *  - This function returns false.
5384d1abfb2Sjoerg  *
5394d1abfb2Sjoerg  * If target is greater than the uncompressed size of the Stream, *iter
5404d1abfb2Sjoerg  * is not modified, and this function returns true.
5414d1abfb2Sjoerg  */
5424d1abfb2Sjoerg extern LZMA_API(lzma_bool) lzma_index_iter_locate(
5434d1abfb2Sjoerg 		lzma_index_iter *iter, lzma_vli target) lzma_nothrow;
5444d1abfb2Sjoerg 
5454d1abfb2Sjoerg 
5464d1abfb2Sjoerg /**
5474d1abfb2Sjoerg  * \brief       Concatenate lzma_indexes
5484d1abfb2Sjoerg  *
5494d1abfb2Sjoerg  * Concatenating lzma_indexes is useful when doing random-access reading in
5504d1abfb2Sjoerg  * multi-Stream .xz file, or when combining multiple Streams into single
5514d1abfb2Sjoerg  * Stream.
5524d1abfb2Sjoerg  *
5534d1abfb2Sjoerg  * \param       dest      lzma_index after which src is appended
5544d1abfb2Sjoerg  * \param       src       lzma_index to be appended after dest. If this
5554d1abfb2Sjoerg  *                        function succeeds, the memory allocated for src
5564d1abfb2Sjoerg  *                        is freed or moved to be part of dest, and all
5574d1abfb2Sjoerg  *                        iterators pointing to src will become invalid.
5584d1abfb2Sjoerg  * \param       allocator Custom memory allocator; can be NULL to use
5594d1abfb2Sjoerg  *                        malloc() and free().
5604d1abfb2Sjoerg  *
5614d1abfb2Sjoerg  * \return      - LZMA_OK: lzma_indexes were concatenated successfully.
5624d1abfb2Sjoerg  *                src is now a dangling pointer.
5634d1abfb2Sjoerg  *              - LZMA_DATA_ERROR: *dest would grow too big.
5644d1abfb2Sjoerg  *              - LZMA_MEM_ERROR
5654d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
5664d1abfb2Sjoerg  */
5677653b22fSchristos extern LZMA_API(lzma_ret) lzma_index_cat(lzma_index *dest, lzma_index *src,
5687653b22fSchristos 		const lzma_allocator *allocator)
5694d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
5704d1abfb2Sjoerg 
5714d1abfb2Sjoerg 
5724d1abfb2Sjoerg /**
5734d1abfb2Sjoerg  * \brief       Duplicate lzma_index
5744d1abfb2Sjoerg  *
5754d1abfb2Sjoerg  * \return      A copy of the lzma_index, or NULL if memory allocation failed.
5764d1abfb2Sjoerg  */
5774d1abfb2Sjoerg extern LZMA_API(lzma_index *) lzma_index_dup(
5787653b22fSchristos 		const lzma_index *i, const lzma_allocator *allocator)
5794d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
5804d1abfb2Sjoerg 
5814d1abfb2Sjoerg 
5824d1abfb2Sjoerg /**
5834d1abfb2Sjoerg  * \brief       Initialize .xz Index encoder
5844d1abfb2Sjoerg  *
5854d1abfb2Sjoerg  * \param       strm        Pointer to properly prepared lzma_stream
5864d1abfb2Sjoerg  * \param       i           Pointer to lzma_index which should be encoded.
5874d1abfb2Sjoerg  *
5884d1abfb2Sjoerg  * The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
589*6b13043cSjoerg  * It is enough to use only one of them (you can choose freely).
5904d1abfb2Sjoerg  *
5914d1abfb2Sjoerg  * \return      - LZMA_OK: Initialization succeeded, continue with lzma_code().
5924d1abfb2Sjoerg  *              - LZMA_MEM_ERROR
5934d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
5944d1abfb2Sjoerg  */
5954d1abfb2Sjoerg extern LZMA_API(lzma_ret) lzma_index_encoder(
5964d1abfb2Sjoerg 		lzma_stream *strm, const lzma_index *i)
5974d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
5984d1abfb2Sjoerg 
5994d1abfb2Sjoerg 
6004d1abfb2Sjoerg /**
6014d1abfb2Sjoerg  * \brief       Initialize .xz Index decoder
6024d1abfb2Sjoerg  *
6034d1abfb2Sjoerg  * \param       strm        Pointer to properly prepared lzma_stream
6044d1abfb2Sjoerg  * \param       i           The decoded Index will be made available via
6054d1abfb2Sjoerg  *                          this pointer. Initially this function will
6064d1abfb2Sjoerg  *                          set *i to NULL (the old value is ignored). If
6074d1abfb2Sjoerg  *                          decoding succeeds (lzma_code() returns
6084d1abfb2Sjoerg  *                          LZMA_STREAM_END), *i will be set to point
6094d1abfb2Sjoerg  *                          to a new lzma_index, which the application
6104d1abfb2Sjoerg  *                          has to later free with lzma_index_end().
6114d1abfb2Sjoerg  * \param       memlimit    How much memory the resulting lzma_index is
612*6b13043cSjoerg  *                          allowed to require. liblzma 5.2.3 and earlier
613*6b13043cSjoerg  *                          don't allow 0 here and return LZMA_PROG_ERROR;
614*6b13043cSjoerg  *                          later versions treat 0 as if 1 had been specified.
6154d1abfb2Sjoerg  *
616*6b13043cSjoerg  * Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
617*6b13043cSjoerg  * There is no need to use LZMA_FINISH, but it's allowed because it may
618*6b13043cSjoerg  * simplify certain types of applications.
6194d1abfb2Sjoerg  *
6204d1abfb2Sjoerg  * \return      - LZMA_OK: Initialization succeeded, continue with lzma_code().
6214d1abfb2Sjoerg  *              - LZMA_MEM_ERROR
6224d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
623*6b13043cSjoerg  *
624*6b13043cSjoerg  *              liblzma 5.2.3 and older list also LZMA_MEMLIMIT_ERROR here
625*6b13043cSjoerg  *              but that error code has never been possible from this
626*6b13043cSjoerg  *              initialization function.
6274d1abfb2Sjoerg  */
6284d1abfb2Sjoerg extern LZMA_API(lzma_ret) lzma_index_decoder(
6294d1abfb2Sjoerg 		lzma_stream *strm, lzma_index **i, uint64_t memlimit)
6304d1abfb2Sjoerg 		lzma_nothrow lzma_attr_warn_unused_result;
6314d1abfb2Sjoerg 
6324d1abfb2Sjoerg 
6334d1abfb2Sjoerg /**
6344d1abfb2Sjoerg  * \brief       Single-call .xz Index encoder
6354d1abfb2Sjoerg  *
6364d1abfb2Sjoerg  * \param       i         lzma_index to be encoded
6374d1abfb2Sjoerg  * \param       out       Beginning of the output buffer
6384d1abfb2Sjoerg  * \param       out_pos   The next byte will be written to out[*out_pos].
6394d1abfb2Sjoerg  *                        *out_pos is updated only if encoding succeeds.
6404d1abfb2Sjoerg  * \param       out_size  Size of the out buffer; the first byte into
6414d1abfb2Sjoerg  *                        which no data is written to is out[out_size].
6424d1abfb2Sjoerg  *
6434d1abfb2Sjoerg  * \return      - LZMA_OK: Encoding was successful.
6444d1abfb2Sjoerg  *              - LZMA_BUF_ERROR: Output buffer is too small. Use
6454d1abfb2Sjoerg  *                lzma_index_size() to find out how much output
6464d1abfb2Sjoerg  *                space is needed.
6474d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
6484d1abfb2Sjoerg  *
6494d1abfb2Sjoerg  * \note        This function doesn't take allocator argument since all
6504d1abfb2Sjoerg  *              the internal data is allocated on stack.
6514d1abfb2Sjoerg  */
6524d1abfb2Sjoerg extern LZMA_API(lzma_ret) lzma_index_buffer_encode(const lzma_index *i,
6534d1abfb2Sjoerg 		uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
6544d1abfb2Sjoerg 
6554d1abfb2Sjoerg 
6564d1abfb2Sjoerg /**
6574d1abfb2Sjoerg  * \brief       Single-call .xz Index decoder
6584d1abfb2Sjoerg  *
6594d1abfb2Sjoerg  * \param       i           If decoding succeeds, *i will point to a new
6604d1abfb2Sjoerg  *                          lzma_index, which the application has to
6614d1abfb2Sjoerg  *                          later free with lzma_index_end(). If an error
6624d1abfb2Sjoerg  *                          occurs, *i will be NULL. The old value of *i
6634d1abfb2Sjoerg  *                          is always ignored and thus doesn't need to be
6644d1abfb2Sjoerg  *                          initialized by the caller.
6654d1abfb2Sjoerg  * \param       memlimit    Pointer to how much memory the resulting
6664d1abfb2Sjoerg  *                          lzma_index is allowed to require. The value
6674d1abfb2Sjoerg  *                          pointed by this pointer is modified if and only
6684d1abfb2Sjoerg  *                          if LZMA_MEMLIMIT_ERROR is returned.
6694d1abfb2Sjoerg  * \param       allocator   Pointer to lzma_allocator, or NULL to use malloc()
6704d1abfb2Sjoerg  * \param       in          Beginning of the input buffer
6714d1abfb2Sjoerg  * \param       in_pos      The next byte will be read from in[*in_pos].
6724d1abfb2Sjoerg  *                          *in_pos is updated only if decoding succeeds.
6734d1abfb2Sjoerg  * \param       in_size     Size of the input buffer; the first byte that
6744d1abfb2Sjoerg  *                          won't be read is in[in_size].
6754d1abfb2Sjoerg  *
6764d1abfb2Sjoerg  * \return      - LZMA_OK: Decoding was successful.
6774d1abfb2Sjoerg  *              - LZMA_MEM_ERROR
6784d1abfb2Sjoerg  *              - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
6794d1abfb2Sjoerg  *                The minimum required memlimit value was stored to *memlimit.
6804d1abfb2Sjoerg  *              - LZMA_DATA_ERROR
6814d1abfb2Sjoerg  *              - LZMA_PROG_ERROR
6824d1abfb2Sjoerg  */
6834d1abfb2Sjoerg extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
6847653b22fSchristos 		uint64_t *memlimit, const lzma_allocator *allocator,
6854d1abfb2Sjoerg 		const uint8_t *in, size_t *in_pos, size_t in_size)
6864d1abfb2Sjoerg 		lzma_nothrow;
687