comparison src/com/jcraft/jzlib/Inflate.java @ 357:46c2115ae1c8

update jzlib to a21be20213d66eff15904d925e9b721956a01ef7
author Carl Byington <carl@five-ten-sg.com>
date Fri, 01 Aug 2014 13:34:58 -0700
parents 0ce5cc452d02
children
comparison
equal deleted inserted replaced
356:5e91b559b5fe 357:46c2115ae1c8
1 /* -*-mode:java; c-basic-offset:2; -*- */ 1 /* -*-mode:java; c-basic-offset:2; -*- */
2 /* 2 /*
3 Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 3 Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
4 4
5 Redistribution and use in source and binary forms, with or without 5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met: 6 modification, are permitted provided that the following conditions are met:
7 7
8 1. Redistributions of source code must retain the above copyright notice, 8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer. 9 this list of conditions and the following disclaimer.
10 10
11 2. Redistributions in binary form must reproduce the above copyright 11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in 12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the distribution. 13 the documentation and/or other materials provided with the distribution.
14 14
15 3. The names of the authors may not be used to endorse or promote products 15 3. The names of the authors may not be used to endorse or promote products
16 derived from this software without specific prior written permission. 16 derived from this software without specific prior written permission.
17 17
32 * and contributors of zlib. 32 * and contributors of zlib.
33 */ 33 */
34 34
35 package com.jcraft.jzlib; 35 package com.jcraft.jzlib;
36 36
37 final class Inflate { 37 final class Inflate{
38 38
39 static final private int MAX_WBITS = 15; // 32K LZ77 window 39 static final private int MAX_WBITS=15; // 32K LZ77 window
40 40
41 // preset dictionary flag in zlib header 41 // preset dictionary flag in zlib header
42 static final private int PRESET_DICT = 0x20; 42 static final private int PRESET_DICT=0x20;
43 43
44 static final int Z_NO_FLUSH = 0; 44 static final int Z_NO_FLUSH=0;
45 static final int Z_PARTIAL_FLUSH = 1; 45 static final int Z_PARTIAL_FLUSH=1;
46 static final int Z_SYNC_FLUSH = 2; 46 static final int Z_SYNC_FLUSH=2;
47 static final int Z_FULL_FLUSH = 3; 47 static final int Z_FULL_FLUSH=3;
48 static final int Z_FINISH = 4; 48 static final int Z_FINISH=4;
49 49
50 static final private int Z_DEFLATED = 8; 50 static final private int Z_DEFLATED=8;
51 51
52 static final private int Z_OK = 0; 52 static final private int Z_OK=0;
53 static final private int Z_STREAM_END = 1; 53 static final private int Z_STREAM_END=1;
54 static final private int Z_NEED_DICT = 2; 54 static final private int Z_NEED_DICT=2;
55 static final private int Z_ERRNO = -1; 55 static final private int Z_ERRNO=-1;
56 static final private int Z_STREAM_ERROR = -2; 56 static final private int Z_STREAM_ERROR=-2;
57 static final private int Z_DATA_ERROR = -3; 57 static final private int Z_DATA_ERROR=-3;
58 static final private int Z_MEM_ERROR = -4; 58 static final private int Z_MEM_ERROR=-4;
59 static final private int Z_BUF_ERROR = -5; 59 static final private int Z_BUF_ERROR=-5;
60 static final private int Z_VERSION_ERROR = -6; 60 static final private int Z_VERSION_ERROR=-6;
61 61
62 static final private int METHOD = 0; // waiting for method byte 62 static final private int METHOD=0; // waiting for method byte
63 static final private int FLAG = 1; // waiting for flag byte 63 static final private int FLAG=1; // waiting for flag byte
64 static final private int DICT4 = 2; // four dictionary check bytes to go 64 static final private int DICT4=2; // four dictionary check bytes to go
65 static final private int DICT3 = 3; // three dictionary check bytes to go 65 static final private int DICT3=3; // three dictionary check bytes to go
66 static final private int DICT2 = 4; // two dictionary check bytes to go 66 static final private int DICT2=4; // two dictionary check bytes to go
67 static final private int DICT1 = 5; // one dictionary check byte to go 67 static final private int DICT1=5; // one dictionary check byte to go
68 static final private int DICT0 = 6; // waiting for inflateSetDictionary 68 static final private int DICT0=6; // waiting for inflateSetDictionary
69 static final private int BLOCKS = 7; // decompressing blocks 69 static final private int BLOCKS=7; // decompressing blocks
70 static final private int CHECK4 = 8; // four check bytes to go 70 static final private int CHECK4=8; // four check bytes to go
71 static final private int CHECK3 = 9; // three check bytes to go 71 static final private int CHECK3=9; // three check bytes to go
72 static final private int CHECK2 = 10; // two check bytes to go 72 static final private int CHECK2=10; // two check bytes to go
73 static final private int CHECK1 = 11; // one check byte to go 73 static final private int CHECK1=11; // one check byte to go
74 static final private int DONE = 12; // finished check, done 74 static final private int DONE=12; // finished check, done
75 static final private int BAD = 13; // got an error--stay here 75 static final private int BAD=13; // got an error--stay here
76 76
77 int mode; // current inflate mode 77 static final private int HEAD=14;
78 78 static final private int LENGTH=15;
79 // mode dependent information 79 static final private int TIME=16;
80 int method; // if FLAGS, method byte 80 static final private int OS=17;
81 81 static final private int EXLEN=18;
82 // if CHECK, check values to compare 82 static final private int EXTRA=19;
83 long[] was = new long[1] ; // computed check value 83 static final private int NAME=20;
84 long need; // stream check value 84 static final private int COMMENT=21;
85 85 static final private int HCRC=22;
86 // if BAD, inflateSync's marker bytes count 86 static final private int FLAGS=23;
87 int marker; 87
88 88 static final int INFLATE_ANY=0x40000000;
89 // mode independent information 89
90 int nowrap; // flag for no wrapper 90 int mode; // current inflate mode
91 int wbits; // log2(window size) (8..15, defaults to 15) 91
92 92 // mode dependent information
93 InfBlocks blocks; // current inflate_blocks state 93 int method; // if FLAGS, method byte
94 94
95 int inflateReset(ZStream z) { 95 // if CHECK, check values to compare
96 if (z == null || z.istate == null) return Z_STREAM_ERROR; 96 long was = -1; // computed check value
97 97 long need; // stream check value
98 z.total_in = z.total_out = 0; 98
99 z.msg = null; 99 // if BAD, inflateSync's marker bytes count
100 z.istate.mode = z.istate.nowrap != 0 ? BLOCKS : METHOD; 100 int marker;
101 z.istate.blocks.reset(z, null); 101
102 return Z_OK; 102 // mode independent information
103 } 103 int wrap; // flag for no wrapper
104 104 // 0: no wrapper
105 int inflateEnd(ZStream z) { 105 // 1: zlib header
106 if (blocks != null) 106 // 2: gzip header
107 blocks.free(z); 107 // 4: auto detection
108 108
109 blocks = null; 109 int wbits; // log2(window size) (8..15, defaults to 15)
110 // ZFREE(z, z->state); 110
111 return Z_OK; 111 InfBlocks blocks; // current inflate_blocks state
112 } 112
113 113 private final ZStream z;
114 int inflateInit(ZStream z, int w) { 114
115 z.msg = null; 115 private int flags;
116 blocks = null; 116
117 // handle undocumented nowrap option (no zlib header or check) 117 private int need_bytes = -1;
118 nowrap = 0; 118 private byte[] crcbuf=new byte[4];
119 119
120 if (w < 0) { 120 GZIPHeader gheader = null;
121 w = - w; 121
122 nowrap = 1; 122 int inflateReset(){
123 } 123 if(z == null) return Z_STREAM_ERROR;
124 124
125 // set window size 125 z.total_in = z.total_out = 0;
126 if (w < 8 || w > 15) { 126 z.msg = null;
127 inflateEnd(z); 127 this.mode = HEAD;
128 return Z_STREAM_ERROR; 128 this.need_bytes = -1;
129 } 129 this.blocks.reset();
130 130 return Z_OK;
131 wbits = w; 131 }
132 z.istate.blocks = new InfBlocks(z, 132
133 z.istate.nowrap != 0 ? null : this, 133 int inflateEnd(){
134 1 << w); 134 if(blocks != null){
135 // reset state 135 blocks.free();
136 inflateReset(z); 136 }
137 return Z_OK; 137 return Z_OK;
138 } 138 }
139 139
140 int inflate(ZStream z, int f) { 140 Inflate(ZStream z){
141 int r; 141 this.z=z;
142 int b; 142 }
143 143
144 if (z == null || z.istate == null || z.next_in == null) 144 int inflateInit(int w){
145 return Z_STREAM_ERROR; 145 z.msg = null;
146 146 blocks = null;
147 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 147
148 r = Z_BUF_ERROR; 148 // handle undocumented wrap option (no zlib header or check)
149 149 wrap = 0;
150 while (true) { 150 if(w < 0){
151 //System.out.println("mode: "+z.istate.mode); 151 w = - w;
152 switch (z.istate.mode) { 152 }
153 case METHOD: 153 else if((w&INFLATE_ANY) != 0){
154 if (z.avail_in == 0)return r; r = f; 154 wrap = 4;
155 155 w &= ~INFLATE_ANY;
156 z.avail_in--; z.total_in++; 156 if(w < 48)
157 157 w &= 15;
158 if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != Z_DEFLATED) { 158 }
159 z.istate.mode = BAD; 159 else if((w & ~31) != 0) { // for example, DEF_WBITS + 32
160 z.msg = "unknown compression method"; 160 wrap = 4; // zlib and gzip wrapped data should be accepted.
161 z.istate.marker = 5; // can't try inflateSync 161 w &= 15;
162 break; 162 }
163 } 163 else {
164 164 wrap = (w >> 4) + 1;
165 if ((z.istate.method >> 4) + 8 > z.istate.wbits) { 165 if(w < 48)
166 z.istate.mode = BAD; 166 w &= 15;
167 z.msg = "invalid window size"; 167 }
168 z.istate.marker = 5; // can't try inflateSync 168
169 break; 169 if(w<8 ||w>15){
170 } 170 inflateEnd();
171 171 return Z_STREAM_ERROR;
172 z.istate.mode = FLAG; 172 }
173 173 if(blocks != null && wbits != w){
174 case FLAG: 174 blocks.free();
175 if (z.avail_in == 0)return r; r = f; 175 blocks=null;
176 176 }
177 z.avail_in--; z.total_in++; 177
178 b = (z.next_in[z.next_in_index++]) & 0xff; 178 // set window size
179 179 wbits=w;
180 if ((((z.istate.method << 8) + b) % 31) != 0) { 180
181 z.istate.mode = BAD; 181 this.blocks=new InfBlocks(z, 1<<w);
182 z.msg = "incorrect header check"; 182
183 z.istate.marker = 5; // can't try inflateSync 183 // reset state
184 break; 184 inflateReset();
185 } 185
186 186 return Z_OK;
187 if ((b & PRESET_DICT) == 0) { 187 }
188 z.istate.mode = BLOCKS; 188
189 break; 189 int inflate(int f){
190 } 190 int hold = 0;
191 191
192 z.istate.mode = DICT4; 192 int r;
193 193 int b;
194 case DICT4: 194
195 if (z.avail_in == 0)return r; r = f; 195 if(z == null || z.next_in == null){
196 196 if(f == Z_FINISH && this.mode==HEAD)
197 z.avail_in--; z.total_in++; 197 return Z_OK;
198 z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L; 198 return Z_STREAM_ERROR;
199 z.istate.mode = DICT3; 199 }
200 200
201 case DICT3: 201 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
202 if (z.avail_in == 0)return r; r = f; 202 r = Z_BUF_ERROR;
203 203 while (true){
204 z.avail_in--; z.total_in++; 204
205 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; 205 switch (this.mode){
206 z.istate.mode = DICT2; 206 case HEAD:
207 207 if(wrap==0){
208 case DICT2: 208 this.mode = BLOCKS;
209 if (z.avail_in == 0)return r; r = f; 209 break;
210 210 }
211 z.avail_in--; z.total_in++; 211
212 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; 212 try { r=readBytes(2, r, f); }
213 z.istate.mode = DICT1; 213 catch(Return e){ return e.r; }
214 214
215 case DICT1: 215 if((wrap == 4 || (wrap&2)!=0) &&
216 if (z.avail_in == 0)return r; r = f; 216 this.need == 0x8b1fL) { // gzip header
217 217 if(wrap == 4){
218 z.avail_in--; z.total_in++; 218 wrap = 2;
219 z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); 219 }
220 z.adler = z.istate.need; 220 z.adler=new CRC32();
221 z.istate.mode = DICT0; 221 checksum(2, this.need);
222 return Z_NEED_DICT; 222
223 223 if(gheader==null)
224 case DICT0: 224 gheader=new GZIPHeader();
225 z.istate.mode = BAD; 225
226 z.msg = "need dictionary"; 226 this.mode = FLAGS;
227 z.istate.marker = 0; // can try inflateSync 227 break;
228 return Z_STREAM_ERROR; 228 }
229 229
230 case BLOCKS: 230 if((wrap&2) != 0){
231 r = z.istate.blocks.proc(z, r); 231 this.mode = BAD;
232 232 z.msg = "incorrect header check";
233 if (r == Z_DATA_ERROR) { 233 break;
234 z.istate.mode = BAD; 234 }
235 z.istate.marker = 0; // can try inflateSync 235
236 break; 236 flags = 0;
237 } 237
238 238 this.method = ((int)this.need)&0xff;
239 if (r == Z_OK) { 239 b=((int)(this.need>>8))&0xff;
240 r = f; 240
241 } 241 if(((wrap&1)==0 || // check if zlib header allowed
242 242 (((this.method << 8)+b) % 31)!=0) &&
243 if (r != Z_STREAM_END) { 243 (this.method&0xf)!=Z_DEFLATED){
244 return r; 244 if(wrap == 4){
245 } 245 z.next_in_index -= 2;
246 246 z.avail_in += 2;
247 r = f; 247 z.total_in -= 2;
248 z.istate.blocks.reset(z, z.istate.was); 248 wrap = 0;
249 249 this.mode = BLOCKS;
250 if (z.istate.nowrap != 0) { 250 break;
251 z.istate.mode = DONE; 251 }
252 break; 252 this.mode = BAD;
253 } 253 z.msg = "incorrect header check";
254 254 // since zlib 1.2, it is allowted to inflateSync for this case.
255 z.istate.mode = CHECK4; 255 /*
256 256 this.marker = 5; // can't try inflateSync
257 case CHECK4: 257 */
258 if (z.avail_in == 0)return r; r = f; 258 break;
259 259 }
260 z.avail_in--; z.total_in++; 260
261 z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L; 261 if((this.method&0xf)!=Z_DEFLATED){
262 z.istate.mode = CHECK3; 262 this.mode = BAD;
263 263 z.msg="unknown compression method";
264 case CHECK3: 264 // since zlib 1.2, it is allowted to inflateSync for this case.
265 if (z.avail_in == 0)return r; r = f; 265 /*
266 266 this.marker = 5; // can't try inflateSync
267 z.avail_in--; z.total_in++; 267 */
268 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; 268 break;
269 z.istate.mode = CHECK2; 269 }
270 270
271 case CHECK2: 271 if(wrap == 4){
272 if (z.avail_in == 0)return r; r = f; 272 wrap = 1;
273 273 }
274 z.avail_in--; z.total_in++; 274
275 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; 275 if((this.method>>4)+8>this.wbits){
276 z.istate.mode = CHECK1; 276 this.mode = BAD;
277 277 z.msg="invalid window size";
278 case CHECK1: 278 // since zlib 1.2, it is allowted to inflateSync for this case.
279 if (z.avail_in == 0)return r; r = f; 279 /*
280 280 this.marker = 5; // can't try inflateSync
281 z.avail_in--; z.total_in++; 281 */
282 z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); 282 break;
283 283 }
284 if (((int)(z.istate.was[0])) != ((int)(z.istate.need))) { 284
285 z.istate.mode = BAD; 285 z.adler=new Adler32();
286 z.msg = "incorrect data check"; 286
287 z.istate.marker = 5; // can't try inflateSync 287 if((b&PRESET_DICT)==0){
288 break; 288 this.mode = BLOCKS;
289 } 289 break;
290 290 }
291 z.istate.mode = DONE; 291 this.mode = DICT4;
292 292 case DICT4:
293 case DONE: 293
294 return Z_STREAM_END; 294 if(z.avail_in==0)return r;r=f;
295 295
296 case BAD: 296 z.avail_in--; z.total_in++;
297 return Z_DATA_ERROR; 297 this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
298 298 this.mode=DICT3;
299 default: 299 case DICT3:
300 return Z_STREAM_ERROR; 300
301 if(z.avail_in==0)return r;r=f;
302
303 z.avail_in--; z.total_in++;
304 this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
305 this.mode=DICT2;
306 case DICT2:
307
308 if(z.avail_in==0)return r;r=f;
309
310 z.avail_in--; z.total_in++;
311 this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
312 this.mode=DICT1;
313 case DICT1:
314
315 if(z.avail_in==0)return r;r=f;
316
317 z.avail_in--; z.total_in++;
318 this.need += (z.next_in[z.next_in_index++]&0xffL);
319 z.adler.reset(this.need);
320 this.mode = DICT0;
321 return Z_NEED_DICT;
322 case DICT0:
323 this.mode = BAD;
324 z.msg = "need dictionary";
325 this.marker = 0; // can try inflateSync
326 return Z_STREAM_ERROR;
327 case BLOCKS:
328 r = this.blocks.proc(r);
329 if(r == Z_DATA_ERROR){
330 this.mode = BAD;
331 this.marker = 0; // can try inflateSync
332 break;
333 }
334 if(r == Z_OK){
335 r = f;
336 }
337 if(r != Z_STREAM_END){
338 return r;
339 }
340 r = f;
341 this.was=z.adler.getValue();
342 this.blocks.reset();
343 if(this.wrap==0){
344 this.mode=DONE;
345 break;
346 }
347 this.mode=CHECK4;
348 case CHECK4:
349
350 if(z.avail_in==0)return r;r=f;
351
352 z.avail_in--; z.total_in++;
353 this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
354 this.mode=CHECK3;
355 case CHECK3:
356
357 if(z.avail_in==0)return r;r=f;
358
359 z.avail_in--; z.total_in++;
360 this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
361 this.mode = CHECK2;
362 case CHECK2:
363
364 if(z.avail_in==0)return r;r=f;
365
366 z.avail_in--; z.total_in++;
367 this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
368 this.mode = CHECK1;
369 case CHECK1:
370
371 if(z.avail_in==0)return r;r=f;
372
373 z.avail_in--; z.total_in++;
374 this.need+=(z.next_in[z.next_in_index++]&0xffL);
375
376 if(flags!=0){ // gzip
377 this.need = ((this.need&0xff000000)>>24 |
378 (this.need&0x00ff0000)>>8 |
379 (this.need&0x0000ff00)<<8 |
380 (this.need&0x0000ffff)<<24)&0xffffffffL;
381 }
382
383 if(((int)(this.was)) != ((int)(this.need))){
384 z.msg = "incorrect data check";
385 // chack is delayed
386 /*
387 this.mode = BAD;
388 this.marker = 5; // can't try inflateSync
389 break;
390 */
391 }
392 else if(flags!=0 && gheader!=null){
393 gheader.crc = this.need;
394 }
395
396 this.mode = LENGTH;
397 case LENGTH:
398 if (wrap!=0 && flags!=0) {
399
400 try { r=readBytes(4, r, f); }
401 catch(Return e){ return e.r; }
402
403 if(z.msg!=null && z.msg.equals("incorrect data check")){
404 this.mode = BAD;
405 this.marker = 5; // can't try inflateSync
406 break;
407 }
408
409 if (this.need != (z.total_out & 0xffffffffL)) {
410 z.msg = "incorrect length check";
411 this.mode = BAD;
412 break;
413 }
414 z.msg = null;
415 }
416 else {
417 if(z.msg!=null && z.msg.equals("incorrect data check")){
418 this.mode = BAD;
419 this.marker = 5; // can't try inflateSync
420 break;
421 }
422 }
423
424 this.mode = DONE;
425 case DONE:
426 return Z_STREAM_END;
427 case BAD:
428 return Z_DATA_ERROR;
429
430 case FLAGS:
431
432 try { r=readBytes(2, r, f); }
433 catch(Return e){ return e.r; }
434
435 flags = ((int)this.need)&0xffff;
436
437 if ((flags & 0xff) != Z_DEFLATED) {
438 z.msg = "unknown compression method";
439 this.mode = BAD;
440 break;
441 }
442 if ((flags & 0xe000)!=0) {
443 z.msg = "unknown header flags set";
444 this.mode = BAD;
445 break;
446 }
447
448 if ((flags & 0x0200)!=0){
449 checksum(2, this.need);
450 }
451
452 this.mode = TIME;
453
454 case TIME:
455 try { r=readBytes(4, r, f); }
456 catch(Return e){ return e.r; }
457 if(gheader!=null)
458 gheader.time = this.need;
459 if ((flags & 0x0200)!=0){
460 checksum(4, this.need);
461 }
462 this.mode = OS;
463 case OS:
464 try { r=readBytes(2, r, f); }
465 catch(Return e){ return e.r; }
466 if(gheader!=null){
467 gheader.xflags = ((int)this.need)&0xff;
468 gheader.os = (((int)this.need)>>8)&0xff;
469 }
470 if ((flags & 0x0200)!=0){
471 checksum(2, this.need);
472 }
473 this.mode = EXLEN;
474 case EXLEN:
475 if ((flags & 0x0400)!=0) {
476 try { r=readBytes(2, r, f); }
477 catch(Return e){ return e.r; }
478 if(gheader!=null){
479 gheader.extra = new byte[((int)this.need)&0xffff];
480 }
481 if ((flags & 0x0200)!=0){
482 checksum(2, this.need);
483 }
484 }
485 else if(gheader!=null){
486 gheader.extra=null;
487 }
488 this.mode = EXTRA;
489
490 case EXTRA:
491 if ((flags & 0x0400)!=0) {
492 try {
493 r=readBytes(r, f);
494 if(gheader!=null){
495 byte[] foo = tmp_string.toByteArray();
496 tmp_string=null;
497 if(foo.length == gheader.extra.length){
498 System.arraycopy(foo, 0, gheader.extra, 0, foo.length);
499 }
500 else{
501 z.msg = "bad extra field length";
502 this.mode = BAD;
503 break;
504 }
301 } 505 }
302 } 506 }
303 } 507 catch(Return e){ return e.r; }
304 508 }
305 509 else if(gheader!=null){
306 int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) { 510 gheader.extra=null;
307 int index = 0; 511 }
308 int length = dictLength; 512 this.mode = NAME;
309 513 case NAME:
310 if (z == null || z.istate == null || z.istate.mode != DICT0) 514 if ((flags & 0x0800)!=0) {
311 return Z_STREAM_ERROR; 515 try {
312 516 r=readString(r, f);
313 if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler) { 517 if(gheader!=null){
314 return Z_DATA_ERROR; 518 gheader.name=tmp_string.toByteArray();
315 }
316
317 z.adler = z._adler.adler32(0, null, 0, 0);
318
319 if (length >= (1 << z.istate.wbits)) {
320 length = (1 << z.istate.wbits) - 1;
321 index = dictLength - length;
322 }
323
324 z.istate.blocks.set_dictionary(dictionary, index, length);
325 z.istate.mode = BLOCKS;
326 return Z_OK;
327 }
328
329 static private byte[] mark = { (byte)0, (byte)0, (byte)0xff, (byte)0xff};
330
331 int inflateSync(ZStream z) {
332 int n; // number of bytes to look at
333 int p; // pointer to bytes
334 int m; // number of marker bytes found in a row
335 long r, w; // temporaries to save total_in and total_out
336
337 // set up
338 if (z == null || z.istate == null)
339 return Z_STREAM_ERROR;
340
341 if (z.istate.mode != BAD) {
342 z.istate.mode = BAD;
343 z.istate.marker = 0;
344 }
345
346 if ((n = z.avail_in) == 0)
347 return Z_BUF_ERROR;
348
349 p = z.next_in_index;
350 m = z.istate.marker;
351
352 // search
353 while (n != 0 && m < 4) {
354 if (z.next_in[p] == mark[m]) {
355 m++;
356 } 519 }
357 else if (z.next_in[p] != 0) { 520 tmp_string=null;
358 m = 0; 521 }
522 catch(Return e){ return e.r; }
523 }
524 else if(gheader!=null){
525 gheader.name=null;
526 }
527 this.mode = COMMENT;
528 case COMMENT:
529 if ((flags & 0x1000)!=0) {
530 try {
531 r=readString(r, f);
532 if(gheader!=null){
533 gheader.comment=tmp_string.toByteArray();
359 } 534 }
360 else { 535 tmp_string=null;
361 m = 4 - m; 536 }
362 } 537 catch(Return e){ return e.r; }
363 538 }
364 p++; n--; 539 else if(gheader!=null){
365 } 540 gheader.comment=null;
366 541 }
367 // restore 542 this.mode = HCRC;
368 z.total_in += p - z.next_in_index; 543 case HCRC:
369 z.next_in_index = p; 544 if ((flags & 0x0200)!=0) {
370 z.avail_in = n; 545 try { r=readBytes(2, r, f); }
371 z.istate.marker = m; 546 catch(Return e){ return e.r; }
372 547 if(gheader!=null){
373 // return no joy or set up to restart on a new block 548 gheader.hcrc=(int)(this.need&0xffff);
374 if (m != 4) { 549 }
375 return Z_DATA_ERROR; 550 if(this.need != (z.adler.getValue()&0xffffL)){
376 } 551 this.mode = BAD;
377 552 z.msg = "header crc mismatch";
378 r = z.total_in; w = z.total_out; 553 this.marker = 5; // can't try inflateSync
379 inflateReset(z); 554 break;
380 z.total_in = r; z.total_out = w; 555 }
381 z.istate.mode = BLOCKS; 556 }
382 return Z_OK; 557 z.adler = new CRC32();
383 } 558
384 559 this.mode = BLOCKS;
385 // Returns true if inflate is currently at the end of a block generated 560 break;
386 // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 561 default:
387 // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH 562 return Z_STREAM_ERROR;
388 // but removes the length bytes of the resulting empty stored block. When 563 }
389 // decompressing, PPP checks that at the end of input packet, inflate is 564 }
390 // waiting for these length bytes. 565 }
391 int inflateSyncPoint(ZStream z) { 566
392 if (z == null || z.istate == null || z.istate.blocks == null) 567 int inflateSetDictionary(byte[] dictionary, int dictLength){
393 return Z_STREAM_ERROR; 568 if(z==null || (this.mode != DICT0 && this.wrap != 0)){
394 569 return Z_STREAM_ERROR;
395 return z.istate.blocks.sync_point(); 570 }
396 } 571
572 int index=0;
573 int length = dictLength;
574
575 if(this.mode==DICT0){
576 long adler_need=z.adler.getValue();
577 z.adler.reset();
578 z.adler.update(dictionary, 0, dictLength);
579 if(z.adler.getValue()!=adler_need){
580 return Z_DATA_ERROR;
581 }
582 }
583
584 z.adler.reset();
585
586 if(length >= (1<<this.wbits)){
587 length = (1<<this.wbits)-1;
588 index=dictLength - length;
589 }
590 this.blocks.set_dictionary(dictionary, index, length);
591 this.mode = BLOCKS;
592 return Z_OK;
593 }
594
595 static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff};
596
597 int inflateSync(){
598 int n; // number of bytes to look at
599 int p; // pointer to bytes
600 int m; // number of marker bytes found in a row
601 long r, w; // temporaries to save total_in and total_out
602
603 // set up
604 if(z == null)
605 return Z_STREAM_ERROR;
606 if(this.mode != BAD){
607 this.mode = BAD;
608 this.marker = 0;
609 }
610 if((n=z.avail_in)==0)
611 return Z_BUF_ERROR;
612
613 p=z.next_in_index;
614 m=this.marker;
615 // search
616 while (n!=0 && m < 4){
617 if(z.next_in[p] == mark[m]){
618 m++;
619 }
620 else if(z.next_in[p]!=0){
621 m = 0;
622 }
623 else{
624 m = 4 - m;
625 }
626 p++; n--;
627 }
628
629 // restore
630 z.total_in += p-z.next_in_index;
631 z.next_in_index = p;
632 z.avail_in = n;
633 this.marker = m;
634
635 // return no joy or set up to restart on a new block
636 if(m != 4){
637 return Z_DATA_ERROR;
638 }
639 r=z.total_in; w=z.total_out;
640 inflateReset();
641 z.total_in=r; z.total_out = w;
642 this.mode = BLOCKS;
643
644 return Z_OK;
645 }
646
647 // Returns true if inflate is currently at the end of a block generated
648 // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
649 // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
650 // but removes the length bytes of the resulting empty stored block. When
651 // decompressing, PPP checks that at the end of input packet, inflate is
652 // waiting for these length bytes.
653 int inflateSyncPoint(){
654 if(z == null || this.blocks == null)
655 return Z_STREAM_ERROR;
656 return this.blocks.sync_point();
657 }
658
659 private int readBytes(int n, int r, int f) throws Return{
660 if(need_bytes == -1){
661 need_bytes=n;
662 this.need=0;
663 }
664 while(need_bytes>0){
665 if(z.avail_in==0){ throw new Return(r); }; r=f;
666 z.avail_in--; z.total_in++;
667 this.need = this.need |
668 ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8));
669 need_bytes--;
670 }
671 if(n==2){
672 this.need&=0xffffL;
673 }
674 else if(n==4) {
675 this.need&=0xffffffffL;
676 }
677 need_bytes=-1;
678 return r;
679 }
680 class Return extends Exception{
681 int r;
682 Return(int r){this.r=r; }
683 }
684
685 private java.io.ByteArrayOutputStream tmp_string = null;
686 private int readString(int r, int f) throws Return{
687 if(tmp_string == null){
688 tmp_string=new java.io.ByteArrayOutputStream();
689 }
690 int b=0;
691 do {
692 if(z.avail_in==0){ throw new Return(r); }; r=f;
693 z.avail_in--; z.total_in++;
694 b = z.next_in[z.next_in_index];
695 if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1);
696 z.adler.update(z.next_in, z.next_in_index, 1);
697 z.next_in_index++;
698 }while(b!=0);
699 return r;
700 }
701
702 private int readBytes(int r, int f) throws Return{
703 if(tmp_string == null){
704 tmp_string=new java.io.ByteArrayOutputStream();
705 }
706 int b=0;
707 while(this.need>0){
708 if(z.avail_in==0){ throw new Return(r); }; r=f;
709 z.avail_in--; z.total_in++;
710 b = z.next_in[z.next_in_index];
711 tmp_string.write(z.next_in, z.next_in_index, 1);
712 z.adler.update(z.next_in, z.next_in_index, 1);
713 z.next_in_index++;
714 this.need--;
715 }
716 return r;
717 }
718
719 private void checksum(int n, long v){
720 for(int i=0; i<n; i++){
721 crcbuf[i]=(byte)(v&0xff);
722 v>>=8;
723 }
724 z.adler.update(crcbuf, 0, n);
725 }
726
727 public GZIPHeader getGZIPHeader(){
728 return gheader;
729 }
730
731 boolean inParsingHeader(){
732 switch(mode){
733 case HEAD:
734 case DICT4:
735 case DICT3:
736 case DICT2:
737 case DICT1:
738 case FLAGS:
739 case TIME:
740 case OS:
741 case EXLEN:
742 case EXTRA:
743 case NAME:
744 case COMMENT:
745 case HCRC:
746 return true;
747 default:
748 return false;
749 }
750 }
397 } 751 }