source: trunk/src/exepack_fill.c@ 83

Last change on this file since 83 was 1, checked in by katerina, 19 years ago

Initial import

File size: 8.6 KB
Line 
1/* +++Date last modified: 05-Jul-1997 */
2
3/*
4** Case-sensitive Boyer-Moore-Horspool pattern match
5**
6** public domain by Raymond Gardner 7/92
7**
8** limitation: pattern length + string length must be less than 32767
9**
10** 10/21/93 rdg Fixed bug found by Jeff Dunlop
11**
12** limitation lifted Rainer Wichmann 07/2000
13*/
14#include "config.h"
15
16#ifdef HAVE_BROKEN_INCLUDES
17#define _ANSI_C_SOURCE
18#define _POSIX_SOURCE
19#endif
20
21#include <limits.h> /* rdg 10/93 */
22#include <stddef.h>
23#include <string.h>
24
25typedef unsigned char uchar;
26
27#define LARGE 2147483647 /* rw 7/2000 */
28
29static long patlen; /* rw 7/2000 */
30static long skip[UCHAR_MAX+1]; /* rw 7/2000 */ /* rdg 10/93 */
31static long skip2; /* rw 7/2000 */
32static uchar *pat; /* rw 7/2000 */
33
34void bmh_init(const char *pattern)
35{
36 long i, lastpatchar;
37
38 pat = (uchar *)pattern;
39 patlen = strlen(pattern);
40 for (i = 0; i <= UCHAR_MAX; ++i) /* rdg 10/93 */
41 skip[i] = patlen;
42 for (i = 0; i < patlen; ++i)
43 skip[pat[i]] = patlen - i - 1;
44 lastpatchar = pat[patlen - 1];
45 skip[lastpatchar] = LARGE;
46 skip2 = patlen; /* Horspool's fixed second shift */
47 for (i = 0; i < patlen - 1; ++i)
48 {
49 if (pat[i] == lastpatchar)
50 skip2 = patlen - i - 1;
51 }
52}
53
54char * bmh_search(const char * string, const long stringlen)
55{
56 long i, j; /* rw 7/2000 */
57 char *s;
58
59 i = patlen - 1 - stringlen;
60 if (i >= 0)
61 return NULL;
62 string += stringlen;
63 for ( ;; )
64 {
65 while ( (i += skip[((uchar *)string)[i]]) < 0 )
66 ; /* mighty fast inner loop */
67 if (i < (LARGE - stringlen))
68 return NULL;
69 i -= LARGE;
70 j = patlen - 1;
71 s = (char *)string + (i - j);
72 while (--j >= 0 && s[j] == pat[j])
73 ;
74 if ( j < 0 ) /* rdg 10/93 */
75 return s; /* rdg 10/93 */
76 if ( (i += skip2) >= 0 ) /* rdg 10/93 */
77 return NULL; /* rdg 10/93 */
78 }
79}
80
81/* Everything below: Copyright 2000, Rainer Wichmann */
82
83char * my_locate (const char * pattern, const char * data, const long datalen)
84{
85 bmh_init (pattern);
86 return (bmh_search (data, datalen) );
87}
88
89#include <stdio.h>
90#include <stdlib.h>
91#include <sys/stat.h>
92#include <unistd.h>
93
94
95#include "config.h"
96
97#include "minilzo.h"
98
99/* integer data type that is _exactly_ 32 bit
100 */
101#if defined(HAVE_INT_32)
102#define UINT32 unsigned int
103#elif defined(HAVE_LONG_32)
104#define UINT32 unsigned long
105#elif defined(HAVE_SHORT_32)
106#define UINT32 unsigned short
107#endif
108
109static UINT32 cstate[3], astate[3];
110
111static UINT32 taus_get_long (UINT32 * state)
112{
113#define TAUSWORTHE(s,a,b,c,d) ((s &c) <<d) ^ (((s <<a) ^s) >>b)
114
115 state[0] = TAUSWORTHE (state[0], 13, 19, 4294967294UL, 12);
116 state[1] = TAUSWORTHE (state[1], 2, 25, 4294967288UL, 4);
117 state[2] = TAUSWORTHE (state[2], 3, 11, 4294967280UL, 17);
118
119 return (state[0] ^ state[1] ^ state[2]);
120}
121
122void taus_set_from_state (UINT32 * state, UINT32 * state0)
123{
124 state[0] = state0[0] | (UINT32) 0x03;
125 state[1] = state0[1] | (UINT32) 0x09;
126 state[2] = state0[2] | (UINT32) 0x17;
127
128 /* 'warm up'
129 */
130 taus_get_long (state);
131 taus_get_long (state);
132 taus_get_long (state);
133 taus_get_long (state);
134 taus_get_long (state);
135 taus_get_long (state);
136
137 return;
138}
139
140int replaceData (char * data, long len, char * in, char * out, long size)
141{
142 char * pos;
143 int i;
144
145 pos = my_locate (in, data, len);
146 if (pos == NULL)
147 return (-1);
148
149 for (i = 0; i < size; ++i)
150 {
151 pos[i] = out[i];
152 }
153
154 return 0;
155}
156
157/* Work-memory needed for compression. Allocate memory in units
158 * of `long' (instead of `char') to make sure it is properly aligned.
159 */
160#define HEAP_ALLOC(var,size) long __LZO_MMODEL var [ ((size) + (sizeof(long) - 1)) / sizeof(long) ]
161
162static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
163
164#include <sys/types.h>
165#include <sys/stat.h>
166#include <fcntl.h>
167
168int main(int argc, char * argv[])
169{
170 FILE * fd;
171 long clen;
172 char * data;
173 struct stat sbuf;
174
175 char * ptest;
176
177 unsigned long i;
178
179 int status;
180
181 unsigned long len = 0;
182 unsigned long have = 0;
183
184 /* For compression.
185 */
186 lzo_byte * inbuf;
187 lzo_byte * outbuf;
188 int r;
189 lzo_uint in_len;
190 lzo_uint out_len;
191
192 UINT32 len_raw;
193 UINT32 len_cmp;
194
195
196 astate[0] = EXEPACK_STATE_0;
197 astate[1] = EXEPACK_STATE_1;
198 astate[2] = EXEPACK_STATE_2;
199
200
201 if (argc < 4)
202 {
203 fprintf(stderr,
204 "Usage: exepack_fill <container_file> <infile> <outfile>\n");
205 exit (EXIT_FAILURE);
206 }
207
208 if (0 != stat (argv[1], &sbuf))
209 {
210 fprintf(stderr, "exepack_fill: could not access file %s\n", argv[1]);
211 return (-1);
212 }
213 clen = sbuf.st_size;
214
215
216 data = (char *) malloc (clen * sizeof(char));
217 if (data == NULL)
218 return (-1);
219
220 fd = fopen (argv[1], "r");
221 if (fd == NULL)
222 return (-1);
223
224 fread (data, 1, clen, fd);
225 fclose (fd);
226
227
228 /*******************
229 *
230 * THE DATA
231 *
232 *******************/
233
234
235
236 if (stat (argv[2], &sbuf) < 0)
237 {
238 perror ("exepack_fill");
239 exit (EXIT_FAILURE);
240 }
241
242 len = (unsigned long) sbuf.st_size;
243
244 /* Because the input block may be incompressible,
245 * we must provide a little more output space in case that compression
246 * is not possible.
247 */
248 inbuf = (lzo_byte *) malloc (sizeof(lzo_byte) * len);
249 outbuf = (lzo_byte *) malloc (sizeof(lzo_byte) * (len + len / 64 + 16 + 3));
250 in_len = len;
251
252 if (NULL == inbuf || NULL == outbuf)
253 {
254 fprintf(stderr, "exepack_fill: Out of memory.");
255 exit (EXIT_FAILURE);
256 }
257
258 if (NULL == (fd = fopen(argv[2], "r")))
259 {
260 perror ("exepack_fill");
261 exit (EXIT_FAILURE);
262 }
263
264 have = fread (inbuf, 1, len, fd);
265 fclose (fd);
266
267 if (have != len)
268 {
269 fprintf (stderr, "exepack_mkdata: Error reading %s", argv[2]);
270 exit (EXIT_FAILURE);
271 }
272
273 /*
274 * Step 1: initialize the LZO library
275 */
276 if (lzo_init() != LZO_E_OK)
277 {
278 fprintf(stderr, "exepack_fill: lzo_init() failed\n");
279 return 3;
280 }
281
282 /*
283 * Step 3: compress from `in' to `out' with LZO1X-1
284 */
285 r = lzo1x_1_compress(inbuf, in_len, outbuf, &out_len, wrkmem);
286
287 if (r == LZO_E_OK)
288 printf("exepack_fill: compressed %lu bytes into %lu bytes\n",
289 (long) in_len, (long) out_len);
290 else
291 {
292 /* this should NEVER happen */
293 printf("exepack_fill: internal error - compression failed: %d\n", r);
294 return 2;
295 }
296
297 /* check for an incompressible block
298 */
299 if (out_len >= in_len)
300 {
301 printf("exepack_fill: Incompressible data.\n");
302 }
303
304 taus_set_from_state (cstate, astate);
305 for (i = 0; i < out_len; ++i)
306 {
307 outbuf[i] ^= (taus_get_long (cstate) & 0xff);
308 }
309
310 len_raw = in_len;
311 len_cmp = out_len;
312
313 if ( (unsigned long) len_cmp > (unsigned long) clen)
314 {
315 printf("exepack_fill: Compressed length (%ld) exceeds container length (%ld).\n", (long) len_cmp, (long) clen);
316 return (8);
317 }
318
319
320 /***********
321 *
322 * Fill program
323 *
324 **********/
325
326 status = replaceData (data, clen, "LLLL", (char *) &len_raw, sizeof(UINT32));
327 if (status < 0)
328 {
329 printf("exepack_fill: Could not write raw lenght %d.\n", len_raw);
330 return (8);
331 }
332 status = replaceData (data, clen, "CCCC", (char *) &len_cmp, sizeof(UINT32));
333 if (status < 0)
334 {
335 printf("exepack_fill: Could not write compressed lenght %d.\n",
336 len_cmp);
337 return (8);
338 }
339 status = replaceData (data, clen, "CONTAINER", outbuf, out_len);
340 if (status < 0)
341 {
342 printf("exepack_fill: Could not write program data.\n");
343 return (8);
344 }
345
346 /***********
347 *
348 * Write program
349 *
350 **********/
351
352 if ( NULL == (fd = fopen(argv[3], "w" )))
353 {
354 perror ("exepack_fill");
355 exit (EXIT_FAILURE);
356 }
357
358 fwrite (data, 1, clen, fd);
359
360 fclose (fd);
361
362 ptest = my_locate("LLLL", data, clen);
363 if (ptest != NULL)
364 {
365 printf("exepack_fill: ERROR: program length not updated.\n");
366 return (8);
367 }
368 ptest = my_locate("CCCC", data, clen);
369 if (ptest != NULL)
370 {
371 printf("exepack_fill: ERROR: compressed program length not updated.\n");
372 return (8);
373 }
374 ptest = my_locate("CONTAINER", data, clen);
375 if (ptest != NULL)
376 {
377 printf("exepack_fill: ERROR: program data not updated.\n");
378 return (8);
379 }
380
381 return 0;
382}
383
Note: See TracBrowser for help on using the repository browser.