annotate src/zlib-1.2.8/contrib/puff/pufftest.c @ 128:5b4145a0d408

Current zlib source
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 18 Oct 2016 14:33:52 +0100
parents
children
rev   line source
cannam@128 1 /*
cannam@128 2 * pufftest.c
cannam@128 3 * Copyright (C) 2002-2013 Mark Adler
cannam@128 4 * For conditions of distribution and use, see copyright notice in puff.h
cannam@128 5 * version 2.3, 21 Jan 2013
cannam@128 6 */
cannam@128 7
cannam@128 8 /* Example of how to use puff().
cannam@128 9
cannam@128 10 Usage: puff [-w] [-f] [-nnn] file
cannam@128 11 ... | puff [-w] [-f] [-nnn]
cannam@128 12
cannam@128 13 where file is the input file with deflate data, nnn is the number of bytes
cannam@128 14 of input to skip before inflating (e.g. to skip a zlib or gzip header), and
cannam@128 15 -w is used to write the decompressed data to stdout. -f is for coverage
cannam@128 16 testing, and causes pufftest to fail with not enough output space (-f does
cannam@128 17 a write like -w, so -w is not required). */
cannam@128 18
cannam@128 19 #include <stdio.h>
cannam@128 20 #include <stdlib.h>
cannam@128 21 #include "puff.h"
cannam@128 22
cannam@128 23 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
cannam@128 24 # include <fcntl.h>
cannam@128 25 # include <io.h>
cannam@128 26 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
cannam@128 27 #else
cannam@128 28 # define SET_BINARY_MODE(file)
cannam@128 29 #endif
cannam@128 30
cannam@128 31 #define local static
cannam@128 32
cannam@128 33 /* Return size times approximately the cube root of 2, keeping the result as 1,
cannam@128 34 3, or 5 times a power of 2 -- the result is always > size, until the result
cannam@128 35 is the maximum value of an unsigned long, where it remains. This is useful
cannam@128 36 to keep reallocations less than ~33% over the actual data. */
cannam@128 37 local size_t bythirds(size_t size)
cannam@128 38 {
cannam@128 39 int n;
cannam@128 40 size_t m;
cannam@128 41
cannam@128 42 m = size;
cannam@128 43 for (n = 0; m; n++)
cannam@128 44 m >>= 1;
cannam@128 45 if (n < 3)
cannam@128 46 return size + 1;
cannam@128 47 n -= 3;
cannam@128 48 m = size >> n;
cannam@128 49 m += m == 6 ? 2 : 1;
cannam@128 50 m <<= n;
cannam@128 51 return m > size ? m : (size_t)(-1);
cannam@128 52 }
cannam@128 53
cannam@128 54 /* Read the input file *name, or stdin if name is NULL, into allocated memory.
cannam@128 55 Reallocate to larger buffers until the entire file is read in. Return a
cannam@128 56 pointer to the allocated data, or NULL if there was a memory allocation
cannam@128 57 failure. *len is the number of bytes of data read from the input file (even
cannam@128 58 if load() returns NULL). If the input file was empty or could not be opened
cannam@128 59 or read, *len is zero. */
cannam@128 60 local void *load(const char *name, size_t *len)
cannam@128 61 {
cannam@128 62 size_t size;
cannam@128 63 void *buf, *swap;
cannam@128 64 FILE *in;
cannam@128 65
cannam@128 66 *len = 0;
cannam@128 67 buf = malloc(size = 4096);
cannam@128 68 if (buf == NULL)
cannam@128 69 return NULL;
cannam@128 70 in = name == NULL ? stdin : fopen(name, "rb");
cannam@128 71 if (in != NULL) {
cannam@128 72 for (;;) {
cannam@128 73 *len += fread((char *)buf + *len, 1, size - *len, in);
cannam@128 74 if (*len < size) break;
cannam@128 75 size = bythirds(size);
cannam@128 76 if (size == *len || (swap = realloc(buf, size)) == NULL) {
cannam@128 77 free(buf);
cannam@128 78 buf = NULL;
cannam@128 79 break;
cannam@128 80 }
cannam@128 81 buf = swap;
cannam@128 82 }
cannam@128 83 fclose(in);
cannam@128 84 }
cannam@128 85 return buf;
cannam@128 86 }
cannam@128 87
cannam@128 88 int main(int argc, char **argv)
cannam@128 89 {
cannam@128 90 int ret, put = 0, fail = 0;
cannam@128 91 unsigned skip = 0;
cannam@128 92 char *arg, *name = NULL;
cannam@128 93 unsigned char *source = NULL, *dest;
cannam@128 94 size_t len = 0;
cannam@128 95 unsigned long sourcelen, destlen;
cannam@128 96
cannam@128 97 /* process arguments */
cannam@128 98 while (arg = *++argv, --argc)
cannam@128 99 if (arg[0] == '-') {
cannam@128 100 if (arg[1] == 'w' && arg[2] == 0)
cannam@128 101 put = 1;
cannam@128 102 else if (arg[1] == 'f' && arg[2] == 0)
cannam@128 103 fail = 1, put = 1;
cannam@128 104 else if (arg[1] >= '0' && arg[1] <= '9')
cannam@128 105 skip = (unsigned)atoi(arg + 1);
cannam@128 106 else {
cannam@128 107 fprintf(stderr, "invalid option %s\n", arg);
cannam@128 108 return 3;
cannam@128 109 }
cannam@128 110 }
cannam@128 111 else if (name != NULL) {
cannam@128 112 fprintf(stderr, "only one file name allowed\n");
cannam@128 113 return 3;
cannam@128 114 }
cannam@128 115 else
cannam@128 116 name = arg;
cannam@128 117 source = load(name, &len);
cannam@128 118 if (source == NULL) {
cannam@128 119 fprintf(stderr, "memory allocation failure\n");
cannam@128 120 return 4;
cannam@128 121 }
cannam@128 122 if (len == 0) {
cannam@128 123 fprintf(stderr, "could not read %s, or it was empty\n",
cannam@128 124 name == NULL ? "<stdin>" : name);
cannam@128 125 free(source);
cannam@128 126 return 3;
cannam@128 127 }
cannam@128 128 if (skip >= len) {
cannam@128 129 fprintf(stderr, "skip request of %d leaves no input\n", skip);
cannam@128 130 free(source);
cannam@128 131 return 3;
cannam@128 132 }
cannam@128 133
cannam@128 134 /* test inflate data with offset skip */
cannam@128 135 len -= skip;
cannam@128 136 sourcelen = (unsigned long)len;
cannam@128 137 ret = puff(NIL, &destlen, source + skip, &sourcelen);
cannam@128 138 if (ret)
cannam@128 139 fprintf(stderr, "puff() failed with return code %d\n", ret);
cannam@128 140 else {
cannam@128 141 fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
cannam@128 142 if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
cannam@128 143 len - sourcelen);
cannam@128 144 }
cannam@128 145
cannam@128 146 /* if requested, inflate again and write decompressd data to stdout */
cannam@128 147 if (put && ret == 0) {
cannam@128 148 if (fail)
cannam@128 149 destlen >>= 1;
cannam@128 150 dest = malloc(destlen);
cannam@128 151 if (dest == NULL) {
cannam@128 152 fprintf(stderr, "memory allocation failure\n");
cannam@128 153 free(source);
cannam@128 154 return 4;
cannam@128 155 }
cannam@128 156 puff(dest, &destlen, source + skip, &sourcelen);
cannam@128 157 SET_BINARY_MODE(stdout);
cannam@128 158 fwrite(dest, 1, destlen, stdout);
cannam@128 159 free(dest);
cannam@128 160 }
cannam@128 161
cannam@128 162 /* clean up */
cannam@128 163 free(source);
cannam@128 164 return ret;
cannam@128 165 }