3 * \brief Handling of .xz Index lists
9 * This file has been put into the public domain.
10 * You can do whatever you want with this file.
12 * See ../lzma.h for information about liblzma as a whole.
15 #ifndef LZMA_H_INTERNAL
16 # error Never include this file directly. Use <lzma.h> instead.
21 * \brief Opaque data type to hold the Index
23 typedef struct lzma_index_s lzma_index;
27 * \brief Index Record and its location
31 * \brief Total encoded size of a Block including Block Padding
33 * This value is useful if you need to know the actual size of the
34 * Block that the Block decoder will read.
39 * \brief Encoded size of a Block excluding Block Padding
41 * This value is stored in the Index. When doing random-access
42 * reading, you should give this value to the Block decoder along
43 * with uncompressed_size.
45 lzma_vli unpadded_size;
48 * \brief Uncompressed Size of a Block
50 lzma_vli uncompressed_size;
53 * \brief Compressed offset in the Stream(s)
55 * This is the offset of the first byte of the Block, that is,
56 * where you need to seek to decode the Block. The offset
57 * is relative to the beginning of the Stream, or if there are
58 * multiple Indexes combined, relative to the beginning of the
61 lzma_vli stream_offset;
64 * \brief Uncompressed offset
66 * When doing random-access reading, it is possible that the target
67 * offset is not exactly at Block boundary. One will need to compare
68 * the target offset against uncompressed_offset, and possibly decode
69 * and throw away some amount of data before reaching the target
72 lzma_vli uncompressed_offset;
78 * \brief Calculate memory usage for Index with given number of Records
80 * On disk, the size of the Index field depends on both the number of Records
81 * stored and how big values the Records store (due to variable-length integer
82 * encoding). When the Index is kept in lzma_index structure, the memory usage
83 * depends only on the number of Records stored in the Index. The size in RAM
84 * is almost always a lot bigger than in encoded form on disk.
86 * This function calculates an approximate amount of memory needed hold the
87 * given number of Records in lzma_index structure. This value may vary
88 * between liblzma versions if the internal implementation is modified.
90 * If you want to know how much memory an existing lzma_index structure is
91 * using, use lzma_index_memusage(lzma_index_count(i)).
93 extern LZMA_API(uint64_t) lzma_index_memusage(lzma_vli record_count)
98 * \brief Allocate and initialize a new lzma_index structure
100 * If i is NULL, a new lzma_index structure is allocated, initialized,
101 * and a pointer to it returned. If allocation fails, NULL is returned.
103 * If i is non-NULL, it is reinitialized and the same pointer returned.
104 * In this case, return value cannot be NULL or a different pointer than
105 * the i that was given as an argument.
107 extern LZMA_API(lzma_index *) lzma_index_init(
108 lzma_index *i, lzma_allocator *allocator) lzma_nothrow;
112 * \brief Deallocate the Index
114 * If i is NULL, this does nothing.
116 extern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
121 * \brief Add a new Record to an Index
123 * \param i Pointer to a lzma_index structure
124 * \param allocator Pointer to lzma_allocator, or NULL to
126 * \param unpadded_size Unpadded Size of a Block. This can be
127 * calculated with lzma_block_unpadded_size()
128 * after encoding or decoding the Block.
129 * \param uncompressed_size Uncompressed Size of a Block. This can be
130 * taken directly from lzma_block structure
131 * after encoding or decoding the Block.
133 * Appending a new Record does not affect the read position.
137 * - LZMA_DATA_ERROR: Compressed or uncompressed size of the
138 * Stream or size of the Index field would grow too big.
141 extern LZMA_API(lzma_ret) lzma_index_append(
142 lzma_index *i, lzma_allocator *allocator,
143 lzma_vli unpadded_size, lzma_vli uncompressed_size)
144 lzma_nothrow lzma_attr_warn_unused_result;
148 * \brief Get the number of Records
150 extern LZMA_API(lzma_vli) lzma_index_count(const lzma_index *i)
151 lzma_nothrow lzma_attr_pure;
155 * \brief Get the size of the Index field as bytes
157 * This is needed to verify the Backward Size field in the Stream Footer.
159 extern LZMA_API(lzma_vli) lzma_index_size(const lzma_index *i)
160 lzma_nothrow lzma_attr_pure;
164 * \brief Get the total size of the Blocks
166 * This doesn't include the Stream Header, Stream Footer, Stream Padding,
169 extern LZMA_API(lzma_vli) lzma_index_total_size(const lzma_index *i)
170 lzma_nothrow lzma_attr_pure;
174 * \brief Get the total size of the Stream
176 * If multiple Indexes have been combined, this works as if the Blocks
177 * were in a single Stream.
179 extern LZMA_API(lzma_vli) lzma_index_stream_size(const lzma_index *i)
180 lzma_nothrow lzma_attr_pure;
184 * \brief Get the total size of the file
186 * When no Indexes have been combined with lzma_index_cat(), this function is
187 * identical to lzma_index_stream_size(). If multiple Indexes have been
188 * combined, this includes also the headers of each separate Stream and the
189 * possible Stream Padding fields.
191 extern LZMA_API(lzma_vli) lzma_index_file_size(const lzma_index *i)
192 lzma_nothrow lzma_attr_pure;
196 * \brief Get the uncompressed size of the Stream
198 extern LZMA_API(lzma_vli) lzma_index_uncompressed_size(const lzma_index *i)
199 lzma_nothrow lzma_attr_pure;
203 * \brief Get the next Record from the Index
205 extern LZMA_API(lzma_bool) lzma_index_read(
206 lzma_index *i, lzma_index_record *record)
207 lzma_nothrow lzma_attr_warn_unused_result;
211 * \brief Rewind the Index
213 * Rewind the Index so that next call to lzma_index_read() will return the
216 extern LZMA_API(void) lzma_index_rewind(lzma_index *i) lzma_nothrow;
220 * \brief Locate a Record
222 * When the Index is available, it is possible to do random-access reading
223 * with granularity of Block size.
225 * \param i Pointer to lzma_index structure
226 * \param record Pointer to a structure to hold the search results
227 * \param target Uncompressed target offset which the caller would
228 * like to locate from the Stream
230 * If the target is smaller than the uncompressed size of the Stream (can be
231 * checked with lzma_index_uncompressed_size()):
232 * - Information about the Record containing the requested uncompressed
233 * offset is stored into *record.
234 * - Read offset will be adjusted so that calling lzma_index_read() can be
235 * used to read subsequent Records.
236 * - This function returns false.
238 * If target is greater than the uncompressed size of the Stream, *record
239 * and the read position are not modified, and this function returns true.
241 extern LZMA_API(lzma_bool) lzma_index_locate(
242 lzma_index *i, lzma_index_record *record, lzma_vli target)
247 * \brief Concatenate Indexes of two Streams
249 * Concatenating Indexes is useful when doing random-access reading in
250 * multi-Stream .xz file, or when combining multiple Streams into single
253 * \param dest Destination Index after which src is appended
254 * \param src Source Index. If this function succeeds, the
255 * memory allocated for src is freed or moved to
257 * \param allocator Custom memory allocator; can be NULL to use
258 * malloc() and free().
259 * \param padding Size of the Stream Padding field between Streams.
260 * This must be a multiple of four.
262 * \return - LZMA_OK: Indexes concatenated successfully. src is now
263 * a dangling pointer.
264 * - LZMA_DATA_ERROR: *dest would grow too big.
268 extern LZMA_API(lzma_ret) lzma_index_cat(lzma_index *lzma_restrict dest,
269 lzma_index *lzma_restrict src,
270 lzma_allocator *allocator, lzma_vli padding)
271 lzma_nothrow lzma_attr_warn_unused_result;
275 * \brief Duplicate an Index list
277 * Makes an identical copy of the Index. Also the read position is copied.
279 * \return A copy of the Index, or NULL if memory allocation failed.
281 extern LZMA_API(lzma_index *) lzma_index_dup(
282 const lzma_index *i, lzma_allocator *allocator)
283 lzma_nothrow lzma_attr_warn_unused_result;
287 * \brief Compare if two Index lists are identical
289 * Read positions are not compared.
291 * \return True if *a and *b are equal, false otherwise.
293 extern LZMA_API(lzma_bool) lzma_index_equal(
294 const lzma_index *a, const lzma_index *b)
295 lzma_nothrow lzma_attr_pure;
299 * \brief Initialize .xz Index encoder
301 * \param strm Pointer to properly prepared lzma_stream
302 * \param i Pointer to lzma_index which should be encoded.
303 * The read position will be at the end of the Index
304 * after lzma_code() has returned LZMA_STREAM_END.
306 * The only valid action value for lzma_code() is LZMA_RUN.
308 * \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
312 extern LZMA_API(lzma_ret) lzma_index_encoder(lzma_stream *strm, lzma_index *i)
313 lzma_nothrow lzma_attr_warn_unused_result;
317 * \brief Initialize .xz Index decoder
319 * \param strm Pointer to properly prepared lzma_stream
320 * \param i The decoded Index will be made available via
321 * this pointer. Initially this function will
322 * set *i to NULL (the old value is ignored). If
323 * decoding succeeds (lzma_code() returns
324 * LZMA_STREAM_END), *i will be set to point
325 * to the decoded Index, which the application
326 * has to later free with lzma_index_end().
327 * \param memlimit How much memory the resulting Index is allowed
330 * The only valid action value for lzma_code() is LZMA_RUN.
332 * \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
334 * - LZMA_MEMLIMIT_ERROR
337 * \note The memory usage limit is checked early in the decoding
338 * (within the first dozen input bytes or so). The actual memory
339 * is allocated later in smaller pieces. If the memory usage
340 * limit is modified with lzma_memlimit_set() after a part
341 * of the Index has already been decoded, the new limit may
344 extern LZMA_API(lzma_ret) lzma_index_decoder(
345 lzma_stream *strm, lzma_index **i, uint64_t memlimit)
346 lzma_nothrow lzma_attr_warn_unused_result;
350 * \brief Single-call .xz Index encoder
352 * \param i Index to be encoded. The read position will be at
353 * the end of the Index if encoding succeeds, or at
354 * unspecified position in case an error occurs.
355 * \param out Beginning of the output buffer
356 * \param out_pos The next byte will be written to out[*out_pos].
357 * *out_pos is updated only if encoding succeeds.
358 * \param out_size Size of the out buffer; the first byte into
359 * which no data is written to is out[out_size].
361 * \return - LZMA_OK: Encoding was successful.
362 * - LZMA_BUF_ERROR: Output buffer is too small. Use
363 * lzma_index_size() to find out how much output
367 * \note This function doesn't take allocator argument since all
368 * the internal data is allocated on stack.
370 extern LZMA_API(lzma_ret) lzma_index_buffer_encode(lzma_index *i,
371 uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
375 * \brief Single-call .xz Index decoder
377 * \param i If decoding succeeds, *i will point to the
378 * decoded Index, which the application has to
379 * later free with lzma_index_end(). If an error
380 * occurs, *i will be NULL. The old value of *i
381 * is always ignored and thus doesn't need to be
382 * initialized by the caller.
383 * \param memlimit Pointer to how much memory the resulting Index
384 * is allowed to require. The value pointed by
385 * this pointer is modified if and only if
386 * LZMA_MEMLIMIT_ERROR is returned.
387 * \param allocator Pointer to lzma_allocator, or NULL to use malloc()
388 * \param in Beginning of the input buffer
389 * \param in_pos The next byte will be read from in[*in_pos].
390 * *in_pos is updated only if decoding succeeds.
391 * \param in_size Size of the input buffer; the first byte that
392 * won't be read is in[in_size].
394 * \return - LZMA_OK: Decoding was successful.
396 * - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
397 * The minimum required memlimit value was stored to *memlimit.
401 extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
402 uint64_t *memlimit, lzma_allocator *allocator,
403 const uint8_t *in, size_t *in_pos, size_t in_size)