1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: expandtab:ts=8:sw=4:softtabstop=4:
3 /**
4  * \file        lzma/index.h
5  * \brief       Handling of .xz Index lists
6  */
7 
8 /*
9  * Author: Lasse Collin
10  *
11  * This file has been put into the public domain.
12  * You can do whatever you want with this file.
13  *
14  * See ../lzma.h for information about liblzma as a whole.
15  */
16 
17 #ifndef LZMA_H_INTERNAL
18 #	error Never include this file directly. Use <lzma.h> instead.
19 #endif
20 
21 
22 /**
23  * \brief       Opaque data type to hold the Index
24  */
25 typedef struct lzma_index_s lzma_index;
26 
27 
28 /**
29  * \brief       Index Record and its location
30  */
31 typedef struct {
32 	/**
33 	 * \brief       Total encoded size of a Block including Block Padding
34 	 *
35 	 * This value is useful if you need to know the actual size of the
36 	 * Block that the Block decoder will read.
37 	 */
38 	lzma_vli total_size;
39 
40 	/**
41 	 * \brief       Encoded size of a Block excluding Block Padding
42 	 *
43 	 * This value is stored in the Index. When doing random-access
44 	 * reading, you should give this value to the Block decoder along
45 	 * with uncompressed_size.
46 	 */
47 	lzma_vli unpadded_size;
48 
49 	/**
50 	 * \brief       Uncompressed Size of a Block
51 	 */
52 	lzma_vli uncompressed_size;
53 
54 	/**
55 	 * \brief       Compressed offset in the Stream(s)
56 	 *
57 	 * This is the offset of the first byte of the Block, that is,
58 	 * where you need to seek to decode the Block. The offset
59 	 * is relative to the beginning of the Stream, or if there are
60 	 * multiple Indexes combined, relative to the beginning of the
61 	 * first Stream.
62 	 */
63 	lzma_vli stream_offset;
64 
65 	/**
66 	 * \brief       Uncompressed offset
67 	 *
68 	 * When doing random-access reading, it is possible that the target
69 	 * offset is not exactly at Block boundary. One will need to compare
70 	 * the target offset against uncompressed_offset, and possibly decode
71 	 * and throw away some amount of data before reaching the target
72 	 * offset.
73 	 */
74 	lzma_vli uncompressed_offset;
75 
76 } lzma_index_record;
77 
78 
79 /**
80  * \brief       Calculate memory usage for Index with given number of Records
81  *
82  * On disk, the size of the Index field depends on both the number of Records
83  * stored and how big values the Records store (due to variable-length integer
84  * encoding). When the Index is kept in lzma_index structure, the memory usage
85  * depends only on the number of Records stored in the Index. The size in RAM
86  * is almost always a lot bigger than in encoded form on disk.
87  *
88  * This function calculates an approximate amount of memory needed hold the
89  * given number of Records in lzma_index structure. This value may vary
90  * between liblzma versions if the internal implementation is modified.
91  *
92  * If you want to know how much memory an existing lzma_index structure is
93  * using, use lzma_index_memusage(lzma_index_count(i)).
94  */
95 extern LZMA_API(uint64_t) lzma_index_memusage(lzma_vli record_count)
96 		lzma_nothrow;
97 
98 
99 /**
100  * \brief       Allocate and initialize a new lzma_index structure
101  *
102  * If i is NULL, a new lzma_index structure is allocated, initialized,
103  * and a pointer to it returned. If allocation fails, NULL is returned.
104  *
105  * If i is non-NULL, it is reinitialized and the same pointer returned.
106  * In this case, return value cannot be NULL or a different pointer than
107  * the i that was given as an argument.
108  */
109 extern LZMA_API(lzma_index *) lzma_index_init(
110 		lzma_index *i, lzma_allocator *allocator) lzma_nothrow;
111 
112 
113 /**
114  * \brief       Deallocate the Index
115  *
116  * If i is NULL, this does nothing.
117  */
118 extern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
119 		lzma_nothrow;
120 
121 
122 /**
123  * \brief       Add a new Record to an Index
124  *
125  * \param       i                 Pointer to a lzma_index structure
126  * \param       allocator         Pointer to lzma_allocator, or NULL to
127  *                                use malloc()
128  * \param       unpadded_size     Unpadded Size of a Block. This can be
129  *                                calculated with lzma_block_unpadded_size()
130  *                                after encoding or decoding the Block.
131  * \param       uncompressed_size Uncompressed Size of a Block. This can be
132  *                                taken directly from lzma_block structure
133  *                                after encoding or decoding the Block.
134  *
135  * Appending a new Record does not affect the read position.
136  *
137  * \return      - LZMA_OK
138  *              - LZMA_MEM_ERROR
139  *              - LZMA_DATA_ERROR: Compressed or uncompressed size of the
140  *                Stream or size of the Index field would grow too big.
141  *              - LZMA_PROG_ERROR
142  */
143 extern LZMA_API(lzma_ret) lzma_index_append(
144 		lzma_index *i, lzma_allocator *allocator,
145 		lzma_vli unpadded_size, lzma_vli uncompressed_size)
146 		lzma_nothrow lzma_attr_warn_unused_result;
147 
148 
149 /**
150  * \brief       Get the number of Records
151  */
152 extern LZMA_API(lzma_vli) lzma_index_count(const lzma_index *i)
153 		lzma_nothrow lzma_attr_pure;
154 
155 
156 /**
157  * \brief       Get the size of the Index field as bytes
158  *
159  * This is needed to verify the Backward Size field in the Stream Footer.
160  */
161 extern LZMA_API(lzma_vli) lzma_index_size(const lzma_index *i)
162 		lzma_nothrow lzma_attr_pure;
163 
164 
165 /**
166  * \brief       Get the total size of the Blocks
167  *
168  * This doesn't include the Stream Header, Stream Footer, Stream Padding,
169  * or Index fields.
170  */
171 extern LZMA_API(lzma_vli) lzma_index_total_size(const lzma_index *i)
172 		lzma_nothrow lzma_attr_pure;
173 
174 
175 /**
176  * \brief       Get the total size of the Stream
177  *
178  * If multiple Indexes have been combined, this works as if the Blocks
179  * were in a single Stream.
180  */
181 extern LZMA_API(lzma_vli) lzma_index_stream_size(const lzma_index *i)
182 		lzma_nothrow lzma_attr_pure;
183 
184 
185 /**
186  * \brief       Get the total size of the file
187  *
188  * When no Indexes have been combined with lzma_index_cat(), this function is
189  * identical to lzma_index_stream_size(). If multiple Indexes have been
190  * combined, this includes also the headers of each separate Stream and the
191  * possible Stream Padding fields.
192  */
193 extern LZMA_API(lzma_vli) lzma_index_file_size(const lzma_index *i)
194 		lzma_nothrow lzma_attr_pure;
195 
196 
197 /**
198  * \brief       Get the uncompressed size of the Stream
199  */
200 extern LZMA_API(lzma_vli) lzma_index_uncompressed_size(const lzma_index *i)
201 		lzma_nothrow lzma_attr_pure;
202 
203 
204 /**
205  * \brief       Get the next Record from the Index
206  */
207 extern LZMA_API(lzma_bool) lzma_index_read(
208 		lzma_index *i, lzma_index_record *record)
209 		lzma_nothrow lzma_attr_warn_unused_result;
210 
211 
212 /**
213  * \brief       Rewind the Index
214  *
215  * Rewind the Index so that next call to lzma_index_read() will return the
216  * first Record.
217  */
218 extern LZMA_API(void) lzma_index_rewind(lzma_index *i) lzma_nothrow;
219 
220 
221 /**
222  * \brief       Locate a Record
223  *
224  * When the Index is available, it is possible to do random-access reading
225  * with granularity of Block size.
226  *
227  * \param       i       Pointer to lzma_index structure
228  * \param       record  Pointer to a structure to hold the search results
229  * \param       target  Uncompressed target offset which the caller would
230  *                      like to locate from the Stream
231  *
232  * If the target is smaller than the uncompressed size of the Stream (can be
233  * checked with lzma_index_uncompressed_size()):
234  *  - Information about the Record containing the requested uncompressed
235  *    offset is stored into *record.
236  *  - Read offset will be adjusted so that calling lzma_index_read() can be
237  *    used to read subsequent Records.
238  *  - This function returns false.
239  *
240  * If target is greater than the uncompressed size of the Stream, *record
241  * and the read position are not modified, and this function returns true.
242  */
243 extern LZMA_API(lzma_bool) lzma_index_locate(
244 		lzma_index *i, lzma_index_record *record, lzma_vli target)
245 		lzma_nothrow;
246 
247 
248 /**
249  * \brief       Concatenate Indexes of two Streams
250  *
251  * Concatenating Indexes is useful when doing random-access reading in
252  * multi-Stream .xz file, or when combining multiple Streams into single
253  * Stream.
254  *
255  * \param       dest      Destination Index after which src is appended
256  * \param       src       Source Index. If this function succeeds, the
257  *                        memory allocated for src is freed or moved to
258  *                        be part of dest.
259  * \param       allocator Custom memory allocator; can be NULL to use
260  *                        malloc() and free().
261  * \param       padding   Size of the Stream Padding field between Streams.
262  *                        This must be a multiple of four.
263  *
264  * \return      - LZMA_OK: Indexes concatenated successfully. src is now
265  *                a dangling pointer.
266  *              - LZMA_DATA_ERROR: *dest would grow too big.
267  *              - LZMA_MEM_ERROR
268  *              - LZMA_PROG_ERROR
269  */
270 extern LZMA_API(lzma_ret) lzma_index_cat(lzma_index *lzma_restrict dest,
271 		lzma_index *lzma_restrict src,
272 		lzma_allocator *allocator, lzma_vli padding)
273 		lzma_nothrow lzma_attr_warn_unused_result;
274 
275 
276 /**
277  * \brief       Duplicate an Index list
278  *
279  * Makes an identical copy of the Index. Also the read position is copied.
280  *
281  * \return      A copy of the Index, or NULL if memory allocation failed.
282  */
283 extern LZMA_API(lzma_index *) lzma_index_dup(
284 		const lzma_index *i, lzma_allocator *allocator)
285 		lzma_nothrow lzma_attr_warn_unused_result;
286 
287 
288 /**
289  * \brief       Compare if two Index lists are identical
290  *
291  * Read positions are not compared.
292  *
293  * \return      True if *a and *b are equal, false otherwise.
294  */
295 extern LZMA_API(lzma_bool) lzma_index_equal(
296 		const lzma_index *a, const lzma_index *b)
297 		lzma_nothrow lzma_attr_pure;
298 
299 
300 /**
301  * \brief       Initialize .xz Index encoder
302  *
303  * \param       strm        Pointer to properly prepared lzma_stream
304  * \param       i           Pointer to lzma_index which should be encoded.
305  *                          The read position will be at the end of the Index
306  *                          after lzma_code() has returned LZMA_STREAM_END.
307  *
308  * The only valid action value for lzma_code() is LZMA_RUN.
309  *
310  * \return      - LZMA_OK: Initialization succeeded, continue with lzma_code().
311  *              - LZMA_MEM_ERROR
312  *              - LZMA_PROG_ERROR
313  */
314 extern LZMA_API(lzma_ret) lzma_index_encoder(lzma_stream *strm, lzma_index *i)
315 		lzma_nothrow lzma_attr_warn_unused_result;
316 
317 
318 /**
319  * \brief       Initialize .xz Index decoder
320  *
321  * \param       strm        Pointer to properly prepared lzma_stream
322  * \param       i           Pointer to a pointer that will be made to point
323  *                          to the final decoded Index once lzma_code() has
324  *                          returned LZMA_STREAM_END. That is,
325  *                          lzma_index_decoder() always takes care of
326  *                          allocating a new lzma_index structure, and *i
327  *                          doesn't need to be initialized by the caller.
328  * \param       memlimit    How much memory the resulting Index is allowed
329  *                          to require.
330  *
331  * The only valid action value for lzma_code() is LZMA_RUN.
332  *
333  * \return      - LZMA_OK: Initialization succeeded, continue with lzma_code().
334  *              - LZMA_MEM_ERROR
335  *              - LZMA_MEMLIMIT_ERROR
336  *              - LZMA_PROG_ERROR
337  *
338  * \note        The memory usage limit is checked early in the decoding
339  *              (within the first dozen input bytes or so). The actual memory
340  *              is allocated later in smaller pieces. If the memory usage
341  *              limit is modified with lzma_memlimit_set() after a part
342  *              of the Index has already been decoded, the new limit may
343  *              get ignored.
344  */
345 extern LZMA_API(lzma_ret) lzma_index_decoder(
346 		lzma_stream *strm, lzma_index **i, uint64_t memlimit)
347 		lzma_nothrow lzma_attr_warn_unused_result;
348 
349 
350 /**
351  * \brief       Single-call .xz Index encoder
352  *
353  * \param       i         Index to be encoded. The read position will be at
354  *                        the end of the Index if encoding succeeds, or at
355  *                        unspecified position in case an error occurs.
356  * \param       out       Beginning of the output buffer
357  * \param       out_pos   The next byte will be written to out[*out_pos].
358  *                        *out_pos is updated only if encoding succeeds.
359  * \param       out_size  Size of the out buffer; the first byte into
360  *                        which no data is written to is out[out_size].
361  *
362  * \return      - LZMA_OK: Encoding was successful.
363  *              - LZMA_BUF_ERROR: Output buffer is too small. Use
364  *                lzma_index_size() to find out how much output
365  *                space is needed.
366  *              - LZMA_PROG_ERROR
367  *
368  * \note        This function doesn't take allocator argument since all
369  *              the internal data is allocated on stack.
370  */
371 extern LZMA_API(lzma_ret) lzma_index_buffer_encode(lzma_index *i,
372 		uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
373 
374 
375 /**
376  * \brief       Single-call .xz Index decoder
377  *
378  * \param       i           Pointer to a pointer that will be made to point
379  *                          to the final decoded Index if decoding is
380  *                          successful. That is, lzma_index_buffer_decode()
381  *                          always takes care of allocating a new
382  *                          lzma_index structure, and *i doesn't need to be
383  *                          initialized by the caller.
384  * \param       memlimit    Pointer to how much memory the resulting Index
385  *                          is allowed to require. The value pointed by
386  *                          this pointer is modified if and only if
387  *                          LZMA_MEMLIMIT_ERROR is returned.
388  * \param       allocator   Pointer to lzma_allocator, or NULL to use malloc()
389  * \param       in          Beginning of the input buffer
390  * \param       in_pos      The next byte will be read from in[*in_pos].
391  *                          *in_pos is updated only if decoding succeeds.
392  * \param       in_size     Size of the input buffer; the first byte that
393  *                          won't be read is in[in_size].
394  *
395  * \return      - LZMA_OK: Decoding was successful.
396  *              - LZMA_MEM_ERROR
397  *              - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
398  *                The minimum required memlimit value was stored to *memlimit.
399  *              - LZMA_DATA_ERROR
400  *              - LZMA_PROG_ERROR
401  */
402 extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
403 		uint64_t *memlimit, lzma_allocator *allocator,
404 		const uint8_t *in, size_t *in_pos, size_t in_size)
405 		lzma_nothrow;
406