vserver 1.9.3
[linux-2.6.git] / lib / zlib_inflate / inflate.c
1 /* inflate.c -- zlib interface to inflate modules
2  * Copyright (C) 1995-1998 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h 
4  */
5
6 #include <linux/module.h>
7 #include <linux/zutil.h>
8 #include "infblock.h"
9 #include "infutil.h"
10
11 int zlib_inflate_workspacesize(void)
12 {
13   return sizeof(struct inflate_workspace);
14 }
15
16
17 int zlib_inflateReset(
18         z_streamp z
19 )
20 {
21   if (z == NULL || z->state == NULL || z->workspace == NULL)
22     return Z_STREAM_ERROR;
23   z->total_in = z->total_out = 0;
24   z->msg = NULL;
25   z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
26   zlib_inflate_blocks_reset(z->state->blocks, z, NULL);
27   return Z_OK;
28 }
29
30
31 int zlib_inflateEnd(
32         z_streamp z
33 )
34 {
35   if (z == NULL || z->state == NULL || z->workspace == NULL)
36     return Z_STREAM_ERROR;
37   if (z->state->blocks != NULL)
38     zlib_inflate_blocks_free(z->state->blocks, z);
39   z->state = NULL;
40   return Z_OK;
41 }
42
43
44 int zlib_inflateInit2_(
45         z_streamp z,
46         int w,
47         const char *version,
48         int stream_size
49 )
50 {
51   if (version == NULL || version[0] != ZLIB_VERSION[0] ||
52       stream_size != sizeof(z_stream) || z->workspace == NULL)
53       return Z_VERSION_ERROR;
54
55   /* initialize state */
56   z->msg = NULL;
57   z->state = &WS(z)->internal_state;
58   z->state->blocks = NULL;
59
60   /* handle undocumented nowrap option (no zlib header or check) */
61   z->state->nowrap = 0;
62   if (w < 0)
63   {
64     w = - w;
65     z->state->nowrap = 1;
66   }
67
68   /* set window size */
69   if (w < 8 || w > 15)
70   {
71     zlib_inflateEnd(z);
72     return Z_STREAM_ERROR;
73   }
74   z->state->wbits = (uInt)w;
75
76   /* create inflate_blocks state */
77   if ((z->state->blocks =
78       zlib_inflate_blocks_new(z, z->state->nowrap ? NULL : zlib_adler32, (uInt)1 << w))
79       == NULL)
80   {
81     zlib_inflateEnd(z);
82     return Z_MEM_ERROR;
83   }
84
85   /* reset state */
86   zlib_inflateReset(z);
87   return Z_OK;
88 }
89
90
91 /*
92  * At the end of a Deflate-compressed PPP packet, we expect to have seen
93  * a `stored' block type value but not the (zero) length bytes.
94  */
95 static int zlib_inflate_packet_flush(inflate_blocks_statef *s)
96 {
97     if (s->mode != LENS)
98         return Z_DATA_ERROR;
99     s->mode = TYPE;
100     return Z_OK;
101 }
102
103
104 int zlib_inflateInit_(
105         z_streamp z,
106         const char *version,
107         int stream_size
108 )
109 {
110   return zlib_inflateInit2_(z, DEF_WBITS, version, stream_size);
111 }
112
113 #undef NEEDBYTE
114 #undef NEXTBYTE
115 #define NEEDBYTE {if(z->avail_in==0)goto empty;r=trv;}
116 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
117
118 int zlib_inflate(
119         z_streamp z,
120         int f
121 )
122 {
123   int r, trv;
124   uInt b;
125
126   if (z == NULL || z->state == NULL || z->next_in == NULL)
127     return Z_STREAM_ERROR;
128   trv = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
129   r = Z_BUF_ERROR;
130   while (1) switch (z->state->mode)
131   {
132     case METHOD:
133       NEEDBYTE
134       if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
135       {
136         z->state->mode = I_BAD;
137         z->msg = (char*)"unknown compression method";
138         z->state->sub.marker = 5;       /* can't try inflateSync */
139         break;
140       }
141       if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
142       {
143         z->state->mode = I_BAD;
144         z->msg = (char*)"invalid window size";
145         z->state->sub.marker = 5;       /* can't try inflateSync */
146         break;
147       }
148       z->state->mode = FLAG;
149     case FLAG:
150       NEEDBYTE
151       b = NEXTBYTE;
152       if (((z->state->sub.method << 8) + b) % 31)
153       {
154         z->state->mode = I_BAD;
155         z->msg = (char*)"incorrect header check";
156         z->state->sub.marker = 5;       /* can't try inflateSync */
157         break;
158       }
159       if (!(b & PRESET_DICT))
160       {
161         z->state->mode = BLOCKS;
162         break;
163       }
164       z->state->mode = DICT4;
165     case DICT4:
166       NEEDBYTE
167       z->state->sub.check.need = (uLong)NEXTBYTE << 24;
168       z->state->mode = DICT3;
169     case DICT3:
170       NEEDBYTE
171       z->state->sub.check.need += (uLong)NEXTBYTE << 16;
172       z->state->mode = DICT2;
173     case DICT2:
174       NEEDBYTE
175       z->state->sub.check.need += (uLong)NEXTBYTE << 8;
176       z->state->mode = DICT1;
177     case DICT1:
178       NEEDBYTE
179       z->state->sub.check.need += (uLong)NEXTBYTE;
180       z->adler = z->state->sub.check.need;
181       z->state->mode = DICT0;
182       return Z_NEED_DICT;
183     case DICT0:
184       z->state->mode = I_BAD;
185       z->msg = (char*)"need dictionary";
186       z->state->sub.marker = 0;       /* can try inflateSync */
187       return Z_STREAM_ERROR;
188     case BLOCKS:
189       r = zlib_inflate_blocks(z->state->blocks, z, r);
190       if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
191           r = zlib_inflate_packet_flush(z->state->blocks);
192       if (r == Z_DATA_ERROR)
193       {
194         z->state->mode = I_BAD;
195         z->state->sub.marker = 0;       /* can try inflateSync */
196         break;
197       }
198       if (r == Z_OK)
199         r = trv;
200       if (r != Z_STREAM_END)
201         return r;
202       r = trv;
203       zlib_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
204       if (z->state->nowrap)
205       {
206         z->state->mode = I_DONE;
207         break;
208       }
209       z->state->mode = CHECK4;
210     case CHECK4:
211       NEEDBYTE
212       z->state->sub.check.need = (uLong)NEXTBYTE << 24;
213       z->state->mode = CHECK3;
214     case CHECK3:
215       NEEDBYTE
216       z->state->sub.check.need += (uLong)NEXTBYTE << 16;
217       z->state->mode = CHECK2;
218     case CHECK2:
219       NEEDBYTE
220       z->state->sub.check.need += (uLong)NEXTBYTE << 8;
221       z->state->mode = CHECK1;
222     case CHECK1:
223       NEEDBYTE
224       z->state->sub.check.need += (uLong)NEXTBYTE;
225
226       if (z->state->sub.check.was != z->state->sub.check.need)
227       {
228         z->state->mode = I_BAD;
229         z->msg = (char*)"incorrect data check";
230         z->state->sub.marker = 5;       /* can't try inflateSync */
231         break;
232       }
233       z->state->mode = I_DONE;
234     case I_DONE:
235       return Z_STREAM_END;
236     case I_BAD:
237       return Z_DATA_ERROR;
238     default:
239       return Z_STREAM_ERROR;
240   }
241  empty:
242   if (f != Z_PACKET_FLUSH)
243     return r;
244   z->state->mode = I_BAD;
245   z->msg = (char *)"need more for packet flush";
246   z->state->sub.marker = 0;       /* can try inflateSync */
247   return Z_DATA_ERROR;
248 }