1207753Smm/**
2207753Smm * \file        lzma/index.h
3207753Smm * \brief       Handling of .xz Index and related information
4207753Smm */
5207753Smm
6207753Smm/*
7207753Smm * Author: Lasse Collin
8207753Smm *
9207753Smm * This file has been put into the public domain.
10207753Smm * You can do whatever you want with this file.
11207753Smm *
12207753Smm * See ../lzma.h for information about liblzma as a whole.
13207753Smm */
14207753Smm
15207753Smm#ifndef LZMA_H_INTERNAL
16207753Smm#	error Never include this file directly. Use <lzma.h> instead.
17207753Smm#endif
18207753Smm
19207753Smm
20207753Smm/**
21207753Smm * \brief       Opaque data type to hold the Index(es) and other information
22207753Smm *
23207753Smm * lzma_index often holds just one .xz Index and possibly the Stream Flags
24207753Smm * of the same Stream and size of the Stream Padding field. However,
25207753Smm * multiple lzma_indexes can be concatenated with lzma_index_cat() and then
26207753Smm * there may be information about multiple Streams in the same lzma_index.
27207753Smm *
28207753Smm * Notes about thread safety: Only one thread may modify lzma_index at
29207753Smm * a time. All functions that take non-const pointer to lzma_index
30207753Smm * modify it. As long as no thread is modifying the lzma_index, getting
31207753Smm * information from the same lzma_index can be done from multiple threads
32207753Smm * at the same time with functions that take a const pointer to
33207753Smm * lzma_index or use lzma_index_iter. The same iterator must be used
34207753Smm * only by one thread at a time, of course, but there can be as many
35207753Smm * iterators for the same lzma_index as needed.
36207753Smm */
37207753Smmtypedef struct lzma_index_s lzma_index;
38207753Smm
39207753Smm
40207753Smm/**
41207753Smm * \brief       Iterator to get information about Blocks and Streams
42207753Smm */
43207753Smmtypedef struct {
44207753Smm	struct {
45207753Smm		/**
46207753Smm		 * \brief       Pointer to Stream Flags
47207753Smm		 *
48207753Smm		 * This is NULL if Stream Flags have not been set for
49207753Smm		 * this Stream with lzma_index_stream_flags().
50207753Smm		 */
51207753Smm		const lzma_stream_flags *flags;
52207753Smm
53207753Smm		const void *reserved_ptr1;
54207753Smm		const void *reserved_ptr2;
55207753Smm		const void *reserved_ptr3;
56207753Smm
57207753Smm		/**
58207753Smm		 * \brief       Stream number in the lzma_index
59207753Smm		 *
60207753Smm		 * The first Stream is 1.
61207753Smm		 */
62207753Smm		lzma_vli number;
63207753Smm
64207753Smm		/**
65207753Smm		 * \brief       Number of Blocks in the Stream
66207753Smm		 *
67207753Smm		 * If this is zero, the block structure below has
68207753Smm		 * undefined values.
69207753Smm		 */
70207753Smm		lzma_vli block_count;
71207753Smm
72207753Smm		/**
73207753Smm		 * \brief       Compressed start offset of this Stream
74207753Smm		 *
75207753Smm		 * The offset is relative to the beginning of the lzma_index
76207753Smm		 * (i.e. usually the beginning of the .xz file).
77207753Smm		 */
78207753Smm		lzma_vli compressed_offset;
79207753Smm
80207753Smm		/**
81207753Smm		 * \brief       Uncompressed start offset of this Stream
82207753Smm		 *
83207753Smm		 * The offset is relative to the beginning of the lzma_index
84207753Smm		 * (i.e. usually the beginning of the .xz file).
85207753Smm		 */
86207753Smm		lzma_vli uncompressed_offset;
87207753Smm
88207753Smm		/**
89207753Smm		 * \brief       Compressed size of this Stream
90207753Smm		 *
91207753Smm		 * This includes all headers except the possible
92207753Smm		 * Stream Padding after this Stream.
93207753Smm		 */
94207753Smm		lzma_vli compressed_size;
95207753Smm
96207753Smm		/**
97207753Smm		 * \brief       Uncompressed size of this Stream
98207753Smm		 */
99207753Smm		lzma_vli uncompressed_size;
100207753Smm
101207753Smm		/**
102207753Smm		 * \brief       Size of Stream Padding after this Stream
103207753Smm		 *
104207753Smm		 * If it hasn't been set with lzma_index_stream_padding(),
105207753Smm		 * this defaults to zero. Stream Padding is always
106207753Smm		 * a multiple of four bytes.
107207753Smm		 */
108207753Smm		lzma_vli padding;
109207753Smm
110207753Smm		lzma_vli reserved_vli1;
111207753Smm		lzma_vli reserved_vli2;
112207753Smm		lzma_vli reserved_vli3;
113207753Smm		lzma_vli reserved_vli4;
114207753Smm	} stream;
115207753Smm
116207753Smm	struct {
117207753Smm		/**
118207753Smm		 * \brief       Block number in the file
119207753Smm		 *
120207753Smm		 * The first Block is 1.
121207753Smm		 */
122207753Smm		lzma_vli number_in_file;
123207753Smm
124207753Smm		/**
125207753Smm		 * \brief       Compressed start offset of this Block
126207753Smm		 *
127207753Smm		 * This offset is relative to the beginning of the
128207753Smm		 * lzma_index (i.e. usually the beginning of the .xz file).
129207753Smm		 * Normally this is where you should seek in the .xz file
130207753Smm		 * to start decompressing this Block.
131207753Smm		 */
132207753Smm		lzma_vli compressed_file_offset;
133207753Smm
134207753Smm		/**
135207753Smm		 * \brief       Uncompressed start offset of this Block
136207753Smm		 *
137207753Smm		 * This offset is relative to the beginning of the lzma_index
138207753Smm		 * (i.e. usually the beginning of the .xz file).
139215187Smm		 *
140215187Smm		 * When doing random-access reading, it is possible that
141215187Smm		 * the target offset is not exactly at Block boundary. One
142215187Smm		 * will need to compare the target offset against
143215187Smm		 * uncompressed_file_offset or uncompressed_stream_offset,
144215187Smm		 * and possibly decode and throw away some amount of data
145215187Smm		 * before reaching the target offset.
146207753Smm		 */
147207753Smm		lzma_vli uncompressed_file_offset;
148207753Smm
149207753Smm		/**
150207753Smm		 * \brief       Block number in this Stream
151207753Smm		 *
152207753Smm		 * The first Block is 1.
153207753Smm		 */
154207753Smm		lzma_vli number_in_stream;
155207753Smm
156207753Smm		/**
157207753Smm		 * \brief       Compressed start offset of this Block
158207753Smm		 *
159207753Smm		 * This offset is relative to the beginning of the Stream
160207753Smm		 * containing this Block.
161207753Smm		 */
162207753Smm		lzma_vli compressed_stream_offset;
163207753Smm
164207753Smm		/**
165207753Smm		 * \brief       Uncompressed start offset of this Block
166207753Smm		 *
167207753Smm		 * This offset is relative to the beginning of the Stream
168207753Smm		 * containing this Block.
169207753Smm		 */
170207753Smm		lzma_vli uncompressed_stream_offset;
171207753Smm
172207753Smm		/**
173207753Smm		 * \brief       Uncompressed size of this Block
174207753Smm		 *
175207753Smm		 * You should pass this to the Block decoder if you will
176215187Smm		 * decode this Block. It will allow the Block decoder to
177215187Smm		 * validate the uncompressed size.
178207753Smm		 */
179207753Smm		lzma_vli uncompressed_size;
180207753Smm
181207753Smm		/**
182207753Smm		 * \brief       Unpadded size of this Block
183207753Smm		 *
184207753Smm		 * You should pass this to the Block decoder if you will
185215187Smm		 * decode this Block. It will allow the Block decoder to
186215187Smm		 * validate the unpadded size.
187207753Smm		 */
188207753Smm		lzma_vli unpadded_size;
189207753Smm
190207753Smm		/**
191207753Smm		 * \brief       Total compressed size
192207753Smm		 *
193207753Smm		 * This includes all headers and padding in this Block.
194207753Smm		 * This is useful if you need to know how many bytes
195207753Smm		 * the Block decoder will actually read.
196207753Smm		 */
197207753Smm		lzma_vli total_size;
198207753Smm
199207753Smm		lzma_vli reserved_vli1;
200207753Smm		lzma_vli reserved_vli2;
201207753Smm		lzma_vli reserved_vli3;
202207753Smm		lzma_vli reserved_vli4;
203207753Smm
204207753Smm		const void *reserved_ptr1;
205207753Smm		const void *reserved_ptr2;
206207753Smm		const void *reserved_ptr3;
207207753Smm		const void *reserved_ptr4;
208207753Smm	} block;
209207753Smm
210207753Smm	/*
211207753Smm	 * Internal data which is used to store the state of the iterator.
212207753Smm	 * The exact format may vary between liblzma versions, so don't
213207753Smm	 * touch these in any way.
214207753Smm	 */
215207753Smm	union {
216207753Smm		const void *p;
217207753Smm		size_t s;
218207753Smm		lzma_vli v;
219207753Smm	} internal[6];
220207753Smm} lzma_index_iter;
221207753Smm
222207753Smm
223207753Smm/**
224207753Smm * \brief       Operation mode for lzma_index_iter_next()
225207753Smm */
226207753Smmtypedef enum {
227207753Smm	LZMA_INDEX_ITER_ANY             = 0,
228207753Smm		/**<
229207753Smm		 * \brief       Get the next Block or Stream
230207753Smm		 *
231207753Smm		 * Go to the next Block if the current Stream has at least
232207753Smm		 * one Block left. Otherwise go to the next Stream even if
233207753Smm		 * it has no Blocks. If the Stream has no Blocks
234207753Smm		 * (lzma_index_iter.stream.block_count == 0),
235207753Smm		 * lzma_index_iter.block will have undefined values.
236207753Smm		 */
237207753Smm
238207753Smm	LZMA_INDEX_ITER_STREAM          = 1,
239207753Smm		/**<
240207753Smm		 * \brief       Get the next Stream
241207753Smm		 *
242207753Smm		 * Go to the next Stream even if the current Stream has
243207753Smm		 * unread Blocks left. If the next Stream has at least one
244207753Smm		 * Block, the iterator will point to the first Block.
245207753Smm		 * If there are no Blocks, lzma_index_iter.block will have
246207753Smm		 * undefined values.
247207753Smm		 */
248207753Smm
249207753Smm	LZMA_INDEX_ITER_BLOCK           = 2,
250207753Smm		/**<
251207753Smm		 * \brief       Get the next Block
252207753Smm		 *
253207753Smm		 * Go to the next Block if the current Stream has at least
254207753Smm		 * one Block left. If the current Stream has no Blocks left,
255207753Smm		 * the next Stream with at least one Block is located and
256207753Smm		 * the iterator will be made to point to the first Block of
257207753Smm		 * that Stream.
258207753Smm		 */
259207753Smm
260207753Smm	LZMA_INDEX_ITER_NONEMPTY_BLOCK  = 3
261207753Smm		/**<
262207753Smm		 * \brief       Get the next non-empty Block
263207753Smm		 *
264207753Smm		 * This is like LZMA_INDEX_ITER_BLOCK except that it will
265207753Smm		 * skip Blocks whose Uncompressed Size is zero.
266207753Smm		 */
267207753Smm
268207753Smm} lzma_index_iter_mode;
269207753Smm
270207753Smm
271207753Smm/**
272207753Smm * \brief       Calculate memory usage of lzma_index
273207753Smm *
274207753Smm * On disk, the size of the Index field depends on both the number of Records
275207753Smm * stored and how big values the Records store (due to variable-length integer
276207753Smm * encoding). When the Index is kept in lzma_index structure, the memory usage
277207753Smm * depends only on the number of Records/Blocks stored in the Index(es), and
278207753Smm * in case of concatenated lzma_indexes, the number of Streams. The size in
279207753Smm * RAM is almost always significantly bigger than in the encoded form on disk.
280207753Smm *
281207753Smm * This function calculates an approximate amount of memory needed hold
282207753Smm * the given number of Streams and Blocks in lzma_index structure. This
283207753Smm * value may vary between CPU architectures and also between liblzma versions
284207753Smm * if the internal implementation is modified.
285207753Smm */
286207753Smmextern LZMA_API(uint64_t) lzma_index_memusage(
287207753Smm		lzma_vli streams, lzma_vli blocks) lzma_nothrow;
288207753Smm
289207753Smm
290207753Smm/**
291207753Smm * \brief       Calculate the memory usage of an existing lzma_index
292207753Smm *
293207753Smm * This is a shorthand for lzma_index_memusage(lzma_index_stream_count(i),
294207753Smm * lzma_index_block_count(i)).
295207753Smm */
296207753Smmextern LZMA_API(uint64_t) lzma_index_memused(const lzma_index *i)
297207753Smm		lzma_nothrow;
298207753Smm
299207753Smm
300207753Smm/**
301207753Smm * \brief       Allocate and initialize a new lzma_index structure
302207753Smm *
303207753Smm * \return      On success, a pointer to an empty initialized lzma_index is
304207753Smm *              returned. If allocation fails, NULL is returned.
305207753Smm */
306207753Smmextern LZMA_API(lzma_index *) lzma_index_init(lzma_allocator *allocator)
307207753Smm		lzma_nothrow;
308207753Smm
309207753Smm
310207753Smm/**
311207753Smm * \brief       Deallocate lzma_index
312207753Smm *
313207753Smm * If i is NULL, this does nothing.
314207753Smm */
315207753Smmextern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
316207753Smm		lzma_nothrow;
317207753Smm
318207753Smm
319207753Smm/**
320207753Smm * \brief       Add a new Block to lzma_index
321207753Smm *
322207753Smm * \param       i                 Pointer to a lzma_index structure
323207753Smm * \param       allocator         Pointer to lzma_allocator, or NULL to
324207753Smm *                                use malloc()
325207753Smm * \param       unpadded_size     Unpadded Size of a Block. This can be
326207753Smm *                                calculated with lzma_block_unpadded_size()
327207753Smm *                                after encoding or decoding the Block.
328207753Smm * \param       uncompressed_size Uncompressed Size of a Block. This can be
329207753Smm *                                taken directly from lzma_block structure
330207753Smm *                                after encoding or decoding the Block.
331207753Smm *
332207753Smm * Appending a new Block does not invalidate iterators. For example,
333207753Smm * if an iterator was pointing to the end of the lzma_index, after
334207753Smm * lzma_index_append() it is possible to read the next Block with
335207753Smm * an existing iterator.
336207753Smm *
337207753Smm * \return      - LZMA_OK
338207753Smm *              - LZMA_MEM_ERROR
339207753Smm *              - LZMA_DATA_ERROR: Compressed or uncompressed size of the
340207753Smm *                Stream or size of the Index field would grow too big.
341207753Smm *              - LZMA_PROG_ERROR
342207753Smm */
343207753Smmextern LZMA_API(lzma_ret) lzma_index_append(
344207753Smm		lzma_index *i, lzma_allocator *allocator,
345207753Smm		lzma_vli unpadded_size, lzma_vli uncompressed_size)
346207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
347207753Smm
348207753Smm
349207753Smm/**
350207753Smm * \brief       Set the Stream Flags
351207753Smm *
352207753Smm * Set the Stream Flags of the last (and typically the only) Stream
353207753Smm * in lzma_index. This can be useful when reading information from the
354207753Smm * lzma_index, because to decode Blocks, knowing the integrity check type
355207753Smm * is needed.
356207753Smm *
357207753Smm * The given Stream Flags are copied into internal preallocated structure
358207753Smm * in the lzma_index, thus the caller doesn't need to keep the *stream_flags
359207753Smm * available after calling this function.
360207753Smm *
361207753Smm * \return      - LZMA_OK
362207753Smm *              - LZMA_OPTIONS_ERROR: Unsupported stream_flags->version.
363207753Smm *              - LZMA_PROG_ERROR
364207753Smm */
365207753Smmextern LZMA_API(lzma_ret) lzma_index_stream_flags(
366207753Smm		lzma_index *i, const lzma_stream_flags *stream_flags)
367207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
368207753Smm
369207753Smm
370207753Smm/**
371207753Smm * \brief       Get the types of integrity Checks
372207753Smm *
373213700Smm * If lzma_index_stream_flags() is used to set the Stream Flags for
374207753Smm * every Stream, lzma_index_checks() can be used to get a bitmask to
375207753Smm * indicate which Check types have been used. It can be useful e.g. if
376207753Smm * showing the Check types to the user.
377207753Smm *
378207753Smm * The bitmask is 1 << check_id, e.g. CRC32 is 1 << 1 and SHA-256 is 1 << 10.
379207753Smm */
380207753Smmextern LZMA_API(uint32_t) lzma_index_checks(const lzma_index *i)
381207753Smm		lzma_nothrow lzma_attr_pure;
382207753Smm
383207753Smm
384207753Smm/**
385207753Smm * \brief       Set the amount of Stream Padding
386207753Smm *
387207753Smm * Set the amount of Stream Padding of the last (and typically the only)
388207753Smm * Stream in the lzma_index. This is needed when planning to do random-access
389207753Smm * reading within multiple concatenated Streams.
390207753Smm *
391207753Smm * By default, the amount of Stream Padding is assumed to be zero bytes.
392207753Smm *
393207753Smm * \return      - LZMA_OK
394207753Smm *              - LZMA_DATA_ERROR: The file size would grow too big.
395207753Smm *              - LZMA_PROG_ERROR
396207753Smm */
397207753Smmextern LZMA_API(lzma_ret) lzma_index_stream_padding(
398207753Smm		lzma_index *i, lzma_vli stream_padding)
399207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
400207753Smm
401207753Smm
402207753Smm/**
403207753Smm * \brief       Get the number of Streams
404207753Smm */
405207753Smmextern LZMA_API(lzma_vli) lzma_index_stream_count(const lzma_index *i)
406207753Smm		lzma_nothrow lzma_attr_pure;
407207753Smm
408207753Smm
409207753Smm/**
410207753Smm * \brief       Get the number of Blocks
411207753Smm *
412207753Smm * This returns the total number of Blocks in lzma_index. To get number
413207753Smm * of Blocks in individual Streams, use lzma_index_iter.
414207753Smm */
415207753Smmextern LZMA_API(lzma_vli) lzma_index_block_count(const lzma_index *i)
416207753Smm		lzma_nothrow lzma_attr_pure;
417207753Smm
418207753Smm
419207753Smm/**
420207753Smm * \brief       Get the size of the Index field as bytes
421207753Smm *
422207753Smm * This is needed to verify the Backward Size field in the Stream Footer.
423207753Smm */
424207753Smmextern LZMA_API(lzma_vli) lzma_index_size(const lzma_index *i)
425207753Smm		lzma_nothrow lzma_attr_pure;
426207753Smm
427207753Smm
428207753Smm/**
429207753Smm * \brief       Get the total size of the Stream
430207753Smm *
431207753Smm * If multiple lzma_indexes have been combined, this works as if the Blocks
432207753Smm * were in a single Stream. This is useful if you are going to combine
433207753Smm * Blocks from multiple Streams into a single new Stream.
434207753Smm */
435207753Smmextern LZMA_API(lzma_vli) lzma_index_stream_size(const lzma_index *i)
436207753Smm		lzma_nothrow lzma_attr_pure;
437207753Smm
438207753Smm
439207753Smm/**
440207753Smm * \brief       Get the total size of the Blocks
441207753Smm *
442207753Smm * This doesn't include the Stream Header, Stream Footer, Stream Padding,
443207753Smm * or Index fields.
444207753Smm */
445207753Smmextern LZMA_API(lzma_vli) lzma_index_total_size(const lzma_index *i)
446207753Smm		lzma_nothrow lzma_attr_pure;
447207753Smm
448207753Smm
449207753Smm/**
450207753Smm * \brief       Get the total size of the file
451207753Smm *
452207753Smm * When no lzma_indexes have been combined with lzma_index_cat() and there is
453207753Smm * no Stream Padding, this function is identical to lzma_index_stream_size().
454207753Smm * If multiple lzma_indexes have been combined, this includes also the headers
455207753Smm * of each separate Stream and the possible Stream Padding fields.
456207753Smm */
457207753Smmextern LZMA_API(lzma_vli) lzma_index_file_size(const lzma_index *i)
458207753Smm		lzma_nothrow lzma_attr_pure;
459207753Smm
460207753Smm
461207753Smm/**
462207753Smm * \brief       Get the uncompressed size of the file
463207753Smm */
464207753Smmextern LZMA_API(lzma_vli) lzma_index_uncompressed_size(const lzma_index *i)
465207753Smm		lzma_nothrow lzma_attr_pure;
466207753Smm
467207753Smm
468207753Smm/**
469207753Smm * \brief       Initialize an iterator
470207753Smm *
471207753Smm * \param       iter    Pointer to a lzma_index_iter structure
472207753Smm * \param       i       lzma_index to which the iterator will be associated
473207753Smm *
474207753Smm * This function associates the iterator with the given lzma_index, and calls
475207753Smm * lzma_index_iter_rewind() on the iterator.
476207753Smm *
477207753Smm * This function doesn't allocate any memory, thus there is no
478207753Smm * lzma_index_iter_end(). The iterator is valid as long as the
479207753Smm * associated lzma_index is valid, that is, until lzma_index_end() or
480207753Smm * using it as source in lzma_index_cat(). Specifically, lzma_index doesn't
481207753Smm * become invalid if new Blocks are added to it with lzma_index_append() or
482207753Smm * if it is used as the destination in lzma_index_cat().
483207753Smm *
484207753Smm * It is safe to make copies of an initialized lzma_index_iter, for example,
485207753Smm * to easily restart reading at some particular position.
486207753Smm */
487207753Smmextern LZMA_API(void) lzma_index_iter_init(
488207753Smm		lzma_index_iter *iter, const lzma_index *i) lzma_nothrow;
489207753Smm
490207753Smm
491207753Smm/**
492207753Smm * \brief       Rewind the iterator
493207753Smm *
494207753Smm * Rewind the iterator so that next call to lzma_index_iter_next() will
495207753Smm * return the first Block or Stream.
496207753Smm */
497207753Smmextern LZMA_API(void) lzma_index_iter_rewind(lzma_index_iter *iter)
498207753Smm		lzma_nothrow;
499207753Smm
500207753Smm
501207753Smm/**
502207753Smm * \brief       Get the next Block or Stream
503207753Smm *
504207753Smm * \param       iter    Iterator initialized with lzma_index_iter_init()
505207753Smm * \param       mode    Specify what kind of information the caller wants
506207753Smm *                      to get. See lzma_index_iter_mode for details.
507207753Smm *
508207753Smm * \return      If next Block or Stream matching the mode was found, *iter
509207753Smm *              is updated and this function returns false. If no Block or
510207753Smm *              Stream matching the mode is found, *iter is not modified
511207753Smm *              and this function returns true. If mode is set to an unknown
512207753Smm *              value, *iter is not modified and this function returns true.
513207753Smm */
514207753Smmextern LZMA_API(lzma_bool) lzma_index_iter_next(
515207753Smm		lzma_index_iter *iter, lzma_index_iter_mode mode)
516207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
517207753Smm
518207753Smm
519207753Smm/**
520207753Smm * \brief       Locate a Block
521207753Smm *
522207753Smm * If it is possible to seek in the .xz file, it is possible to parse
523207753Smm * the Index field(s) and use lzma_index_iter_locate() to do random-access
524207753Smm * reading with granularity of Block size.
525207753Smm *
526207753Smm * \param       iter    Iterator that was earlier initialized with
527207753Smm *                      lzma_index_iter_init().
528207753Smm * \param       target  Uncompressed target offset which the caller would
529207753Smm *                      like to locate from the Stream
530207753Smm *
531207753Smm * If the target is smaller than the uncompressed size of the Stream (can be
532207753Smm * checked with lzma_index_uncompressed_size()):
533207753Smm *  - Information about the Stream and Block containing the requested
534207753Smm *    uncompressed offset is stored into *iter.
535207753Smm *  - Internal state of the iterator is adjusted so that
536207753Smm *    lzma_index_iter_next() can be used to read subsequent Blocks or Streams.
537207753Smm *  - This function returns false.
538207753Smm *
539207753Smm * If target is greater than the uncompressed size of the Stream, *iter
540207753Smm * is not modified, and this function returns true.
541207753Smm */
542207753Smmextern LZMA_API(lzma_bool) lzma_index_iter_locate(
543207753Smm		lzma_index_iter *iter, lzma_vli target) lzma_nothrow;
544207753Smm
545207753Smm
546207753Smm/**
547207753Smm * \brief       Concatenate lzma_indexes
548207753Smm *
549207753Smm * Concatenating lzma_indexes is useful when doing random-access reading in
550207753Smm * multi-Stream .xz file, or when combining multiple Streams into single
551207753Smm * Stream.
552207753Smm *
553207753Smm * \param       dest      lzma_index after which src is appended
554207753Smm * \param       src       lzma_index to be appended after dest. If this
555207753Smm *                        function succeeds, the memory allocated for src
556207753Smm *                        is freed or moved to be part of dest, and all
557207753Smm *                        iterators pointing to src will become invalid.
558207753Smm * \param       allocator Custom memory allocator; can be NULL to use
559207753Smm *                        malloc() and free().
560207753Smm *
561207753Smm * \return      - LZMA_OK: lzma_indexes were concatenated successfully.
562207753Smm *                src is now a dangling pointer.
563207753Smm *              - LZMA_DATA_ERROR: *dest would grow too big.
564207753Smm *              - LZMA_MEM_ERROR
565207753Smm *              - LZMA_PROG_ERROR
566207753Smm */
567213700Smmextern LZMA_API(lzma_ret) lzma_index_cat(
568213700Smm		lzma_index *dest, lzma_index *src, lzma_allocator *allocator)
569207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
570207753Smm
571207753Smm
572207753Smm/**
573207753Smm * \brief       Duplicate lzma_index
574207753Smm *
575207753Smm * \return      A copy of the lzma_index, or NULL if memory allocation failed.
576207753Smm */
577207753Smmextern LZMA_API(lzma_index *) lzma_index_dup(
578207753Smm		const lzma_index *i, lzma_allocator *allocator)
579207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
580207753Smm
581207753Smm
582207753Smm/**
583207753Smm * \brief       Initialize .xz Index encoder
584207753Smm *
585207753Smm * \param       strm        Pointer to properly prepared lzma_stream
586207753Smm * \param       i           Pointer to lzma_index which should be encoded.
587207753Smm *
588215187Smm * The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
589215187Smm * It is enough to use only one of them (you can choose freely; use LZMA_RUN
590215187Smm * to support liblzma versions older than 5.0.0).
591207753Smm *
592207753Smm * \return      - LZMA_OK: Initialization succeeded, continue with lzma_code().
593207753Smm *              - LZMA_MEM_ERROR
594207753Smm *              - LZMA_PROG_ERROR
595207753Smm */
596207753Smmextern LZMA_API(lzma_ret) lzma_index_encoder(
597207753Smm		lzma_stream *strm, const lzma_index *i)
598207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
599207753Smm
600207753Smm
601207753Smm/**
602207753Smm * \brief       Initialize .xz Index decoder
603207753Smm *
604207753Smm * \param       strm        Pointer to properly prepared lzma_stream
605207753Smm * \param       i           The decoded Index will be made available via
606207753Smm *                          this pointer. Initially this function will
607207753Smm *                          set *i to NULL (the old value is ignored). If
608207753Smm *                          decoding succeeds (lzma_code() returns
609207753Smm *                          LZMA_STREAM_END), *i will be set to point
610207753Smm *                          to a new lzma_index, which the application
611207753Smm *                          has to later free with lzma_index_end().
612207753Smm * \param       memlimit    How much memory the resulting lzma_index is
613207753Smm *                          allowed to require.
614207753Smm *
615215187Smm * The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
616215187Smm * It is enough to use only one of them (you can choose freely; use LZMA_RUN
617215187Smm * to support liblzma versions older than 5.0.0).
618207753Smm *
619207753Smm * \return      - LZMA_OK: Initialization succeeded, continue with lzma_code().
620207753Smm *              - LZMA_MEM_ERROR
621207753Smm *              - LZMA_MEMLIMIT_ERROR
622207753Smm *              - LZMA_PROG_ERROR
623207753Smm */
624207753Smmextern LZMA_API(lzma_ret) lzma_index_decoder(
625207753Smm		lzma_stream *strm, lzma_index **i, uint64_t memlimit)
626207753Smm		lzma_nothrow lzma_attr_warn_unused_result;
627207753Smm
628207753Smm
629207753Smm/**
630207753Smm * \brief       Single-call .xz Index encoder
631207753Smm *
632207753Smm * \param       i         lzma_index to be encoded
633207753Smm * \param       out       Beginning of the output buffer
634207753Smm * \param       out_pos   The next byte will be written to out[*out_pos].
635207753Smm *                        *out_pos is updated only if encoding succeeds.
636207753Smm * \param       out_size  Size of the out buffer; the first byte into
637207753Smm *                        which no data is written to is out[out_size].
638207753Smm *
639207753Smm * \return      - LZMA_OK: Encoding was successful.
640207753Smm *              - LZMA_BUF_ERROR: Output buffer is too small. Use
641207753Smm *                lzma_index_size() to find out how much output
642207753Smm *                space is needed.
643207753Smm *              - LZMA_PROG_ERROR
644207753Smm *
645207753Smm * \note        This function doesn't take allocator argument since all
646207753Smm *              the internal data is allocated on stack.
647207753Smm */
648207753Smmextern LZMA_API(lzma_ret) lzma_index_buffer_encode(const lzma_index *i,
649207753Smm		uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
650207753Smm
651207753Smm
652207753Smm/**
653207753Smm * \brief       Single-call .xz Index decoder
654207753Smm *
655207753Smm * \param       i           If decoding succeeds, *i will point to a new
656207753Smm *                          lzma_index, which the application has to
657207753Smm *                          later free with lzma_index_end(). If an error
658207753Smm *                          occurs, *i will be NULL. The old value of *i
659207753Smm *                          is always ignored and thus doesn't need to be
660207753Smm *                          initialized by the caller.
661207753Smm * \param       memlimit    Pointer to how much memory the resulting
662207753Smm *                          lzma_index is allowed to require. The value
663207753Smm *                          pointed by this pointer is modified if and only
664207753Smm *                          if LZMA_MEMLIMIT_ERROR is returned.
665207753Smm * \param       allocator   Pointer to lzma_allocator, or NULL to use malloc()
666207753Smm * \param       in          Beginning of the input buffer
667207753Smm * \param       in_pos      The next byte will be read from in[*in_pos].
668207753Smm *                          *in_pos is updated only if decoding succeeds.
669207753Smm * \param       in_size     Size of the input buffer; the first byte that
670207753Smm *                          won't be read is in[in_size].
671207753Smm *
672207753Smm * \return      - LZMA_OK: Decoding was successful.
673207753Smm *              - LZMA_MEM_ERROR
674207753Smm *              - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
675207753Smm *                The minimum required memlimit value was stored to *memlimit.
676207753Smm *              - LZMA_DATA_ERROR
677207753Smm *              - LZMA_PROG_ERROR
678207753Smm */
679207753Smmextern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
680207753Smm		uint64_t *memlimit, lzma_allocator *allocator,
681207753Smm		const uint8_t *in, size_t *in_pos, size_t in_size)
682207753Smm		lzma_nothrow;
683