]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/common.h
Imported to git.
[icculus/xz.git] / src / liblzma / common / common.h
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       common.h
4 /// \brief      Definitions common to the whole liblzma library
5 //
6 //  Copyright (C) 2007 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #ifndef LZMA_COMMON_H
21 #define LZMA_COMMON_H
22
23 #include "sysdefs.h"
24
25 // Don't use ifdef...
26 #if HAVE_VISIBILITY
27 #       define LZMA_API __attribute__((__visibility__("default")))
28 #else
29 #       define LZMA_API
30 #endif
31
32
33 /// Size of temporary buffers needed in some filters
34 #define LZMA_BUFFER_SIZE 4096
35
36
37 /// Internal helper filter used by Subblock decoder. It is mapped to an
38 /// otherwise invalid Filter ID, which is impossible to get from any input
39 /// file (even if malicious file).
40 #define LZMA_FILTER_SUBBLOCK_HELPER (UINT64_MAX - 2)
41
42
43 ///////////
44 // Types //
45 ///////////
46
47 typedef struct lzma_coder_s lzma_coder;
48
49 typedef struct lzma_next_coder_s lzma_next_coder;
50
51 typedef struct lzma_filter_info_s lzma_filter_info;
52
53
54 typedef lzma_ret (*lzma_init_function)(
55                 lzma_next_coder *next, lzma_allocator *allocator,
56                 const lzma_filter_info *filters);
57
58 typedef lzma_ret (*lzma_code_function)(
59                 lzma_coder *coder, lzma_allocator *allocator,
60                 const uint8_t *restrict in, size_t *restrict in_pos,
61                 size_t in_size, uint8_t *restrict out,
62                 size_t *restrict out_pos, size_t out_size,
63                 lzma_action action);
64
65 typedef void (*lzma_end_function)(
66                 lzma_coder *coder, lzma_allocator *allocator);
67
68
69 /// Hold data and function pointers of the next filter in the chain.
70 struct lzma_next_coder_s {
71         /// Pointer to coder-specific data
72         lzma_coder *coder;
73
74         /// "Pointer" to init function. This is never called here.
75         /// We need only to detect if we are initializing a coder
76         /// that was allocated earlier. See code.c and next_coder.c.
77         uintptr_t init;
78
79         /// Pointer to function to do the actual coding
80         lzma_code_function code;
81
82         /// Pointer to function to free lzma_next_coder.coder
83         lzma_end_function end;
84 };
85
86 #define LZMA_NEXT_CODER_INIT \
87         (lzma_next_coder){ \
88                 .coder = NULL, \
89                 .init = 0, \
90                 .code = NULL, \
91                 .end = NULL, \
92         }
93
94
95 struct lzma_internal_s {
96         lzma_next_coder next;
97
98         enum {
99                 ISEQ_RUN,
100                 ISEQ_SYNC_FLUSH,
101                 ISEQ_FULL_FLUSH,
102                 ISEQ_FINISH,
103                 ISEQ_END,
104                 ISEQ_ERROR,
105         } sequence;
106
107         bool supported_actions[4];
108         bool allow_buf_error;
109         size_t avail_in;
110 };
111
112
113 struct lzma_filter_info_s {
114         /// Pointer to function used to initialize the filter.
115         /// This is NULL to indicate end of array.
116         lzma_init_function init;
117
118         /// Pointer to filter's options structure
119         void *options;
120
121         /// Uncompressed size of the filter, or LZMA_VLI_VALUE_UNKNOWN
122         /// if unknown.
123         lzma_vli uncompressed_size;
124 };
125
126
127 /*
128 typedef struct {
129         lzma_init_function init;
130         uint32_t (*input_alignment)(lzma_vli id, const void *options);
131         uint32_t (*output_alignment)(lzma_vli id, const void *options);
132         bool changes_uncompressed_size;
133         bool supports_eopm;
134 } lzma_filter_hook;
135 */
136
137
138 ///////////////
139 // Functions //
140 ///////////////
141
142 /// Allocates memory
143 extern void *lzma_alloc(size_t size, lzma_allocator *allocator)
144                 lzma_attribute((malloc));
145
146 /// Frees memory
147 extern void lzma_free(void *ptr, lzma_allocator *allocator);
148
149 /// Initializes lzma_stream FIXME desc
150 extern lzma_ret lzma_strm_init(lzma_stream *strm);
151
152 ///
153 extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,
154                 lzma_allocator *allocator, const lzma_filter_info *filters);
155
156 ///
157 extern void lzma_next_coder_end(lzma_next_coder *next,
158                 lzma_allocator *allocator);
159
160
161 extern lzma_ret lzma_filter_flags_decoder_init(lzma_next_coder *next,
162                 lzma_allocator *allocator, lzma_options_filter *options);
163
164 extern lzma_ret lzma_block_header_decoder_init(lzma_next_coder *next,
165                 lzma_allocator *allocator, lzma_options_block *options);
166
167 extern lzma_ret lzma_stream_encoder_single_init(lzma_next_coder *next,
168                 lzma_allocator *allocator, const lzma_options_stream *options);
169
170 extern lzma_ret lzma_stream_decoder_init(
171                 lzma_next_coder *next, lzma_allocator *allocator,
172                 lzma_extra **header, lzma_extra **footer);
173
174
175 /// \brief      Wrapper for memcpy()
176 ///
177 /// This function copies as much data as possible from in[] to out[] and
178 /// updates *in_pos and *out_pos accordingly.
179 ///
180 static inline size_t
181 bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size,
182                 uint8_t *restrict out, size_t *restrict out_pos,
183                 size_t out_size)
184 {
185         const size_t in_avail = in_size - *in_pos;
186         const size_t out_avail = out_size - *out_pos;
187         const size_t copy_size = MIN(in_avail, out_avail);
188
189         memcpy(out + *out_pos, in + *in_pos, copy_size);
190
191         *in_pos += copy_size;
192         *out_pos += copy_size;
193
194         return copy_size;
195 }
196
197
198 /// \brief      Initializing the next coder
199 ///
200 /// lzma_next_coder can point to different types of coders. The existing
201 /// coder may be different than what we are initializing now. In that case
202 /// we must git rid of the old coder first. Otherwise we reuse the existing
203 /// coder structure.
204 ///
205 #define lzma_next_coder_init2(next, allocator, cmpfunc, func, ...) \
206 do { \
207         if ((uintptr_t)(&cmpfunc) != (next)->init) \
208                 lzma_next_coder_end(next, allocator); \
209         const lzma_ret ret = func(next, __VA_ARGS__); \
210         if (ret == LZMA_OK) { \
211                 (next)->init = (uintptr_t)(&cmpfunc); \
212                 assert((next)->code != NULL); \
213                 assert((next)->end != NULL); \
214         } else { \
215                 lzma_next_coder_end(next, allocator); \
216         } \
217         return ret; \
218 } while (0)
219
220 /// \brief      Initializing lzma_next_coder
221 ///
222 /// Call the initialization function, which must take at least one
223 /// argument in addition to lzma_next_coder and lzma_allocator.
224 #define lzma_next_coder_init(func, next, allocator, ...) \
225         lzma_next_coder_init2(next, allocator, \
226                         func, func, allocator, __VA_ARGS__)
227
228
229 /// \brief      Initializing lzma_stream
230 ///
231 /// lzma_strm initialization with more detailed options.
232 #define lzma_next_strm_init2(strm, cmpfunc, func, ...) \
233 do { \
234         lzma_ret ret = lzma_strm_init(strm); \
235         if (ret != LZMA_OK) \
236                 return ret; \
237         if ((uintptr_t)(&cmpfunc) != (strm)->internal->next.init) \
238                 lzma_next_coder_end(\
239                                 &(strm)->internal->next, (strm)->allocator); \
240         ret = func(&(strm)->internal->next, __VA_ARGS__); \
241         if (ret != LZMA_OK) { \
242                 lzma_end(strm); \
243                 return ret; \
244         } \
245         (strm)->internal->next.init = (uintptr_t)(&cmpfunc); \
246         assert((strm)->internal->next.code != NULL); \
247         assert((strm)->internal->next.end != NULL); \
248 } while (0)
249
250 /// \brief      Initializing lzma_stream
251 ///
252 /// Call the initialization function, which must take at least one
253 /// argument in addition to lzma_next_coder and lzma_allocator.
254 #define lzma_next_strm_init(strm, func, ...) \
255         lzma_next_strm_init2(strm, func, func, (strm)->allocator, __VA_ARGS__)
256
257
258 /// \brief      Return if expression doesn't evaluate to LZMA_OK
259 ///
260 /// There are several situations where we want to return immediatelly
261 /// with the value of expr if it isn't LZMA_OK. This macro shortens
262 /// the code a bit.
263 ///
264 #define return_if_error(expr) \
265 do { \
266         const lzma_ret ret_ = expr; \
267         if (ret_ != LZMA_OK) \
268                 return ret_; \
269 } while (0)
270
271 #endif