"Fossies" - the Fresh Open Source Software Archive 
Member "xdelta3-3.0.11/xdelta3-second.h" (11 Nov 2015, 7312 Bytes) of package /linux/misc/xdelta3-3.0.11.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "xdelta3-second.h" see the
Fossies "Dox" file reference documentation.
1 /* xdelta 3 - delta compression tools and library
2 * Copyright (C) 2002, 2003, 2006, 2007, 2013. Joshua P. MacDonald
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #ifndef _XDELTA3_SECOND_H_
20 #define _XDELTA3_SECOND_H_
21
22 static inline void xd3_bit_state_encode_init (bit_state *bits)
23 {
24 bits->cur_byte = 0;
25 bits->cur_mask = 1;
26 }
27
28 static inline int xd3_decode_bits (xd3_stream *stream,
29 bit_state *bits,
30 const uint8_t **input,
31 const uint8_t *input_max,
32 usize_t nbits,
33 usize_t *valuep)
34 {
35 usize_t value = 0;
36 usize_t vmask = 1 << nbits;
37
38 if (bits->cur_mask == 0x100) { goto next_byte; }
39
40 for (;;)
41 {
42 do
43 {
44 vmask >>= 1;
45
46 if (bits->cur_byte & bits->cur_mask)
47 {
48 value |= vmask;
49 }
50
51 bits->cur_mask <<= 1;
52
53 if (vmask == 1) { goto done; }
54 }
55 while (bits->cur_mask != 0x100);
56
57 next_byte:
58
59 if (*input == input_max)
60 {
61 stream->msg = "secondary decoder end of input";
62 return XD3_INTERNAL;
63 }
64
65 bits->cur_byte = *(*input)++;
66 bits->cur_mask = 1;
67 }
68
69 done:
70
71 IF_DEBUG2 (DP(RINT "(d) %u ", value));
72
73 (*valuep) = value;
74 return 0;
75 }
76
77 #if REGRESSION_TEST
78 /* There may be extra bits at the end of secondary decompression, this macro
79 * checks for non-zero bits. This is overly strict, but helps pass the
80 * single-bit-error regression test. */
81 static int
82 xd3_test_clean_bits (xd3_stream *stream, bit_state *bits)
83 {
84 for (; bits->cur_mask != 0x100; bits->cur_mask <<= 1)
85 {
86 if (bits->cur_byte & bits->cur_mask)
87 {
88 stream->msg = "secondary decoder garbage";
89 return XD3_INTERNAL;
90 }
91 }
92
93 return 0;
94 }
95 #endif
96
97 static int
98 xd3_get_secondary (xd3_stream *stream, xd3_sec_stream **sec_streamp,
99 int is_encode)
100 {
101 if (*sec_streamp == NULL)
102 {
103 int ret;
104
105 if ((*sec_streamp = stream->sec_type->alloc (stream)) == NULL)
106 {
107 stream->msg = "error initializing secondary stream";
108 return XD3_INVALID;
109 }
110
111 if ((ret = stream->sec_type->init (stream, *sec_streamp, is_encode)) != 0)
112 {
113 return ret;
114 }
115 }
116
117 return 0;
118 }
119
120 static int
121 xd3_decode_secondary (xd3_stream *stream,
122 xd3_desect *sect,
123 xd3_sec_stream **sec_streamp)
124 {
125 uint32_t dec_size;
126 uint8_t *out_used;
127 int ret;
128
129 if ((ret = xd3_get_secondary (stream, sec_streamp, 0)) != 0)
130 {
131 return ret;
132 }
133
134 /* Decode the size, allocate the buffer. */
135 if ((ret = xd3_read_size (stream, & sect->buf,
136 sect->buf_max, & dec_size)) ||
137 (ret = xd3_decode_allocate (stream, dec_size,
138 & sect->copied2, & sect->alloc2)))
139 {
140 return ret;
141 }
142
143 if (dec_size == 0)
144 {
145 stream->msg = "secondary decoder invalid output size";
146 return XD3_INVALID_INPUT;
147 }
148
149 out_used = sect->copied2;
150
151 if ((ret = stream->sec_type->decode (stream, *sec_streamp,
152 & sect->buf, sect->buf_max,
153 & out_used, out_used + dec_size)))
154 {
155 return ret;
156 }
157
158 if (sect->buf != sect->buf_max)
159 {
160 stream->msg = "secondary decoder finished with unused input";
161 return XD3_INTERNAL;
162 }
163
164 if (out_used != sect->copied2 + dec_size)
165 {
166 stream->msg = "secondary decoder short output";
167 return XD3_INTERNAL;
168 }
169
170 sect->buf = sect->copied2;
171 sect->buf_max = sect->copied2 + dec_size;
172 sect->size = dec_size;
173
174 return 0;
175 }
176
177 #if XD3_ENCODER
178 static inline int xd3_encode_bit (xd3_stream *stream,
179 xd3_output **output,
180 bit_state *bits,
181 usize_t bit)
182 {
183 int ret;
184
185 if (bit)
186 {
187 bits->cur_byte |= bits->cur_mask;
188 }
189
190 /* OPT: Might help to buffer more than 8 bits at once. */
191 if (bits->cur_mask == 0x80)
192 {
193 if ((ret = xd3_emit_byte (stream, output, bits->cur_byte)) != 0)
194 {
195 return ret;
196 }
197
198 bits->cur_mask = 1;
199 bits->cur_byte = 0;
200 }
201 else
202 {
203 bits->cur_mask <<= 1;
204 }
205
206 return 0;
207 }
208
209 static inline int xd3_flush_bits (xd3_stream *stream,
210 xd3_output **output,
211 bit_state *bits)
212 {
213 return (bits->cur_mask == 1) ? 0 :
214 xd3_emit_byte (stream, output, bits->cur_byte);
215 }
216
217 static inline int xd3_encode_bits (xd3_stream *stream,
218 xd3_output **output,
219 bit_state *bits,
220 usize_t nbits,
221 usize_t value)
222 {
223 int ret;
224 usize_t mask = 1 << nbits;
225
226 XD3_ASSERT (nbits > 0);
227 XD3_ASSERT (nbits < sizeof (usize_t) * 8);
228 XD3_ASSERT (value < mask);
229
230 do
231 {
232 mask >>= 1;
233
234 if ((ret = xd3_encode_bit (stream, output, bits, value & mask)))
235 {
236 return ret;
237 }
238 }
239 while (mask != 1);
240
241 IF_DEBUG2 (DP(RINT "(e) %u ", value));
242
243 return 0;
244 }
245
246 static int
247 xd3_encode_secondary (xd3_stream *stream,
248 xd3_output **head,
249 xd3_output **tail,
250 xd3_sec_stream **sec_streamp,
251 xd3_sec_cfg *cfg,
252 int *did_it)
253 {
254 xd3_output *tmp_head;
255 xd3_output *tmp_tail;
256
257 usize_t comp_size;
258 usize_t orig_size;
259
260 int ret;
261
262 orig_size = xd3_sizeof_output (*head);
263
264 if (orig_size < SECONDARY_MIN_INPUT) { return 0; }
265
266 if ((ret = xd3_get_secondary (stream, sec_streamp, 1)) != 0)
267 {
268 return ret;
269 }
270
271 tmp_head = xd3_alloc_output (stream, NULL);
272
273 /* Encode the size, encode the data. Encoding the size makes it
274 * simpler, but is a little gross. Should not need the entire
275 * section in contiguous memory, but it is much easier this way. */
276 if ((ret = xd3_emit_size (stream, & tmp_head, orig_size)) ||
277 (ret = stream->sec_type->encode (stream, *sec_streamp, *head,
278 tmp_head, cfg)))
279 {
280 goto getout;
281 }
282
283 /* If the secondary compressor determines it's no good, it returns
284 * XD3_NOSECOND. */
285
286 /* Setup tmp_tail, comp_size */
287 tmp_tail = tmp_head;
288 comp_size = tmp_head->next;
289
290 while (tmp_tail->next_page != NULL)
291 {
292 tmp_tail = tmp_tail->next_page;
293 comp_size += tmp_tail->next;
294 }
295
296 XD3_ASSERT (comp_size == xd3_sizeof_output (tmp_head));
297 XD3_ASSERT (tmp_tail != NULL);
298
299 if (comp_size < (orig_size - SECONDARY_MIN_SAVINGS) || cfg->inefficient)
300 {
301 if (comp_size < orig_size)
302 {
303 IF_DEBUG1(DP(RINT "[encode_secondary] saved %u bytes: %u -> %u (%0.2f%%)\n",
304 orig_size - comp_size, orig_size, comp_size,
305 100.0 * (double) comp_size / (double) orig_size));
306 }
307
308 xd3_free_output (stream, *head);
309
310 *head = tmp_head;
311 *tail = tmp_tail;
312 *did_it = 1;
313 }
314 else
315 {
316 getout:
317 if (ret == XD3_NOSECOND) { ret = 0; }
318 xd3_free_output (stream, tmp_head);
319 }
320
321 return ret;
322 }
323 #endif /* XD3_ENCODER */
324 #endif /* _XDELTA3_SECOND_H_ */