aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/api/lzma/info.h
blob: 3a91850fd0b5c5c1d4e1a61465f9ee381cd33fc0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/**
 * \file        lzma/info.h
 * \brief       Handling of Stream size information
 *
 * \author      Copyright (C) 1999-2006 Igor Pavlov
 * \author      Copyright (C) 2007 Lasse Collin
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#ifndef LZMA_H_INTERNAL
#	error Never include this file directly. Use <lzma.h> instead.
#endif


/**********
 * Basics *
 **********/

/**
 * \brief       Opaque data type to hold the size information
 */
typedef struct lzma_info_s lzma_info;


typedef struct {
	/**
	 * \brief       Total Size of this Block
	 *
	 * This can be LZMA_VLI_VALUE_UNKNOWN.
	 */
	lzma_vli total_size;

	/**
	 * \brief       Uncompressed Size of this Block
	 *
	 * This can be LZMA_VLI_VALUE_UNKNOWN.
	 */
	lzma_vli uncompressed_size;

	/**
	 * \brief       Offset of the first byte of the Block
	 *
	 * In encoder, this is useful to find out the alignment of the Block.
	 *
	 * In decoder, this is useful when doing random-access reading
	 * with help from lzma_info_data_locate().
	 */
	lzma_vli stream_offset;

	/**
	 * \brief       Uncompressed offset of the Block
	 *
	 * Offset of the first uncompressed byte of the Block relative to
	 * all uncompressed data in the Block.
	 * FIXME desc
	 */
	lzma_vli uncompressed_offset;

	/**
	 * \brief       Pointers to internal data structures
	 *
	 * Applications must not touch these.
	 */
	void *internal[4];

} lzma_info_iter;


typedef enum {
	LZMA_INFO_STREAM_START,
	LZMA_INFO_HEADER_METADATA,
	LZMA_INFO_TOTAL,
	LZMA_INFO_UNCOMPRESSED,
	LZMA_INFO_FOOTER_METADATA
} lzma_info_size;


/**
 * \brief       Allocates and initializes a new lzma_info structure
 *
 * If info is NULL, a new lzma_info structure is allocated, initialized, and
 * a pointer to it returned. If allocation fails, NULL is returned.
 *
 * If info is non-NULL, it is reinitialized and the same pointer returned.
 * (In this case, return value cannot be NULL or a different pointer than
 * the info given as argument.)
 */
extern lzma_info *lzma_info_init(lzma_info *info, lzma_allocator *allocator);


/**
 * \brief       Resets lzma_info
 *
 * This is like calling lzma_info_end() and lzma_info_create(), but
 * re-uses the existing base structure.
 */
extern void lzma_info_reset(
		lzma_info *info, lzma_allocator *allocator);


/**
 * \brief       Frees memory allocated for a lzma_info structure
 */
extern void lzma_info_free(lzma_info *info, lzma_allocator *allocator);


/************************
 * Setting known values *
 ************************/

/**
 * \brief       Set a known size value
 *
 * \param       info    Pointer returned by lzma_info_create()
 * \param       type    Any value from lzma_info_size
 * \param       size    Value to set or verify
 *
 * \return      LZMA_OK on success, LZMA_DATA_ERROR if the size doesn't
 *              match the existing information, or LZMA_PROG_ERROR
 *              if type is invalid or size is not a valid VLI.
 */
extern lzma_ret lzma_info_size_set(
		lzma_info *info, lzma_info_size type, lzma_vli size);


/**
 * \brief       Sets the Index
 *
 * The given lzma_index list is "absorbed" by this function. The application
 * must not access it after this function call, even if this function returns
 * an error.
 *
 * \note        The given lzma_index will at some point get freed by the
 *              lzma_info_* functions. If you use a custom lzma_allocator,
 *              make sure that it can free the lzma_index.
 */
extern lzma_ret lzma_info_index_set(
		lzma_info *info, lzma_allocator *allocator,
		lzma_index *index, lzma_bool eat_index);


/**
 * \brief       Sets information from a known Metadata Block
 *
 * This is a shortcut for calling lzma_info_size_set() with different type
 * arguments, lzma_info_index_set() with metadata->index.
 */
extern lzma_ret lzma_info_metadata_set(lzma_info *info,
		lzma_allocator *allocator, lzma_metadata *metadata,
		lzma_bool is_header_metadata, lzma_bool eat_index);


/***************
 * Incremental *
 ***************/

/**
 * \brief       Prepares an iterator to be used with given lzma_info structure
 *
 *
 */
extern void lzma_info_iter_begin(lzma_info *info, lzma_info_iter *iter);


/**
 * \brief       Moves to the next Index Record
 *
 *
 */
extern lzma_ret lzma_info_iter_next(
		lzma_info_iter *iter, lzma_allocator *allocator);


