Annotation of libwww/Library/src/HTZip.c, revision 2.6
2.1 frystyk 1: /*
2: ** ZIP ENCODING / DECODING MODULE
3: **
4: ** (c) COPYRIGHT MIT 1995.
5: ** Please first read the full copyright statement in the file COPYRIGH.
2.6 ! frystyk 6: ** @(#) $Id: HTZip.c,v 2.5 1997/11/26 16:06:03 frystyk Exp $
2.1 frystyk 7: **
8: ** This module requires zlib in order to compile/link
9: */
10:
11: /* Library include files */
12: #include "sysdep.h"
13: #include "WWWUtil.h"
14: #include "WWWCore.h"
15: #include "HTZip.h" /* Implemented here */
16:
2.3 frystyk 17: #ifdef WWW_MSWINDOWS
18: #define ZLIB_DLL
19: #endif
20:
2.6 ! frystyk 21: #include <zlib.h>
2.1 frystyk 22:
2.6 ! frystyk 23: #define OUTBUF_SIZE 32768
2.1 frystyk 24:
25: struct _HTStream {
26: const HTStreamClass * isa;
27: int state;
28: HTRequest * request;
29: HTStream * target; /* Our output target */
30: z_stream * zstream; /* Zlib stream */
31: char outbuf [OUTBUF_SIZE]; /* Inflated data */
32: };
33:
34: PRIVATE int CompressionLevel = Z_DEFAULT_COMPRESSION;
35:
36: /* ------------------------------------------------------------------------- */
37:
38: PRIVATE BOOL Zlib_init (HTStream * me, int level)
39: {
40: if (me && me->zstream &&
41: (level == Z_DEFAULT_COMPRESSION ||
42: (level >= Z_BEST_SPEED && level <= Z_BEST_COMPRESSION))) {
43: int status;
2.4 frystyk 44: if (STREAM_TRACE)
45: HTTrace("Zlib Inflate Init stream %p with compression level %d\n", me, level);
2.1 frystyk 46: if ((status = inflateInit(me->zstream)) != Z_OK) {
2.4 frystyk 47: if (STREAM_TRACE) HTTrace("Zlib........ Failed with status %d\n", status);
2.1 frystyk 48: return NO;
49: }
50: return YES;
51: }
52: return NO;
53: }
54:
55: PRIVATE BOOL ZLib_terminate (HTStream * me)
56: {
2.4 frystyk 57: if (STREAM_TRACE) HTTrace("Zlib Inflate Terminating stream %p\n", me);
2.1 frystyk 58: if (me) {
59: int status;
60: if (STREAM_TRACE)
2.4 frystyk 61: HTTrace("Results..... Inflated incoming data: deflated %lu, inflated %lu, factor %.2f\n",
62: me->zstream->total_in, me->zstream->total_out,
63: me->zstream->total_in == 0 ? 0.0 :
64: (double) me->zstream->total_out / me->zstream->total_in);
2.1 frystyk 65: if ((status = inflateEnd(me->zstream)) != Z_OK) {
2.4 frystyk 66: if (STREAM_TRACE) HTTrace("Zlib........ Failed with status %d\n", status);
2.1 frystyk 67: return NO;
68: }
69: return YES;
70: }
71: return NO;
72: }
73:
74: PRIVATE int HTZLibInflate_flush (HTStream * me)
75: {
76: return (*me->target->isa->flush)(me->target);
77: }
78:
79: PRIVATE int HTZLibInflate_free (HTStream * me)
80: {
81: int status = HT_OK;
82: ZLib_terminate(me);
83: if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
84: return HT_WOULD_BLOCK;
2.4 frystyk 85: if (STREAM_TRACE) HTTrace("Zlib Inflate FREEING...\n");
2.1 frystyk 86: HT_FREE(me->zstream);
87: HT_FREE(me);
88: return status;
89: }
90:
91: PRIVATE int HTZLibInflate_abort (HTStream * me, HTList * e)
92: {
2.4 frystyk 93: if (STREAM_TRACE) HTTrace("Zlib Inflate ABORTING...\n");
2.1 frystyk 94: ZLib_terminate(me);
95: (*me->target->isa->abort)(me->target, NULL);
96: HT_FREE(me->zstream);
97: HT_FREE(me);
98: return HT_ERROR;
99: }
100:
101: PRIVATE int HTZLibInflate_write (HTStream * me, const char * buf, int len)
102: {
103: if (me->state != HT_OK) {
104: me->state = (*me->target->isa->put_block)(me->target,
105: me->outbuf,
106: OUTBUF_SIZE - me->zstream->avail_out);
107: if (me->state != HT_OK) return me->state;
108: }
109:
110: /*
111: ** Setup the zstream buffers to handle the new data
112: */
113: me->zstream->next_in = (unsigned char *) buf;
114: me->zstream->avail_in = len;
115: me->zstream->next_out = (unsigned char *) me->outbuf;
116: me->zstream->avail_out = OUTBUF_SIZE;
117:
118: /*
119: ** Now run through the data and inflate it. We use Z_PARTIAL_FLUSH
120: ** in order to put as much data in the output buffer as quick as
121: ** possible.
122: */
123: for (;;) {
124: int status = inflate(me->zstream, Z_PARTIAL_FLUSH);
125: switch (status) {
126: case Z_OK:
127: me->state = (*me->target->isa->put_block)(me->target,
128: me->outbuf,
129: OUTBUF_SIZE - me->zstream->avail_out);
130: if (me->state != HT_OK) return me->state;
131:
132: /*
133: ** All data was consumed and we are ready to handle the
134: ** next data.
135: */
136: me->zstream->next_out = (unsigned char *) me->outbuf;
137: me->zstream->avail_out = OUTBUF_SIZE;
138: break;
139:
140: case Z_MEM_ERROR:
141: HT_OUTOFMEM("HTZLibInflate_write");
142: return HT_ERROR;
143:
144: case Z_BUF_ERROR:
145: /*
146: ** No action was taken anf we can take this as a sign ot it
147: ** having finished all data in the input buffer.
148: */
2.5 frystyk 149: return HT_OK;
150:
151: case Z_STREAM_END:
152: me->state = (*me->target->isa->put_block)(me->target,
153: me->outbuf,
154: OUTBUF_SIZE - me->zstream->avail_out);
155: if (me->state != HT_OK) return me->state;
156:
157: if (STREAM_TRACE) HTTrace("Zlib Inflate End of Stream\n");
2.1 frystyk 158: return HT_OK;
159:
160: default:
2.4 frystyk 161: if (STREAM_TRACE) HTTrace("Zlib Inflate Inflate returned %d\n", status);
2.1 frystyk 162: return HT_ERROR;
163: }
164: }
165: return HT_OK;
166: }
167:
168: PRIVATE int HTZLibInflate_put_character (HTStream * me, char c)
169: {
170: return HTZLibInflate_write(me, &c, 1);
171: }
172:
173: PRIVATE int HTZLibInflate_put_string (HTStream * me, const char * s)
174: {
175: return HTZLibInflate_write(me, s, (int) strlen(s));
176: }
177:
178: PRIVATE const HTStreamClass HTInflate =
179: {
180: "ZlibInflate",
181: HTZLibInflate_flush,
182: HTZLibInflate_free,
183: HTZLibInflate_abort,
184: HTZLibInflate_put_character,
185: HTZLibInflate_put_string,
186: HTZLibInflate_write
187: };
188:
189: PUBLIC BOOL HTZLib_setCompressionLevel (int level)
190: {
191: if (level >= Z_BEST_SPEED && level <= Z_BEST_COMPRESSION) {
192: CompressionLevel = level;
2.4 frystyk 193: if (STREAM_TRACE) HTTrace("Zlib........ Compression level set to %d\n", level);
2.1 frystyk 194: }
195: return NO;
196: }
197:
198: PUBLIC int HTZLib_compressionLevel (void)
199: {
200: return CompressionLevel;
201: }
202:
203: PUBLIC HTStream * HTZLib_inflate (HTRequest * request,
204: void * param,
205: HTEncoding coding,
206: HTStream * target)
207: {
208: HTStream * me = NULL;
209: if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL ||
210: (me->zstream = (z_stream *) HT_CALLOC(1, sizeof(z_stream))) == NULL)
211: HT_OUTOFMEM("HTZLib_inflate");
212: me->isa = &HTInflate;
213: me->state = HT_OK;
214: me->request = request;
215: me->target = target ? target : HTErrorStream();
216: if (Zlib_init(me, CompressionLevel) != YES) {
217: HT_FREE(me);
218: return HTErrorStream();
219: }
2.4 frystyk 220: if (STREAM_TRACE) HTTrace("Zlib Inflate Stream created\n");
2.1 frystyk 221: return me;
222: }
Webmaster