diff options
-rw-r--r-- | contrib/blast/blast.c | 44 | ||||
-rw-r--r-- | contrib/blast/blast.h | 14 |
2 files changed, 43 insertions, 15 deletions
diff --git a/contrib/blast/blast.c b/contrib/blast/blast.c index 69ef0fe..52b59da 100644 --- a/contrib/blast/blast.c +++ b/contrib/blast/blast.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* blast.c | 1 | /* blast.c |
2 | * Copyright (C) 2003, 2012 Mark Adler | 2 | * Copyright (C) 2003, 2012, 2013 Mark Adler |
3 | * For conditions of distribution and use, see copyright notice in blast.h | 3 | * For conditions of distribution and use, see copyright notice in blast.h |
4 | * version 1.2, 24 Oct 2012 | 4 | * version 1.3, 24 Aug 2013 |
5 | * | 5 | * |
6 | * blast.c decompresses data compressed by the PKWare Compression Library. | 6 | * blast.c decompresses data compressed by the PKWare Compression Library. |
7 | * This function provides functionality similar to the explode() function of | 7 | * This function provides functionality similar to the explode() function of |
@@ -24,8 +24,12 @@ | |||
24 | * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data | 24 | * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data |
25 | * 1.2 24 Oct 2012 - Add note about using binary mode in stdio | 25 | * 1.2 24 Oct 2012 - Add note about using binary mode in stdio |
26 | * - Fix comparisons of differently signed integers | 26 | * - Fix comparisons of differently signed integers |
27 | * 1.3 24 Aug 2013 - Return unused input from blast() | ||
28 | * - Fix test code to correctly report unused input | ||
29 | * - Enable the provision of initial input to blast() | ||
27 | */ | 30 | */ |
28 | 31 | ||
32 | #include <stddef.h> /* for NULL */ | ||
29 | #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ | 33 | #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ |
30 | #include "blast.h" /* prototype for blast() */ | 34 | #include "blast.h" /* prototype for blast() */ |
31 | 35 | ||
@@ -376,7 +380,8 @@ local int decomp(struct state *s) | |||
376 | } | 380 | } |
377 | 381 | ||
378 | /* See comments in blast.h */ | 382 | /* See comments in blast.h */ |
379 | int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) | 383 | int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow, |
384 | unsigned *left, unsigned char **in) | ||
380 | { | 385 | { |
381 | struct state s; /* input/output state */ | 386 | struct state s; /* input/output state */ |
382 | int err; /* return value */ | 387 | int err; /* return value */ |
@@ -384,7 +389,12 @@ int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) | |||
384 | /* initialize input state */ | 389 | /* initialize input state */ |
385 | s.infun = infun; | 390 | s.infun = infun; |
386 | s.inhow = inhow; | 391 | s.inhow = inhow; |
387 | s.left = 0; | 392 | if (left != NULL && *left) { |
393 | s.left = *left; | ||
394 | s.in = *in; | ||
395 | } | ||
396 | else | ||
397 | s.left = 0; | ||
388 | s.bitbuf = 0; | 398 | s.bitbuf = 0; |
389 | s.bitcnt = 0; | 399 | s.bitcnt = 0; |
390 | 400 | ||
@@ -400,6 +410,12 @@ int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) | |||
400 | else | 410 | else |
401 | err = decomp(&s); /* decompress */ | 411 | err = decomp(&s); /* decompress */ |
402 | 412 | ||
413 | /* return unused input */ | ||
414 | if (left != NULL) | ||
415 | *left = s.left; | ||
416 | if (in != NULL) | ||
417 | *in = s.left ? s.in : NULL; | ||
418 | |||
403 | /* write any leftover output and update the error code if needed */ | 419 | /* write any leftover output and update the error code if needed */ |
404 | if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) | 420 | if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) |
405 | err = 1; | 421 | err = 1; |
@@ -429,16 +445,20 @@ local int outf(void *how, unsigned char *buf, unsigned len) | |||
429 | /* Decompress a PKWare Compression Library stream from stdin to stdout */ | 445 | /* Decompress a PKWare Compression Library stream from stdin to stdout */ |
430 | int main(void) | 446 | int main(void) |
431 | { | 447 | { |
432 | int ret, n; | 448 | int ret; |
449 | unsigned left; | ||
433 | 450 | ||
434 | /* decompress to stdout */ | 451 | /* decompress to stdout */ |
435 | ret = blast(inf, stdin, outf, stdout); | 452 | left = 0; |
436 | if (ret != 0) fprintf(stderr, "blast error: %d\n", ret); | 453 | ret = blast(inf, stdin, outf, stdout, &left, NULL); |
437 | 454 | if (ret != 0) | |
438 | /* see if there are any leftover bytes */ | 455 | fprintf(stderr, "blast error: %d\n", ret); |
439 | n = 0; | 456 | |
440 | while (getchar() != EOF) n++; | 457 | /* count any leftover bytes */ |
441 | if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n); | 458 | while (getchar() != EOF) |
459 | left++; | ||
460 | if (left) | ||
461 | fprintf(stderr, "blast warning: %u unused bytes of input\n", left); | ||
442 | 462 | ||
443 | /* return blast() error code */ | 463 | /* return blast() error code */ |
444 | return ret; | 464 | return ret; |
diff --git a/contrib/blast/blast.h b/contrib/blast/blast.h index 658cfd3..6cf65ed 100644 --- a/contrib/blast/blast.h +++ b/contrib/blast/blast.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* blast.h -- interface for blast.c | 1 | /* blast.h -- interface for blast.c |
2 | Copyright (C) 2003, 2012 Mark Adler | 2 | Copyright (C) 2003, 2012, 2013 Mark Adler |
3 | version 1.2, 24 Oct 2012 | 3 | version 1.3, 24 Aug 2013 |
4 | 4 | ||
5 | This software is provided 'as-is', without any express or implied | 5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the author be held liable for any damages | 6 | warranty. In no event will the author be held liable for any damages |
@@ -42,7 +42,8 @@ typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len); | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | 44 | ||
45 | int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); | 45 | int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow, |
46 | unsigned *left, unsigned char **in); | ||
46 | /* Decompress input to output using the provided infun() and outfun() calls. | 47 | /* Decompress input to output using the provided infun() and outfun() calls. |
47 | * On success, the return value of blast() is zero. If there is an error in | 48 | * On success, the return value of blast() is zero. If there is an error in |
48 | * the source data, i.e. it is not in the proper format, then a negative value | 49 | * the source data, i.e. it is not in the proper format, then a negative value |
@@ -55,12 +56,19 @@ int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); | |||
55 | * an input error. (blast() only asks for input if it needs it.) inhow is for | 56 | * an input error. (blast() only asks for input if it needs it.) inhow is for |
56 | * use by the application to pass an input descriptor to infun(), if desired. | 57 | * use by the application to pass an input descriptor to infun(), if desired. |
57 | * | 58 | * |
59 | * If left and in are not NULL and *left is not zero when blast() is called, | ||
60 | * then the *left bytes are *in are consumed for input before infun() is used. | ||
61 | * | ||
58 | * The output function is invoked: err = outfun(how, buf, len), where the bytes | 62 | * The output function is invoked: err = outfun(how, buf, len), where the bytes |
59 | * to be written are buf[0..len-1]. If err is not zero, then blast() returns | 63 | * to be written are buf[0..len-1]. If err is not zero, then blast() returns |
60 | * with an output error. outfun() is always called with len <= 4096. outhow | 64 | * with an output error. outfun() is always called with len <= 4096. outhow |
61 | * is for use by the application to pass an output descriptor to outfun(), if | 65 | * is for use by the application to pass an output descriptor to outfun(), if |
62 | * desired. | 66 | * desired. |
63 | * | 67 | * |
68 | * If there is any unused input, *left is set to the number of bytes that were | ||
69 | * read and *in points to them. Otherwise *left is set to zero and *in is set | ||
70 | * to NULL. If left or in are NULL, then they are not set. | ||
71 | * | ||
64 | * The return codes are: | 72 | * The return codes are: |
65 | * | 73 | * |
66 | * 2: ran out of input before completing decompression | 74 | * 2: ran out of input before completing decompression |