00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <assert.h>
00016 #include "zlib.h"
00017
00018 #define CHUNK 16384
00019
00020
00021
00022
00023
00024
00025
00026 int def(FILE *source, FILE *dest, int level)
00027 {
00028 int ret, flush;
00029 unsigned have;
00030 z_stream strm;
00031 char in[CHUNK];
00032 char out[CHUNK];
00033
00034
00035 strm.zalloc = Z_NULL;
00036 strm.zfree = Z_NULL;
00037 strm.opaque = Z_NULL;
00038 ret = deflateInit(&strm, level);
00039 if (ret != Z_OK)
00040 return ret;
00041
00042
00043 do {
00044 strm.avail_in = fread(in, 1, CHUNK, source);
00045 if (ferror(source)) {
00046 (void)deflateEnd(&strm);
00047 return Z_ERRNO;
00048 }
00049 flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
00050 strm.next_in = in;
00051
00052
00053
00054 do {
00055 strm.avail_out = CHUNK;
00056 strm.next_out = out;
00057 ret = deflate(&strm, flush);
00058 assert(ret != Z_STREAM_ERROR);
00059 have = CHUNK - strm.avail_out;
00060 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
00061 (void)deflateEnd(&strm);
00062 return Z_ERRNO;
00063 }
00064 } while (strm.avail_out == 0);
00065 assert(strm.avail_in == 0);
00066
00067
00068 } while (flush != Z_FINISH);
00069 assert(ret == Z_STREAM_END);
00070
00071
00072 (void)deflateEnd(&strm);
00073 return Z_OK;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 int inf(FILE *source, FILE *dest)
00083 {
00084 int ret;
00085 unsigned have;
00086 z_stream strm;
00087 char in[CHUNK];
00088 char out[CHUNK];
00089
00090
00091 strm.zalloc = Z_NULL;
00092 strm.zfree = Z_NULL;
00093 strm.opaque = Z_NULL;
00094 strm.avail_in = 0;
00095 strm.next_in = Z_NULL;
00096 ret = inflateInit(&strm);
00097 if (ret != Z_OK)
00098 return ret;
00099
00100
00101 do {
00102 strm.avail_in = fread(in, 1, CHUNK, source);
00103 if (ferror(source)) {
00104 (void)inflateEnd(&strm);
00105 return Z_ERRNO;
00106 }
00107 if (strm.avail_in == 0)
00108 break;
00109 strm.next_in = in;
00110
00111
00112 do {
00113 strm.avail_out = CHUNK;
00114 strm.next_out = out;
00115 ret = inflate(&strm, Z_NO_FLUSH);
00116 assert(ret != Z_STREAM_ERROR);
00117 switch (ret) {
00118 case Z_NEED_DICT:
00119 ret = Z_DATA_ERROR;
00120 case Z_DATA_ERROR:
00121 case Z_MEM_ERROR:
00122 (void)inflateEnd(&strm);
00123 return ret;
00124 }
00125 have = CHUNK - strm.avail_out;
00126 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
00127 (void)inflateEnd(&strm);
00128 return Z_ERRNO;
00129 }
00130 } while (strm.avail_out == 0);
00131
00132
00133 } while (ret != Z_STREAM_END);
00134
00135
00136 (void)inflateEnd(&strm);
00137 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
00138 }
00139
00140
00141 void zerr(int ret)
00142 {
00143 fputs("zpipe: ", stderr);
00144 switch (ret) {
00145 case Z_ERRNO:
00146 if (ferror(stdin))
00147 fputs("error reading stdin\n", stderr);
00148 if (ferror(stdout))
00149 fputs("error writing stdout\n", stderr);
00150 break;
00151 case Z_STREAM_ERROR:
00152 fputs("invalid compression level\n", stderr);
00153 break;
00154 case Z_DATA_ERROR:
00155 fputs("invalid or incomplete deflate data\n", stderr);
00156 break;
00157 case Z_MEM_ERROR:
00158 fputs("out of memory\n", stderr);
00159 break;
00160 case Z_VERSION_ERROR:
00161 fputs("zlib version mismatch!\n", stderr);
00162 }
00163 }
00164
00165
00166 int main(int argc, char **argv)
00167 {
00168 int ret;
00169
00170
00171 if (argc == 1) {
00172 ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
00173 if (ret != Z_OK)
00174 zerr(ret);
00175 return ret;
00176 }
00177
00178
00179 else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
00180 ret = inf(stdin, stdout);
00181 if (ret != Z_OK)
00182 zerr(ret);
00183 return ret;
00184 }
00185
00186
00187 else {
00188 fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
00189 return 1;
00190 }
00191 }