/**
 * \brief       Sets or verifies the sizes in the Index Record
 *
 * \param       iter    Pointer to iterator to be set or verified
 * \param       total_size
 *                      Total Size in bytes or LZMA_VLI_VALUE_UNKNOWN
 * \param       uncompressed_size
 *                      Uncompressed Size or LZMA_VLI_VALUE_UNKNOWN
 *
 * \return      - LZMA_OK: All OK.
 *              - LZMA_DATA_ERROR: Given sizes don't match with the already
 *                known sizes.
 *              - LZMA_PROG_ERROR: Internal error, possibly integer
 *                overflow (e.g. the sum of all the known sizes is too big)
 */
extern lzma_ret lzma_info_iter_set(lzma_info_iter *iter,
		lzma_vli total_size, lzma_vli uncompressed_size);


/**
 * \brief       Locates a Data Block
 *
 * \param       iter        Properly initialized iterator
 * \param       allocator   Pointer to lzma_allocator or NULL
 * \param       uncompressed_offset
 *                          Target offset to locate. The final offset
 *                          will be equal or smaller than this.
 * \param       allow_alloc True if this function is allowed to call
 *                          lzma_info_iter_next() to allocate a new Record
 *                          if the requested offset reached end of Index
 *                          Record list. Note that if Index has been marked
 *                          final, lzma_info_iter_next() is never called.
 *
 * \return      - LZMA_OK: All OK, *iter updated accordingly.
 *              - LZMA_DATA_ERROR: Trying to search past the end of the Index
 *                Record list, and allocating a new Record was not allowed
 *                either because allow_alloc was false or Index was final.
 *              - LZMA_PROG_ERROR: Internal error (probably integer
 *                overflow causing some lzma_vli getting too big).
 */
extern lzma_ret lzma_info_iter_locate(lzma_info_iter *iter,
		lzma_allocator *allocator, lzma_vli uncompressed_offset,
		lzma_bool allow_alloc);


/**
 * \brief       Finishes incrementally constructed Index
 *
 * This sets the known Total Size and Uncompressed of the Data Blocks
 * based on the information collected from the Index Records, and marks
 * the Index as final.
 */
extern lzma_ret lzma_info_index_finish(lzma_info *info);


/***************************
 * Reading the information *
 ***************************/

/**
 * \brief       Gets a known size
 *
 *
 */
extern lzma_vli lzma_info_size_get(
		const lzma_info *info, lzma_info_size type);

extern lzma_vli lzma_info_metadata_locate(
		const lzma_info *info, lzma_bool is_header_metadata);

/**
 * \brief       Gets a pointer to the beginning of the Index list
 *
 * If detach is true, the Index will be detached from the lzma_info
 * structure, and thus not be modified or freed by lzma_info_end().
 *
 * If detach is false, the application must not modify the Index in any way.
 * Also, the Index list is guaranteed to be valid only till the next call
 * to any lzma_info_* function.
 */
extern lzma_index *lzma_info_index_get(lzma_info *info, lzma_bool detach);


extern size_t lzma_info_index_count_get(const lzma_info *info);


extern uint32_t lzma_info_metadata_alignment_get(
		const lzma_info *info, lzma_bool is_header_metadata);



/**
 * \brief       Locate a Block containing the given uncompressed offset
 *
 * This function is useful when you need to do random-access reading in
 * a Multi-Block Stream.
 *
 * \param       info    Pointer to lzma_info that has at least one
 *                      Index Record. The Index doesn't need to be finished.
 * \param       uncompressed_target
 *                      Uncompressed target offset which the caller would
 *                      like to locate from the Stream.
 * \param       stream_offset
 *                      Starting offset (relative to the beginning the Stream)
 *                      of the Block containing the requested location.
 * \param       uncompressed_offset
 *                      The actual uncompressed offset of the beginning of
 *                      the Block. uncompressed_offset <= uncompressed_target
 *                      is always true; the application needs to uncompress
 *                      uncompressed_target - uncompressed_offset bytes to
 *                      reach the requested target offset.
 * \param       total_size
 *                      Total Size of the Block. If the Index is incomplete,
 *                      this may be LZMA_VLI_VALUE_UNKNOWN indicating unknown
 *                      size.
 * \param       uncompressed_size
 *                      Uncompressed Size of the Block. If the Index is
 *                      incomplete, this may be LZMA_VLI_VALUE_UNKNOWN
 *                      indicating unknown size. The application must pass
 *                      this value to the Block decoder to verify FIXME
 *
 * \return
 *
 * \note        This function is currently implemented as a linear search.
 *              If there are many Index Records, this can be really slow.
 *              This can be improved in newer liblzma versions if needed.
 */
extern lzma_bool lzma_info_data_locate(const lzma_info *info,
		lzma_vli uncompressed_target,
		lzma_vli *lzma_restrict stream_offset,
		lzma_vli *lzma_restrict uncompressed_offset,
		lzma_vli *lzma_restrict total_size,
		lzma_vli *lzma_restrict uncompressed_size);