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