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