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