aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/blast/blast.c44
-rw-r--r--contrib/blast/blast.h14
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 */
379int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) 383int 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 */
430int main(void) 446int 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
45int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); 45int 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