0
|
1 /* -*-mode:java; c-basic-offset:2; -*- */
|
|
2 /*
|
|
3 Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
|
|
4
|
|
5 Redistribution and use in source and binary forms, with or without
|
|
6 modification, are permitted provided that the following conditions are met:
|
|
7
|
|
8 1. Redistributions of source code must retain the above copyright notice,
|
|
9 this list of conditions and the following disclaimer.
|
|
10
|
|
11 2. Redistributions in binary form must reproduce the above copyright
|
|
12 notice, this list of conditions and the following disclaimer in
|
|
13 the documentation and/or other materials provided with the distribution.
|
|
14
|
|
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.
|
|
17
|
|
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28 */
|
|
29 /*
|
|
30 * This program is based on zlib-1.1.3, so all credit should go authors
|
|
31 * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
|
|
32 * and contributors of zlib.
|
|
33 */
|
|
34
|
|
35 package com.jcraft.jzlib;
|
|
36
|
|
37 final class InfBlocks {
|
|
38 static final private int MANY = 1440;
|
|
39
|
|
40 // And'ing with mask[n] masks the lower n bits
|
|
41 static final private int[] inflate_mask = {
|
|
42 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
|
|
43 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
|
|
44 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
|
|
45 0x00007fff, 0x0000ffff
|
|
46 };
|
|
47
|
|
48 // Table for deflate from PKZIP's appnote.txt.
|
|
49 static final int[] border = { // Order of the bit length code lengths
|
|
50 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
|
51 };
|
|
52
|
|
53 static final private int Z_OK = 0;
|
|
54 static final private int Z_STREAM_END = 1;
|
|
55 static final private int Z_NEED_DICT = 2;
|
|
56 static final private int Z_ERRNO = -1;
|
|
57 static final private int Z_STREAM_ERROR = -2;
|
|
58 static final private int Z_DATA_ERROR = -3;
|
|
59 static final private int Z_MEM_ERROR = -4;
|
|
60 static final private int Z_BUF_ERROR = -5;
|
|
61 static final private int Z_VERSION_ERROR = -6;
|
|
62
|
|
63 static final private int TYPE = 0; // get type bits (3, including end bit)
|
|
64 static final private int LENS = 1; // get lengths for stored
|
|
65 static final private int STORED = 2; // processing stored block
|
|
66 static final private int TABLE = 3; // get table lengths
|
|
67 static final private int BTREE = 4; // get bit lengths tree for a dynamic block
|
|
68 static final private int DTREE = 5; // get length, distance trees for a dynamic block
|
|
69 static final private int CODES = 6; // processing fixed or dynamic block
|
|
70 static final private int DRY = 7; // output remaining window bytes
|
|
71 static final private int DONE = 8; // finished last block, done
|
|
72 static final private int BAD = 9; // ot a data error--stuck here
|
|
73
|
|
74 int mode; // current inflate_block mode
|
|
75
|
|
76 int left; // if STORED, bytes left to copy
|
|
77
|
|
78 int table; // table lengths (14 bits)
|
|
79 int index; // index into blens (or border)
|
|
80 int[] blens; // bit lengths of codes
|
|
81 int[] bb = new int[1]; // bit length tree depth
|
|
82 int[] tb = new int[1]; // bit length decoding tree
|
|
83
|
|
84 InfCodes codes = new InfCodes(); // if CODES, current state
|
|
85
|
|
86 int last; // true if this block is the last block
|
|
87
|
|
88 // mode independent information
|
|
89 int bitk; // bits in bit buffer
|
|
90 int bitb; // bit buffer
|
|
91 int[] hufts; // single malloc for tree space
|
|
92 byte[] window; // sliding window
|
|
93 int end; // one byte after sliding window
|
|
94 int read; // window read pointer
|
|
95 int write; // window write pointer
|
|
96 Object checkfn; // check function
|
|
97 long check; // check on output
|
|
98
|
|
99 InfTree inftree = new InfTree();
|
|
100
|
|
101 InfBlocks(ZStream z, Object checkfn, int w) {
|
|
102 hufts = new int[MANY * 3];
|
|
103 window = new byte[w];
|
|
104 end = w;
|
|
105 this.checkfn = checkfn;
|
|
106 mode = TYPE;
|
|
107 reset(z, null);
|
|
108 }
|
|
109
|
|
110 void reset(ZStream z, long[] c) {
|
|
111 if (c != null) c[0] = check;
|
|
112
|
|
113 if (mode == BTREE || mode == DTREE) {
|
|
114 }
|
|
115
|
|
116 if (mode == CODES) {
|
|
117 codes.free(z);
|
|
118 }
|
|
119
|
|
120 mode = TYPE;
|
|
121 bitk = 0;
|
|
122 bitb = 0;
|
|
123 read = write = 0;
|
|
124
|
|
125 if (checkfn != null)
|
|
126 z.adler = check = z._adler.adler32(0L, null, 0, 0);
|
|
127 }
|
|
128
|
|
129 int proc(ZStream z, int r) {
|
|
130 int t; // temporary storage
|
|
131 int b; // bit buffer
|
|
132 int k; // bits in bit buffer
|
|
133 int p; // input data pointer
|
|
134 int n; // bytes available there
|
|
135 int q; // output window write pointer
|
|
136 int m; // bytes to end of window or read pointer
|
|
137 // copy input/output information to locals (UPDATE macro restores)
|
|
138 {p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;}
|
|
139 {q = write; m = (int)(q < read ? read - q - 1 : end - q);}
|
|
140
|
|
141 // process input based on current state
|
|
142 while (true) {
|
|
143 switch (mode) {
|
|
144 case TYPE:
|
|
145 while (k < (3)) {
|
|
146 if (n != 0) {
|
|
147 r = Z_OK;
|
|
148 }
|
|
149 else {
|
|
150 bitb = b; bitk = k;
|
|
151 z.avail_in = n;
|
|
152 z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
153 write = q;
|
|
154 return inflate_flush(z, r);
|
|
155 };
|
|
156
|
|
157 n--;
|
|
158
|
|
159 b |= (z.next_in[p++] & 0xff) << k;
|
|
160
|
|
161 k += 8;
|
|
162 }
|
|
163
|
|
164 t = (int)(b & 7);
|
|
165 last = t & 1;
|
|
166
|
|
167 switch (t >>> 1) {
|
|
168 case 0: // stored
|
|
169 {b >>>= (3); k -= (3);}
|
|
170
|
|
171 t = k & 7; // go to byte boundary
|
|
172 {b >>>= (t); k -= (t);}
|
|
173 mode = LENS; // get length of stored block
|
|
174 break;
|
|
175
|
|
176 case 1: { // fixed
|
|
177 int[] bl = new int[1];
|
|
178 int[] bd = new int[1];
|
|
179 int[][] tl = new int[1][];
|
|
180 int[][] td = new int[1][];
|
|
181 InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
|
|
182 codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z);
|
|
183 }
|
|
184
|
|
185 {b >>>= (3); k -= (3);}
|
|
186
|
|
187 mode = CODES;
|
|
188 break;
|
|
189
|
|
190 case 2: // dynamic
|
|
191 {b >>>= (3); k -= (3);}
|
|
192
|
|
193 mode = TABLE;
|
|
194 break;
|
|
195
|
|
196 case 3: // illegal
|
|
197 {b >>>= (3); k -= (3);}
|
|
198
|
|
199 mode = BAD;
|
|
200 z.msg = "invalid block type";
|
|
201 r = Z_DATA_ERROR;
|
|
202 bitb = b; bitk = k;
|
|
203 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
204 write = q;
|
|
205 return inflate_flush(z, r);
|
|
206 }
|
|
207
|
|
208 break;
|
|
209
|
|
210 case LENS:
|
|
211 while (k < (32)) {
|
|
212 if (n != 0) {
|
|
213 r = Z_OK;
|
|
214 }
|
|
215 else {
|
|
216 bitb = b; bitk = k;
|
|
217 z.avail_in = n;
|
|
218 z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
219 write = q;
|
|
220 return inflate_flush(z, r);
|
|
221 };
|
|
222
|
|
223 n--;
|
|
224
|
|
225 b |= (z.next_in[p++] & 0xff) << k;
|
|
226
|
|
227 k += 8;
|
|
228 }
|
|
229
|
|
230 if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) {
|
|
231 mode = BAD;
|
|
232 z.msg = "invalid stored block lengths";
|
|
233 r = Z_DATA_ERROR;
|
|
234 bitb = b; bitk = k;
|
|
235 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
236 write = q;
|
|
237 return inflate_flush(z, r);
|
|
238 }
|
|
239
|
|
240 left = (b & 0xffff);
|
|
241 b = k = 0; // dump bits
|
|
242 mode = left != 0 ? STORED : (last != 0 ? DRY : TYPE);
|
|
243 break;
|
|
244
|
|
245 case STORED:
|
|
246 if (n == 0) {
|
|
247 bitb = b; bitk = k;
|
|
248 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
249 write = q;
|
|
250 return inflate_flush(z, r);
|
|
251 }
|
|
252
|
|
253 if (m == 0) {
|
|
254 if (q == end && read != 0) {
|
|
255 q = 0; m = (int)(q < read ? read - q - 1 : end - q);
|
|
256 }
|
|
257
|
|
258 if (m == 0) {
|
|
259 write = q;
|
|
260 r = inflate_flush(z, r);
|
|
261 q = write; m = (int)(q < read ? read - q - 1 : end - q);
|
|
262
|
|
263 if (q == end && read != 0) {
|
|
264 q = 0; m = (int)(q < read ? read - q - 1 : end - q);
|
|
265 }
|
|
266
|
|
267 if (m == 0) {
|
|
268 bitb = b; bitk = k;
|
|
269 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
270 write = q;
|
|
271 return inflate_flush(z, r);
|
|
272 }
|
|
273 }
|
|
274 }
|
|
275
|
|
276 r = Z_OK;
|
|
277 t = left;
|
|
278
|
|
279 if (t > n) t = n;
|
|
280
|
|
281 if (t > m) t = m;
|
|
282
|
|
283 System.arraycopy(z.next_in, p, window, q, t);
|
|
284 p += t; n -= t;
|
|
285 q += t; m -= t;
|
|
286
|
|
287 if ((left -= t) != 0)
|
|
288 break;
|
|
289
|
|
290 mode = last != 0 ? DRY : TYPE;
|
|
291 break;
|
|
292
|
|
293 case TABLE:
|
|
294 while (k < (14)) {
|
|
295 if (n != 0) {
|
|
296 r = Z_OK;
|
|
297 }
|
|
298 else {
|
|
299 bitb = b; bitk = k;
|
|
300 z.avail_in = n;
|
|
301 z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
302 write = q;
|
|
303 return inflate_flush(z, r);
|
|
304 };
|
|
305
|
|
306 n--;
|
|
307
|
|
308 b |= (z.next_in[p++] & 0xff) << k;
|
|
309
|
|
310 k += 8;
|
|
311 }
|
|
312
|
|
313 table = t = (b & 0x3fff);
|
|
314
|
|
315 if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
|
|
316 mode = BAD;
|
|
317 z.msg = "too many length or distance symbols";
|
|
318 r = Z_DATA_ERROR;
|
|
319 bitb = b; bitk = k;
|
|
320 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
321 write = q;
|
|
322 return inflate_flush(z, r);
|
|
323 }
|
|
324
|
|
325 t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
|
|
326
|
|
327 if (blens == null || blens.length < t) {
|
|
328 blens = new int[t];
|
|
329 }
|
|
330 else {
|
|
331 for (int i = 0; i < t; i++) {blens[i] = 0;}
|
|
332 }
|
|
333
|
|
334 {b >>>= (14); k -= (14);}
|
|
335
|
|
336 index = 0;
|
|
337 mode = BTREE;
|
|
338
|
|
339 case BTREE:
|
|
340 while (index < 4 + (table >>> 10)) {
|
|
341 while (k < (3)) {
|
|
342 if (n != 0) {
|
|
343 r = Z_OK;
|
|
344 }
|
|
345 else {
|
|
346 bitb = b; bitk = k;
|
|
347 z.avail_in = n;
|
|
348 z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
349 write = q;
|
|
350 return inflate_flush(z, r);
|
|
351 };
|
|
352
|
|
353 n--;
|
|
354
|
|
355 b |= (z.next_in[p++] & 0xff) << k;
|
|
356
|
|
357 k += 8;
|
|
358 }
|
|
359
|
|
360 blens[border[index++]] = b & 7;
|
|
361 {b >>>= (3); k -= (3);}
|
|
362 }
|
|
363
|
|
364 while (index < 19) {
|
|
365 blens[border[index++]] = 0;
|
|
366 }
|
|
367
|
|
368 bb[0] = 7;
|
|
369 t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
|
|
370
|
|
371 if (t != Z_OK) {
|
|
372 r = t;
|
|
373
|
|
374 if (r == Z_DATA_ERROR) {
|
|
375 blens = null;
|
|
376 mode = BAD;
|
|
377 }
|
|
378
|
|
379 bitb = b; bitk = k;
|
|
380 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
381 write = q;
|
|
382 return inflate_flush(z, r);
|
|
383 }
|
|
384
|
|
385 index = 0;
|
|
386 mode = DTREE;
|
|
387
|
|
388 case DTREE:
|
|
389 while (true) {
|
|
390 t = table;
|
|
391
|
|
392 if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
|
|
393 break;
|
|
394 }
|
|
395
|
|
396 int[] h;
|
|
397 int i, j, c;
|
|
398 t = bb[0];
|
|
399
|
|
400 while (k < (t)) {
|
|
401 if (n != 0) {
|
|
402 r = Z_OK;
|
|
403 }
|
|
404 else {
|
|
405 bitb = b; bitk = k;
|
|
406 z.avail_in = n;
|
|
407 z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
408 write = q;
|
|
409 return inflate_flush(z, r);
|
|
410 };
|
|
411
|
|
412 n--;
|
|
413
|
|
414 b |= (z.next_in[p++] & 0xff) << k;
|
|
415
|
|
416 k += 8;
|
|
417 }
|
|
418
|
|
419 if (tb[0] == -1) {
|
|
420 //System.err.println("null...");
|
|
421 }
|
|
422
|
|
423 t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
|
|
424 c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];
|
|
425
|
|
426 if (c < 16) {
|
|
427 b >>>= (t); k -= (t);
|
|
428 blens[index++] = c;
|
|
429 }
|
|
430 else { // c == 16..18
|
|
431 i = c == 18 ? 7 : c - 14;
|
|
432 j = c == 18 ? 11 : 3;
|
|
433
|
|
434 while (k < (t + i)) {
|
|
435 if (n != 0) {
|
|
436 r = Z_OK;
|
|
437 }
|
|
438 else {
|
|
439 bitb = b; bitk = k;
|
|
440 z.avail_in = n;
|
|
441 z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
442 write = q;
|
|
443 return inflate_flush(z, r);
|
|
444 };
|
|
445
|
|
446 n--;
|
|
447
|
|
448 b |= (z.next_in[p++] & 0xff) << k;
|
|
449
|
|
450 k += 8;
|
|
451 }
|
|
452
|
|
453 b >>>= (t); k -= (t);
|
|
454 j += (b & inflate_mask[i]);
|
|
455 b >>>= (i); k -= (i);
|
|
456 i = index;
|
|
457 t = table;
|
|
458
|
|
459 if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
|
|
460 (c == 16 && i < 1)) {
|
|
461 blens = null;
|
|
462 mode = BAD;
|
|
463 z.msg = "invalid bit length repeat";
|
|
464 r = Z_DATA_ERROR;
|
|
465 bitb = b; bitk = k;
|
|
466 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
467 write = q;
|
|
468 return inflate_flush(z, r);
|
|
469 }
|
|
470
|
|
471 c = c == 16 ? blens[i - 1] : 0;
|
|
472
|
|
473 do {
|
|
474 blens[i++] = c;
|
|
475 }
|
|
476 while (--j != 0);
|
|
477
|
|
478 index = i;
|
|
479 }
|
|
480 }
|
|
481
|
|
482 tb[0] = -1;
|
|
483 {
|
|
484 int[] bl = new int[1];
|
|
485 int[] bd = new int[1];
|
|
486 int[] tl = new int[1];
|
|
487 int[] td = new int[1];
|
|
488 bl[0] = 9; // must be <= 9 for lookahead assumptions
|
|
489 bd[0] = 6; // must be <= 9 for lookahead assumptions
|
|
490 t = table;
|
|
491 t = inftree.inflate_trees_dynamic(257 + (t & 0x1f),
|
|
492 1 + ((t >> 5) & 0x1f),
|
|
493 blens, bl, bd, tl, td, hufts, z);
|
|
494
|
|
495 if (t != Z_OK) {
|
|
496 if (t == Z_DATA_ERROR) {
|
|
497 blens = null;
|
|
498 mode = BAD;
|
|
499 }
|
|
500
|
|
501 r = t;
|
|
502 bitb = b; bitk = k;
|
|
503 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
504 write = q;
|
|
505 return inflate_flush(z, r);
|
|
506 }
|
|
507
|
|
508 codes.init(bl[0], bd[0], hufts, tl[0], hufts, td[0], z);
|
|
509 }
|
|
510 mode = CODES;
|
|
511
|
|
512 case CODES:
|
|
513 bitb = b; bitk = k;
|
|
514 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
515 write = q;
|
|
516
|
|
517 if ((r = codes.proc(this, z, r)) != Z_STREAM_END) {
|
|
518 return inflate_flush(z, r);
|
|
519 }
|
|
520
|
|
521 r = Z_OK;
|
|
522 codes.free(z);
|
|
523 p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;
|
|
524 q = write; m = (int)(q < read ? read - q - 1 : end - q);
|
|
525
|
|
526 if (last == 0) {
|
|
527 mode = TYPE;
|
|
528 break;
|
|
529 }
|
|
530
|
|
531 mode = DRY;
|
|
532
|
|
533 case DRY:
|
|
534 write = q;
|
|
535 r = inflate_flush(z, r);
|
|
536 q = write; m = (int)(q < read ? read - q - 1 : end - q);
|
|
537
|
|
538 if (read != write) {
|
|
539 bitb = b; bitk = k;
|
|
540 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
541 write = q;
|
|
542 return inflate_flush(z, r);
|
|
543 }
|
|
544
|
|
545 mode = DONE;
|
|
546
|
|
547 case DONE:
|
|
548 r = Z_STREAM_END;
|
|
549 bitb = b; bitk = k;
|
|
550 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
551 write = q;
|
|
552 return inflate_flush(z, r);
|
|
553
|
|
554 case BAD:
|
|
555 r = Z_DATA_ERROR;
|
|
556 bitb = b; bitk = k;
|
|
557 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
558 write = q;
|
|
559 return inflate_flush(z, r);
|
|
560
|
|
561 default:
|
|
562 r = Z_STREAM_ERROR;
|
|
563 bitb = b; bitk = k;
|
|
564 z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
|
|
565 write = q;
|
|
566 return inflate_flush(z, r);
|
|
567 }
|
|
568 }
|
|
569 }
|
|
570
|
|
571 void free(ZStream z) {
|
|
572 reset(z, null);
|
|
573 window = null;
|
|
574 hufts = null;
|
|
575 //ZFREE(z, s);
|
|
576 }
|
|
577
|
|
578 void set_dictionary(byte[] d, int start, int n) {
|
|
579 System.arraycopy(d, start, window, 0, n);
|
|
580 read = write = n;
|
|
581 }
|
|
582
|
|
583 // Returns true if inflate is currently at the end of a block generated
|
|
584 // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
|
|
585 int sync_point() {
|
|
586 return mode == LENS ? 1 : 0;
|
|
587 }
|
|
588
|
|
589 // copy as much as possible from the sliding window to the output area
|
|
590 int inflate_flush(ZStream z, int r) {
|
|
591 int n;
|
|
592 int p;
|
|
593 int q;
|
|
594 // local copies of source and destination pointers
|
|
595 p = z.next_out_index;
|
|
596 q = read;
|
|
597 // compute number of bytes to copy as far as end of window
|
|
598 n = (int)((q <= write ? write : end) - q);
|
|
599
|
|
600 if (n > z.avail_out) n = z.avail_out;
|
|
601
|
|
602 if (n != 0 && r == Z_BUF_ERROR) r = Z_OK;
|
|
603
|
|
604 // update counters
|
|
605 z.avail_out -= n;
|
|
606 z.total_out += n;
|
|
607
|
|
608 // update check information
|
|
609 if (checkfn != null)
|
|
610 z.adler = check = z._adler.adler32(check, window, q, n);
|
|
611
|
|
612 // copy as far as end of window
|
|
613 System.arraycopy(window, q, z.next_out, p, n);
|
|
614 p += n;
|
|
615 q += n;
|
|
616
|
|
617 // see if more to copy at beginning of window
|
|
618 if (q == end) {
|
|
619 // wrap pointers
|
|
620 q = 0;
|
|
621
|
|
622 if (write == end)
|
|
623 write = 0;
|
|
624
|
|
625 // compute bytes to copy
|
|
626 n = write - q;
|
|
627
|
|
628 if (n > z.avail_out) n = z.avail_out;
|
|
629
|
|
630 if (n != 0 && r == Z_BUF_ERROR) r = Z_OK;
|
|
631
|
|
632 // update counters
|
|
633 z.avail_out -= n;
|
|
634 z.total_out += n;
|
|
635
|
|
636 // update check information
|
|
637 if (checkfn != null)
|
|
638 z.adler = check = z._adler.adler32(check, window, q, n);
|
|
639
|
|
640 // copy
|
|
641 System.arraycopy(window, q, z.next_out, p, n);
|
|
642 p += n;
|
|
643 q += n;
|
|
644 }
|
|
645
|
|
646 // update pointers
|
|
647 z.next_out_index = p;
|
|
648 read = q;
|
|
649 // done
|
|
650 return r;
|
|
651 }
|
|
652 }
|